KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > modules > binascii


1 /*
2  * Copyright 1998 Finn Bock.
3  *
4  * This program contains material copyrighted by:
5  * Copyright (c) 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
6  * Amsterdam, The Netherlands.
7  */

8
9 package org.python.modules;
10
11
12 import java.util.*;
13
14 import org.python.core.*;
15
16 /**
17  * The <tt>binascii.java</tt> module contains a number of methods to convert
18  * between binary and various ASCII-encoded binary
19  * representations. Normally, you will not use these modules directly but
20  * use wrapper modules like <tt>uu</tt><a name="l2h-"></a> or
21  * <tt>hexbin</tt><a name="l2h-"></a> instead, this module solely
22  * exists because bit-manipuation of large amounts of data is slow in
23  * Python.
24  *
25  * <P>
26  * The <tt>binascii.java</tt> module defines the following functions:
27  * <P>
28  * <dl><dt><b><a name="l2h-19960"><tt>a2b_uu</tt></a></b> (<var>string</var>)
29  * <dd>
30  * Convert a single line of uuencoded data back to binary and return the
31  * binary data. Lines normally contain 45 (binary) bytes, except for the
32  * last line. Line data may be followed by whitespace.
33  * </dl>
34  *
35  * <P>
36  * <dl><dt><b><tt>b2a_uu</tt></b> (<var>data</var>)
37  * <dd>
38  * Convert binary data to a line of ASCII characters, the return value
39  * is the converted line, including a newline char. The length of
40  * <i>data</i> should be at most 45.
41  * </dl>
42  *
43  * <P>
44  * <dl><dt><b><tt>a2b_base64</tt></b> (<var>string</var>)
45  * <dd>
46  * Convert a block of base64 data back to binary and return the
47  * binary data. More than one line may be passed at a time.
48  * </dl>
49  *
50  * <P>
51  * <dl><dt><b><tt>b2a_base64</tt></b> (<var>data</var>)
52  * <dd>
53  * Convert binary data to a line of ASCII characters in base64 coding.
54  * The return value is the converted line, including a newline char.
55  * The length of <i>data</i> should be at most 57 to adhere to the base64
56  * standard.
57  * </dl>
58  *
59  * <P>
60  * <dl><dt><b><tt>a2b_hqx</tt></b> (<var>string</var>)
61  * <dd>
62  * Convert binhex4 formatted ASCII data to binary, without doing
63  * RLE-decompression. The string should contain a complete number of
64  * binary bytes, or (in case of the last portion of the binhex4 data)
65  * have the remaining bits zero.
66  * </dl>
67  *
68  * <P>
69  * <dl><dt><b><tt>rledecode_hqx</tt></b> (<var>data</var>)
70  * <dd>
71  * Perform RLE-decompression on the data, as per the binhex4
72  * standard. The algorithm uses <tt>0x90</tt> after a byte as a repeat
73  * indicator, followed by a count. A count of <tt>0</tt> specifies a byte
74  * value of <tt>0x90</tt>. The routine returns the decompressed data,
75  * unless data input data ends in an orphaned repeat indicator, in which
76  * case the <tt>Incomplete</tt> exception is raised.
77  * </dl>
78  *
79  * <P>
80  * <dl><dt><b><tt>rlecode_hqx</tt></b> (<var>data</var>)
81  * <dd>
82  * Perform binhex4 style RLE-compression on <i>data</i> and return the
83  * result.
84  * </dl>
85  *
86  * <P>
87  * <dl><dt><b><tt>b2a_hqx</tt></b> (<var>data</var>)
88  * <dd>
89  * Perform hexbin4 binary-to-ASCII translation and return the
90  * resulting string. The argument should already be RLE-coded, and have a
91  * length divisible by 3 (except possibly the last fragment).
92  * </dl>
93  *
94  * <P>
95  * <dl><dt><b><tt>crc_hqx</tt></b> (<var>data, crc</var>)
96  * <dd>
97  * Compute the binhex4 crc value of <i>data</i>, starting with an initial
98  * <i>crc</i> and returning the result.
99  * </dl>
100  *
101  * <dl><dt><b><tt>Error</tt></b>
102  * <dd>
103  * Exception raised on errors. These are usually programming errors.
104  * </dl>
105  *
106  * <P>
107  * <dl><dt><b><tt>Incomplete</tt></b>
108  * <dd>
109  * Exception raised on incomplete data. These are usually not programming
110  * errors, but may be handled by reading a little more data and trying
111  * again.
112  * </dl>
113  *
114  * The module is a line-by-line conversion of the original binasciimodule.c
115  * written by Jack Jansen, except that all mistakes and errors are my own.
116  * <p>
117  * @author Finn Bock, bckfnn@pipmail.dknet.dk
118  * @version binascii.java,v 1.6 1999/02/20 11:37:07 fb Exp
119
120  */

121 public class binascii {
122
123     public static String JavaDoc __doc__ = "Conversion between binary data and ASCII";
124
125     public static final PyString Error = new PyString("binascii.Error");
126
127     public static final PyString Incomplete =
128                                      new PyString("binascii.Incomplete");
129
130
131     // hqx lookup table, ascii->binary.
132
private static char RUNCHAR = 0x90;
133
134     private static short DONE = 0x7F;
135     private static short SKIP = 0x7E;
136     private static short FAIL = 0x7D;
137
138     private static short[] table_a2b_hqx = {
139         /* ^@ ^A ^B ^C ^D ^E ^F ^G */
140         /* 0*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
141         /* \b \t \n ^K ^L \r ^N ^O */
142         /* 1*/ FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
143         /* ^P ^Q ^R ^S ^T ^U ^V ^W */
144         /* 2*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
145         /* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
146         /* 3*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
147         /* ! " # $ % & ' */
148         /* 4*/ FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
149         /* ( ) * + , - . / */
150         /* 5*/ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
151         /* 0 1 2 3 4 5 6 7 */
152         /* 6*/ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
153         /* 8 9 : ; < = > ? */
154         /* 7*/ 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
155         /* @ A B C D E F G */
156         /* 8*/ 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
157         /* H I J K L M N O */
158         /* 9*/ 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
159         /* P Q R S T U V W */
160         /*10*/ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
161         /* X Y Z [ \ ] ^ _ */
162         /*11*/ 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
163         /* ` a b c d e f g */
164         /*12*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
165         /* h i j k l m n o */
166         /*13*/ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
167         /* p q r s t u v w */
168         /*14*/ 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
169         /* x y z { | } ~ ^? */
170         /*15*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
171         /*16*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
172                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
173                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
174                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
175                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
176                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
177                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
178                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
179                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
180                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
181                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
182                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
183                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
184                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
185                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
186                 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
187     };
188
189     private static byte[] table_b2a_hqx =
190         "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr".
191            getBytes();
192
193
194
195
196     private static short table_a2b_base64[] = {
197         -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
198         -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
199         -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
200         52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */
201         -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
202         15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
203         -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
204         41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
205     };
206
207     private static char BASE64_PAD = '=';
208
209     /* Max binary chunk size (76 char line) */
210     private static int BASE64_MAXBIN = 57;
211
212     private static byte[] table_b2a_base64 =
213         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".
214             getBytes();
215
216
217
218     private static int[] crctab_hqx = {
219         0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
220         0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
221         0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
222         0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
223         0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
224         0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
225         0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
226         0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
227         0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
228         0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
229         0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
230         0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
231         0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
232         0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
233         0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
234         0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
235         0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
236         0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
237         0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
238         0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
239         0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
240         0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
241         0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
242         0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
243         0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
244         0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
245         0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
246         0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
247         0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
248         0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
249         0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
250         0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
251     };
252
253
254
255     public static PyString __doc__a2b_uu = new PyString(
256         "(ascii) -> bin. Decode a line of uuencoded data"
257     );
258
259
260     /**
261      * Convert a single line of uuencoded data back to binary and return the
262      * binary data. Lines normally contain 45 (binary) bytes, except for the
263      * last line. Line data may be followed by whitespace.
264      */

265     public static String JavaDoc a2b_uu(String JavaDoc ascii_data) {
266         int leftbits = 0;
267         int leftchar = 0;
268
269         StringBuffer JavaDoc bin_data = new StringBuffer JavaDoc();
270
271         char this_ch;
272         int i;
273
274         int ascii_len = ascii_data.length()-1;
275
276         int bin_len = (ascii_data.charAt(0) - ' ') & 077;
277
278         for (i = 0; bin_len > 0; i++, ascii_len--) {
279             this_ch = ascii_data.charAt(i+1);
280             if (this_ch == '\n' || this_ch == '\r' || ascii_len <= 0) {
281                 // Whitespace. Assume some spaces got eaten at
282
// end-of-line. (We check this later)
283
this_ch = 0;
284             } else {
285                 // Check the character for legality
286
// The 64 in stead of the expected 63 is because
287
// there are a few uuencodes out there that use
288
// '@' as zero instead of space.
289
if ( this_ch < ' ' || this_ch > (' ' + 64)) {
290                     throw new PyException(Error, "Illegal char");
291                 }
292                 this_ch = (char)((this_ch - ' ') & 077);
293             }
294             // Shift it in on the low end, and see if there's
295
// a byte ready for output.
296
leftchar = (leftchar << 6) | (this_ch);
297             leftbits += 6;
298             if (leftbits >= 8) {
299                 leftbits -= 8;
300                 bin_data.append((char)((leftchar >> leftbits) & 0xff));
301                 leftchar &= ((1 << leftbits) - 1);
302                 bin_len--;
303             }
304         }
305         // Finally, check that if there's anything left on the line
306
// that it's whitespace only.
307
while (ascii_len-- > 0) {
308             this_ch = ascii_data.charAt(++i);
309             // Extra '@' may be written as padding in some cases
310
if (this_ch != ' ' && this_ch != '@' &&
311                      this_ch != '\n' && this_ch != '\r') {
312                 throw new PyException(Error, "Trailing garbage");
313             }
314         }
315         return bin_data.toString();
316     }
317
318
319
320     public static PyString __doc__b2a_uu = new PyString(
321         "(bin) -> ascii. Uuencode line of data"
322     );
323
324
325     /**
326      * Convert binary data to a line of ASCII characters, the return value
327      * is the converted line, including a newline char. The length of
328      * <i>data</i> should be at most 45.
329      */

330     public static String JavaDoc b2a_uu(String JavaDoc bin_data) {
331         int leftbits = 0;
332         char this_ch;
333         int leftchar = 0;
334
335         int bin_len = bin_data.length();
336         if (bin_len > 45) {
337             // The 45 is a limit that appears in all uuencode's
338
throw new PyException(Error, "At most 45 bytes at once");
339         }
340
341         StringBuffer JavaDoc ascii_data = new StringBuffer JavaDoc();
342
343         // Store the length */
344
ascii_data.append((char)(' ' + (bin_len & 077)));
345
346         for (int i = 0; bin_len > 0 || leftbits != 0; i++, bin_len--) {
347             // Shift the data (or padding) into our buffer
348
if (bin_len > 0) // Data
349
leftchar = (leftchar << 8) | bin_data.charAt(i);
350             else // Padding
351
leftchar <<= 8;
352             leftbits += 8;
353
354             // See if there are 6-bit groups ready
355
while (leftbits >= 6) {
356                 this_ch = (char)((leftchar >> (leftbits-6)) & 0x3f);
357                 leftbits -= 6;
358                 ascii_data.append((char)(this_ch + ' '));
359             }
360         }
361         ascii_data.append('\n'); // Append a courtesy newline
362

363         return ascii_data.toString();
364     }
365
366
367     private static int binascii_find_valid(String JavaDoc s, int offset, int num) {
368         int slen = s.length() - offset;
369
370         /* Finds & returns the (num+1)th
371         ** valid character for base64, or -1 if none.
372         */

373
374         int ret = -1;
375
376         while ((slen > 0) && (ret == -1)) {
377             int c = (int)s.charAt(offset);
378             short b64val = table_a2b_base64[c & 0x7f];
379             if (((c <= 0x7f) && (b64val != -1)) ) {
380                 if (num == 0)
381                      ret = c;
382                 num--;
383             }
384
385             offset++;
386             slen--;
387         }
388         return ret;
389     }
390
391
392
393     public static PyString __doc__a2b_base64 = new PyString(
394          "(ascii) -> bin. Decode a line of base64 data"
395     );
396
397     /**
398      * Convert a block of base64 data back to binary and return the
399      * binary data. More than one line may be passed at a time.
400      */

401     public static String JavaDoc a2b_base64(String JavaDoc ascii_data) {
402         int leftbits = 0;
403         char this_ch;
404         int leftchar = 0;
405         int quad_pos = 0;
406
407         int ascii_len = ascii_data.length();
408
409         int bin_len = 0;
410         StringBuffer JavaDoc bin_data = new StringBuffer JavaDoc();
411
412         for(int i = 0; ascii_len > 0 ; ascii_len--, i++) {
413             // Skip some punctuation
414
this_ch = ascii_data.charAt(i);
415             if ((int) this_ch > 0x7F || this_ch == '\r' ||
416                       this_ch == '\n' || this_ch == ' ')
417                 continue;
418
419             if (this_ch == BASE64_PAD) {
420                 if (quad_pos < 2 || (quad_pos == 2 &&
421                          binascii_find_valid(ascii_data, i, 1) != BASE64_PAD))
422                     continue;
423                 else {
424                     // A pad sequence means no more input.
425
// We've already interpreted the data
426
// from the quad at this point.
427
leftbits = 0;
428                     break;
429                 }
430             }
431
432             short this_v = table_a2b_base64[(int) this_ch];
433             if (this_v == -1)
434                 continue;
435
436             // Shift it in on the low end, and see if there's
437
// a byte ready for output.
438
quad_pos = (quad_pos + 1) & 0x03;
439             leftchar = (leftchar << 6) | (this_v);
440             leftbits += 6;
441             if (leftbits >= 8) {
442                 leftbits -= 8;
443                 bin_data.append((char)((leftchar >> leftbits) & 0xff));
444                 bin_len++;
445                 leftchar &= ((1 << leftbits) - 1);
446             }
447         }
448         // Check that no bits are left
449
if (leftbits != 0) {
450             throw new PyException(Error, "Incorrect padding");
451         }
452         return bin_data.toString();
453     }
454
455
456
457     public static PyString __doc__b2a_base64 = new PyString(
458         "(bin) -> ascii. Base64-code line of data"
459     );
460
461
462     /**
463      * Convert binary data to a line of ASCII characters in base64 coding.
464      * The return value is the converted line, including a newline char.
465      * The length of <i>data</i> should be at most 57 to adhere to the base64
466      * standard.
467      */

468     public static String JavaDoc b2a_base64(String JavaDoc bin_data) {
469         int leftbits = 0;
470         char this_ch;
471         int leftchar = 0;
472
473         StringBuffer JavaDoc ascii_data = new StringBuffer JavaDoc();
474
475         int bin_len = bin_data.length();
476         if (bin_len > BASE64_MAXBIN) {
477             throw new PyException(Error,"Too much data for base64 line");
478         }
479
480         for (int i = 0; bin_len > 0 ; bin_len--, i++) {
481             // Shift the data into our buffer
482
leftchar = (leftchar << 8) | bin_data.charAt(i);
483             leftbits += 8;
484
485             // See if there are 6-bit groups ready
486
while (leftbits >= 6) {
487                 this_ch = (char)((leftchar >> (leftbits-6)) & 0x3f);
488                 leftbits -= 6;
489                 ascii_data.append((char)table_b2a_base64[this_ch]);
490             }
491         }
492         if (leftbits == 2) {
493             ascii_data.append((char)table_b2a_base64[(leftchar&3) << 4]);
494             ascii_data.append(BASE64_PAD);
495             ascii_data.append(BASE64_PAD);
496         } else if (leftbits == 4) {
497             ascii_data.append((char)table_b2a_base64[(leftchar&0xf) << 2]);
498             ascii_data.append(BASE64_PAD);
499         }
500         ascii_data.append('\n'); // Append a courtesy newline
501

502         return ascii_data.toString();
503     }
504
505
506     public static PyString __doc__a2b_hqx = new PyString(
507          "ascii -> bin, done. Decode .hqx coding"
508     );
509
510     /**
511      * Convert binhex4 formatted ASCII data to binary, without doing
512      * RLE-decompression. The string should contain a complete number of
513      * binary bytes, or (in case of the last portion of the binhex4 data)
514      * have the remaining bits zero.
515      */

516     public static PyTuple a2b_hqx(String JavaDoc ascii_data) {
517         int leftbits = 0;
518         char this_ch;
519         int leftchar = 0;
520
521         boolean done = false;
522
523         int len = ascii_data.length();
524
525         StringBuffer JavaDoc bin_data = new StringBuffer JavaDoc();
526
527         for(int i = 0; len > 0 ; len--, i++) {
528             // Get the byte and look it up
529
this_ch = (char) table_a2b_hqx[ascii_data.charAt(i)];
530             if (this_ch == SKIP)
531                 continue;
532             if (this_ch == FAIL) {
533                 throw new PyException(Error, "Illegal char");
534             }
535             if (this_ch == DONE) {
536                 // The terminating colon
537
done = true;
538                 break;
539             }
540
541             // Shift it into the buffer and see if any bytes are ready
542
leftchar = (leftchar << 6) | (this_ch);
543             leftbits += 6;
544             if (leftbits >= 8) {
545                 leftbits -= 8;
546                 bin_data.append((char)((leftchar >> leftbits) & 0xff));
547                 leftchar &= ((1 << leftbits) - 1);
548             }
549         }
550
551         if (leftbits != 0 && !done) {
552             throw new PyException(Incomplete,
553                                   "String has incomplete number of bytes");
554         }
555
556         return new PyTuple(new PyObject[] {
557                            Py.java2py(bin_data.toString()),
558                            Py.newInteger(done ? 1 : 0) });
559     }
560
561
562     public static PyString __doc__rlecode_hqx = new PyString(
563          "Binhex RLE-code binary data"
564     );
565
566     /**
567      * Perform binhex4 style RLE-compression on <i>data</i> and return the
568      * result.
569      */

570     static public String JavaDoc rlecode_hqx(String JavaDoc in_data) {
571         int len = in_data.length();
572
573         StringBuffer JavaDoc out_data = new StringBuffer JavaDoc();
574
575         for (int in=0; in < len; in++) {
576             char ch = in_data.charAt(in);
577             if (ch == RUNCHAR) {
578                 // RUNCHAR. Escape it.
579
out_data.append(RUNCHAR);
580                 out_data.append(0);
581             } else {
582                 // Check how many following are the same
583
int inend;
584                 for (inend=in+1; inend < len &&
585                                  in_data.charAt(inend) == ch &&
586                                  inend < in+255; inend++)
587                     ;
588                 if (inend - in > 3) {
589                     // More than 3 in a row. Output RLE.
590
out_data.append(ch);
591                     out_data.append(RUNCHAR);
592                     out_data.append((char) (inend-in));
593                     in = inend-1;
594                 } else {
595                     // Less than 3. Output the byte itself
596
out_data.append(ch);
597                 }
598             }
599         }
600         return out_data.toString();
601     }
602
603
604     public static PyString __doc__b2a_hqx = new PyString(
605          "Encode .hqx data"
606     );
607
608     /**
609      * Perform hexbin4 binary-to-ASCII translation and return the
610      * resulting string. The argument should already be RLE-coded, and have a
611      * length divisible by 3 (except possibly the last fragment).
612      */

613     public static String JavaDoc b2a_hqx(String JavaDoc bin_data) {
614         int leftbits = 0;
615         char this_ch;
616         int leftchar = 0;
617
618         int len = bin_data.length();
619
620         StringBuffer JavaDoc ascii_data = new StringBuffer JavaDoc();
621
622         for(int i = 0; len > 0; len--, i++) {
623             // Shift into our buffer, and output any 6bits ready
624
leftchar = (leftchar << 8) | bin_data.charAt(i);
625             leftbits += 8;
626             while (leftbits >= 6) {
627                 this_ch = (char) ((leftchar >> (leftbits-6)) & 0x3f);
628                 leftbits -= 6;
629                 ascii_data.append((char) table_b2a_hqx[this_ch]);
630             }
631         }
632         // Output a possible runt byte
633
if (leftbits != 0) {
634             leftchar <<= (6-leftbits);
635             ascii_data.append((char) table_b2a_hqx[leftchar & 0x3f]);
636         }
637         return ascii_data.toString();
638     }
639
640
641
642     public static PyString __doc__rledecode_hqx = new PyString(
643         "Decode hexbin RLE-coded string"
644     );
645
646
647     /**
648      * Perform RLE-decompression on the data, as per the binhex4
649      * standard. The algorithm uses <tt>0x90</tt> after a byte as a repeat
650      * indicator, followed by a count. A count of <tt>0</tt> specifies a byte
651      * value of <tt>0x90</tt>. The routine returns the decompressed data,
652      * unless data input data ends in an orphaned repeat indicator, in which
653      * case the <tt>Incomplete</tt> exception is raised.
654      */

655     static public String JavaDoc rledecode_hqx(String JavaDoc in_data) {
656         char in_byte, in_repeat;
657
658         int in_len = in_data.length();
659         int i = 0;
660
661         // Empty string is a special case
662
if (in_len == 0)
663             return "";
664
665         StringBuffer JavaDoc out_data = new StringBuffer JavaDoc();
666
667         // Handle first byte separately (since we have to get angry
668
// in case of an orphaned RLE code).
669
if (--in_len < 0) throw new PyException(Incomplete);
670         in_byte = in_data.charAt(i++);
671
672         if (in_byte == RUNCHAR) {
673             if (--in_len < 0) throw new PyException(Incomplete);
674             in_repeat = in_data.charAt(i++);
675
676             if (in_repeat != 0) {
677                 // Note Error, not Incomplete (which is at the end
678
// of the string only). This is a programmer error.
679
throw new PyException(Error, "Orphaned RLE code at start");
680             }
681             out_data.append(RUNCHAR);
682         } else {
683             out_data.append(in_byte);
684         }
685
686         while (in_len > 0) {
687             if (--in_len < 0) throw new PyException(Incomplete);
688             in_byte = in_data.charAt(i++);
689
690             if (in_byte == RUNCHAR) {
691                 if (--in_len < 0) throw new PyException(Incomplete);
692                 in_repeat = in_data.charAt(i++);
693
694                 if (in_repeat == 0) {
695                     // Just an escaped RUNCHAR value
696
out_data.append(RUNCHAR);
697                 } else {
698                     // Pick up value and output a sequence of it
699
in_byte = out_data.charAt(out_data.length()-1);
700                     while (--in_repeat > 0)
701                         out_data.append(in_byte);
702                 }
703             } else {
704                 // Normal byte
705
out_data.append(in_byte);
706             }
707         }
708         return out_data.toString();
709     }
710
711
712
713     public static PyString __doc__crc_hqx = new PyString(
714         "(data, oldcrc) -> newcrc. Compute hqx CRC incrementally"
715     );
716
717
718     /**
719      * Compute the binhex4 crc value of <i>data</i>, starting with an initial
720      * <i>crc</i> and returning the result.
721      */

722     public static int crc_hqx(String JavaDoc bin_data, int crc) {
723         int len = bin_data.length();
724         int i = 0;
725
726         while(len-- > 0) {
727             crc=((crc<<8)&0xff00) ^
728                        crctab_hqx[((crc>>8)&0xff)^bin_data.charAt(i++)];
729         }
730
731         return crc;
732     }
733
734
735
736
737 static long[] crc_32_tab = new long[] {
738 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
739 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
740 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
741 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
742 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
743 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
744 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
745 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
746 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
747 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
748 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
749 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
750 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
751 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
752 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
753 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
754 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
755 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
756 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
757 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
758 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
759 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
760 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
761 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
762 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
763 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
764 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
765 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
766 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
767 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
768 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
769 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
770 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
771 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
772 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
773 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
774 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
775 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
776 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
777 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
778 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
779 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
780 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
781 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
782 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
783 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
784 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
785 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
786 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
787 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
788 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
789 0x2d02ef8dL
790 };
791
792     public static int crc32(String JavaDoc bin_data) {
793         return crc32(bin_data, 0);
794     }
795
796     public static int crc32(String JavaDoc bin_data, long crc) {
797         int len = bin_data.length();
798
799         crc &= 0xFFFFFFFFL;
800         crc = crc ^ 0xFFFFFFFFL;
801         for (int i = 0; i < len; i++) {
802             char ch = bin_data.charAt(i);
803             crc = (int)crc_32_tab[(int) ((crc ^ ch) & 0xffL)] ^ (crc >> 8);
804             /* Note: (crc >> 8) MUST zero fill on left */
805             crc &= 0xFFFFFFFFL;
806         }
807         if (crc >= 0x80000000)
808             return -(int)(crc+1 & 0xFFFFFFFF);
809         else
810             return (int)(crc & 0xFFFFFFFF);
811     }
812
813
814     private static char[] hexdigit = "0123456789abcdef".toCharArray();
815
816
817     public static PyString __doc__b2a_hex = new PyString(
818         "b2a_hex(data) -> s; Hexadecimal representation of binary data.\n" +
819         "\n" +
820         "This function is also available as \"hexlify()\"."
821     );
822
823     public static String JavaDoc b2a_hex(String JavaDoc argbuf) {
824         int arglen = argbuf.length();
825
826         StringBuffer JavaDoc retbuf = new StringBuffer JavaDoc(arglen*2);
827
828         /* make hex version of string, taken from shamodule.c */
829         for (int i = 0; i < arglen; i++) {
830             char ch = argbuf.charAt(i);
831             retbuf.append(hexdigit[(ch >>> 4) & 0xF]);
832             retbuf.append(hexdigit[ch & 0xF]);
833         }
834         return retbuf.toString();
835
836     }
837
838
839     public static String JavaDoc hexlify(String JavaDoc argbuf) {
840         return b2a_hex(argbuf);
841     }
842
843
844     public static PyString a2b_hex$doc = new PyString(
845         "a2b_hex(hexstr) -> s; Binary data of hexadecimal representation.\n" +
846         "\n" +
847         "hexstr must contain an even number of hex digits "+
848         "(upper or lower case).\n"+
849         "This function is also available as \"unhexlify()\""
850     );
851
852
853     public static String JavaDoc a2b_hex(String JavaDoc argbuf) {
854         int arglen = argbuf.length();
855
856         /* XXX What should we do about strings with an odd length? Should
857          * we add an implicit leading zero, or a trailing zero? For now,
858          * raise an exception.
859          */

860         if (arglen % 2 != 0)
861             throw Py.TypeError("Odd-length string");
862
863         StringBuffer JavaDoc retbuf = new StringBuffer JavaDoc(arglen/2);
864
865         for (int i = 0; i < arglen; i += 2) {
866             int top = Character.digit(argbuf.charAt(i), 16);
867             int bot = Character.digit(argbuf.charAt(i+1), 16);
868             if (top == -1 || bot == -1)
869                 throw Py.TypeError("Non-hexadecimal digit found");
870             retbuf.append((char) ((top << 4) + bot));
871         }
872         return retbuf.toString();
873     }
874
875
876     public static String JavaDoc unhexlify(String JavaDoc argbuf) {
877         return a2b_hex(argbuf);
878     }
879
880
881
882 /*
883     public static void main(String[] args) {
884         String l = b2a_uu("Hello");
885         System.out.println(l);
886         System.out.println(a2b_uu(l));
887
888         l = b2a_base64("Hello");
889         System.out.println(l);
890         System.out.println(a2b_base64(l));
891
892         l = b2a_hqx("Hello-");
893         System.out.println(l);
894         System.out.println(a2b_hqx(l));
895     }
896 */

897 }
898
Popular Tags