Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions
nsMsgBinHex.h File Reference
#include "nsFileSpec.h"
#include "nsFileStream.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _binhex_header
struct  _binhex_encode_object
union  longbuf
struct  _binhex_decode_object

Defines

#define BINHEX_STATE_START   0
#define BINHEX_STATE_FNAME   1
#define BINHEX_STATE_HEADER   2
#define BINHEX_STATE_HCRC   3
#define BINHEX_STATE_DFORK   4
#define BINHEX_STATE_DCRC   5
#define BINHEX_STATE_RFORK   6
#define BINHEX_STATE_RCRC   7
#define BINHEX_STATE_FINISH   8
#define BINHEX_STATE_DONE   9
#define MAX_BUFF_SIZE   256

Typedefs

typedef struct _binhex_header binhex_header
typedef struct
_binhex_encode_object 
binhex_encode_object
typedef struct
_binhex_decode_object 
binhex_decode_object

Functions

XP_BEGIN_PROTOS int binhex_encode_init (binhex_encode_object *p_bh_encode_obj)
int binhex_encode_next (binhex_encode_object *p_bh_encode_obj, char *in_buff, int32 in_size, char *out_buff, int32 buff_size, int32 *real_size)
int binhex_encode_end (binhex_encode_object *p_bh_encode_obj, XP_Bool is_aborting)
int binhex_reencode_head (binhex_encode_object *p_bh_encode_obj, char *outbuff, int32 buff_size, int32 *real_size)
int binhex_decode_init (binhex_decode_object *p_bh_decode_env)
int binhex_decode_next (binhex_decode_object *p_bh_decode_env, const char *in_buff, int32 buff_size)
int binhex_decode_end (binhex_decode_object *p_bh_decode_env, XP_Bool is_aborting)

Class Documentation

struct _binhex_header

Definition at line 72 of file nsMsgBinHex.h.

Class Members
PRUint32 creator
uint32 creator
PRInt32 dlen
int32 dlen
PRUint16 flags
uint16 flags
PRInt32 rlen
int32 rlen
PRUint32 type
uint32 type
struct _binhex_encode_object

Definition at line 80 of file nsMsgBinHex.h.

Collaboration diagram for _binhex_encode_object:
Class Members
char c
unsigned long CRC
binhex_header head
char * inbuff
int line_length
char name
char newline
char * outbuff
char overflow
int pos_inbuff
int pos_outbuff
int s_inbuff
int s_outbuff
int s_overflow
char saved_bits
int state
int state86
union longbuf

Definition at line 115 of file nsMsgBinHex.h.

Class Members
unsigned char c
PRUint32 val
uint32 val
struct _binhex_decode_object

Definition at line 124 of file nsMsgBinHex.h.

Collaboration diagram for _binhex_decode_object:
Class Members
int32 count
uint16 CRC
int16 donepos
uint16 fileCRC
nsIOFileStream * fileId
binhex_header head
char * inbuff
int16 inCRC
int16 marker
nsFileSpec * name
longbuf octetbuf
int16 octetin
char outbuff
int32 pos_inbuff
int32 pos_outbuff
unsigned char rlebuf
int32 s_inbuff
int state

Define Documentation

Definition at line 62 of file nsMsgBinHex.h.

Definition at line 61 of file nsMsgBinHex.h.

Definition at line 66 of file nsMsgBinHex.h.

Definition at line 65 of file nsMsgBinHex.h.

Definition at line 58 of file nsMsgBinHex.h.

Definition at line 60 of file nsMsgBinHex.h.

Definition at line 59 of file nsMsgBinHex.h.

Definition at line 64 of file nsMsgBinHex.h.

Definition at line 63 of file nsMsgBinHex.h.

Definition at line 57 of file nsMsgBinHex.h.

#define MAX_BUFF_SIZE   256

Definition at line 122 of file nsMsgBinHex.h.


Typedef Documentation

typedef struct _binhex_header binhex_header

Function Documentation

int binhex_decode_end ( binhex_decode_object p_bh_decode_env,
XP_Bool  is_aborting 
)

Definition at line 1023 of file nsMsgBinHex.cpp.

{
#ifdef XP_MAC
       if (p_bh_decode_obj->fileId)
       {
              FSClose(p_bh_decode_obj->fileId);
              p_bh_decode_obj->fileId = 0;
              
              if (is_aborting)
              {
                     HDelete(p_bh_decode_obj->vRefNum, 
                                   p_bh_decode_obj->parID, 
                                   (unsigned char*)p_bh_decode_obj->name);
              }
       }
       
#else

       if (p_bh_decode_obj->fileId)
       {
              p_bh_decode_obj->fileId->close();
              
              if (is_aborting)
                     p_bh_decode_obj->name->Delete(PR_FALSE);
       }
       FREEIF(p_bh_decode_obj->name);
#endif

       return NOERR;
}

Here is the call graph for this function:

Definition at line 520 of file nsMsgBinHex.cpp.

{
       memset(p_bh_decode_obj, 0, sizeof(binhex_decode_object));
       
       p_bh_decode_obj->octetin    = 26;
       p_bh_decode_obj->donepos    = 3;

       return NOERR;
}

Here is the call graph for this function:

int binhex_decode_next ( binhex_decode_object p_bh_decode_env,
const char *  in_buff,
int32  buff_size 
)

Definition at line 864 of file nsMsgBinHex.cpp.

{
       int    found_start;
       int octetpos, c = 0;
       uint32               val;
       
       /*
       **     reset the buff first. 
       */
       p_bh_decode_obj->inbuff     = (char*)in_buff;
       p_bh_decode_obj->s_inbuff   = buff_size;
       p_bh_decode_obj->pos_inbuff = 0;
       
       /*
       **     if it is the first time, seek to the right start place. 
       */
       if (p_bh_decode_obj->state == BINHEX_STATE_START)
       {
               found_start = FALSE;
              /*
              **     go through the line, until we get a ':'
              */
              while (p_bh_decode_obj->pos_inbuff < p_bh_decode_obj->s_inbuff)
              {
                     c = p_bh_decode_obj->inbuff[p_bh_decode_obj->pos_inbuff++];
                     while (c == CR || c == LF)
                     {
                            if (p_bh_decode_obj->pos_inbuff >= p_bh_decode_obj->s_inbuff)
                                   break;
                                                                                                                
                            c = p_bh_decode_obj->inbuff[p_bh_decode_obj->pos_inbuff++];
                            if (c == ':')
                            {
                                   found_start = TRUE;
                                   break;
                            }
                     }
                     if (found_start)     break;        /* we got the start point.                       */
              }
              
              if (p_bh_decode_obj->pos_inbuff >= p_bh_decode_obj->s_inbuff)
                     return NOERR;               /* we meet buff end before we get the     */
                                                               /* start point, wait till next fills.     */
              
              if (c != ':')
                     return errDecoding;         /* can't find the start character. */
       }
       
       /*
       **     run - through the in-stream now.
       */
       while (p_bh_decode_obj->state >= 0 && 
                 p_bh_decode_obj->state < BINHEX_STATE_DONE) 
       {
              /* fill in octetbuf */
              do 
              {
                     if (p_bh_decode_obj->pos_inbuff >= p_bh_decode_obj->s_inbuff)
                            return NOERR;               /* end of buff, go on for the nxet calls. */
                                   
                     c = get_next_char(p_bh_decode_obj);
                     if (c == 0)
                            return NOERR;
                             
                     if ((val = BHEXVAL(c)) == -1) 
                     {
                            /*
                            ** we incount an invalid character.
                            */
                            if (c) 
                            {
                                   /*
                                   ** rolling back.
                                   */
                                   p_bh_decode_obj->donepos --;
                                   if (p_bh_decode_obj->octetin >= 14)              p_bh_decode_obj->donepos--;
                                   if (p_bh_decode_obj->octetin >= 20)       p_bh_decode_obj->donepos--;
                            }
                            break;
                     }
                     p_bh_decode_obj->octetbuf.val |= val << p_bh_decode_obj->octetin;
              } 
              while ((p_bh_decode_obj->octetin -= 6) > 2);
                     
              /* handle decoded characters -- run length encoding (rle) detection */

#ifndef XP_MAC              
              p_bh_decode_obj->octetbuf.val 
                     = ntohl(p_bh_decode_obj->octetbuf.val);
#endif

              for (octetpos = 0; octetpos < p_bh_decode_obj->donepos; ++octetpos) 
              {
                     c = p_bh_decode_obj->octetbuf.c[octetpos];
                     
                     if (c == 0x90 && !p_bh_decode_obj->marker++) 
                            continue;
                                          
                     if (p_bh_decode_obj->marker) 
                     {
                            if (c == 0) 
                            {
                                   p_bh_decode_obj->rlebuf = 0x90;
                                   binhex_process(p_bh_decode_obj);
                            } 
                            else 
                            {
                                   while (--c > 0)                           /* we are in the run lenght mode */ 
                                   {
                                          binhex_process(p_bh_decode_obj);
                                   }
                            }
                            p_bh_decode_obj->marker = 0;
                     } 
                     else 
                     {
                            p_bh_decode_obj->rlebuf = (unsigned char) c;
                            binhex_process(p_bh_decode_obj);
                     }
                     
                     
                     if (p_bh_decode_obj->state >= BINHEX_STATE_FINISH) 
                            break;
              }
              
              /* prepare for next 3 characters.  */
              if (p_bh_decode_obj->donepos < 3 && p_bh_decode_obj->state < BINHEX_STATE_FINISH) 
                     p_bh_decode_obj->state = errDecoding;
                                   
              p_bh_decode_obj->octetin           = 26;
              p_bh_decode_obj->octetbuf.val      = 0;
       }
       
       /* 
       **     Error clean-ups 
       */
       if (p_bh_decode_obj->state < 0 && p_bh_decode_obj->fileId) 
       {
#ifdef XP_MAC
              FSClose(p_bh_decode_obj->fileId);
              p_bh_decode_obj->fileId = 0;
              HDelete(p_bh_decode_obj->vRefNum, 
                            p_bh_decode_obj->parID, 
                            (unsigned char*)p_bh_decode_obj->name);
#else
              p_bh_decode_obj->fileId->close();
              delete p_bh_decode_obj->fileId;
              p_bh_decode_obj->name->delete(PR_FALSE);
#endif
       }
       
       
       return        p_bh_decode_obj->state < 0                                ? (p_bh_decode_obj->state) : 
                     p_bh_decode_obj->state >= BINHEX_STATE_FINISH ? errDone : NOERR;
}

Here is the call graph for this function:

int binhex_encode_end ( binhex_encode_object p_bh_encode_obj,
XP_Bool  is_aborting 
)

Definition at line 484 of file nsMsgBinHex.cpp.

{
       return NOERR;
}

Definition at line 241 of file nsMsgBinHex.cpp.

{      
       /*
       ** init all the status.
       */
       memset(p_bh_encode_obj, 0, sizeof(binhex_encode_object));
       
       p_bh_encode_obj->line_length = 1;
       
       p_bh_encode_obj->newline[0] = 2;
       p_bh_encode_obj->newline[1] = CR;
       p_bh_encode_obj->newline[2] = LF;         /*     to confirm with rfc822, use CRLF   */
       
       return NOERR;
}

Here is the call graph for this function:

int binhex_encode_next ( binhex_encode_object p_bh_encode_obj,
char *  in_buff,
int32  in_size,
char *  out_buff,
int32  buff_size,
int32 real_size 
)

Definition at line 257 of file nsMsgBinHex.cpp.

{
       int status = 0;
       /*
       ** setup the buffer information.
       */
       p_bh_encode_obj->outbuff     = out_buff;
       p_bh_encode_obj->s_outbuff   = buff_size;
       p_bh_encode_obj->pos_outbuff = 0;
       
       /*
       ** copy over the left over from last time.
       */
       if (p_bh_encode_obj->s_overflow)
       {
              memcpy(p_bh_encode_obj->overflow, 
                     p_bh_encode_obj->outbuff, 
                     p_bh_encode_obj->s_overflow);
                            
              p_bh_encode_obj->pos_outbuff = p_bh_encode_obj->s_overflow;
              p_bh_encode_obj->s_overflow = 0;
       } 
       
       /*
       **     Jump to the right state.
       */
       if ( p_bh_encode_obj->state < BINHEX_STATE_DONE)
       {
              if (in_buff == NULL && in_size == 0)
              {
                     /* this is our special token of end of a part, time to append crc codes      */
                     if (p_bh_encode_obj->state != BINHEX_STATE_FINISH)                    
                            status = binhex_encode_end_a_part(p_bh_encode_obj);
                     else
                            status = binhex_encode_finishing(p_bh_encode_obj);
                     
                     p_bh_encode_obj->state += 2;              /* so we can jump to the next state.*/
              }
              else
              {
                     if  (p_bh_encode_obj->state == BINHEX_STATE_START)
                     {
                            PL_strcpy(p_bh_encode_obj->outbuff + p_bh_encode_obj->pos_outbuff,
                                                 "\r\n(This file must be converted with BinHex 4.0)\r\n\r\n:");
                            p_bh_encode_obj->pos_outbuff += 52;
                     
                            p_bh_encode_obj->state = BINHEX_STATE_HEADER;
                            
                            memcpy(p_bh_encode_obj->name,
                                   in_buff, 
                                   in_size);     
                     }
                     else if  (p_bh_encode_obj->state == BINHEX_STATE_HEADER)
                     {
                            memcpy(&(p_bh_encode_obj->head),
                                   in_buff, 
                                   sizeof(binhex_header));
                            
                            if (in_size == 20)   /* in the platform that alignment is 4-bytes. */
                                   in_size = 18;
                                                 
                            p_bh_encode_obj->head.dlen = 0;           /* we just can't trust the dlen from      */
                                                                                           /* apple double decoder told us.          */
                                                                                           /* do our own counting.                                 */                          
                     }                    
                     else if  (p_bh_encode_obj->state == BINHEX_STATE_DFORK)
                     {
                            if (p_bh_encode_obj->head.dlen == 0)
                            {
                                   p_bh_encode_obj->c[0] = in_buff[0];       /* save the first 2 bytes, in case  */
                                   p_bh_encode_obj->c[1] = in_buff[1]; /* head and data share 1 code block */
                            }
                            p_bh_encode_obj->head.dlen += in_size;
                     }
                     
                     status        = binhex_encode_buff(p_bh_encode_obj, 
                                                 (unsigned char *)in_buff, 
                                                 in_size);
              }
       }                           
       *real_size = p_bh_encode_obj->pos_outbuff;
       return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int binhex_reencode_head ( binhex_encode_object p_bh_encode_obj,
char *  outbuff,
int32  buff_size,
int32 real_size 
)

Definition at line 351 of file nsMsgBinHex.cpp.

{
       int32  size, dlen;
       int    status;
       char   buff[64];
       
       p_bh_encode_obj->state             = 0;   
       p_bh_encode_obj->state86    = 0;   
       p_bh_encode_obj->CRC        = 0;
       p_bh_encode_obj->line_length= 1;
       p_bh_encode_obj->saved_bits = 0;
       p_bh_encode_obj->s_overflow = 0    ;
       
       status = binhex_encode_next(
                                          p_bh_encode_obj, 
                                          p_bh_encode_obj->name,             
                                          p_bh_encode_obj->name[0]+2,        /* in_size */
                                          outbuff, 
                                          buff_size,
                                          real_size);
       if (status != NOERR)
              return status;
              
       size = *real_size;
       
       /* now we should have the right data length in the head structure, but don't               */
       /* forget convert it back to the net byte order (i.e., Motolora) before write it    */
       /*                                                                                                                                                 */
       /* Note:      since we don't change the size of rlen, so don't need to worry about it      */
       
       p_bh_encode_obj->head.dlen = htonl(dlen = p_bh_encode_obj->head.dlen);
       
       /* make a copy before do the encoding, -- it may modify the head!!!. */
       memcpy(buff, (char*)&p_bh_encode_obj->head, 
              sizeof(binhex_header));
       if (18 < sizeof(binhex_header))
       {
              /* we get an alignment problem here.      */
        memcpy(buff + 10, buff + 12, 8);
       }
                                                               
       status = binhex_encode_next(
                                          p_bh_encode_obj, 
                                          (char*)buff,         
                                          18,                                       /* sizeof(binhex_header),*/
                                          outbuff   + size, 
                                          buff_size - size,
                                          real_size);
       if (status != NOERR)
              return status;
       
       size += *real_size;
              
       status = binhex_encode_next(                                   /* for CRC */
                                          p_bh_encode_obj, 
                                          NULL,         
                                          0,                                               /* in_size */
                                          outbuff  + size, 
                                          buff_size - size,
                                          real_size);
       
       if (status != NOERR)
              return status;
              
       size += *real_size;

       if (p_bh_encode_obj->state86 != 0)
       {
              /*     
              **     Make sure we don't destroy the orignal valid coding.
              **
              **     (Keep in mind that 3 characters share 4 coding chars,
              **      so it is possible for the head and data stream share one 4 code group.
              **
              **     How about only one or zero character in the data fork?
              **            ---- just rerun the encoding, not a big deal.
              */
              if (dlen <= 1)
              {
                     /* why just rerun the encoding once more. */
                     status = binhex_encode_next(
                                          p_bh_encode_obj,
                                          p_bh_encode_obj->c,
                                          dlen,
                                          outbuff   + size,
                                          buff_size - size,
                                          real_size);
                     if (status != NOERR)
                            return status;
                            
                     size += *real_size;                                            /* encode the data fork            */
                     
                     status = binhex_encode_next(
                                          p_bh_encode_obj,
                                          NULL,
                                          0,
                                          outbuff   + size,
                                          buff_size - size,
                                          real_size);
                     if (status != NOERR)
                            return status;

                     size += *real_size;                                            /* for the end up data fork */
                     
                     status = binhex_encode_next(
                                          p_bh_encode_obj,
                                          NULL,
                                          0,
                                          outbuff   + size,
                                          buff_size - size,
                                          real_size);                                      /* for the end up encoding*/
              }
              else
              {
                     status = binhex_encode_next(
                                          p_bh_encode_obj, 
                                          p_bh_encode_obj->c,         
                                          3 - p_bh_encode_obj->state86,      /* in_size */
                                          outbuff   + size, 
                                          buff_size - size,
                                          real_size);
              }
              size += *real_size;  
       }
       *real_size = size;
       
       return status;
}

Here is the call graph for this function: