Annotation of libwww/Library/src/HTUU.c, revision 2.1

2.1     ! luotonen    1: 
        !             2: /* MODULE                                                      HTUU.c
        !             3: **                     UUENCODE AND UUDECODE
        !             4: **
        !             5: ** ACKNOWLEDGEMENT:
        !             6: **     This code is taken from rpem distribution, and was originally
        !             7: **     written by Mark Riordan.
        !             8: **
        !             9: ** AUTHORS:
        !            10: **     MR      Mark Riordan    riordanmr@clvax1.cl.msu.edu
        !            11: **     AL      Ari Luotonen    luotonen@dxcern.cern.ch
        !            12: **
        !            13: ** HISTORY:
        !            14: **     Added as part of the WWW library and edited to conform
        !            15: **     with the WWW project coding standards by:       AL  5 Aug 1993
        !            16: **     Originally written by:                          MR 12 Aug 1990
        !            17: **     Original header text:
        !            18: ** -------------------------------------------------------------
        !            19: **  File containing routines to convert a buffer
        !            20: **  of bytes to/from RFC 1113 printable encoding format.
        !            21: **
        !            22: **  This technique is similar to the familiar Unix uuencode
        !            23: **  format in that it maps 6 binary bits to one ASCII
        !            24: **  character (or more aptly, 3 binary bytes to 4 ASCII
        !            25: **  characters).  However, RFC 1113 does not use the same
        !            26: **  mapping to printable characters as uuencode.
        !            27: **
        !            28: **  Mark Riordan   12 August 1990 and 17 Feb 1991.
        !            29: **  This code is hereby placed in the public domain.
        !            30: ** -------------------------------------------------------------
        !            31: **
        !            32: ** BUGS:
        !            33: **
        !            34: **
        !            35: */
        !            36: 
        !            37: #include "HTUtils.h"
        !            38: #include "HTUU.h"
        !            39: 
        !            40: 
        !            41: PRIVATE char six2pr[64] = {
        !            42:     'A','B','C','D','E','F','G','H','I','J','K','L','M',
        !            43:     'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
        !            44:     'a','b','c','d','e','f','g','h','i','j','k','l','m',
        !            45:     'n','o','p','q','r','s','t','u','v','w','x','y','z',
        !            46:     '0','1','2','3','4','5','6','7','8','9','+','/'
        !            47: };
        !            48: 
        !            49: PRIVATE unsigned char pr2six[256];
        !            50: 
        !            51: 
        !            52: /*--- function HTUU_encode -----------------------------------------------
        !            53:  *
        !            54:  *   Encode a single line of binary data to a standard format that
        !            55:  *   uses only printing ASCII characters (but takes up 33% more bytes).
        !            56:  *
        !            57:  *    Entry    bufin    points to a buffer of bytes.  If nbytes is not
        !            58:  *                      a multiple of three, then the byte just beyond
        !            59:  *                      the last byte in the buffer must be 0.
        !            60:  *             nbytes   is the number of bytes in that buffer.
        !            61:  *                      This cannot be more than 48.
        !            62:  *             bufcoded points to an output buffer.  Be sure that this
        !            63:  *                      can hold at least 1 + (4*nbytes)/3 characters.
        !            64:  *
        !            65:  *    Exit     bufcoded contains the coded line.  The first 4*nbytes/3 bytes
        !            66:  *                      contain printing ASCII characters representing
        !            67:  *                      those binary bytes. This may include one or
        !            68:  *                      two '=' characters used as padding at the end.
        !            69:  *                      The last byte is a zero byte.
        !            70:  *             Returns the number of ASCII characters in "bufcoded".
        !            71:  */
        !            72: PUBLIC int HTUU_encode ARGS3(unsigned char *,  bufin,
        !            73:                             unsigned int,      nbytes,
        !            74:                             char *,            bufcoded)
        !            75: {
        !            76: /* ENC is the basic 1 character encoding function to make a char printing */
        !            77: #define ENC(c) six2pr[c]
        !            78: 
        !            79:    register char *outptr = bufcoded;
        !            80:    unsigned int i;
        !            81:    /* This doesn't seem to be needed (AL):   register unsigned char *inptr  = bufin; */
        !            82: 
        !            83:    for (i=0; i<nbytes; i += 3) {
        !            84:       *(outptr++) = ENC(*bufin >> 2);            /* c1 */
        !            85:       *(outptr++) = ENC((*bufin << 4) & 060 | (bufin[1] >> 4) & 017);  /* c2 */
        !            86:       *(outptr++) = ENC((bufin[1] << 2) & 074 | (bufin[2] >> 6) & 03); /* c3 */
        !            87:       *(outptr++) = ENC(bufin[2] & 077);         /* c4 */
        !            88: 
        !            89:       bufin += 3;
        !            90:    }
        !            91: 
        !            92:    /* If nbytes was not a multiple of 3, then we have encoded too
        !            93:     * many characters.  Adjust appropriately.
        !            94:     */
        !            95:    if(i == nbytes+1) {
        !            96:       /* There were only 2 bytes in that last group */
        !            97:       outptr[-1] = '=';
        !            98:    } else if(i == nbytes+2) {
        !            99:       /* There was only 1 byte in that last group */
        !           100:       outptr[-1] = '=';
        !           101:       outptr[-2] = '=';
        !           102:    }
        !           103:    *outptr = '\0';
        !           104:    return(outptr - bufcoded);
        !           105: }
        !           106: 
        !           107: 
        !           108: /*--- function HTUU_decode ------------------------------------------------
        !           109:  *
        !           110:  *  Decode an ASCII-encoded buffer back to its original binary form.
        !           111:  *
        !           112:  *    Entry    bufcoded    points to a uuencoded string.  It is 
        !           113:  *                         terminated by any character not in
        !           114:  *                         the printable character table six2pr, but
        !           115:  *                         leading whitespace is stripped.
        !           116:  *             bufplain    points to the output buffer; must be big
        !           117:  *                         enough to hold the decoded string (generally
        !           118:  *                         shorter than the encoded string) plus
        !           119:  *                         as many as two extra bytes used during
        !           120:  *                         the decoding process.
        !           121:  *             outbufsize  is the maximum number of bytes that
        !           122:  *                         can fit in bufplain.
        !           123:  *
        !           124:  *    Exit     Returns the number of binary bytes decoded.
        !           125:  *             bufplain    contains these bytes.
        !           126:  */
        !           127: PUBLIC int HTUU_decode ARGS3(char *,           bufcoded,
        !           128:                             unsigned char *,   bufplain,
        !           129:                             int,               outbufsize)
        !           130: {
        !           131: /* single character decode */
        !           132: #define DEC(c) pr2six[c]
        !           133: #define MAXVAL 63
        !           134: 
        !           135:    static int first = 1;
        !           136: 
        !           137:    int nbytesdecoded, j;
        !           138:    register char *bufin = bufcoded;
        !           139:    register unsigned char *bufout = bufplain;
        !           140:    register int nprbytes;
        !           141: 
        !           142:    /* If this is the first call, initialize the mapping table.
        !           143:     * This code should work even on non-ASCII machines.
        !           144:     */
        !           145:    if(first) {
        !           146:       first = 0;
        !           147:       for(j=0; j<256; j++) pr2six[j] = MAXVAL+1;
        !           148: 
        !           149:       for(j=0; j<64; j++) pr2six[six2pr[j]] = (unsigned char) j;
        !           150: #if 0
        !           151:       pr2six['A']= 0; pr2six['B']= 1; pr2six['C']= 2; pr2six['D']= 3; 
        !           152:       pr2six['E']= 4; pr2six['F']= 5; pr2six['G']= 6; pr2six['H']= 7; 
        !           153:       pr2six['I']= 8; pr2six['J']= 9; pr2six['K']=10; pr2six['L']=11; 
        !           154:       pr2six['M']=12; pr2six['N']=13; pr2six['O']=14; pr2six['P']=15; 
        !           155:       pr2six['Q']=16; pr2six['R']=17; pr2six['S']=18; pr2six['T']=19; 
        !           156:       pr2six['U']=20; pr2six['V']=21; pr2six['W']=22; pr2six['X']=23; 
        !           157:       pr2six['Y']=24; pr2six['Z']=25; pr2six['a']=26; pr2six['b']=27; 
        !           158:       pr2six['c']=28; pr2six['d']=29; pr2six['e']=30; pr2six['f']=31; 
        !           159:       pr2six['g']=32; pr2six['h']=33; pr2six['i']=34; pr2six['j']=35; 
        !           160:       pr2six['k']=36; pr2six['l']=37; pr2six['m']=38; pr2six['n']=39; 
        !           161:       pr2six['o']=40; pr2six['p']=41; pr2six['q']=42; pr2six['r']=43; 
        !           162:       pr2six['s']=44; pr2six['t']=45; pr2six['u']=46; pr2six['v']=47; 
        !           163:       pr2six['w']=48; pr2six['x']=49; pr2six['y']=50; pr2six['z']=51; 
        !           164:       pr2six['0']=52; pr2six['1']=53; pr2six['2']=54; pr2six['3']=55; 
        !           165:       pr2six['4']=56; pr2six['5']=57; pr2six['6']=58; pr2six['7']=59; 
        !           166:       pr2six['8']=60; pr2six['9']=61; pr2six['+']=62; pr2six['/']=63;
        !           167: #endif
        !           168:    }
        !           169: 
        !           170:    /* Strip leading whitespace. */
        !           171: 
        !           172:    while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
        !           173: 
        !           174:    /* Figure out how many characters are in the input buffer.
        !           175:     * If this would decode into more bytes than would fit into
        !           176:     * the output buffer, adjust the number of input bytes downwards.
        !           177:     */
        !           178:    bufin = bufcoded;
        !           179:    while(pr2six[*(bufin++)] <= MAXVAL);
        !           180:    nprbytes = bufin - bufcoded - 1;
        !           181:    nbytesdecoded = ((nprbytes+3)/4) * 3;
        !           182:    if(nbytesdecoded > outbufsize) {
        !           183:       nprbytes = (outbufsize*4)/3;
        !           184:    }
        !           185: 
        !           186:    bufin = bufcoded;
        !           187:    
        !           188:    while (nprbytes > 0) {
        !           189:       *(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4);
        !           190:       *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2);
        !           191:       *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3]));
        !           192:       bufin += 4;
        !           193:       nprbytes -= 4;
        !           194:    }
        !           195:    
        !           196:    if(nprbytes & 03) {
        !           197:       if(pr2six[bufin[-2]] > MAXVAL) {
        !           198:          nbytesdecoded -= 2;
        !           199:       } else {
        !           200:          nbytesdecoded -= 1;
        !           201:       }
        !           202:    }
        !           203: 
        !           204:    return(nbytesdecoded);
        !           205: }
        !           206: 

Webmaster