blob: 7450349d8999dc5098771f070eaf14f85dfde739 [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.
38** hqx:
39** File starts with introductory text, real data starts and ends
40** with colons.
41** Data consists of three similar parts: info, datafork, resourcefork.
42** Each part is protected (at the end) with a 16-bit crc
43** The binary data is run-length encoded, and then ascii-fied:
44** binary: 01234567 abcdefgh ijklmnop
45** ascii: 012345 67abcd efghij klmnop
46** ASCII encoding is table-driven, see the code.
47** Short binary data results in the runt ascii-byte being output with
48** the bits in the right place.
49**
50** While I was reading dozens of programs that encode or decode the formats
51** here (documentation? hihi:-) I have formulated Jansen's Observation:
52**
53** Programs that encode binary data in ASCII are written in
54** such a style that they are as unreadable as possible. Devices used
55** include unnecessary global variables, burying important tables
56** in unrelated sourcefiles, putting functions in include files,
57** using seemingly-descriptive variable names for different purposes,
58** calls to empty subroutines and a host of others.
59**
60** I have attempted to break with this tradition, but I guess that that
61** does make the performance sub-optimal. Oh well, too bad...
62**
63** Jack Jansen, CWI, July 1995.
64*/
65
66
67#include "Python.h"
68
69static PyObject *Error;
70static PyObject *Incomplete;
71
72/*
73** hqx lookup table, ascii->binary.
74*/
75
76#define RUNCHAR 0x90
77
78#define DONE 0x7F
79#define SKIP 0x7E
80#define FAIL 0x7D
81
82static unsigned char table_a2b_hqx[256] = {
83/* ^@ ^A ^B ^C ^D ^E ^F ^G */
84/* 0*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
85/* \b \t \n ^K ^L \r ^N ^O */
86/* 1*/ FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
87/* ^P ^Q ^R ^S ^T ^U ^V ^W */
88/* 2*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
89/* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
90/* 3*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
91/* ! " # $ % & ' */
92/* 4*/ FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
93/* ( ) * + , - . / */
94/* 5*/ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
95/* 0 1 2 3 4 5 6 7 */
96/* 6*/ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
97/* 8 9 : ; < = > ? */
98/* 7*/ 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
99/* @ A B C D E F G */
100/* 8*/ 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
101/* H I J K L M N O */
102/* 9*/ 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
103/* P Q R S T U V W */
104/*10*/ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
105/* X Y Z [ \ ] ^ _ */
106/*11*/ 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
107/* ` a b c d e f g */
108/*12*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
109/* h i j k l m n o */
110/*13*/ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
111/* p q r s t u v w */
112/*14*/ 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
113/* x y z { | } ~ ^? */
114/*15*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
115/*16*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
116 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
117 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
118 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
119 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
120 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};
132
133static unsigned char table_b2a_hqx[] =
134 "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
135
136static unsigned short crctab_hqx[256] = {
137 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
138 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
139 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
140 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
141 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
142 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
143 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
144 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
145 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
146 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
147 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
148 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
149 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
150 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
151 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
152 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
153 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
154 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
155 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
156 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
157 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
158 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
159 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
160 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
161 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
162 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
163 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
164 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
165 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
166 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
167 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
168 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
169};
170
171static char doc_a2b_uu[] = "(ascii) -> bin. Decode a line of uuencoded data";
172
173static PyObject *
174binascii_a2b_uu(self, args)
175 PyObject *self;
176 PyObject *args;
177{
178 unsigned char *ascii_data, *bin_data;
179 int leftbits = 0;
180 unsigned char this_ch;
181 unsigned int leftchar = 0;
182 PyObject *rv;
183 int ascii_len, bin_len;
184
185 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &ascii_len) )
186 return NULL;
187
188 /* First byte: binary data length (in bytes) */
189 bin_len = (*ascii_data++ - ' ') & 077;
190 ascii_len--;
191
192 /* Allocate the buffer */
193 if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
194 return NULL;
195 bin_data = (unsigned char *)PyString_AsString(rv);
196
197 for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
198 this_ch = *ascii_data;
199 if ( this_ch == '\n' || this_ch == '\r' || ascii_len <= 0) {
200 /*
201 ** Whitespace. Assume some spaces got eaten at
202 ** end-of-line. (We check this later)
203 */
204 this_ch = 0;
205 } else {
206 /* Check the character for legality */
207 if ( this_ch < ' ' || this_ch > (' ' + 63)) {
208 PyErr_SetString(Error, "Illegal char");
209 Py_DECREF(rv);
210 return NULL;
211 }
212 this_ch = (this_ch - ' ') & 077;
213 }
214 /*
215 ** Shift it in on the low end, and see if there's
216 ** a byte ready for output.
217 */
218 leftchar = (leftchar << 6) | (this_ch);
219 leftbits += 6;
220 if ( leftbits >= 8 ) {
221 leftbits -= 8;
222 *bin_data++ = (leftchar >> leftbits) & 0xff;
223 leftchar &= ((1 << leftbits) - 1);
224 bin_len--;
225 }
226 }
227 /*
228 ** Finally, check that if there's anything left on the line
229 ** that it's whitespace only.
230 */
231 while( ascii_len-- > 0 ) {
232 this_ch = *ascii_data++;
233 if ( this_ch != ' ' && this_ch != '\n' && this_ch != '\r' ) {
234 PyErr_SetString(Error, "Trailing garbage");
235 Py_DECREF(rv);
236 return NULL;
237 }
238 }
239 return rv;
240}
241
242static char doc_b2a_uu[] = "(bin) -> ascii. Uuencode line of data";
243
244static PyObject *
245binascii_b2a_uu(self, args)
246 PyObject *self;
247 PyObject *args;
248{
249 unsigned char *ascii_data, *bin_data;
250 int leftbits = 0;
251 unsigned char this_ch;
252 unsigned int leftchar = 0;
253 PyObject *rv;
254 int bin_len;
255
256 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &bin_len) )
257 return NULL;
258 if ( bin_len > 45 ) {
259 /* The 45 is a limit that appears in all uuencode's */
260 PyErr_SetString(Error, "At most 45 bytes at once");
261 return NULL;
262 }
263
264 /* We're lazy and allocate to much (fixed up later) */
265 if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL )
266 return NULL;
267 ascii_data = (unsigned char *)PyString_AsString(rv);
268
269 /* Store the length */
270 *ascii_data++ = ' ' + (bin_len & 077);
271
272 for( ; bin_len > 0 || leftbits != 0 ; bin_len--, bin_data++ ) {
273 /* Shift the data (or padding) into our buffer */
274 if ( bin_len > 0 ) /* Data */
275 leftchar = (leftchar << 8) | *bin_data;
276 else /* Padding */
277 leftchar <<= 8;
278 leftbits += 8;
279
280 /* See if there are 6-bit groups ready */
281 while ( leftbits >= 6 ) {
282 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
283 leftbits -= 6;
284 *ascii_data++ = this_ch + ' ';
285 }
286 }
287 *ascii_data++ = '\n'; /* Append a courtesy newline */
288
289 _PyString_Resize(&rv, (ascii_data - (unsigned char *)PyString_AsString(rv)));
290 return rv;
291}
292
293static char doc_a2b_hqx[] = "ascii -> bin, done. Decode .hqx coding";
294
295static PyObject *
296binascii_a2b_hqx(self, args)
297 PyObject *self;
298 PyObject *args;
299{
300 unsigned char *ascii_data, *bin_data;
301 int leftbits = 0;
302 unsigned char this_ch;
Jack Janseneaeb1c81995-08-14 12:17:57 +0000303 unsigned int leftchar = 0;
Jack Jansen72781191995-08-07 14:34:15 +0000304 PyObject *rv;
305 int len;
306 int done = 0;
307
308 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &len) )
309 return NULL;
310
311 /* Allocate a string that is too big (fixed later) */
312 if ( (rv=PyString_FromStringAndSize(NULL, len)) == NULL )
313 return NULL;
314 bin_data = (unsigned char *)PyString_AsString(rv);
315
316 for( ; len > 0 ; len--, ascii_data++ ) {
317 /* Get the byte and look it up */
318 this_ch = table_a2b_hqx[*ascii_data];
319 if ( this_ch == SKIP )
320 continue;
321 if ( this_ch == FAIL ) {
322 PyErr_SetString(Error, "Illegal char");
323 Py_DECREF(rv);
324 return NULL;
325 }
326 if ( this_ch == DONE ) {
327 /* The terminating colon */
328 done = 1;
329 break;
330 }
331
332 /* Shift it into the buffer and see if any bytes are ready */
333 leftchar = (leftchar << 6) | (this_ch);
334 leftbits += 6;
335 if ( leftbits >= 8 ) {
336 leftbits -= 8;
337 *bin_data++ = (leftchar >> leftbits) & 0xff;
338 leftchar &= ((1 << leftbits) - 1);
339 }
340 }
341
342 if ( leftbits && !done ) {
343 PyErr_SetString(Incomplete,
344 "String has incomplete number of bytes");
345 Py_DECREF(rv);
346 return NULL;
347 }
348 _PyString_Resize(&rv, (bin_data - (unsigned char *)PyString_AsString(rv)));
349 if ( rv )
350 return Py_BuildValue("Oi", rv, done);
351 return NULL;
352}
353
354static char doc_rlecode_hqx[] = "Binhex RLE-code binary data";
355
356static PyObject *
357binascii_rlecode_hqx(self, args)
358 PyObject *self;
359 PyObject *args;
360{
361 unsigned char *in_data, *out_data;
362 PyObject *rv;
363 unsigned char ch;
364 int in, inend, len;
365
366 if ( !PyArg_ParseTuple(args, "s#", &in_data, &len) )
367 return NULL;
368
369 /* Worst case: output is twice as big as input (fixed later) */
370 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
371 return NULL;
372 out_data = (unsigned char *)PyString_AsString(rv);
373
374 for( in=0; in<len; in++) {
375 ch = in_data[in];
376 if ( ch == RUNCHAR ) {
377 /* RUNCHAR. Escape it. */
378 *out_data++ = RUNCHAR;
379 *out_data++ = 0;
380 } else {
381 /* Check how many following are the same */
382 for(inend=in+1;
383 inend<len && in_data[inend] == ch &&
384 inend < in+255;
385 inend++) ;
Jack Jansen0223aa11995-08-31 13:44:23 +0000386 if ( inend - in > 3 ) {
387 /* More than 3 in a row. Output RLE. */
Jack Jansen72781191995-08-07 14:34:15 +0000388 *out_data++ = ch;
389 *out_data++ = RUNCHAR;
390 *out_data++ = inend-in;
391 in = inend-1;
392 } else {
393 /* Less than 3. Output the byte itself */
394 *out_data++ = ch;
395 }
396 }
397 }
398 _PyString_Resize(&rv, (out_data - (unsigned char *)PyString_AsString(rv)));
399 return rv;
400}
401
402static char doc_b2a_hqx[] = "Encode .hqx data";
403
404static PyObject *
405binascii_b2a_hqx(self, args)
406 PyObject *self;
407 PyObject *args;
408{
409 unsigned char *ascii_data, *bin_data;
410 int leftbits = 0;
411 unsigned char this_ch;
Jack Janseneaeb1c81995-08-14 12:17:57 +0000412 unsigned int leftchar = 0;
Jack Jansen72781191995-08-07 14:34:15 +0000413 PyObject *rv;
414 int len;
415
416 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &len) )
417 return NULL;
418
419 /* Allocate a buffer that is at least large enough */
420 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
421 return NULL;
422 ascii_data = (unsigned char *)PyString_AsString(rv);
423
424 for( ; len > 0 ; len--, bin_data++ ) {
425 /* Shift into our buffer, and output any 6bits ready */
426 leftchar = (leftchar << 8) | *bin_data;
427 leftbits += 8;
428 while ( leftbits >= 6 ) {
429 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
430 leftbits -= 6;
431 *ascii_data++ = table_b2a_hqx[this_ch];
432 }
433 }
434 /* Output a possible runt byte */
435 if ( leftbits ) {
436 leftchar <<= (6-leftbits);
437 *ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
438 }
439 _PyString_Resize(&rv, (ascii_data - (unsigned char *)PyString_AsString(rv)));
440 return rv;
441}
442
443static char doc_rledecode_hqx[] = "Decode hexbin RLE-coded string";
444
445static PyObject *
446binascii_rledecode_hqx(self, args)
447 PyObject *self;
448 PyObject *args;
449{
450 unsigned char *in_data, *out_data;
451 unsigned char in_byte, in_repeat;
452 PyObject *rv;
453 int in_len, out_len, out_len_left;
454
455 if ( !PyArg_ParseTuple(args, "s#", &in_data, &in_len) )
456 return NULL;
457
458 /* Empty string is a special case */
459 if ( in_len == 0 )
460 return Py_BuildValue("s", "");
461
462 /* Allocate a buffer of reasonable size. Resized when needed */
463 out_len = in_len*2;
464 if ( (rv=PyString_FromStringAndSize(NULL, out_len)) == NULL )
465 return NULL;
466 out_len_left = out_len;
467 out_data = (unsigned char *)PyString_AsString(rv);
468
469 /*
470 ** We need two macros here to get/put bytes and handle
471 ** end-of-buffer for input and output strings.
472 */
473#define INBYTE(b) \
474 do { \
475 if ( --in_len < 0 ) { \
476 PyErr_SetString(Incomplete, ""); \
477 Py_DECREF(rv); \
478 return NULL; \
479 } \
480 b = *in_data++; \
481 } while(0)
482
483#define OUTBYTE(b) \
484 do { \
485 if ( --out_len_left < 0 ) { \
486 _PyString_Resize(&rv, 2*out_len); \
487 if ( rv == NULL ) return NULL; \
488 out_data = (unsigned char *)PyString_AsString(rv) + out_len; \
489 out_len_left = out_len; \
490 out_len = out_len * 2; \
491 } \
492 *out_data++ = b; \
493 } while(0)
494
495 /*
496 ** Handle first byte separately (since we have to get angry
497 ** in case of an orphaned RLE code).
498 */
499 INBYTE(in_byte);
500
501 if (in_byte == RUNCHAR) {
502 INBYTE(in_repeat);
503 if (in_repeat != 0) {
504 /* Note Error, not Incomplete (which is at the end
505 ** of the string only). This is a programmer error.
506 */
507 PyErr_SetString(Error, "Orphaned RLE code at start");
508 Py_DECREF(rv);
509 return NULL;
510 }
511 OUTBYTE(RUNCHAR);
512 } else {
513 OUTBYTE(in_byte);
514 }
515
516 while( in_len > 0 ) {
517 INBYTE(in_byte);
518
519 if (in_byte == RUNCHAR) {
520 INBYTE(in_repeat);
521 if ( in_repeat == 0 ) {
522 /* Just an escaped RUNCHAR value */
523 OUTBYTE(RUNCHAR);
524 } else {
525 /* Pick up value and output a sequence of it */
526 in_byte = out_data[-1];
527 while ( --in_repeat > 0 )
528 OUTBYTE(in_byte);
529 }
530 } else {
531 /* Normal byte */
532 OUTBYTE(in_byte);
533 }
534 }
535 _PyString_Resize(&rv, (out_data - (unsigned char *)PyString_AsString(rv)));
536 return rv;
537}
538
539static char doc_crc_hqx[] = "(data, oldcrc) -> newcrc. Compute hqx CRC incrementally";
540
541static PyObject *
542binascii_crc_hqx(self, args)
543 PyObject *self;
544 PyObject *args;
545{
546 unsigned char *bin_data;
547 unsigned int crc;
548 int len;
549
550 if ( !PyArg_ParseTuple(args, "s#i", &bin_data, &len, &crc) )
551 return NULL;
552
553 while(len--) {
554 crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
555 }
556
557 return Py_BuildValue("i", crc);
558}
559
560/* List of functions defined in the module */
561
562static struct PyMethodDef binascii_module_methods[] = {
563 {"a2b_uu", binascii_a2b_uu, 1, doc_a2b_uu},
564 {"b2a_uu", binascii_b2a_uu, 1, doc_b2a_uu},
565 {"a2b_hqx", binascii_a2b_hqx, 1, doc_a2b_hqx},
566 {"b2a_hqx", binascii_b2a_hqx, 1, doc_b2a_hqx},
567 {"rlecode_hqx", binascii_rlecode_hqx, 1,
568 doc_rlecode_hqx},
569 {"rledecode_hqx", binascii_rledecode_hqx, 1,
570 doc_rledecode_hqx},
571 {"crc_hqx", binascii_crc_hqx, 1, doc_crc_hqx},
572 {NULL, NULL} /* sentinel */
573};
574
575
576/* Initialization function for the module (*must* be called initbinascii) */
577static char doc_binascii[] = "Conversion between binary data and ASCII";
578
579void
580initbinascii()
581{
582 PyObject *m, *d, *x;
583
584 /* Create the module and add the functions */
585 m = Py_InitModule("binascii", binascii_module_methods);
586
587 d = PyModule_GetDict(m);
588 x = PyString_FromString(doc_binascii);
589 PyDict_SetItemString(d, "__doc__", x);
590
591 Error = PyString_FromString("binascii.Error");
592 PyDict_SetItemString(d, "Error", Error);
593 Incomplete = PyString_FromString("binascii.Incomplete");
594 PyDict_SetItemString(d, "Incomplete", Incomplete);
595
596 /* Check for errors */
597 if (PyErr_Occurred())
598 Py_FatalError("can't initialize module binascii");
599}