Use py_resource module
[python/dscho.git] / Modules / binascii.c
blobc74ed3c21947e6482c8b97cfa29f9a73f0f4fe01
1 /***********************************************************
2 Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
3 Amsterdam, The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
26 ** Routines to represent binary data in ASCII and vice-versa
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.
38 ** 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 '='.
43 ** 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.
55 ** While I was reading dozens of programs that encode or decode the formats
56 ** here (documentation? hihi:-) I have formulated Jansen's Observation:
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.
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...
68 ** Jack Jansen, CWI, July 1995.
72 #include "Python.h"
74 static PyObject *Error;
75 static PyObject *Incomplete;
78 ** hqx lookup table, ascii->binary.
81 #define RUNCHAR 0x90
83 #define DONE 0x7F
84 #define SKIP 0x7E
85 #define FAIL 0x7D
87 static 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,
138 static unsigned char table_b2a_hqx[] =
139 "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
141 static 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
152 #define BASE64_PAD '='
153 #define BASE64_MAXBIN 57 /* Max binary chunk size (76 char line) */
155 static unsigned char table_b2a_base64[] =
156 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
160 static 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,
195 static char doc_a2b_uu[] = "(ascii) -> bin. Decode a line of uuencoded data";
197 static PyObject *
198 binascii_a2b_uu(self, args)
199 PyObject *self;
200 PyObject *args;
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;
209 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &ascii_len) )
210 return NULL;
212 /* First byte: binary data length (in bytes) */
213 bin_len = (*ascii_data++ - ' ') & 077;
214 ascii_len--;
216 /* Allocate the buffer */
217 if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
218 return NULL;
219 bin_data = (unsigned char *)PyString_AsString(rv);
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) {
225 ** Whitespace. Assume some spaces got eaten at
226 ** end-of-line. (We check this later)
228 this_ch = 0;
229 } else {
230 /* Check the character for legality
231 ** The 64 in stead of the expected 63 is because there are a few
232 ** uuencodes out there that use '@' as zero in stead of space.
234 if ( this_ch < ' ' || this_ch > (' ' + 64)) {
235 PyErr_SetString(Error, "Illegal char");
236 Py_DECREF(rv);
237 return NULL;
239 this_ch = (this_ch - ' ') & 077;
242 ** Shift it in on the low end, and see if there's
243 ** a byte ready for output.
245 leftchar = (leftchar << 6) | (this_ch);
246 leftbits += 6;
247 if ( leftbits >= 8 ) {
248 leftbits -= 8;
249 *bin_data++ = (leftchar >> leftbits) & 0xff;
250 leftchar &= ((1 << leftbits) - 1);
251 bin_len--;
255 ** Finally, check that if there's anything left on the line
256 ** that it's whitespace only.
258 while( ascii_len-- > 0 ) {
259 this_ch = *ascii_data++;
260 if ( this_ch != ' ' && this_ch != '\n' && this_ch != '\r' ) {
261 PyErr_SetString(Error, "Trailing garbage");
262 Py_DECREF(rv);
263 return NULL;
266 return rv;
269 static char doc_b2a_uu[] = "(bin) -> ascii. Uuencode line of data";
271 static PyObject *
272 binascii_b2a_uu(self, args)
273 PyObject *self;
274 PyObject *args;
276 unsigned char *ascii_data, *bin_data;
277 int leftbits = 0;
278 unsigned char this_ch;
279 unsigned int leftchar = 0;
280 PyObject *rv;
281 int bin_len;
283 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &bin_len) )
284 return NULL;
285 if ( bin_len > 45 ) {
286 /* The 45 is a limit that appears in all uuencode's */
287 PyErr_SetString(Error, "At most 45 bytes at once");
288 return NULL;
291 /* We're lazy and allocate to much (fixed up later) */
292 if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL )
293 return NULL;
294 ascii_data = (unsigned char *)PyString_AsString(rv);
296 /* Store the length */
297 *ascii_data++ = ' ' + (bin_len & 077);
299 for( ; bin_len > 0 || leftbits != 0 ; bin_len--, bin_data++ ) {
300 /* Shift the data (or padding) into our buffer */
301 if ( bin_len > 0 ) /* Data */
302 leftchar = (leftchar << 8) | *bin_data;
303 else /* Padding */
304 leftchar <<= 8;
305 leftbits += 8;
307 /* See if there are 6-bit groups ready */
308 while ( leftbits >= 6 ) {
309 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
310 leftbits -= 6;
311 *ascii_data++ = this_ch + ' ';
314 *ascii_data++ = '\n'; /* Append a courtesy newline */
316 _PyString_Resize(&rv, (ascii_data - (unsigned char *)PyString_AsString(rv)));
317 return rv;
320 static char doc_a2b_base64[] = "(ascii) -> bin. Decode a line of base64 data";
322 static PyObject *
323 binascii_a2b_base64(self, args)
324 PyObject *self;
325 PyObject *args;
327 unsigned char *ascii_data, *bin_data;
328 int leftbits = 0;
329 unsigned char this_ch;
330 unsigned int leftchar = 0;
331 int npad = 0;
332 PyObject *rv;
333 int ascii_len, bin_len;
335 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &ascii_len) )
336 return NULL;
338 bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
340 /* Allocate the buffer */
341 if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
342 return NULL;
343 bin_data = (unsigned char *)PyString_AsString(rv);
344 bin_len = 0;
345 for( ; ascii_len > 0 ; ascii_len--, ascii_data++ ) {
346 /* Skip some punctuation */
347 this_ch = (*ascii_data & 0x7f);
348 if ( this_ch == '\r' || this_ch == '\n' || this_ch == ' ' )
349 continue;
351 if ( this_ch == BASE64_PAD )
352 npad++;
353 this_ch = table_a2b_base64[(*ascii_data) & 0x7f];
354 if ( this_ch == (unsigned char) -1 ) continue;
356 ** Shift it in on the low end, and see if there's
357 ** a byte ready for output.
359 leftchar = (leftchar << 6) | (this_ch);
360 leftbits += 6;
361 if ( leftbits >= 8 ) {
362 leftbits -= 8;
363 *bin_data++ = (leftchar >> leftbits) & 0xff;
364 leftchar &= ((1 << leftbits) - 1);
365 bin_len++;
368 /* Check that no bits are left */
369 if ( leftbits ) {
370 PyErr_SetString(Error, "Incorrect padding");
371 Py_DECREF(rv);
372 return NULL;
374 /* and remove any padding */
375 bin_len -= npad;
376 /* and set string size correctly */
377 _PyString_Resize(&rv, bin_len);
378 return rv;
381 static char doc_b2a_base64[] = "(bin) -> ascii. Base64-code line of data";
383 static PyObject *
384 binascii_b2a_base64(self, args)
385 PyObject *self;
386 PyObject *args;
388 unsigned char *ascii_data, *bin_data;
389 int leftbits = 0;
390 unsigned char this_ch;
391 unsigned int leftchar = 0;
392 PyObject *rv;
393 int bin_len;
395 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &bin_len) )
396 return NULL;
397 if ( bin_len > BASE64_MAXBIN ) {
398 PyErr_SetString(Error, "Too much data for base64 line");
399 return NULL;
402 /* We're lazy and allocate to much (fixed up later) */
403 if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL )
404 return NULL;
405 ascii_data = (unsigned char *)PyString_AsString(rv);
407 for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
408 /* Shift the data into our buffer */
409 leftchar = (leftchar << 8) | *bin_data;
410 leftbits += 8;
412 /* See if there are 6-bit groups ready */
413 while ( leftbits >= 6 ) {
414 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
415 leftbits -= 6;
416 *ascii_data++ = table_b2a_base64[this_ch];
419 if ( leftbits == 2 ) {
420 *ascii_data++ = table_b2a_base64[(leftchar&3) << 4];
421 *ascii_data++ = BASE64_PAD;
422 *ascii_data++ = BASE64_PAD;
423 } else if ( leftbits == 4 ) {
424 *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2];
425 *ascii_data++ = BASE64_PAD;
427 *ascii_data++ = '\n'; /* Append a courtesy newline */
429 _PyString_Resize(&rv, (ascii_data - (unsigned char *)PyString_AsString(rv)));
430 return rv;
433 static char doc_a2b_hqx[] = "ascii -> bin, done. Decode .hqx coding";
435 static PyObject *
436 binascii_a2b_hqx(self, args)
437 PyObject *self;
438 PyObject *args;
440 unsigned char *ascii_data, *bin_data;
441 int leftbits = 0;
442 unsigned char this_ch;
443 unsigned int leftchar = 0;
444 PyObject *rv;
445 int len;
446 int done = 0;
448 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &len) )
449 return NULL;
451 /* Allocate a string that is too big (fixed later) */
452 if ( (rv=PyString_FromStringAndSize(NULL, len)) == NULL )
453 return NULL;
454 bin_data = (unsigned char *)PyString_AsString(rv);
456 for( ; len > 0 ; len--, ascii_data++ ) {
457 /* Get the byte and look it up */
458 this_ch = table_a2b_hqx[*ascii_data];
459 if ( this_ch == SKIP )
460 continue;
461 if ( this_ch == FAIL ) {
462 PyErr_SetString(Error, "Illegal char");
463 Py_DECREF(rv);
464 return NULL;
466 if ( this_ch == DONE ) {
467 /* The terminating colon */
468 done = 1;
469 break;
472 /* Shift it into the buffer and see if any bytes are ready */
473 leftchar = (leftchar << 6) | (this_ch);
474 leftbits += 6;
475 if ( leftbits >= 8 ) {
476 leftbits -= 8;
477 *bin_data++ = (leftchar >> leftbits) & 0xff;
478 leftchar &= ((1 << leftbits) - 1);
482 if ( leftbits && !done ) {
483 PyErr_SetString(Incomplete,
484 "String has incomplete number of bytes");
485 Py_DECREF(rv);
486 return NULL;
488 _PyString_Resize(&rv, (bin_data - (unsigned char *)PyString_AsString(rv)));
489 if ( rv )
490 return Py_BuildValue("Oi", rv, done);
491 return NULL;
494 static char doc_rlecode_hqx[] = "Binhex RLE-code binary data";
496 static PyObject *
497 binascii_rlecode_hqx(self, args)
498 PyObject *self;
499 PyObject *args;
501 unsigned char *in_data, *out_data;
502 PyObject *rv;
503 unsigned char ch;
504 int in, inend, len;
506 if ( !PyArg_ParseTuple(args, "s#", &in_data, &len) )
507 return NULL;
509 /* Worst case: output is twice as big as input (fixed later) */
510 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
511 return NULL;
512 out_data = (unsigned char *)PyString_AsString(rv);
514 for( in=0; in<len; in++) {
515 ch = in_data[in];
516 if ( ch == RUNCHAR ) {
517 /* RUNCHAR. Escape it. */
518 *out_data++ = RUNCHAR;
519 *out_data++ = 0;
520 } else {
521 /* Check how many following are the same */
522 for(inend=in+1;
523 inend<len && in_data[inend] == ch &&
524 inend < in+255;
525 inend++) ;
526 if ( inend - in > 3 ) {
527 /* More than 3 in a row. Output RLE. */
528 *out_data++ = ch;
529 *out_data++ = RUNCHAR;
530 *out_data++ = inend-in;
531 in = inend-1;
532 } else {
533 /* Less than 3. Output the byte itself */
534 *out_data++ = ch;
538 _PyString_Resize(&rv, (out_data - (unsigned char *)PyString_AsString(rv)));
539 return rv;
542 static char doc_b2a_hqx[] = "Encode .hqx data";
544 static PyObject *
545 binascii_b2a_hqx(self, args)
546 PyObject *self;
547 PyObject *args;
549 unsigned char *ascii_data, *bin_data;
550 int leftbits = 0;
551 unsigned char this_ch;
552 unsigned int leftchar = 0;
553 PyObject *rv;
554 int len;
556 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &len) )
557 return NULL;
559 /* Allocate a buffer that is at least large enough */
560 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
561 return NULL;
562 ascii_data = (unsigned char *)PyString_AsString(rv);
564 for( ; len > 0 ; len--, bin_data++ ) {
565 /* Shift into our buffer, and output any 6bits ready */
566 leftchar = (leftchar << 8) | *bin_data;
567 leftbits += 8;
568 while ( leftbits >= 6 ) {
569 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
570 leftbits -= 6;
571 *ascii_data++ = table_b2a_hqx[this_ch];
574 /* Output a possible runt byte */
575 if ( leftbits ) {
576 leftchar <<= (6-leftbits);
577 *ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
579 _PyString_Resize(&rv, (ascii_data - (unsigned char *)PyString_AsString(rv)));
580 return rv;
583 static char doc_rledecode_hqx[] = "Decode hexbin RLE-coded string";
585 static PyObject *
586 binascii_rledecode_hqx(self, args)
587 PyObject *self;
588 PyObject *args;
590 unsigned char *in_data, *out_data;
591 unsigned char in_byte, in_repeat;
592 PyObject *rv;
593 int in_len, out_len, out_len_left;
595 if ( !PyArg_ParseTuple(args, "s#", &in_data, &in_len) )
596 return NULL;
598 /* Empty string is a special case */
599 if ( in_len == 0 )
600 return Py_BuildValue("s", "");
602 /* Allocate a buffer of reasonable size. Resized when needed */
603 out_len = in_len*2;
604 if ( (rv=PyString_FromStringAndSize(NULL, out_len)) == NULL )
605 return NULL;
606 out_len_left = out_len;
607 out_data = (unsigned char *)PyString_AsString(rv);
610 ** We need two macros here to get/put bytes and handle
611 ** end-of-buffer for input and output strings.
613 #define INBYTE(b) \
614 do { \
615 if ( --in_len < 0 ) { \
616 PyErr_SetString(Incomplete, ""); \
617 Py_DECREF(rv); \
618 return NULL; \
620 b = *in_data++; \
621 } while(0)
623 #define OUTBYTE(b) \
624 do { \
625 if ( --out_len_left < 0 ) { \
626 _PyString_Resize(&rv, 2*out_len); \
627 if ( rv == NULL ) return NULL; \
628 out_data = (unsigned char *)PyString_AsString(rv) + out_len; \
629 out_len_left = out_len-1; \
630 out_len = out_len * 2; \
632 *out_data++ = b; \
633 } while(0)
636 ** Handle first byte separately (since we have to get angry
637 ** in case of an orphaned RLE code).
639 INBYTE(in_byte);
641 if (in_byte == RUNCHAR) {
642 INBYTE(in_repeat);
643 if (in_repeat != 0) {
644 /* Note Error, not Incomplete (which is at the end
645 ** of the string only). This is a programmer error.
647 PyErr_SetString(Error, "Orphaned RLE code at start");
648 Py_DECREF(rv);
649 return NULL;
651 OUTBYTE(RUNCHAR);
652 } else {
653 OUTBYTE(in_byte);
656 while( in_len > 0 ) {
657 INBYTE(in_byte);
659 if (in_byte == RUNCHAR) {
660 INBYTE(in_repeat);
661 if ( in_repeat == 0 ) {
662 /* Just an escaped RUNCHAR value */
663 OUTBYTE(RUNCHAR);
664 } else {
665 /* Pick up value and output a sequence of it */
666 in_byte = out_data[-1];
667 while ( --in_repeat > 0 )
668 OUTBYTE(in_byte);
670 } else {
671 /* Normal byte */
672 OUTBYTE(in_byte);
675 _PyString_Resize(&rv, (out_data - (unsigned char *)PyString_AsString(rv)));
676 return rv;
679 static char doc_crc_hqx[] = "(data, oldcrc) -> newcrc. Compute hqx CRC incrementally";
681 static PyObject *
682 binascii_crc_hqx(self, args)
683 PyObject *self;
684 PyObject *args;
686 unsigned char *bin_data;
687 unsigned int crc;
688 int len;
690 if ( !PyArg_ParseTuple(args, "s#i", &bin_data, &len, &crc) )
691 return NULL;
693 while(len--) {
694 crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
697 return Py_BuildValue("i", crc);
700 /* List of functions defined in the module */
702 static struct PyMethodDef binascii_module_methods[] = {
703 {"a2b_uu", binascii_a2b_uu, 1, doc_a2b_uu},
704 {"b2a_uu", binascii_b2a_uu, 1, doc_b2a_uu},
705 {"a2b_base64", binascii_a2b_base64, 1,
706 doc_a2b_base64},
707 {"b2a_base64", binascii_b2a_base64, 1,
708 doc_b2a_base64},
709 {"a2b_hqx", binascii_a2b_hqx, 1, doc_a2b_hqx},
710 {"b2a_hqx", binascii_b2a_hqx, 1, doc_b2a_hqx},
711 {"rlecode_hqx", binascii_rlecode_hqx, 1,
712 doc_rlecode_hqx},
713 {"rledecode_hqx", binascii_rledecode_hqx, 1,
714 doc_rledecode_hqx},
715 {"crc_hqx", binascii_crc_hqx, 1, doc_crc_hqx},
716 {NULL, NULL} /* sentinel */
720 /* Initialization function for the module (*must* be called initbinascii) */
721 static char doc_binascii[] = "Conversion between binary data and ASCII";
723 void
724 initbinascii()
726 PyObject *m, *d, *x;
728 /* Create the module and add the functions */
729 m = Py_InitModule("binascii", binascii_module_methods);
731 d = PyModule_GetDict(m);
732 x = PyString_FromString(doc_binascii);
733 PyDict_SetItemString(d, "__doc__", x);
735 Error = PyString_FromString("binascii.Error");
736 PyDict_SetItemString(d, "Error", Error);
737 Incomplete = PyString_FromString("binascii.Incomplete");
738 PyDict_SetItemString(d, "Incomplete", Incomplete);
740 /* Check for errors */
741 if (PyErr_Occurred())
742 Py_FatalError("can't initialize module binascii");