Browse Source

Move Base64 class to nexus

Change-Id: I527b04b644d415e8fdaaab7aab24a4102c414615
Reviewed-on: http://gerrit.dmdirc.com/2880
Reviewed-by: Chris Smith <chris@dmdirc.com>
Automatic-Compile: DMDirc Build Manager
tags/0.8rc1
Greg Holmes 10 years ago
parent
commit
f37d313590
4 changed files with 10 additions and 759 deletions
  1. 7
    1
      build.xml
  2. 1
    0
      etc/ivy/ivysettings.xml
  3. 2
    0
      ivy.xml
  4. 0
    758
      src/net/miginfocom/Base64.java

+ 7
- 1
build.xml View File

@@ -54,6 +54,12 @@
54 54
         </jar>
55 55
     </target>
56 56
 
57
+    <target name="-bundle-base64">
58
+        <jar destfile="${dist.jar}" update="true">
59
+            <zipfileset src="lib/main/base64.jar" includes="net/miginfocom/**"/>
60
+        </jar>
61
+    </target>
62
+
57 63
     <target name="-bundle-dagger">
58 64
         <jar destfile="${dist.jar}" update="true">
59 65
             <zipfileset src="lib/main/dagger.jar" includes="dagger/**"/>
@@ -68,6 +74,6 @@
68 74
     <target name="-pre-init" depends="-init-dependencies,-init-submodule-dependencies,-init-private-properties"/>
69 75
     <target name="-post-compile" depends="-write-version, build-plugins"/>
70 76
     <target name="-post-test-run" depends="-do-test-reports"/>
71
-    <target name="-post-jar" depends="-update-bundled-plugins,-bundle-slf4j,-bundle-dagger"/>
77
+    <target name="-post-jar" depends="-update-bundled-plugins,-bundle-slf4j,-bundle-dagger,-bundle-base64"/>
72 78
 
73 79
 </project>

+ 1
- 0
etc/ivy/ivysettings.xml View File

@@ -27,6 +27,7 @@
27 27
         <module organisation="net.sourceforge.fikin-ant-tasks" name="ant-fikin" resolver="packager"/>
28 28
         <module organisation="org.eclipse.jgit" name="*" resolver="jgit"/>
29 29
         <module organisation="org.projectlombok" name="*" resolver="dmdirc-thirdparty"/>
30
+        <module organisation="net.miginfocom" name="*" resolver="dmdirc-thirdparty"/>
30 31
         <module organisation="com.dmdirc" name="*" resolver="dmdirc-releases"/>
31 32
     </modules>
32 33
 </ivysettings>

+ 2
- 0
ivy.xml View File

@@ -23,6 +23,8 @@
23 23
         <dependency org="com.squareup.dagger" name="dagger" rev="1.1.+" conf="main->default" />
24 24
         <dependency org="com.squareup.dagger" name="dagger-compiler" rev="1.1.+" conf="main->default" />
25 25
 
26
+        <dependency org="net.miginfocom" name="base64" rev="2.2" conf="main->default" />
27
+
26 28
         <dependency org="junit" name="junit" rev="4.+" conf="test->default" />
27 29
         <dependency org="org.mockito" name="mockito-all" rev="1.+" conf="test->default" />
28 30
         <dependency org="com.cenqua.clover" name="clover" rev="3.+" conf="test->default" />

+ 0
- 758
src/net/miginfocom/Base64.java View File

@@ -1,758 +0,0 @@
1
-package net.miginfocom;
2
-
3
-import java.util.Arrays;
4
-
5
-/**
6
- * A very fast and memory efficient class to encode and decode to and from
7
- * BASE64 in full accordance
8
- * with RFC 2045.<br>
9
- * <br>
10
- * On Windows XP sp1 with 1.4.2_04 and later ;), this encoder and decoder is
11
- * about 10 times faster
12
- * on small arrays (10 - 1000 bytes) and 2-3 times as fast on larger arrays
13
- * (10000 - 1000000 bytes)
14
- * compared to <code>sun.misc.Encoder()/Decoder()</code>.<br>
15
- * <br>
16
- *
17
- * On byte arrays the encoder is about 20% faster than Jakarta Commons Base64
18
- * Codec for encode and
19
- * about 50% faster for decoding large arrays. This implementation is about
20
- * twice as fast on very small
21
- * arrays (&lt 30 bytes). If source/destination is a <code>String</code> this
22
- * version is about three times as fast due to the fact that the Commons Codec
23
- * result has to be recoded
24
- * to a <code>String</code> from <code>byte[]</code>, which is very expensive.<br>
25
- * <br>
26
- *
27
- * This encode/decode algorithm doesn't create any temporary arrays as many
28
- * other codecs do, it only
29
- * allocates the resulting array. This produces less garbage and it is possible
30
- * to handle arrays twice
31
- * as large as algorithms that create a temporary array. (E.g. Jakarta Commons
32
- * Codec). It is unknown
33
- * whether Sun's <code>sun.misc.Encoder()/Decoder()</code> produce temporary
34
- * arrays but since performance
35
- * is quite low it probably does.<br>
36
- * <br>
37
- *
38
- * The encoder produces the same output as the Sun one except that the Sun's
39
- * encoder appends
40
- * a trailing line separator if the last character isn't a pad. Unclear why but
41
- * it only adds to the
42
- * length and is probably a side effect. Both are in conformance with RFC 2045
43
- * though.<br>
44
- * Commons codec seem to always att a trailing line separator.<br>
45
- * <br>
46
- *
47
- * <b>Note!</b>
48
- * The encode/decode method pairs (types) come in three versions with the
49
- * <b>exact</b> same algorithm and
50
- * thus a lot of code redundancy. This is to not create any temporary arrays for
51
- * transcoding to/from different
52
- * format types. The methods not used can simply be commented out.<br>
53
- * <br>
54
- *
55
- * There is also a "fast" version of all decode methods that works the same way
56
- * as the normal ones, but
57
- * har a few demands on the decoded input. Normally though, these fast verions
58
- * should be used if the source if
59
- * the input is known and it hasn't bee tampered with.<br>
60
- * <br>
61
- *
62
- * If you find the code useful or you find a bug, please send me a note at
63
- * base64 @ miginfocom . com.
64
- *
65
- * Licence (BSD):
66
- * ==============
67
- *
68
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (base64 @ miginfocom . com)
69
- * All rights reserved.
70
- *
71
- * Redistribution and use in source and binary forms, with or without
72
- * modification,
73
- * are permitted provided that the following conditions are met:
74
- * Redistributions of source code must retain the above copyright notice, this
75
- * list
76
- * of conditions and the following disclaimer.
77
- * Redistributions in binary form must reproduce the above copyright notice,
78
- * this
79
- * list of conditions and the following disclaimer in the documentation and/or
80
- * other
81
- * materials provided with the distribution.
82
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may
83
- * be
84
- * used to endorse or promote products derived from this software without
85
- * specific
86
- * prior written permission.
87
- *
88
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
89
- * AND
90
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92
- * DISCLAIMED.
93
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
94
- * DIRECT,
95
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96
- * (INCLUDING,
97
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98
- * DATA,
99
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
100
- * LIABILITY,
101
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
102
- * OTHERWISE)
103
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
104
- * POSSIBILITY
105
- * OF SUCH DAMAGE.
106
- *
107
- * @version 2.2
108
- * @author Mikael Grev
109
- *         Date: 2004-aug-02
110
- *         Time: 11:31:11
111
- */
112
-
113
-public class Base64 {
114
-    private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
115
-            .toCharArray();
116
-    private static final int[] IA = new int[256];
117
-    static {
118
-        Arrays.fill(IA, -1);
119
-        for (int i = 0, iS = CA.length; i < iS; i++) {
120
-            IA[CA[i]] = i;
121
-        }
122
-        IA['='] = 0;
123
-    }
124
-
125
-    // ****************************************************************************************
126
-    // * char[] version
127
-    // ****************************************************************************************
128
-
129
-    /**
130
-     * Encodes a raw byte array into a BASE64 <code>char[]</code> representation
131
-     * i accordance with RFC 2045.
132
-     *
133
-     * @param sArr
134
-     *            The bytes to convert. If <code>null</code> or length 0 an
135
-     *            empty array will be returned.
136
-     * @param lineSep
137
-     *            Optional "\r\n" after 76 characters, unless end of file.<br>
138
-     *            No line separator will be in breach of RFC 2045 which
139
-     *            specifies max 76 per line but will be a
140
-     *            little faster.
141
-     * @return A BASE64 encoded array. Never <code>null</code>.
142
-     */
143
-    public static final char[] encodeToChar(final byte[] sArr,
144
-            final boolean lineSep) {
145
-        // Check special case
146
-        final int sLen = sArr != null ? sArr.length : 0;
147
-        if (sLen == 0) {
148
-            return new char[0];
149
-        }
150
-
151
-        final int eLen = sLen / 3 * 3; // Length of even 24-bits.
152
-        final int cCnt = (sLen - 1) / 3 + 1 << 2; // Returned character count
153
-        final int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length
154
-                                                                      // of
155
-                                                                      // returned
156
-                                                                      // array
157
-        final char[] dArr = new char[dLen];
158
-
159
-        // Encode even 24-bits
160
-        for (int s = 0, d = 0, cc = 0; s < eLen;) {
161
-            // Copy next three bytes into lower 24 bits of int, paying attension
162
-            // to sign.
163
-            final int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8
164
-                    | sArr[s++] & 0xff;
165
-
166
-            // Encode the int into four chars
167
-            dArr[d++] = CA[i >>> 18 & 0x3f];
168
-            dArr[d++] = CA[i >>> 12 & 0x3f];
169
-            dArr[d++] = CA[i >>> 6 & 0x3f];
170
-            dArr[d++] = CA[i & 0x3f];
171
-
172
-            // Add optional line separator
173
-            if (lineSep && ++cc == 19 && d < dLen - 2) {
174
-                dArr[d++] = '\r';
175
-                dArr[d++] = '\n';
176
-                cc = 0;
177
-            }
178
-        }
179
-
180
-        // Pad and encode last bits if source isn't even 24 bits.
181
-        final int left = sLen - eLen; // 0 - 2.
182
-        if (left > 0) {
183
-            // Prepare the int
184
-            final int i = (sArr[eLen] & 0xff) << 10
185
-                    | (left == 2 ? (sArr[sLen - 1] & 0xff) << 2 : 0);
186
-
187
-            // Set last four chars
188
-            dArr[dLen - 4] = CA[i >> 12];
189
-            dArr[dLen - 3] = CA[i >>> 6 & 0x3f];
190
-            dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
191
-            dArr[dLen - 1] = '=';
192
-        }
193
-        return dArr;
194
-    }
195
-
196
-    /**
197
-     * Decodes a BASE64 encoded char array. All illegal characters will be
198
-     * ignored and can handle both arrays with
199
-     * and without line separators.
200
-     *
201
-     * @param sArr
202
-     *            The source array. <code>null</code> or length 0 will return an
203
-     *            empty array.
204
-     * @return The decoded array of bytes. May be of length 0. Will be
205
-     *         <code>null</code> if the legal characters
206
-     *         (including '=') isn't divideable by 4. (I.e. definitely
207
-     *         corrupted).
208
-     */
209
-    public static final byte[] decode(final char[] sArr) {
210
-        // Check special case
211
-        final int sLen = sArr != null ? sArr.length : 0;
212
-        if (sLen == 0) {
213
-            return new byte[0];
214
-        }
215
-
216
-        // Count illegal characters (including '\r', '\n') to know what size the
217
-        // returned array will be,
218
-        // so we don't have to reallocate & copy it later.
219
-        int sepCnt = 0; // Number of separator characters. (Actually illegal
220
-                        // characters, but that's a bonus...)
221
-        for (int i = 0; i < sLen; i++) {
222
-            if (IA[sArr[i]] < 0) {
223
-                sepCnt++;
224
-            }
225
-        }
226
-
227
-        // Check so that legal chars (including '=') are evenly divideable by 4
228
-        // as specified in RFC 2045.
229
-        if ((sLen - sepCnt) % 4 != 0) {
230
-            return null;
231
-        }
232
-
233
-        int pad = 0;
234
-        for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0;) {
235
-            if (sArr[i] == '=') {
236
-                pad++;
237
-            }
238
-        }
239
-
240
-        final int len = ((sLen - sepCnt) * 6 >> 3) - pad;
241
-
242
-        final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
243
-
244
-        for (int s = 0, d = 0; d < len;) {
245
-            // Assemble three bytes into an int from four "valid" characters.
246
-            int i = 0;
247
-            for (int j = 0; j < 4; j++) { // j only increased if a valid char
248
-                                          // was found.
249
-                final int c = IA[sArr[s++]];
250
-                if (c >= 0) {
251
-                    i |= c << 18 - j * 6;
252
-                } else {
253
-                    j--;
254
-                }
255
-            }
256
-            // Add the bytes
257
-            dArr[d++] = (byte) (i >> 16);
258
-            if (d < len) {
259
-                dArr[d++] = (byte) (i >> 8);
260
-                if (d < len) {
261
-                    dArr[d++] = (byte) i;
262
-                }
263
-            }
264
-        }
265
-        return dArr;
266
-    }
267
-
268
-    /**
269
-     * Decodes a BASE64 encoded char array that is known to be resonably well
270
-     * formatted. The method is about twice as
271
-     * fast as {@link #decode(char[])}. The preconditions are:<br>
272
-     * + The array must have a line length of 76 chars OR no line separators at
273
-     * all (one line).<br>
274
-     * + Line separator must be "\r\n", as specified in RFC 2045
275
-     * + The array must not contain illegal characters within the encoded string<br>
276
-     * + The array CAN have illegal characters at the beginning and end, those
277
-     * will be dealt with appropriately.<br>
278
-     *
279
-     * @param sArr
280
-     *            The source array. Length 0 will return an empty array.
281
-     *            <code>null</code> will throw an exception.
282
-     * @return The decoded array of bytes. May be of length 0.
283
-     */
284
-    public static final byte[] decodeFast(final char[] sArr) {
285
-        // Check special case
286
-        final int sLen = sArr.length;
287
-        if (sLen == 0) {
288
-            return new byte[0];
289
-        }
290
-
291
-        int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
292
-
293
-        // Trim illegal chars from start
294
-        while (sIx < eIx && IA[sArr[sIx]] < 0) {
295
-            sIx++;
296
-        }
297
-
298
-        // Trim illegal chars from end
299
-        while (eIx > 0 && IA[sArr[eIx]] < 0) {
300
-            eIx--;
301
-        }
302
-
303
-        // get the padding count (=) (0, 1 or 2)
304
-        final int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count
305
-                                                                               // '='
306
-                                                                               // at
307
-                                                                               // end.
308
-        final int cCnt = eIx - sIx + 1; // Content count including possible
309
-                                        // separators
310
-        final int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1
311
-                : 0;
312
-
313
-        final int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of
314
-                                                          // decoded bytes
315
-        final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
316
-
317
-        // Decode all but the last 0 - 2 bytes.
318
-        int d = 0;
319
-        for (int cc = 0, eLen = len / 3 * 3; d < eLen;) {
320
-            // Assemble three bytes into an int from four "valid" characters.
321
-            final int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12
322
-                    | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
323
-
324
-            // Add the bytes
325
-            dArr[d++] = (byte) (i >> 16);
326
-            dArr[d++] = (byte) (i >> 8);
327
-            dArr[d++] = (byte) i;
328
-
329
-            // If line separator, jump over it.
330
-            if (sepCnt > 0 && ++cc == 19) {
331
-                sIx += 2;
332
-                cc = 0;
333
-            }
334
-        }
335
-
336
-        if (d < len) {
337
-            // Decode last 1-3 bytes (incl '=') into 1-3 bytes
338
-            int i = 0;
339
-            for (int j = 0; sIx <= eIx - pad; j++) {
340
-                i |= IA[sArr[sIx++]] << 18 - j * 6;
341
-            }
342
-
343
-            for (int r = 16; d < len; r -= 8) {
344
-                dArr[d++] = (byte) (i >> r);
345
-            }
346
-        }
347
-
348
-        return dArr;
349
-    }
350
-
351
-    // ****************************************************************************************
352
-    // * byte[] version
353
-    // ****************************************************************************************
354
-
355
-    /**
356
-     * Encodes a raw byte array into a BASE64 <code>byte[]</code> representation
357
-     * i accordance with RFC 2045.
358
-     *
359
-     * @param sArr
360
-     *            The bytes to convert. If <code>null</code> or length 0 an
361
-     *            empty array will be returned.
362
-     * @param lineSep
363
-     *            Optional "\r\n" after 76 characters, unless end of file.<br>
364
-     *            No line separator will be in breach of RFC 2045 which
365
-     *            specifies max 76 per line but will be a
366
-     *            little faster.
367
-     * @return A BASE64 encoded array. Never <code>null</code>.
368
-     */
369
-    public static final byte[] encodeToByte(final byte[] sArr,
370
-            final boolean lineSep) {
371
-        // Check special case
372
-        final int sLen = sArr != null ? sArr.length : 0;
373
-        if (sLen == 0) {
374
-            return new byte[0];
375
-        }
376
-
377
-        final int eLen = sLen / 3 * 3; // Length of even 24-bits.
378
-        final int cCnt = (sLen - 1) / 3 + 1 << 2; // Returned character count
379
-        final int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length
380
-                                                                      // of
381
-                                                                      // returned
382
-                                                                      // array
383
-        final byte[] dArr = new byte[dLen];
384
-
385
-        // Encode even 24-bits
386
-        for (int s = 0, d = 0, cc = 0; s < eLen;) {
387
-            // Copy next three bytes into lower 24 bits of int, paying attension
388
-            // to sign.
389
-            final int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8
390
-                    | sArr[s++] & 0xff;
391
-
392
-            // Encode the int into four chars
393
-            dArr[d++] = (byte) CA[i >>> 18 & 0x3f];
394
-            dArr[d++] = (byte) CA[i >>> 12 & 0x3f];
395
-            dArr[d++] = (byte) CA[i >>> 6 & 0x3f];
396
-            dArr[d++] = (byte) CA[i & 0x3f];
397
-
398
-            // Add optional line separator
399
-            if (lineSep && ++cc == 19 && d < dLen - 2) {
400
-                dArr[d++] = '\r';
401
-                dArr[d++] = '\n';
402
-                cc = 0;
403
-            }
404
-        }
405
-
406
-        // Pad and encode last bits if source isn't an even 24 bits.
407
-        final int left = sLen - eLen; // 0 - 2.
408
-        if (left > 0) {
409
-            // Prepare the int
410
-            final int i = (sArr[eLen] & 0xff) << 10
411
-                    | (left == 2 ? (sArr[sLen - 1] & 0xff) << 2 : 0);
412
-
413
-            // Set last four chars
414
-            dArr[dLen - 4] = (byte) CA[i >> 12];
415
-            dArr[dLen - 3] = (byte) CA[i >>> 6 & 0x3f];
416
-            dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '=';
417
-            dArr[dLen - 1] = '=';
418
-        }
419
-        return dArr;
420
-    }
421
-
422
-    /**
423
-     * Decodes a BASE64 encoded byte array. All illegal characters will be
424
-     * ignored and can handle both arrays with
425
-     * and without line separators.
426
-     *
427
-     * @param sArr
428
-     *            The source array. Length 0 will return an empty array.
429
-     *            <code>null</code> will throw an exception.
430
-     * @return The decoded array of bytes. May be of length 0. Will be
431
-     *         <code>null</code> if the legal characters
432
-     *         (including '=') isn't divideable by 4. (I.e. definitely
433
-     *         corrupted).
434
-     */
435
-    public static final byte[] decode(final byte[] sArr) {
436
-        // Check special case
437
-        final int sLen = sArr.length;
438
-
439
-        // Count illegal characters (including '\r', '\n') to know what size the
440
-        // returned array will be,
441
-        // so we don't have to reallocate & copy it later.
442
-        int sepCnt = 0; // Number of separator characters. (Actually illegal
443
-                        // characters, but that's a bonus...)
444
-        for (int i = 0; i < sLen; i++) {
445
-            if (IA[sArr[i] & 0xff] < 0) {
446
-                sepCnt++;
447
-            }
448
-        }
449
-
450
-        // Check so that legal chars (including '=') are evenly divideable by 4
451
-        // as specified in RFC 2045.
452
-        if ((sLen - sepCnt) % 4 != 0) {
453
-            return null;
454
-        }
455
-
456
-        int pad = 0;
457
-        for (int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0;) {
458
-            if (sArr[i] == '=') {
459
-                pad++;
460
-            }
461
-        }
462
-
463
-        final int len = ((sLen - sepCnt) * 6 >> 3) - pad;
464
-
465
-        final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
466
-
467
-        for (int s = 0, d = 0; d < len;) {
468
-            // Assemble three bytes into an int from four "valid" characters.
469
-            int i = 0;
470
-            for (int j = 0; j < 4; j++) { // j only increased if a valid char
471
-                                          // was found.
472
-                final int c = IA[sArr[s++] & 0xff];
473
-                if (c >= 0) {
474
-                    i |= c << 18 - j * 6;
475
-                } else {
476
-                    j--;
477
-                }
478
-            }
479
-
480
-            // Add the bytes
481
-            dArr[d++] = (byte) (i >> 16);
482
-            if (d < len) {
483
-                dArr[d++] = (byte) (i >> 8);
484
-                if (d < len) {
485
-                    dArr[d++] = (byte) i;
486
-                }
487
-            }
488
-        }
489
-
490
-        return dArr;
491
-    }
492
-
493
-    /**
494
-     * Decodes a BASE64 encoded byte array that is known to be resonably well
495
-     * formatted. The method is about twice as
496
-     * fast as {@link #decode(byte[])}. The preconditions are:<br>
497
-     * + The array must have a line length of 76 chars OR no line separators at
498
-     * all (one line).<br>
499
-     * + Line separator must be "\r\n", as specified in RFC 2045
500
-     * + The array must not contain illegal characters within the encoded string<br>
501
-     * + The array CAN have illegal characters at the beginning and end, those
502
-     * will be dealt with appropriately.<br>
503
-     *
504
-     * @param sArr
505
-     *            The source array. Length 0 will return an empty array.
506
-     *            <code>null</code> will throw an exception.
507
-     * @return The decoded array of bytes. May be of length 0.
508
-     */
509
-    public static final byte[] decodeFast(final byte[] sArr) {
510
-        // Check special case
511
-        final int sLen = sArr.length;
512
-        if (sLen == 0) {
513
-            return new byte[0];
514
-        }
515
-
516
-        int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
517
-
518
-        // Trim illegal chars from start
519
-        while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0) {
520
-            sIx++;
521
-        }
522
-
523
-        // Trim illegal chars from end
524
-        while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0) {
525
-            eIx--;
526
-        }
527
-
528
-        // get the padding count (=) (0, 1 or 2)
529
-        final int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count
530
-                                                                               // '='
531
-                                                                               // at
532
-                                                                               // end.
533
-        final int cCnt = eIx - sIx + 1; // Content count including possible
534
-                                        // separators
535
-        final int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1
536
-                : 0;
537
-
538
-        final int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of
539
-                                                          // decoded bytes
540
-        final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
541
-
542
-        // Decode all but the last 0 - 2 bytes.
543
-        int d = 0;
544
-        for (int cc = 0, eLen = len / 3 * 3; d < eLen;) {
545
-            // Assemble three bytes into an int from four "valid" characters.
546
-            final int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12
547
-                    | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
548
-
549
-            // Add the bytes
550
-            dArr[d++] = (byte) (i >> 16);
551
-            dArr[d++] = (byte) (i >> 8);
552
-            dArr[d++] = (byte) i;
553
-
554
-            // If line separator, jump over it.
555
-            if (sepCnt > 0 && ++cc == 19) {
556
-                sIx += 2;
557
-                cc = 0;
558
-            }
559
-        }
560
-
561
-        if (d < len) {
562
-            // Decode last 1-3 bytes (incl '=') into 1-3 bytes
563
-            int i = 0;
564
-            for (int j = 0; sIx <= eIx - pad; j++) {
565
-                i |= IA[sArr[sIx++]] << 18 - j * 6;
566
-            }
567
-
568
-            for (int r = 16; d < len; r -= 8) {
569
-                dArr[d++] = (byte) (i >> r);
570
-            }
571
-        }
572
-
573
-        return dArr;
574
-    }
575
-
576
-    // ****************************************************************************************
577
-    // * String version
578
-    // ****************************************************************************************
579
-
580
-    /**
581
-     * Encodes a raw byte array into a BASE64 <code>String</code> representation
582
-     * i accordance with RFC 2045.
583
-     *
584
-     * @param sArr
585
-     *            The bytes to convert. If <code>null</code> or length 0 an
586
-     *            empty array will be returned.
587
-     * @param lineSep
588
-     *            Optional "\r\n" after 76 characters, unless end of file.<br>
589
-     *            No line separator will be in breach of RFC 2045 which
590
-     *            specifies max 76 per line but will be a
591
-     *            little faster.
592
-     * @return A BASE64 encoded array. Never <code>null</code>.
593
-     */
594
-    public static final String encodeToString(final byte[] sArr,
595
-            final boolean lineSep) {
596
-        // Reuse char[] since we can't create a String incrementally anyway and
597
-        // StringBuffer/Builder would be slower.
598
-        return new String(encodeToChar(sArr, lineSep));
599
-    }
600
-
601
-    /**
602
-     * Decodes a BASE64 encoded <code>String</code>. All illegal characters will
603
-     * be ignored and can handle both strings with
604
-     * and without line separators.<br>
605
-     * <b>Note!</b> It can be up to about 2x the speed to call
606
-     * <code>decode(str.toCharArray())</code> instead. That
607
-     * will create a temporary array though. This version will use
608
-     * <code>str.charAt(i)</code> to iterate the string.
609
-     *
610
-     * @param str
611
-     *            The source string. <code>null</code> or length 0 will return
612
-     *            an empty array.
613
-     * @return The decoded array of bytes. May be of length 0. Will be
614
-     *         <code>null</code> if the legal characters
615
-     *         (including '=') isn't divideable by 4. (I.e. definitely
616
-     *         corrupted).
617
-     */
618
-    public static final byte[] decode(final String str) {
619
-        // Check special case
620
-        final int sLen = str != null ? str.length() : 0;
621
-        if (sLen == 0) {
622
-            return new byte[0];
623
-        }
624
-
625
-        // Count illegal characters (including '\r', '\n') to know what size the
626
-        // returned array will be,
627
-        // so we don't have to reallocate & copy it later.
628
-        int sepCnt = 0; // Number of separator characters. (Actually illegal
629
-                        // characters, but that's a bonus...)
630
-        for (int i = 0; i < sLen; i++) {
631
-            if (IA[str.charAt(i)] < 0) {
632
-                sepCnt++;
633
-            }
634
-        }
635
-
636
-        // Check so that legal chars (including '=') are evenly divideable by 4
637
-        // as specified in RFC 2045.
638
-        if ((sLen - sepCnt) % 4 != 0) {
639
-            return null;
640
-        }
641
-
642
-        // Count '=' at end
643
-        int pad = 0;
644
-        for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0;) {
645
-            if (str.charAt(i) == '=') {
646
-                pad++;
647
-            }
648
-        }
649
-
650
-        final int len = ((sLen - sepCnt) * 6 >> 3) - pad;
651
-
652
-        final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
653
-
654
-        for (int s = 0, d = 0; d < len;) {
655
-            // Assemble three bytes into an int from four "valid" characters.
656
-            int i = 0;
657
-            for (int j = 0; j < 4; j++) { // j only increased if a valid char
658
-                                          // was found.
659
-                final int c = IA[str.charAt(s++)];
660
-                if (c >= 0) {
661
-                    i |= c << 18 - j * 6;
662
-                } else {
663
-                    j--;
664
-                }
665
-            }
666
-            // Add the bytes
667
-            dArr[d++] = (byte) (i >> 16);
668
-            if (d < len) {
669
-                dArr[d++] = (byte) (i >> 8);
670
-                if (d < len) {
671
-                    dArr[d++] = (byte) i;
672
-                }
673
-            }
674
-        }
675
-        return dArr;
676
-    }
677
-
678
-    /**
679
-     * Decodes a BASE64 encoded string that is known to be resonably well
680
-     * formatted. The method is about twice as
681
-     * fast as {@link #decode(String)}. The preconditions are:<br>
682
-     * + The array must have a line length of 76 chars OR no line separators at
683
-     * all (one line).<br>
684
-     * + Line separator must be "\r\n", as specified in RFC 2045
685
-     * + The array must not contain illegal characters within the encoded string<br>
686
-     * + The array CAN have illegal characters at the beginning and end, those
687
-     * will be dealt with appropriately.<br>
688
-     *
689
-     * @param s
690
-     *            The source string. Length 0 will return an empty array.
691
-     *            <code>null</code> will throw an exception.
692
-     * @return The decoded array of bytes. May be of length 0.
693
-     */
694
-    public static final byte[] decodeFast(final String s) {
695
-        // Check special case
696
-        final int sLen = s.length();
697
-        if (sLen == 0) {
698
-            return new byte[0];
699
-        }
700
-
701
-        int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
702
-
703
-        // Trim illegal chars from start
704
-        while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0) {
705
-            sIx++;
706
-        }
707
-
708
-        // Trim illegal chars from end
709
-        while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0) {
710
-            eIx--;
711
-        }
712
-
713
-        // get the padding count (=) (0, 1 or 2)
714
-        final int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2
715
-                : 1) : 0; // Count '=' at end.
716
-        final int cCnt = eIx - sIx + 1; // Content count including possible
717
-                                        // separators
718
-        final int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1
719
-                : 0;
720
-
721
-        final int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of
722
-                                                          // decoded bytes
723
-        final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
724
-
725
-        // Decode all but the last 0 - 2 bytes.
726
-        int d = 0;
727
-        for (int cc = 0, eLen = len / 3 * 3; d < eLen;) {
728
-            // Assemble three bytes into an int from four "valid" characters.
729
-            final int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12
730
-                    | IA[s.charAt(sIx++)] << 6 | IA[s.charAt(sIx++)];
731
-
732
-            // Add the bytes
733
-            dArr[d++] = (byte) (i >> 16);
734
-            dArr[d++] = (byte) (i >> 8);
735
-            dArr[d++] = (byte) i;
736
-
737
-            // If line separator, jump over it.
738
-            if (sepCnt > 0 && ++cc == 19) {
739
-                sIx += 2;
740
-                cc = 0;
741
-            }
742
-        }
743
-
744
-        if (d < len) {
745
-            // Decode last 1-3 bytes (incl '=') into 1-3 bytes
746
-            int i = 0;
747
-            for (int j = 0; sIx <= eIx - pad; j++) {
748
-                i |= IA[s.charAt(sIx++)] << 18 - j * 6;
749
-            }
750
-
751
-            for (int r = 16; d < len; r -= 8) {
752
-                dArr[d++] = (byte) (i >> r);
753
-            }
754
-        }
755
-
756
-        return dArr;
757
-    }
758
-}

Loading…
Cancel
Save