blob: 62beaeab018ed8a9a40b94018c9cc2951d246186 [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[] =
146 "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
147
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[] =
163 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
164
165
166
Jack Jansen72781191995-08-07 14:34:15 +0000167static unsigned short crctab_hqx[256] = {
168 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,
200};
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;
207 PyObject *args;
208{
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
238 ** The 64 in stead of the expected 63 is because there are a few
239 ** uuencodes out there that use '@' as zero in stead of space.
240 */
241 if ( this_ch < ' ' || this_ch > (' ' + 64)) {
Jack Jansen72781191995-08-07 14:34:15 +0000242 PyErr_SetString(Error, "Illegal char");
243 Py_DECREF(rv);
244 return NULL;
245 }
246 this_ch = (this_ch - ' ') & 077;
247 }
248 /*
249 ** Shift it in on the low end, and see if there's
250 ** a byte ready for output.
251 */
252 leftchar = (leftchar << 6) | (this_ch);
253 leftbits += 6;
254 if ( leftbits >= 8 ) {
255 leftbits -= 8;
256 *bin_data++ = (leftchar >> leftbits) & 0xff;
257 leftchar &= ((1 << leftbits) - 1);
258 bin_len--;
259 }
260 }
261 /*
262 ** Finally, check that if there's anything left on the line
263 ** that it's whitespace only.
264 */
265 while( ascii_len-- > 0 ) {
266 this_ch = *ascii_data++;
267 if ( this_ch != ' ' && this_ch != '\n' && this_ch != '\r' ) {
268 PyErr_SetString(Error, "Trailing garbage");
269 Py_DECREF(rv);
270 return NULL;
271 }
272 }
273 return rv;
274}
275
276static char doc_b2a_uu[] = "(bin) -> ascii. Uuencode line of data";
277
278static PyObject *
279binascii_b2a_uu(self, args)
280 PyObject *self;
281 PyObject *args;
282{
283 unsigned char *ascii_data, *bin_data;
284 int leftbits = 0;
285 unsigned char this_ch;
286 unsigned int leftchar = 0;
287 PyObject *rv;
288 int bin_len;
289
290 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &bin_len) )
291 return NULL;
292 if ( bin_len > 45 ) {
293 /* The 45 is a limit that appears in all uuencode's */
294 PyErr_SetString(Error, "At most 45 bytes at once");
295 return NULL;
296 }
297
298 /* We're lazy and allocate to much (fixed up later) */
299 if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL )
300 return NULL;
301 ascii_data = (unsigned char *)PyString_AsString(rv);
302
303 /* Store the length */
304 *ascii_data++ = ' ' + (bin_len & 077);
305
306 for( ; bin_len > 0 || leftbits != 0 ; bin_len--, bin_data++ ) {
307 /* Shift the data (or padding) into our buffer */
308 if ( bin_len > 0 ) /* Data */
309 leftchar = (leftchar << 8) | *bin_data;
310 else /* Padding */
311 leftchar <<= 8;
312 leftbits += 8;
313
314 /* See if there are 6-bit groups ready */
315 while ( leftbits >= 6 ) {
316 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
317 leftbits -= 6;
318 *ascii_data++ = this_ch + ' ';
319 }
320 }
321 *ascii_data++ = '\n'; /* Append a courtesy newline */
322
323 _PyString_Resize(&rv, (ascii_data - (unsigned char *)PyString_AsString(rv)));
324 return rv;
325}
326
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000327static char doc_a2b_base64[] = "(ascii) -> bin. Decode a line of base64 data";
328
329static PyObject *
330binascii_a2b_base64(self, args)
331 PyObject *self;
332 PyObject *args;
333{
334 unsigned char *ascii_data, *bin_data;
335 int leftbits = 0;
336 unsigned char this_ch;
337 unsigned int leftchar = 0;
338 int npad = 0;
339 PyObject *rv;
340 int ascii_len, bin_len;
341
342 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &ascii_len) )
343 return NULL;
344
345 bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
346
347 /* Allocate the buffer */
348 if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
349 return NULL;
350 bin_data = (unsigned char *)PyString_AsString(rv);
351 bin_len = 0;
352 for( ; ascii_len > 0 ; ascii_len--, ascii_data++ ) {
Jack Jansenba1de3b1996-01-22 10:47:15 +0000353 /* Skip some punctuation */
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000354 this_ch = (*ascii_data & 0x7f);
Jack Jansenba1de3b1996-01-22 10:47:15 +0000355 if ( this_ch == '\r' || this_ch == '\n' || this_ch == ' ' )
356 continue;
357
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000358 if ( this_ch == BASE64_PAD )
359 npad++;
360 this_ch = table_a2b_base64[(*ascii_data) & 0x7f];
Guido van Rossum485f2da1996-02-25 04:50:30 +0000361 if ( this_ch == (unsigned char) -1 ) continue;
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000362 /*
363 ** Shift it in on the low end, and see if there's
364 ** a byte ready for output.
365 */
366 leftchar = (leftchar << 6) | (this_ch);
367 leftbits += 6;
368 if ( leftbits >= 8 ) {
369 leftbits -= 8;
370 *bin_data++ = (leftchar >> leftbits) & 0xff;
371 leftchar &= ((1 << leftbits) - 1);
372 bin_len++;
373 }
374 }
375 /* Check that no bits are left */
376 if ( leftbits ) {
377 PyErr_SetString(Error, "Incorrect padding");
378 Py_DECREF(rv);
379 return NULL;
380 }
381 /* and remove any padding */
382 bin_len -= npad;
383 /* and set string size correctly */
384 _PyString_Resize(&rv, bin_len);
385 return rv;
386}
387
388static char doc_b2a_base64[] = "(bin) -> ascii. Base64-code line of data";
389
390static PyObject *
391binascii_b2a_base64(self, args)
392 PyObject *self;
393 PyObject *args;
394{
395 unsigned char *ascii_data, *bin_data;
396 int leftbits = 0;
397 unsigned char this_ch;
398 unsigned int leftchar = 0;
399 PyObject *rv;
400 int bin_len;
401
402 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &bin_len) )
403 return NULL;
404 if ( bin_len > BASE64_MAXBIN ) {
405 PyErr_SetString(Error, "Too much data for base64 line");
406 return NULL;
407 }
408
409 /* We're lazy and allocate to much (fixed up later) */
410 if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL )
411 return NULL;
412 ascii_data = (unsigned char *)PyString_AsString(rv);
413
414 for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
415 /* Shift the data into our buffer */
416 leftchar = (leftchar << 8) | *bin_data;
417 leftbits += 8;
418
419 /* See if there are 6-bit groups ready */
420 while ( leftbits >= 6 ) {
421 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
422 leftbits -= 6;
423 *ascii_data++ = table_b2a_base64[this_ch];
424 }
425 }
426 if ( leftbits == 2 ) {
427 *ascii_data++ = table_b2a_base64[(leftchar&3) << 4];
428 *ascii_data++ = BASE64_PAD;
429 *ascii_data++ = BASE64_PAD;
430 } else if ( leftbits == 4 ) {
431 *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2];
432 *ascii_data++ = BASE64_PAD;
433 }
434 *ascii_data++ = '\n'; /* Append a courtesy newline */
435
436 _PyString_Resize(&rv, (ascii_data - (unsigned char *)PyString_AsString(rv)));
437 return rv;
438}
439
Jack Jansen72781191995-08-07 14:34:15 +0000440static char doc_a2b_hqx[] = "ascii -> bin, done. Decode .hqx coding";
441
442static PyObject *
443binascii_a2b_hqx(self, args)
444 PyObject *self;
445 PyObject *args;
446{
447 unsigned char *ascii_data, *bin_data;
448 int leftbits = 0;
449 unsigned char this_ch;
Jack Janseneaeb1c81995-08-14 12:17:57 +0000450 unsigned int leftchar = 0;
Jack Jansen72781191995-08-07 14:34:15 +0000451 PyObject *rv;
452 int len;
453 int done = 0;
454
455 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &len) )
456 return NULL;
457
458 /* Allocate a string that is too big (fixed later) */
459 if ( (rv=PyString_FromStringAndSize(NULL, len)) == NULL )
460 return NULL;
461 bin_data = (unsigned char *)PyString_AsString(rv);
462
463 for( ; len > 0 ; len--, ascii_data++ ) {
464 /* Get the byte and look it up */
465 this_ch = table_a2b_hqx[*ascii_data];
466 if ( this_ch == SKIP )
467 continue;
468 if ( this_ch == FAIL ) {
469 PyErr_SetString(Error, "Illegal char");
470 Py_DECREF(rv);
471 return NULL;
472 }
473 if ( this_ch == DONE ) {
474 /* The terminating colon */
475 done = 1;
476 break;
477 }
478
479 /* Shift it into the buffer and see if any bytes are ready */
480 leftchar = (leftchar << 6) | (this_ch);
481 leftbits += 6;
482 if ( leftbits >= 8 ) {
483 leftbits -= 8;
484 *bin_data++ = (leftchar >> leftbits) & 0xff;
485 leftchar &= ((1 << leftbits) - 1);
486 }
487 }
488
489 if ( leftbits && !done ) {
490 PyErr_SetString(Incomplete,
491 "String has incomplete number of bytes");
492 Py_DECREF(rv);
493 return NULL;
494 }
495 _PyString_Resize(&rv, (bin_data - (unsigned char *)PyString_AsString(rv)));
496 if ( rv )
497 return Py_BuildValue("Oi", rv, done);
498 return NULL;
499}
500
501static char doc_rlecode_hqx[] = "Binhex RLE-code binary data";
502
503static PyObject *
504binascii_rlecode_hqx(self, args)
505 PyObject *self;
506 PyObject *args;
507{
508 unsigned char *in_data, *out_data;
509 PyObject *rv;
510 unsigned char ch;
511 int in, inend, len;
512
513 if ( !PyArg_ParseTuple(args, "s#", &in_data, &len) )
514 return NULL;
515
516 /* Worst case: output is twice as big as input (fixed later) */
517 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
518 return NULL;
519 out_data = (unsigned char *)PyString_AsString(rv);
520
521 for( in=0; in<len; in++) {
522 ch = in_data[in];
523 if ( ch == RUNCHAR ) {
524 /* RUNCHAR. Escape it. */
525 *out_data++ = RUNCHAR;
526 *out_data++ = 0;
527 } else {
528 /* Check how many following are the same */
529 for(inend=in+1;
530 inend<len && in_data[inend] == ch &&
531 inend < in+255;
532 inend++) ;
Jack Jansen0223aa11995-08-31 13:44:23 +0000533 if ( inend - in > 3 ) {
534 /* More than 3 in a row. Output RLE. */
Jack Jansen72781191995-08-07 14:34:15 +0000535 *out_data++ = ch;
536 *out_data++ = RUNCHAR;
537 *out_data++ = inend-in;
538 in = inend-1;
539 } else {
540 /* Less than 3. Output the byte itself */
541 *out_data++ = ch;
542 }
543 }
544 }
545 _PyString_Resize(&rv, (out_data - (unsigned char *)PyString_AsString(rv)));
546 return rv;
547}
548
549static char doc_b2a_hqx[] = "Encode .hqx data";
550
551static PyObject *
552binascii_b2a_hqx(self, args)
553 PyObject *self;
554 PyObject *args;
555{
556 unsigned char *ascii_data, *bin_data;
557 int leftbits = 0;
558 unsigned char this_ch;
Jack Janseneaeb1c81995-08-14 12:17:57 +0000559 unsigned int leftchar = 0;
Jack Jansen72781191995-08-07 14:34:15 +0000560 PyObject *rv;
561 int len;
562
563 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &len) )
564 return NULL;
565
566 /* Allocate a buffer that is at least large enough */
567 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
568 return NULL;
569 ascii_data = (unsigned char *)PyString_AsString(rv);
570
571 for( ; len > 0 ; len--, bin_data++ ) {
572 /* Shift into our buffer, and output any 6bits ready */
573 leftchar = (leftchar << 8) | *bin_data;
574 leftbits += 8;
575 while ( leftbits >= 6 ) {
576 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
577 leftbits -= 6;
578 *ascii_data++ = table_b2a_hqx[this_ch];
579 }
580 }
581 /* Output a possible runt byte */
582 if ( leftbits ) {
583 leftchar <<= (6-leftbits);
584 *ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
585 }
586 _PyString_Resize(&rv, (ascii_data - (unsigned char *)PyString_AsString(rv)));
587 return rv;
588}
589
590static char doc_rledecode_hqx[] = "Decode hexbin RLE-coded string";
591
592static PyObject *
593binascii_rledecode_hqx(self, args)
594 PyObject *self;
595 PyObject *args;
596{
597 unsigned char *in_data, *out_data;
598 unsigned char in_byte, in_repeat;
599 PyObject *rv;
600 int in_len, out_len, out_len_left;
601
602 if ( !PyArg_ParseTuple(args, "s#", &in_data, &in_len) )
603 return NULL;
604
605 /* Empty string is a special case */
606 if ( in_len == 0 )
607 return Py_BuildValue("s", "");
608
609 /* Allocate a buffer of reasonable size. Resized when needed */
610 out_len = in_len*2;
611 if ( (rv=PyString_FromStringAndSize(NULL, out_len)) == NULL )
612 return NULL;
613 out_len_left = out_len;
614 out_data = (unsigned char *)PyString_AsString(rv);
615
616 /*
617 ** We need two macros here to get/put bytes and handle
618 ** end-of-buffer for input and output strings.
619 */
620#define INBYTE(b) \
621 do { \
622 if ( --in_len < 0 ) { \
623 PyErr_SetString(Incomplete, ""); \
624 Py_DECREF(rv); \
625 return NULL; \
626 } \
627 b = *in_data++; \
628 } while(0)
629
630#define OUTBYTE(b) \
631 do { \
632 if ( --out_len_left < 0 ) { \
633 _PyString_Resize(&rv, 2*out_len); \
634 if ( rv == NULL ) return NULL; \
635 out_data = (unsigned char *)PyString_AsString(rv) + out_len; \
Jack Jansenba1de3b1996-01-22 10:47:15 +0000636 out_len_left = out_len-1; \
Jack Jansen72781191995-08-07 14:34:15 +0000637 out_len = out_len * 2; \
638 } \
639 *out_data++ = b; \
640 } while(0)
641
642 /*
643 ** Handle first byte separately (since we have to get angry
644 ** in case of an orphaned RLE code).
645 */
646 INBYTE(in_byte);
647
648 if (in_byte == RUNCHAR) {
649 INBYTE(in_repeat);
650 if (in_repeat != 0) {
651 /* Note Error, not Incomplete (which is at the end
652 ** of the string only). This is a programmer error.
653 */
654 PyErr_SetString(Error, "Orphaned RLE code at start");
655 Py_DECREF(rv);
656 return NULL;
657 }
658 OUTBYTE(RUNCHAR);
659 } else {
660 OUTBYTE(in_byte);
661 }
662
663 while( in_len > 0 ) {
664 INBYTE(in_byte);
665
666 if (in_byte == RUNCHAR) {
667 INBYTE(in_repeat);
668 if ( in_repeat == 0 ) {
669 /* Just an escaped RUNCHAR value */
670 OUTBYTE(RUNCHAR);
671 } else {
672 /* Pick up value and output a sequence of it */
673 in_byte = out_data[-1];
674 while ( --in_repeat > 0 )
675 OUTBYTE(in_byte);
676 }
677 } else {
678 /* Normal byte */
679 OUTBYTE(in_byte);
680 }
681 }
682 _PyString_Resize(&rv, (out_data - (unsigned char *)PyString_AsString(rv)));
683 return rv;
684}
685
686static char doc_crc_hqx[] = "(data, oldcrc) -> newcrc. Compute hqx CRC incrementally";
687
688static PyObject *
689binascii_crc_hqx(self, args)
690 PyObject *self;
691 PyObject *args;
692{
693 unsigned char *bin_data;
694 unsigned int crc;
695 int len;
696
697 if ( !PyArg_ParseTuple(args, "s#i", &bin_data, &len, &crc) )
698 return NULL;
699
700 while(len--) {
701 crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
702 }
703
704 return Py_BuildValue("i", crc);
705}
706
707/* List of functions defined in the module */
708
709static struct PyMethodDef binascii_module_methods[] = {
710 {"a2b_uu", binascii_a2b_uu, 1, doc_a2b_uu},
711 {"b2a_uu", binascii_b2a_uu, 1, doc_b2a_uu},
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000712 {"a2b_base64", binascii_a2b_base64, 1,
713 doc_a2b_base64},
714 {"b2a_base64", binascii_b2a_base64, 1,
715 doc_b2a_base64},
Jack Jansen72781191995-08-07 14:34:15 +0000716 {"a2b_hqx", binascii_a2b_hqx, 1, doc_a2b_hqx},
717 {"b2a_hqx", binascii_b2a_hqx, 1, doc_b2a_hqx},
718 {"rlecode_hqx", binascii_rlecode_hqx, 1,
719 doc_rlecode_hqx},
720 {"rledecode_hqx", binascii_rledecode_hqx, 1,
721 doc_rledecode_hqx},
722 {"crc_hqx", binascii_crc_hqx, 1, doc_crc_hqx},
723 {NULL, NULL} /* sentinel */
724};
725
726
727/* Initialization function for the module (*must* be called initbinascii) */
728static char doc_binascii[] = "Conversion between binary data and ASCII";
729
730void
731initbinascii()
732{
733 PyObject *m, *d, *x;
734
735 /* Create the module and add the functions */
736 m = Py_InitModule("binascii", binascii_module_methods);
737
738 d = PyModule_GetDict(m);
739 x = PyString_FromString(doc_binascii);
740 PyDict_SetItemString(d, "__doc__", x);
741
742 Error = PyString_FromString("binascii.Error");
743 PyDict_SetItemString(d, "Error", Error);
744 Incomplete = PyString_FromString("binascii.Incomplete");
745 PyDict_SetItemString(d, "Incomplete", Incomplete);
746
747 /* Check for errors */
748 if (PyErr_Occurred())
749 Py_FatalError("can't initialize module binascii");
750}