blob: c4c97b5d78535989a625e81fd06a877e5c966bea [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 }
Guido van Rossum9c6ba5e1997-01-12 20:02:04 +0000495 _PyString_Resize(
496 &rv, (bin_data - (unsigned char *)PyString_AsString(rv)));
497 if (rv) {
498 PyObject *rrv = Py_BuildValue("Oi", rv, done);
499 Py_DECREF(rv);
500 return rrv;
501 }
Jack Jansen72781191995-08-07 14:34:15 +0000502 return NULL;
503}
504
505static char doc_rlecode_hqx[] = "Binhex RLE-code binary data";
506
507static PyObject *
508binascii_rlecode_hqx(self, args)
509 PyObject *self;
510 PyObject *args;
511{
512 unsigned char *in_data, *out_data;
513 PyObject *rv;
514 unsigned char ch;
515 int in, inend, len;
516
517 if ( !PyArg_ParseTuple(args, "s#", &in_data, &len) )
518 return NULL;
519
520 /* Worst case: output is twice as big as input (fixed later) */
521 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
522 return NULL;
523 out_data = (unsigned char *)PyString_AsString(rv);
524
525 for( in=0; in<len; in++) {
526 ch = in_data[in];
527 if ( ch == RUNCHAR ) {
528 /* RUNCHAR. Escape it. */
529 *out_data++ = RUNCHAR;
530 *out_data++ = 0;
531 } else {
532 /* Check how many following are the same */
533 for(inend=in+1;
534 inend<len && in_data[inend] == ch &&
535 inend < in+255;
536 inend++) ;
Jack Jansen0223aa11995-08-31 13:44:23 +0000537 if ( inend - in > 3 ) {
538 /* More than 3 in a row. Output RLE. */
Jack Jansen72781191995-08-07 14:34:15 +0000539 *out_data++ = ch;
540 *out_data++ = RUNCHAR;
541 *out_data++ = inend-in;
542 in = inend-1;
543 } else {
544 /* Less than 3. Output the byte itself */
545 *out_data++ = ch;
546 }
547 }
548 }
549 _PyString_Resize(&rv, (out_data - (unsigned char *)PyString_AsString(rv)));
550 return rv;
551}
552
553static char doc_b2a_hqx[] = "Encode .hqx data";
554
555static PyObject *
556binascii_b2a_hqx(self, args)
557 PyObject *self;
558 PyObject *args;
559{
560 unsigned char *ascii_data, *bin_data;
561 int leftbits = 0;
562 unsigned char this_ch;
Jack Janseneaeb1c81995-08-14 12:17:57 +0000563 unsigned int leftchar = 0;
Jack Jansen72781191995-08-07 14:34:15 +0000564 PyObject *rv;
565 int len;
566
567 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &len) )
568 return NULL;
569
570 /* Allocate a buffer that is at least large enough */
571 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
572 return NULL;
573 ascii_data = (unsigned char *)PyString_AsString(rv);
574
575 for( ; len > 0 ; len--, bin_data++ ) {
576 /* Shift into our buffer, and output any 6bits ready */
577 leftchar = (leftchar << 8) | *bin_data;
578 leftbits += 8;
579 while ( leftbits >= 6 ) {
580 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
581 leftbits -= 6;
582 *ascii_data++ = table_b2a_hqx[this_ch];
583 }
584 }
585 /* Output a possible runt byte */
586 if ( leftbits ) {
587 leftchar <<= (6-leftbits);
588 *ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
589 }
590 _PyString_Resize(&rv, (ascii_data - (unsigned char *)PyString_AsString(rv)));
591 return rv;
592}
593
594static char doc_rledecode_hqx[] = "Decode hexbin RLE-coded string";
595
596static PyObject *
597binascii_rledecode_hqx(self, args)
598 PyObject *self;
599 PyObject *args;
600{
601 unsigned char *in_data, *out_data;
602 unsigned char in_byte, in_repeat;
603 PyObject *rv;
604 int in_len, out_len, out_len_left;
605
606 if ( !PyArg_ParseTuple(args, "s#", &in_data, &in_len) )
607 return NULL;
608
609 /* Empty string is a special case */
610 if ( in_len == 0 )
611 return Py_BuildValue("s", "");
612
613 /* Allocate a buffer of reasonable size. Resized when needed */
614 out_len = in_len*2;
615 if ( (rv=PyString_FromStringAndSize(NULL, out_len)) == NULL )
616 return NULL;
617 out_len_left = out_len;
618 out_data = (unsigned char *)PyString_AsString(rv);
619
620 /*
621 ** We need two macros here to get/put bytes and handle
622 ** end-of-buffer for input and output strings.
623 */
624#define INBYTE(b) \
625 do { \
626 if ( --in_len < 0 ) { \
627 PyErr_SetString(Incomplete, ""); \
628 Py_DECREF(rv); \
629 return NULL; \
630 } \
631 b = *in_data++; \
632 } while(0)
633
634#define OUTBYTE(b) \
635 do { \
636 if ( --out_len_left < 0 ) { \
637 _PyString_Resize(&rv, 2*out_len); \
638 if ( rv == NULL ) return NULL; \
639 out_data = (unsigned char *)PyString_AsString(rv) + out_len; \
Jack Jansenba1de3b1996-01-22 10:47:15 +0000640 out_len_left = out_len-1; \
Jack Jansen72781191995-08-07 14:34:15 +0000641 out_len = out_len * 2; \
642 } \
643 *out_data++ = b; \
644 } while(0)
645
646 /*
647 ** Handle first byte separately (since we have to get angry
648 ** in case of an orphaned RLE code).
649 */
650 INBYTE(in_byte);
651
652 if (in_byte == RUNCHAR) {
653 INBYTE(in_repeat);
654 if (in_repeat != 0) {
655 /* Note Error, not Incomplete (which is at the end
656 ** of the string only). This is a programmer error.
657 */
658 PyErr_SetString(Error, "Orphaned RLE code at start");
659 Py_DECREF(rv);
660 return NULL;
661 }
662 OUTBYTE(RUNCHAR);
663 } else {
664 OUTBYTE(in_byte);
665 }
666
667 while( in_len > 0 ) {
668 INBYTE(in_byte);
669
670 if (in_byte == RUNCHAR) {
671 INBYTE(in_repeat);
672 if ( in_repeat == 0 ) {
673 /* Just an escaped RUNCHAR value */
674 OUTBYTE(RUNCHAR);
675 } else {
676 /* Pick up value and output a sequence of it */
677 in_byte = out_data[-1];
678 while ( --in_repeat > 0 )
679 OUTBYTE(in_byte);
680 }
681 } else {
682 /* Normal byte */
683 OUTBYTE(in_byte);
684 }
685 }
686 _PyString_Resize(&rv, (out_data - (unsigned char *)PyString_AsString(rv)));
687 return rv;
688}
689
690static char doc_crc_hqx[] = "(data, oldcrc) -> newcrc. Compute hqx CRC incrementally";
691
692static PyObject *
693binascii_crc_hqx(self, args)
694 PyObject *self;
695 PyObject *args;
696{
697 unsigned char *bin_data;
698 unsigned int crc;
699 int len;
700
701 if ( !PyArg_ParseTuple(args, "s#i", &bin_data, &len, &crc) )
702 return NULL;
703
704 while(len--) {
705 crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
706 }
707
708 return Py_BuildValue("i", crc);
709}
710
711/* List of functions defined in the module */
712
713static struct PyMethodDef binascii_module_methods[] = {
714 {"a2b_uu", binascii_a2b_uu, 1, doc_a2b_uu},
715 {"b2a_uu", binascii_b2a_uu, 1, doc_b2a_uu},
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000716 {"a2b_base64", binascii_a2b_base64, 1,
717 doc_a2b_base64},
718 {"b2a_base64", binascii_b2a_base64, 1,
719 doc_b2a_base64},
Jack Jansen72781191995-08-07 14:34:15 +0000720 {"a2b_hqx", binascii_a2b_hqx, 1, doc_a2b_hqx},
721 {"b2a_hqx", binascii_b2a_hqx, 1, doc_b2a_hqx},
722 {"rlecode_hqx", binascii_rlecode_hqx, 1,
723 doc_rlecode_hqx},
724 {"rledecode_hqx", binascii_rledecode_hqx, 1,
725 doc_rledecode_hqx},
726 {"crc_hqx", binascii_crc_hqx, 1, doc_crc_hqx},
727 {NULL, NULL} /* sentinel */
728};
729
730
731/* Initialization function for the module (*must* be called initbinascii) */
732static char doc_binascii[] = "Conversion between binary data and ASCII";
733
734void
735initbinascii()
736{
737 PyObject *m, *d, *x;
738
739 /* Create the module and add the functions */
740 m = Py_InitModule("binascii", binascii_module_methods);
741
742 d = PyModule_GetDict(m);
743 x = PyString_FromString(doc_binascii);
744 PyDict_SetItemString(d, "__doc__", x);
745
746 Error = PyString_FromString("binascii.Error");
747 PyDict_SetItemString(d, "Error", Error);
748 Incomplete = PyString_FromString("binascii.Incomplete");
749 PyDict_SetItemString(d, "Incomplete", Incomplete);
750
751 /* Check for errors */
752 if (PyErr_Occurred())
753 Py_FatalError("can't initialize module binascii");
754}