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