blob: 477617075560bdbc6fe3ba567b0fd547de379edd [file] [log] [blame]
Jack Jansen72781191995-08-07 14:34:15 +00001/***********************************************************
2Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
4
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Jack Jansen72781191995-08-07 14:34:15 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Jack Jansen72781191995-08-07 14:34:15 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Jack Jansen72781191995-08-07 14:34:15 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Jack Jansen72781191995-08-07 14:34:15 +000029
30******************************************************************/
31
32/*
33** Routines to represent binary data in ASCII and vice-versa
34**
35** This module currently supports the following encodings:
36** uuencode:
37** each line encodes 45 bytes (except possibly the last)
38** First char encodes (binary) length, rest data
39** each char encodes 6 bits, as follows:
40** binary: 01234567 abcdefgh ijklmnop
41** ascii: 012345 67abcd efghij klmnop
42** ASCII encoding method is "excess-space": 000000 is encoded as ' ', etc.
43** short binary data is zero-extended (so the bits are always in the
44** right place), this does *not* reflect in the length.
Jack Jansen84bbc2e1995-10-04 16:38:44 +000045** base64:
46** Line breaks are insignificant, but lines are at most 76 chars
47** each char encodes 6 bits, in similar order as uucode/hqx. Encoding
48** is done via a table.
49** Short binary data is filled (in ASCII) with '='.
Jack Jansen72781191995-08-07 14:34:15 +000050** hqx:
51** File starts with introductory text, real data starts and ends
52** with colons.
53** Data consists of three similar parts: info, datafork, resourcefork.
54** Each part is protected (at the end) with a 16-bit crc
55** The binary data is run-length encoded, and then ascii-fied:
56** binary: 01234567 abcdefgh ijklmnop
57** ascii: 012345 67abcd efghij klmnop
58** ASCII encoding is table-driven, see the code.
59** Short binary data results in the runt ascii-byte being output with
60** the bits in the right place.
61**
62** While I was reading dozens of programs that encode or decode the formats
63** here (documentation? hihi:-) I have formulated Jansen's Observation:
64**
65** Programs that encode binary data in ASCII are written in
66** such a style that they are as unreadable as possible. Devices used
67** include unnecessary global variables, burying important tables
68** in unrelated sourcefiles, putting functions in include files,
69** using seemingly-descriptive variable names for different purposes,
70** calls to empty subroutines and a host of others.
71**
72** I have attempted to break with this tradition, but I guess that that
73** does make the performance sub-optimal. Oh well, too bad...
74**
75** Jack Jansen, CWI, July 1995.
76*/
77
78
79#include "Python.h"
80
81static PyObject *Error;
82static PyObject *Incomplete;
83
84/*
85** hqx lookup table, ascii->binary.
86*/
87
88#define RUNCHAR 0x90
89
90#define DONE 0x7F
91#define SKIP 0x7E
92#define FAIL 0x7D
93
94static unsigned char table_a2b_hqx[256] = {
95/* ^@ ^A ^B ^C ^D ^E ^F ^G */
96/* 0*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
97/* \b \t \n ^K ^L \r ^N ^O */
98/* 1*/ FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
99/* ^P ^Q ^R ^S ^T ^U ^V ^W */
100/* 2*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
101/* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
102/* 3*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
103/* ! " # $ % & ' */
104/* 4*/ FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
105/* ( ) * + , - . / */
106/* 5*/ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
107/* 0 1 2 3 4 5 6 7 */
108/* 6*/ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
109/* 8 9 : ; < = > ? */
110/* 7*/ 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
111/* @ A B C D E F G */
112/* 8*/ 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
113/* H I J K L M N O */
114/* 9*/ 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
115/* P Q R S T U V W */
116/*10*/ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
117/* X Y Z [ \ ] ^ _ */
118/*11*/ 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
119/* ` a b c d e f g */
120/*12*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
121/* h i j k l m n o */
122/*13*/ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
123/* p q r s t u v w */
124/*14*/ 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
125/* x y z { | } ~ ^? */
126/*15*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
127/*16*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
128 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
129 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
130 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
131 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
132 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
133 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
134 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
135 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
136 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
137 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
138 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
139 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
140 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
141 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
142 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
143};
144
145static unsigned char table_b2a_hqx[] =
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000146"!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
Jack Jansen72781191995-08-07 14:34:15 +0000147
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000148static char table_a2b_base64[] = {
149 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
150 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
151 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
152 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */
153 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
154 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
155 -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
156 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
157};
158
159#define BASE64_PAD '='
160#define BASE64_MAXBIN 57 /* Max binary chunk size (76 char line) */
161
162static unsigned char table_b2a_base64[] =
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000163"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000164
165
166
Jack Jansen72781191995-08-07 14:34:15 +0000167static unsigned short crctab_hqx[256] = {
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000168 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
169 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
170 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
171 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
172 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
173 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
174 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
175 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
176 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
177 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
178 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
179 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
180 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
181 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
182 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
183 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
184 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
185 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
186 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
187 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
188 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
189 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
190 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
191 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
192 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
193 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
194 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
195 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
196 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
197 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
198 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
199 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
Jack Jansen72781191995-08-07 14:34:15 +0000200};
201
202static char doc_a2b_uu[] = "(ascii) -> bin. Decode a line of uuencoded data";
203
204static PyObject *
205binascii_a2b_uu(self, args)
206 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000207 PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000208{
209 unsigned char *ascii_data, *bin_data;
210 int leftbits = 0;
211 unsigned char this_ch;
212 unsigned int leftchar = 0;
213 PyObject *rv;
214 int ascii_len, bin_len;
215
216 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &ascii_len) )
217 return NULL;
218
219 /* First byte: binary data length (in bytes) */
220 bin_len = (*ascii_data++ - ' ') & 077;
221 ascii_len--;
222
223 /* Allocate the buffer */
224 if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
225 return NULL;
226 bin_data = (unsigned char *)PyString_AsString(rv);
227
228 for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
229 this_ch = *ascii_data;
230 if ( this_ch == '\n' || this_ch == '\r' || ascii_len <= 0) {
231 /*
232 ** Whitespace. Assume some spaces got eaten at
233 ** end-of-line. (We check this later)
234 */
235 this_ch = 0;
236 } else {
Jack Jansen5d957971995-11-14 10:35:19 +0000237 /* Check the character for legality
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000238 ** The 64 in stead of the expected 63 is because
239 ** there are a few uuencodes out there that use
240 ** '@' as zero instead of space.
Jack Jansen5d957971995-11-14 10:35:19 +0000241 */
242 if ( this_ch < ' ' || this_ch > (' ' + 64)) {
Jack Jansen72781191995-08-07 14:34:15 +0000243 PyErr_SetString(Error, "Illegal char");
244 Py_DECREF(rv);
245 return NULL;
246 }
247 this_ch = (this_ch - ' ') & 077;
248 }
249 /*
250 ** Shift it in on the low end, and see if there's
251 ** a byte ready for output.
252 */
253 leftchar = (leftchar << 6) | (this_ch);
254 leftbits += 6;
255 if ( leftbits >= 8 ) {
256 leftbits -= 8;
257 *bin_data++ = (leftchar >> leftbits) & 0xff;
258 leftchar &= ((1 << leftbits) - 1);
259 bin_len--;
260 }
261 }
262 /*
263 ** Finally, check that if there's anything left on the line
264 ** that it's whitespace only.
265 */
266 while( ascii_len-- > 0 ) {
267 this_ch = *ascii_data++;
268 if ( this_ch != ' ' && this_ch != '\n' && this_ch != '\r' ) {
269 PyErr_SetString(Error, "Trailing garbage");
270 Py_DECREF(rv);
271 return NULL;
272 }
273 }
274 return rv;
275}
276
277static char doc_b2a_uu[] = "(bin) -> ascii. Uuencode line of data";
278
279static PyObject *
280binascii_b2a_uu(self, args)
281 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000282 PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000283{
284 unsigned char *ascii_data, *bin_data;
285 int leftbits = 0;
286 unsigned char this_ch;
287 unsigned int leftchar = 0;
288 PyObject *rv;
289 int bin_len;
290
291 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &bin_len) )
292 return NULL;
293 if ( bin_len > 45 ) {
294 /* The 45 is a limit that appears in all uuencode's */
295 PyErr_SetString(Error, "At most 45 bytes at once");
296 return NULL;
297 }
298
299 /* We're lazy and allocate to much (fixed up later) */
300 if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL )
301 return NULL;
302 ascii_data = (unsigned char *)PyString_AsString(rv);
303
304 /* Store the length */
305 *ascii_data++ = ' ' + (bin_len & 077);
306
307 for( ; bin_len > 0 || leftbits != 0 ; bin_len--, bin_data++ ) {
308 /* Shift the data (or padding) into our buffer */
309 if ( bin_len > 0 ) /* Data */
310 leftchar = (leftchar << 8) | *bin_data;
311 else /* Padding */
312 leftchar <<= 8;
313 leftbits += 8;
314
315 /* See if there are 6-bit groups ready */
316 while ( leftbits >= 6 ) {
317 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
318 leftbits -= 6;
319 *ascii_data++ = this_ch + ' ';
320 }
321 }
322 *ascii_data++ = '\n'; /* Append a courtesy newline */
323
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000324 _PyString_Resize(&rv, (ascii_data -
325 (unsigned char *)PyString_AsString(rv)));
Jack Jansen72781191995-08-07 14:34:15 +0000326 return rv;
327}
328
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000329static char doc_a2b_base64[] = "(ascii) -> bin. Decode a line of base64 data";
330
331static PyObject *
332binascii_a2b_base64(self, args)
333 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000334 PyObject *args;
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000335{
336 unsigned char *ascii_data, *bin_data;
337 int leftbits = 0;
338 unsigned char this_ch;
339 unsigned int leftchar = 0;
340 int npad = 0;
341 PyObject *rv;
342 int ascii_len, bin_len;
343
344 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &ascii_len) )
345 return NULL;
346
347 bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
348
349 /* Allocate the buffer */
350 if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
351 return NULL;
352 bin_data = (unsigned char *)PyString_AsString(rv);
353 bin_len = 0;
354 for( ; ascii_len > 0 ; ascii_len--, ascii_data++ ) {
Jack Jansenba1de3b1996-01-22 10:47:15 +0000355 /* Skip some punctuation */
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000356 this_ch = (*ascii_data & 0x7f);
Jack Jansenba1de3b1996-01-22 10:47:15 +0000357 if ( this_ch == '\r' || this_ch == '\n' || this_ch == ' ' )
358 continue;
359
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000360 if ( this_ch == BASE64_PAD )
361 npad++;
362 this_ch = table_a2b_base64[(*ascii_data) & 0x7f];
Guido van Rossum485f2da1996-02-25 04:50:30 +0000363 if ( this_ch == (unsigned char) -1 ) continue;
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000364 /*
365 ** Shift it in on the low end, and see if there's
366 ** a byte ready for output.
367 */
368 leftchar = (leftchar << 6) | (this_ch);
369 leftbits += 6;
370 if ( leftbits >= 8 ) {
371 leftbits -= 8;
372 *bin_data++ = (leftchar >> leftbits) & 0xff;
373 leftchar &= ((1 << leftbits) - 1);
374 bin_len++;
375 }
376 }
377 /* Check that no bits are left */
378 if ( leftbits ) {
379 PyErr_SetString(Error, "Incorrect padding");
380 Py_DECREF(rv);
381 return NULL;
382 }
383 /* and remove any padding */
384 bin_len -= npad;
385 /* and set string size correctly */
386 _PyString_Resize(&rv, bin_len);
387 return rv;
388}
389
390static char doc_b2a_base64[] = "(bin) -> ascii. Base64-code line of data";
391
392static PyObject *
393binascii_b2a_base64(self, args)
394 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000395 PyObject *args;
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000396{
397 unsigned char *ascii_data, *bin_data;
398 int leftbits = 0;
399 unsigned char this_ch;
400 unsigned int leftchar = 0;
401 PyObject *rv;
402 int bin_len;
403
404 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &bin_len) )
405 return NULL;
406 if ( bin_len > BASE64_MAXBIN ) {
407 PyErr_SetString(Error, "Too much data for base64 line");
408 return NULL;
409 }
410
411 /* We're lazy and allocate to much (fixed up later) */
412 if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL )
413 return NULL;
414 ascii_data = (unsigned char *)PyString_AsString(rv);
415
416 for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
417 /* Shift the data into our buffer */
418 leftchar = (leftchar << 8) | *bin_data;
419 leftbits += 8;
420
421 /* See if there are 6-bit groups ready */
422 while ( leftbits >= 6 ) {
423 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
424 leftbits -= 6;
425 *ascii_data++ = table_b2a_base64[this_ch];
426 }
427 }
428 if ( leftbits == 2 ) {
429 *ascii_data++ = table_b2a_base64[(leftchar&3) << 4];
430 *ascii_data++ = BASE64_PAD;
431 *ascii_data++ = BASE64_PAD;
432 } else if ( leftbits == 4 ) {
433 *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2];
434 *ascii_data++ = BASE64_PAD;
435 }
436 *ascii_data++ = '\n'; /* Append a courtesy newline */
437
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000438 _PyString_Resize(&rv, (ascii_data -
439 (unsigned char *)PyString_AsString(rv)));
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000440 return rv;
441}
442
Jack Jansen72781191995-08-07 14:34:15 +0000443static char doc_a2b_hqx[] = "ascii -> bin, done. Decode .hqx coding";
444
445static PyObject *
446binascii_a2b_hqx(self, args)
447 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000448 PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000449{
450 unsigned char *ascii_data, *bin_data;
451 int leftbits = 0;
452 unsigned char this_ch;
Jack Janseneaeb1c81995-08-14 12:17:57 +0000453 unsigned int leftchar = 0;
Jack Jansen72781191995-08-07 14:34:15 +0000454 PyObject *rv;
455 int len;
456 int done = 0;
457
458 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &len) )
459 return NULL;
460
461 /* Allocate a string that is too big (fixed later) */
462 if ( (rv=PyString_FromStringAndSize(NULL, len)) == NULL )
463 return NULL;
464 bin_data = (unsigned char *)PyString_AsString(rv);
465
466 for( ; len > 0 ; len--, ascii_data++ ) {
467 /* Get the byte and look it up */
468 this_ch = table_a2b_hqx[*ascii_data];
469 if ( this_ch == SKIP )
470 continue;
471 if ( this_ch == FAIL ) {
472 PyErr_SetString(Error, "Illegal char");
473 Py_DECREF(rv);
474 return NULL;
475 }
476 if ( this_ch == DONE ) {
477 /* The terminating colon */
478 done = 1;
479 break;
480 }
481
482 /* Shift it into the buffer and see if any bytes are ready */
483 leftchar = (leftchar << 6) | (this_ch);
484 leftbits += 6;
485 if ( leftbits >= 8 ) {
486 leftbits -= 8;
487 *bin_data++ = (leftchar >> leftbits) & 0xff;
488 leftchar &= ((1 << leftbits) - 1);
489 }
490 }
491
492 if ( leftbits && !done ) {
493 PyErr_SetString(Incomplete,
494 "String has incomplete number of bytes");
495 Py_DECREF(rv);
496 return NULL;
497 }
Guido van Rossum9c6ba5e1997-01-12 20:02:04 +0000498 _PyString_Resize(
499 &rv, (bin_data - (unsigned char *)PyString_AsString(rv)));
500 if (rv) {
501 PyObject *rrv = Py_BuildValue("Oi", rv, done);
502 Py_DECREF(rv);
503 return rrv;
504 }
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000505
Jack Jansen72781191995-08-07 14:34:15 +0000506 return NULL;
507}
508
509static char doc_rlecode_hqx[] = "Binhex RLE-code binary data";
510
511static PyObject *
512binascii_rlecode_hqx(self, args)
513 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000514PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000515{
516 unsigned char *in_data, *out_data;
517 PyObject *rv;
518 unsigned char ch;
519 int in, inend, len;
520
521 if ( !PyArg_ParseTuple(args, "s#", &in_data, &len) )
522 return NULL;
523
524 /* Worst case: output is twice as big as input (fixed later) */
525 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
526 return NULL;
527 out_data = (unsigned char *)PyString_AsString(rv);
528
529 for( in=0; in<len; in++) {
530 ch = in_data[in];
531 if ( ch == RUNCHAR ) {
532 /* RUNCHAR. Escape it. */
533 *out_data++ = RUNCHAR;
534 *out_data++ = 0;
535 } else {
536 /* Check how many following are the same */
537 for(inend=in+1;
538 inend<len && in_data[inend] == ch &&
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000539 inend < in+255;
Jack Jansen72781191995-08-07 14:34:15 +0000540 inend++) ;
Jack Jansen0223aa11995-08-31 13:44:23 +0000541 if ( inend - in > 3 ) {
542 /* More than 3 in a row. Output RLE. */
Jack Jansen72781191995-08-07 14:34:15 +0000543 *out_data++ = ch;
544 *out_data++ = RUNCHAR;
545 *out_data++ = inend-in;
546 in = inend-1;
547 } else {
548 /* Less than 3. Output the byte itself */
549 *out_data++ = ch;
550 }
551 }
552 }
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000553 _PyString_Resize(&rv, (out_data -
554 (unsigned char *)PyString_AsString(rv)));
Jack Jansen72781191995-08-07 14:34:15 +0000555 return rv;
556}
557
558static char doc_b2a_hqx[] = "Encode .hqx data";
559
560static PyObject *
561binascii_b2a_hqx(self, args)
562 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000563 PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000564{
565 unsigned char *ascii_data, *bin_data;
566 int leftbits = 0;
567 unsigned char this_ch;
Jack Janseneaeb1c81995-08-14 12:17:57 +0000568 unsigned int leftchar = 0;
Jack Jansen72781191995-08-07 14:34:15 +0000569 PyObject *rv;
570 int len;
571
572 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &len) )
573 return NULL;
574
575 /* Allocate a buffer that is at least large enough */
576 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
577 return NULL;
578 ascii_data = (unsigned char *)PyString_AsString(rv);
579
580 for( ; len > 0 ; len--, bin_data++ ) {
581 /* Shift into our buffer, and output any 6bits ready */
582 leftchar = (leftchar << 8) | *bin_data;
583 leftbits += 8;
584 while ( leftbits >= 6 ) {
585 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
586 leftbits -= 6;
587 *ascii_data++ = table_b2a_hqx[this_ch];
588 }
589 }
590 /* Output a possible runt byte */
591 if ( leftbits ) {
592 leftchar <<= (6-leftbits);
593 *ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
594 }
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000595 _PyString_Resize(&rv, (ascii_data -
596 (unsigned char *)PyString_AsString(rv)));
Jack Jansen72781191995-08-07 14:34:15 +0000597 return rv;
598}
599
600static char doc_rledecode_hqx[] = "Decode hexbin RLE-coded string";
601
602static PyObject *
603binascii_rledecode_hqx(self, args)
604 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000605 PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000606{
607 unsigned char *in_data, *out_data;
608 unsigned char in_byte, in_repeat;
609 PyObject *rv;
610 int in_len, out_len, out_len_left;
611
612 if ( !PyArg_ParseTuple(args, "s#", &in_data, &in_len) )
613 return NULL;
614
615 /* Empty string is a special case */
616 if ( in_len == 0 )
617 return Py_BuildValue("s", "");
618
619 /* Allocate a buffer of reasonable size. Resized when needed */
620 out_len = in_len*2;
621 if ( (rv=PyString_FromStringAndSize(NULL, out_len)) == NULL )
622 return NULL;
623 out_len_left = out_len;
624 out_data = (unsigned char *)PyString_AsString(rv);
625
626 /*
627 ** We need two macros here to get/put bytes and handle
628 ** end-of-buffer for input and output strings.
629 */
630#define INBYTE(b) \
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000631 do { \
632 if ( --in_len < 0 ) { \
633 PyErr_SetString(Incomplete, ""); \
634 Py_DECREF(rv); \
635 return NULL; \
636 } \
637 b = *in_data++; \
638 } while(0)
Jack Jansen72781191995-08-07 14:34:15 +0000639
640#define OUTBYTE(b) \
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000641 do { \
642 if ( --out_len_left < 0 ) { \
643 _PyString_Resize(&rv, 2*out_len); \
644 if ( rv == NULL ) return NULL; \
645 out_data = (unsigned char *)PyString_AsString(rv) \
646 + out_len; \
647 out_len_left = out_len-1; \
648 out_len = out_len * 2; \
649 } \
650 *out_data++ = b; \
651 } while(0)
Jack Jansen72781191995-08-07 14:34:15 +0000652
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000653 /*
654 ** Handle first byte separately (since we have to get angry
655 ** in case of an orphaned RLE code).
656 */
657 INBYTE(in_byte);
Jack Jansen72781191995-08-07 14:34:15 +0000658
659 if (in_byte == RUNCHAR) {
660 INBYTE(in_repeat);
661 if (in_repeat != 0) {
662 /* Note Error, not Incomplete (which is at the end
663 ** of the string only). This is a programmer error.
664 */
665 PyErr_SetString(Error, "Orphaned RLE code at start");
666 Py_DECREF(rv);
667 return NULL;
668 }
669 OUTBYTE(RUNCHAR);
670 } else {
671 OUTBYTE(in_byte);
672 }
673
674 while( in_len > 0 ) {
675 INBYTE(in_byte);
676
677 if (in_byte == RUNCHAR) {
678 INBYTE(in_repeat);
679 if ( in_repeat == 0 ) {
680 /* Just an escaped RUNCHAR value */
681 OUTBYTE(RUNCHAR);
682 } else {
683 /* Pick up value and output a sequence of it */
684 in_byte = out_data[-1];
685 while ( --in_repeat > 0 )
686 OUTBYTE(in_byte);
687 }
688 } else {
689 /* Normal byte */
690 OUTBYTE(in_byte);
691 }
692 }
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000693 _PyString_Resize(&rv, (out_data -
694 (unsigned char *)PyString_AsString(rv)));
Jack Jansen72781191995-08-07 14:34:15 +0000695 return rv;
696}
697
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000698static char doc_crc_hqx[] =
699"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally";
Jack Jansen72781191995-08-07 14:34:15 +0000700
701static PyObject *
702binascii_crc_hqx(self, args)
703 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000704PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000705{
706 unsigned char *bin_data;
707 unsigned int crc;
708 int len;
709
710 if ( !PyArg_ParseTuple(args, "s#i", &bin_data, &len, &crc) )
711 return NULL;
712
713 while(len--) {
714 crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
715 }
716
717 return Py_BuildValue("i", crc);
718}
719
720/* List of functions defined in the module */
721
722static struct PyMethodDef binascii_module_methods[] = {
723 {"a2b_uu", binascii_a2b_uu, 1, doc_a2b_uu},
724 {"b2a_uu", binascii_b2a_uu, 1, doc_b2a_uu},
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000725 {"a2b_base64", binascii_a2b_base64, 1,
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000726 doc_a2b_base64},
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000727 {"b2a_base64", binascii_b2a_base64, 1,
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000728 doc_b2a_base64},
Jack Jansen72781191995-08-07 14:34:15 +0000729 {"a2b_hqx", binascii_a2b_hqx, 1, doc_a2b_hqx},
730 {"b2a_hqx", binascii_b2a_hqx, 1, doc_b2a_hqx},
731 {"rlecode_hqx", binascii_rlecode_hqx, 1,
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000732 doc_rlecode_hqx},
Jack Jansen72781191995-08-07 14:34:15 +0000733 {"rledecode_hqx", binascii_rledecode_hqx, 1,
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000734 doc_rledecode_hqx},
Jack Jansen72781191995-08-07 14:34:15 +0000735 {"crc_hqx", binascii_crc_hqx, 1, doc_crc_hqx},
736 {NULL, NULL} /* sentinel */
737};
738
739
740/* Initialization function for the module (*must* be called initbinascii) */
741static char doc_binascii[] = "Conversion between binary data and ASCII";
742
743void
744initbinascii()
745{
746 PyObject *m, *d, *x;
747
748 /* Create the module and add the functions */
749 m = Py_InitModule("binascii", binascii_module_methods);
750
751 d = PyModule_GetDict(m);
752 x = PyString_FromString(doc_binascii);
753 PyDict_SetItemString(d, "__doc__", x);
754
755 Error = PyString_FromString("binascii.Error");
756 PyDict_SetItemString(d, "Error", Error);
757 Incomplete = PyString_FromString("binascii.Incomplete");
758 PyDict_SetItemString(d, "Incomplete", Incomplete);
759
760 /* Check for errors */
761 if (PyErr_Occurred())
762 Py_FatalError("can't initialize module binascii");
763}