blob: 295ff74b1b8df2f8ed37b98287532217b98356c4 [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[] =
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000146"!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
Jack Jansen72781191995-08-07 14:34:15 +0000147
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[] =
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000163"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000164
165
166
Jack Jansen72781191995-08-07 14:34:15 +0000167static unsigned short crctab_hqx[256] = {
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000168 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,
Jack Jansen72781191995-08-07 14:34:15 +0000200};
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;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000207 PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000208{
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
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000238 ** The 64 in stead of the expected 63 is because
239 ** there are a few uuencodes out there that use
240 ** '@' as zero instead of space.
Jack Jansen5d957971995-11-14 10:35:19 +0000241 */
242 if ( this_ch < ' ' || this_ch > (' ' + 64)) {
Jack Jansen72781191995-08-07 14:34:15 +0000243 PyErr_SetString(Error, "Illegal char");
244 Py_DECREF(rv);
245 return NULL;
246 }
247 this_ch = (this_ch - ' ') & 077;
248 }
249 /*
250 ** Shift it in on the low end, and see if there's
251 ** a byte ready for output.
252 */
253 leftchar = (leftchar << 6) | (this_ch);
254 leftbits += 6;
255 if ( leftbits >= 8 ) {
256 leftbits -= 8;
257 *bin_data++ = (leftchar >> leftbits) & 0xff;
258 leftchar &= ((1 << leftbits) - 1);
259 bin_len--;
260 }
261 }
262 /*
263 ** Finally, check that if there's anything left on the line
264 ** that it's whitespace only.
265 */
266 while( ascii_len-- > 0 ) {
267 this_ch = *ascii_data++;
Guido van Rossum1243ae71997-07-11 18:36:28 +0000268 /* Extra '@' may be written as padding in some cases */
269 if ( this_ch != ' ' && this_ch != '@' &&
270 this_ch != '\n' && this_ch != '\r' ) {
Jack Jansen72781191995-08-07 14:34:15 +0000271 PyErr_SetString(Error, "Trailing garbage");
272 Py_DECREF(rv);
273 return NULL;
274 }
275 }
276 return rv;
277}
278
279static char doc_b2a_uu[] = "(bin) -> ascii. Uuencode line of data";
280
281static PyObject *
282binascii_b2a_uu(self, args)
283 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000284 PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000285{
286 unsigned char *ascii_data, *bin_data;
287 int leftbits = 0;
288 unsigned char this_ch;
289 unsigned int leftchar = 0;
290 PyObject *rv;
291 int bin_len;
292
293 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &bin_len) )
294 return NULL;
295 if ( bin_len > 45 ) {
296 /* The 45 is a limit that appears in all uuencode's */
297 PyErr_SetString(Error, "At most 45 bytes at once");
298 return NULL;
299 }
300
301 /* We're lazy and allocate to much (fixed up later) */
302 if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL )
303 return NULL;
304 ascii_data = (unsigned char *)PyString_AsString(rv);
305
306 /* Store the length */
307 *ascii_data++ = ' ' + (bin_len & 077);
308
309 for( ; bin_len > 0 || leftbits != 0 ; bin_len--, bin_data++ ) {
310 /* Shift the data (or padding) into our buffer */
311 if ( bin_len > 0 ) /* Data */
312 leftchar = (leftchar << 8) | *bin_data;
313 else /* Padding */
314 leftchar <<= 8;
315 leftbits += 8;
316
317 /* See if there are 6-bit groups ready */
318 while ( leftbits >= 6 ) {
319 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
320 leftbits -= 6;
321 *ascii_data++ = this_ch + ' ';
322 }
323 }
324 *ascii_data++ = '\n'; /* Append a courtesy newline */
325
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000326 _PyString_Resize(&rv, (ascii_data -
327 (unsigned char *)PyString_AsString(rv)));
Jack Jansen72781191995-08-07 14:34:15 +0000328 return rv;
329}
330
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000331static char doc_a2b_base64[] = "(ascii) -> bin. Decode a line of base64 data";
332
333static PyObject *
334binascii_a2b_base64(self, args)
335 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000336 PyObject *args;
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000337{
338 unsigned char *ascii_data, *bin_data;
339 int leftbits = 0;
340 unsigned char this_ch;
341 unsigned int leftchar = 0;
342 int npad = 0;
343 PyObject *rv;
344 int ascii_len, bin_len;
345
346 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &ascii_len) )
347 return NULL;
348
349 bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
350
351 /* Allocate the buffer */
352 if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
353 return NULL;
354 bin_data = (unsigned char *)PyString_AsString(rv);
355 bin_len = 0;
356 for( ; ascii_len > 0 ; ascii_len--, ascii_data++ ) {
Jack Jansenba1de3b1996-01-22 10:47:15 +0000357 /* Skip some punctuation */
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000358 this_ch = (*ascii_data & 0x7f);
Jack Jansenba1de3b1996-01-22 10:47:15 +0000359 if ( this_ch == '\r' || this_ch == '\n' || this_ch == ' ' )
360 continue;
361
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000362 if ( this_ch == BASE64_PAD )
363 npad++;
364 this_ch = table_a2b_base64[(*ascii_data) & 0x7f];
Guido van Rossum485f2da1996-02-25 04:50:30 +0000365 if ( this_ch == (unsigned char) -1 ) continue;
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000366 /*
367 ** Shift it in on the low end, and see if there's
368 ** a byte ready for output.
369 */
370 leftchar = (leftchar << 6) | (this_ch);
371 leftbits += 6;
372 if ( leftbits >= 8 ) {
373 leftbits -= 8;
374 *bin_data++ = (leftchar >> leftbits) & 0xff;
375 leftchar &= ((1 << leftbits) - 1);
376 bin_len++;
377 }
378 }
379 /* Check that no bits are left */
380 if ( leftbits ) {
381 PyErr_SetString(Error, "Incorrect padding");
382 Py_DECREF(rv);
383 return NULL;
384 }
385 /* and remove any padding */
386 bin_len -= npad;
387 /* and set string size correctly */
388 _PyString_Resize(&rv, bin_len);
389 return rv;
390}
391
392static char doc_b2a_base64[] = "(bin) -> ascii. Base64-code line of data";
393
394static PyObject *
395binascii_b2a_base64(self, args)
396 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000397 PyObject *args;
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000398{
399 unsigned char *ascii_data, *bin_data;
400 int leftbits = 0;
401 unsigned char this_ch;
402 unsigned int leftchar = 0;
403 PyObject *rv;
404 int bin_len;
405
406 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &bin_len) )
407 return NULL;
408 if ( bin_len > BASE64_MAXBIN ) {
409 PyErr_SetString(Error, "Too much data for base64 line");
410 return NULL;
411 }
412
413 /* We're lazy and allocate to much (fixed up later) */
414 if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL )
415 return NULL;
416 ascii_data = (unsigned char *)PyString_AsString(rv);
417
418 for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
419 /* Shift the data into our buffer */
420 leftchar = (leftchar << 8) | *bin_data;
421 leftbits += 8;
422
423 /* See if there are 6-bit groups ready */
424 while ( leftbits >= 6 ) {
425 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
426 leftbits -= 6;
427 *ascii_data++ = table_b2a_base64[this_ch];
428 }
429 }
430 if ( leftbits == 2 ) {
431 *ascii_data++ = table_b2a_base64[(leftchar&3) << 4];
432 *ascii_data++ = BASE64_PAD;
433 *ascii_data++ = BASE64_PAD;
434 } else if ( leftbits == 4 ) {
435 *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2];
436 *ascii_data++ = BASE64_PAD;
437 }
438 *ascii_data++ = '\n'; /* Append a courtesy newline */
439
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000440 _PyString_Resize(&rv, (ascii_data -
441 (unsigned char *)PyString_AsString(rv)));
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000442 return rv;
443}
444
Jack Jansen72781191995-08-07 14:34:15 +0000445static char doc_a2b_hqx[] = "ascii -> bin, done. Decode .hqx coding";
446
447static PyObject *
448binascii_a2b_hqx(self, args)
449 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000450 PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000451{
452 unsigned char *ascii_data, *bin_data;
453 int leftbits = 0;
454 unsigned char this_ch;
Jack Janseneaeb1c81995-08-14 12:17:57 +0000455 unsigned int leftchar = 0;
Jack Jansen72781191995-08-07 14:34:15 +0000456 PyObject *rv;
457 int len;
458 int done = 0;
459
460 if ( !PyArg_ParseTuple(args, "s#", &ascii_data, &len) )
461 return NULL;
462
463 /* Allocate a string that is too big (fixed later) */
464 if ( (rv=PyString_FromStringAndSize(NULL, len)) == NULL )
465 return NULL;
466 bin_data = (unsigned char *)PyString_AsString(rv);
467
468 for( ; len > 0 ; len--, ascii_data++ ) {
469 /* Get the byte and look it up */
470 this_ch = table_a2b_hqx[*ascii_data];
471 if ( this_ch == SKIP )
472 continue;
473 if ( this_ch == FAIL ) {
474 PyErr_SetString(Error, "Illegal char");
475 Py_DECREF(rv);
476 return NULL;
477 }
478 if ( this_ch == DONE ) {
479 /* The terminating colon */
480 done = 1;
481 break;
482 }
483
484 /* Shift it into the buffer and see if any bytes are ready */
485 leftchar = (leftchar << 6) | (this_ch);
486 leftbits += 6;
487 if ( leftbits >= 8 ) {
488 leftbits -= 8;
489 *bin_data++ = (leftchar >> leftbits) & 0xff;
490 leftchar &= ((1 << leftbits) - 1);
491 }
492 }
493
494 if ( leftbits && !done ) {
495 PyErr_SetString(Incomplete,
496 "String has incomplete number of bytes");
497 Py_DECREF(rv);
498 return NULL;
499 }
Guido van Rossum9c6ba5e1997-01-12 20:02:04 +0000500 _PyString_Resize(
501 &rv, (bin_data - (unsigned char *)PyString_AsString(rv)));
502 if (rv) {
503 PyObject *rrv = Py_BuildValue("Oi", rv, done);
504 Py_DECREF(rv);
505 return rrv;
506 }
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000507
Jack Jansen72781191995-08-07 14:34:15 +0000508 return NULL;
509}
510
511static char doc_rlecode_hqx[] = "Binhex RLE-code binary data";
512
513static PyObject *
514binascii_rlecode_hqx(self, args)
515 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000516PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000517{
518 unsigned char *in_data, *out_data;
519 PyObject *rv;
520 unsigned char ch;
521 int in, inend, len;
522
523 if ( !PyArg_ParseTuple(args, "s#", &in_data, &len) )
524 return NULL;
525
526 /* Worst case: output is twice as big as input (fixed later) */
527 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
528 return NULL;
529 out_data = (unsigned char *)PyString_AsString(rv);
530
531 for( in=0; in<len; in++) {
532 ch = in_data[in];
533 if ( ch == RUNCHAR ) {
534 /* RUNCHAR. Escape it. */
535 *out_data++ = RUNCHAR;
536 *out_data++ = 0;
537 } else {
538 /* Check how many following are the same */
539 for(inend=in+1;
540 inend<len && in_data[inend] == ch &&
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000541 inend < in+255;
Jack Jansen72781191995-08-07 14:34:15 +0000542 inend++) ;
Jack Jansen0223aa11995-08-31 13:44:23 +0000543 if ( inend - in > 3 ) {
544 /* More than 3 in a row. Output RLE. */
Jack Jansen72781191995-08-07 14:34:15 +0000545 *out_data++ = ch;
546 *out_data++ = RUNCHAR;
547 *out_data++ = inend-in;
548 in = inend-1;
549 } else {
550 /* Less than 3. Output the byte itself */
551 *out_data++ = ch;
552 }
553 }
554 }
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000555 _PyString_Resize(&rv, (out_data -
556 (unsigned char *)PyString_AsString(rv)));
Jack Jansen72781191995-08-07 14:34:15 +0000557 return rv;
558}
559
560static char doc_b2a_hqx[] = "Encode .hqx data";
561
562static PyObject *
563binascii_b2a_hqx(self, args)
564 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000565 PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000566{
567 unsigned char *ascii_data, *bin_data;
568 int leftbits = 0;
569 unsigned char this_ch;
Jack Janseneaeb1c81995-08-14 12:17:57 +0000570 unsigned int leftchar = 0;
Jack Jansen72781191995-08-07 14:34:15 +0000571 PyObject *rv;
572 int len;
573
574 if ( !PyArg_ParseTuple(args, "s#", &bin_data, &len) )
575 return NULL;
576
577 /* Allocate a buffer that is at least large enough */
578 if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
579 return NULL;
580 ascii_data = (unsigned char *)PyString_AsString(rv);
581
582 for( ; len > 0 ; len--, bin_data++ ) {
583 /* Shift into our buffer, and output any 6bits ready */
584 leftchar = (leftchar << 8) | *bin_data;
585 leftbits += 8;
586 while ( leftbits >= 6 ) {
587 this_ch = (leftchar >> (leftbits-6)) & 0x3f;
588 leftbits -= 6;
589 *ascii_data++ = table_b2a_hqx[this_ch];
590 }
591 }
592 /* Output a possible runt byte */
593 if ( leftbits ) {
594 leftchar <<= (6-leftbits);
595 *ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
596 }
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000597 _PyString_Resize(&rv, (ascii_data -
598 (unsigned char *)PyString_AsString(rv)));
Jack Jansen72781191995-08-07 14:34:15 +0000599 return rv;
600}
601
602static char doc_rledecode_hqx[] = "Decode hexbin RLE-coded string";
603
604static PyObject *
605binascii_rledecode_hqx(self, args)
606 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000607 PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000608{
609 unsigned char *in_data, *out_data;
610 unsigned char in_byte, in_repeat;
611 PyObject *rv;
612 int in_len, out_len, out_len_left;
613
614 if ( !PyArg_ParseTuple(args, "s#", &in_data, &in_len) )
615 return NULL;
616
617 /* Empty string is a special case */
618 if ( in_len == 0 )
619 return Py_BuildValue("s", "");
620
621 /* Allocate a buffer of reasonable size. Resized when needed */
622 out_len = in_len*2;
623 if ( (rv=PyString_FromStringAndSize(NULL, out_len)) == NULL )
624 return NULL;
625 out_len_left = out_len;
626 out_data = (unsigned char *)PyString_AsString(rv);
627
628 /*
629 ** We need two macros here to get/put bytes and handle
630 ** end-of-buffer for input and output strings.
631 */
632#define INBYTE(b) \
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000633 do { \
634 if ( --in_len < 0 ) { \
635 PyErr_SetString(Incomplete, ""); \
636 Py_DECREF(rv); \
637 return NULL; \
638 } \
639 b = *in_data++; \
640 } while(0)
Jack Jansen72781191995-08-07 14:34:15 +0000641
642#define OUTBYTE(b) \
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000643 do { \
644 if ( --out_len_left < 0 ) { \
645 _PyString_Resize(&rv, 2*out_len); \
646 if ( rv == NULL ) return NULL; \
647 out_data = (unsigned char *)PyString_AsString(rv) \
648 + out_len; \
649 out_len_left = out_len-1; \
650 out_len = out_len * 2; \
651 } \
652 *out_data++ = b; \
653 } while(0)
Jack Jansen72781191995-08-07 14:34:15 +0000654
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000655 /*
656 ** Handle first byte separately (since we have to get angry
657 ** in case of an orphaned RLE code).
658 */
659 INBYTE(in_byte);
Jack Jansen72781191995-08-07 14:34:15 +0000660
661 if (in_byte == RUNCHAR) {
662 INBYTE(in_repeat);
663 if (in_repeat != 0) {
664 /* Note Error, not Incomplete (which is at the end
665 ** of the string only). This is a programmer error.
666 */
667 PyErr_SetString(Error, "Orphaned RLE code at start");
668 Py_DECREF(rv);
669 return NULL;
670 }
671 OUTBYTE(RUNCHAR);
672 } else {
673 OUTBYTE(in_byte);
674 }
675
676 while( in_len > 0 ) {
677 INBYTE(in_byte);
678
679 if (in_byte == RUNCHAR) {
680 INBYTE(in_repeat);
681 if ( in_repeat == 0 ) {
682 /* Just an escaped RUNCHAR value */
683 OUTBYTE(RUNCHAR);
684 } else {
685 /* Pick up value and output a sequence of it */
686 in_byte = out_data[-1];
687 while ( --in_repeat > 0 )
688 OUTBYTE(in_byte);
689 }
690 } else {
691 /* Normal byte */
692 OUTBYTE(in_byte);
693 }
694 }
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000695 _PyString_Resize(&rv, (out_data -
696 (unsigned char *)PyString_AsString(rv)));
Jack Jansen72781191995-08-07 14:34:15 +0000697 return rv;
698}
699
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000700static char doc_crc_hqx[] =
701"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally";
Jack Jansen72781191995-08-07 14:34:15 +0000702
703static PyObject *
704binascii_crc_hqx(self, args)
705 PyObject *self;
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000706PyObject *args;
Jack Jansen72781191995-08-07 14:34:15 +0000707{
708 unsigned char *bin_data;
709 unsigned int crc;
710 int len;
711
712 if ( !PyArg_ParseTuple(args, "s#i", &bin_data, &len, &crc) )
713 return NULL;
714
715 while(len--) {
716 crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
717 }
718
719 return Py_BuildValue("i", crc);
720}
721
722/* List of functions defined in the module */
723
724static struct PyMethodDef binascii_module_methods[] = {
725 {"a2b_uu", binascii_a2b_uu, 1, doc_a2b_uu},
726 {"b2a_uu", binascii_b2a_uu, 1, doc_b2a_uu},
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000727 {"a2b_base64", binascii_a2b_base64, 1,
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000728 doc_a2b_base64},
Jack Jansen84bbc2e1995-10-04 16:38:44 +0000729 {"b2a_base64", binascii_b2a_base64, 1,
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000730 doc_b2a_base64},
Jack Jansen72781191995-08-07 14:34:15 +0000731 {"a2b_hqx", binascii_a2b_hqx, 1, doc_a2b_hqx},
732 {"b2a_hqx", binascii_b2a_hqx, 1, doc_b2a_hqx},
733 {"rlecode_hqx", binascii_rlecode_hqx, 1,
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000734 doc_rlecode_hqx},
Jack Jansen72781191995-08-07 14:34:15 +0000735 {"rledecode_hqx", binascii_rledecode_hqx, 1,
Roger E. Masse5f4ce181997-01-16 17:10:22 +0000736 doc_rledecode_hqx},
Jack Jansen72781191995-08-07 14:34:15 +0000737 {"crc_hqx", binascii_crc_hqx, 1, doc_crc_hqx},
738 {NULL, NULL} /* sentinel */
739};
740
741
742/* Initialization function for the module (*must* be called initbinascii) */
743static char doc_binascii[] = "Conversion between binary data and ASCII";
744
745void
746initbinascii()
747{
748 PyObject *m, *d, *x;
749
750 /* Create the module and add the functions */
751 m = Py_InitModule("binascii", binascii_module_methods);
752
753 d = PyModule_GetDict(m);
754 x = PyString_FromString(doc_binascii);
755 PyDict_SetItemString(d, "__doc__", x);
Guido van Rossum5c159bd1997-08-04 23:55:25 +0000756 Py_XDECREF(x);
Jack Jansen72781191995-08-07 14:34:15 +0000757
Guido van Rossum7dbb48a1997-10-08 15:26:07 +0000758 Error = PyErr_NewException("binascii.Error", NULL, NULL);
Jack Jansen72781191995-08-07 14:34:15 +0000759 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum7dbb48a1997-10-08 15:26:07 +0000760 Incomplete = PyErr_NewException("binascii.Incomplete", NULL, NULL);
Jack Jansen72781191995-08-07 14:34:15 +0000761 PyDict_SetItemString(d, "Incomplete", Incomplete);
Jack Jansen72781191995-08-07 14:34:15 +0000762}