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

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

Webmaster