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