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