/[projects]/android/TrainInfo/src/com/example/android/trivialdrivesample/util/Base64.java
ViewVC logotype

Contents of /android/TrainInfo/src/com/example/android/trivialdrivesample/util/Base64.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2123 - (show annotations) (download)
Wed Mar 5 12:11:16 2014 UTC (10 years, 2 months ago) by torben
File size: 24284 byte(s)
Add billing code
1 // Portions copyright 2002, Google, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package com.example.android.trivialdrivesample.util;
16
17 // This code was converted from code at http://iharder.sourceforge.net/base64/
18 // Lots of extraneous features were removed.
19 /* The original code said:
20 * <p>
21 * I am placing this code in the Public Domain. Do with it as you will.
22 * This software comes with no guarantees or warranties but with
23 * plenty of well-wishing instead!
24 * Please visit
25 * <a href="http://iharder.net/xmlizable">http://iharder.net/xmlizable</a>
26 * periodically to check for updates or to contribute improvements.
27 * </p>
28 *
29 * @author Robert Harder
30 * @author rharder@usa.net
31 * @version 1.3
32 */
33
34 /**
35 * Base64 converter class. This code is not a complete MIME encoder;
36 * it simply converts binary data to base64 data and back.
37 *
38 * <p>Note {@link CharBase64} is a GWT-compatible implementation of this
39 * class.
40 */
41 public class Base64 {
42 /** Specify encoding (value is {@code true}). */
43 public final static boolean ENCODE = true;
44
45 /** Specify decoding (value is {@code false}). */
46 public final static boolean DECODE = false;
47
48 /** The equals sign (=) as a byte. */
49 private final static byte EQUALS_SIGN = (byte) '=';
50
51 /** The new line character (\n) as a byte. */
52 private final static byte NEW_LINE = (byte) '\n';
53
54 /**
55 * The 64 valid Base64 values.
56 */
57 private final static byte[] ALPHABET =
58 {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
59 (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K',
60 (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',
61 (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
62 (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
63 (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
64 (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
65 (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
66 (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
67 (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y',
68 (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',
69 (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8',
70 (byte) '9', (byte) '+', (byte) '/'};
71
72 /**
73 * The 64 valid web safe Base64 values.
74 */
75 private final static byte[] WEBSAFE_ALPHABET =
76 {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
77 (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K',
78 (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',
79 (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
80 (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
81 (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
82 (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
83 (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
84 (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
85 (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y',
86 (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',
87 (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8',
88 (byte) '9', (byte) '-', (byte) '_'};
89
90 /**
91 * Translates a Base64 value to either its 6-bit reconstruction value
92 * or a negative number indicating some other meaning.
93 **/
94 private final static byte[] DECODABET = {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
95 -5, -5, // Whitespace: Tab and Linefeed
96 -9, -9, // Decimal 11 - 12
97 -5, // Whitespace: Carriage Return
98 -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
99 -9, -9, -9, -9, -9, // Decimal 27 - 31
100 -5, // Whitespace: Space
101 -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
102 62, // Plus sign at decimal 43
103 -9, -9, -9, // Decimal 44 - 46
104 63, // Slash at decimal 47
105 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
106 -9, -9, -9, // Decimal 58 - 60
107 -1, // Equals sign at decimal 61
108 -9, -9, -9, // Decimal 62 - 64
109 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
110 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
111 -9, -9, -9, -9, -9, -9, // Decimal 91 - 96
112 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
113 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
114 -9, -9, -9, -9, -9 // Decimal 123 - 127
115 /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
116 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
117 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
118 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
119 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
120 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
121 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
122 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
123 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
124 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
125 };
126
127 /** The web safe decodabet */
128 private final static byte[] WEBSAFE_DECODABET =
129 {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
130 -5, -5, // Whitespace: Tab and Linefeed
131 -9, -9, // Decimal 11 - 12
132 -5, // Whitespace: Carriage Return
133 -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
134 -9, -9, -9, -9, -9, // Decimal 27 - 31
135 -5, // Whitespace: Space
136 -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 44
137 62, // Dash '-' sign at decimal 45
138 -9, -9, // Decimal 46-47
139 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
140 -9, -9, -9, // Decimal 58 - 60
141 -1, // Equals sign at decimal 61
142 -9, -9, -9, // Decimal 62 - 64
143 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
144 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
145 -9, -9, -9, -9, // Decimal 91-94
146 63, // Underscore '_' at decimal 95
147 -9, // Decimal 96
148 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
149 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
150 -9, -9, -9, -9, -9 // Decimal 123 - 127
151 /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
152 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
153 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
154 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
155 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
156 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
157 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
158 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
159 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
160 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
161 };
162
163 // Indicates white space in encoding
164 private final static byte WHITE_SPACE_ENC = -5;
165 // Indicates equals sign in encoding
166 private final static byte EQUALS_SIGN_ENC = -1;
167
168 /** Defeats instantiation. */
169 private Base64() {
170 }
171
172 /* ******** E N C O D I N G M E T H O D S ******** */
173
174 /**
175 * Encodes up to three bytes of the array <var>source</var>
176 * and writes the resulting four Base64 bytes to <var>destination</var>.
177 * The source and destination arrays can be manipulated
178 * anywhere along their length by specifying
179 * <var>srcOffset</var> and <var>destOffset</var>.
180 * This method does not check to make sure your arrays
181 * are large enough to accommodate <var>srcOffset</var> + 3 for
182 * the <var>source</var> array or <var>destOffset</var> + 4 for
183 * the <var>destination</var> array.
184 * The actual number of significant bytes in your array is
185 * given by <var>numSigBytes</var>.
186 *
187 * @param source the array to convert
188 * @param srcOffset the index where conversion begins
189 * @param numSigBytes the number of significant bytes in your array
190 * @param destination the array to hold the conversion
191 * @param destOffset the index where output will be put
192 * @param alphabet is the encoding alphabet
193 * @return the <var>destination</var> array
194 * @since 1.3
195 */
196 private static byte[] encode3to4(byte[] source, int srcOffset,
197 int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) {
198 // 1 2 3
199 // 01234567890123456789012345678901 Bit position
200 // --------000000001111111122222222 Array position from threeBytes
201 // --------| || || || | Six bit groups to index alphabet
202 // >>18 >>12 >> 6 >> 0 Right shift necessary
203 // 0x3f 0x3f 0x3f Additional AND
204
205 // Create buffer with zero-padding if there are only one or two
206 // significant bytes passed in the array.
207 // We have to shift left 24 in order to flush out the 1's that appear
208 // when Java treats a value as negative that is cast from a byte to an int.
209 int inBuff =
210 (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
211 | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
212 | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
213
214 switch (numSigBytes) {
215 case 3:
216 destination[destOffset] = alphabet[(inBuff >>> 18)];
217 destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
218 destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
219 destination[destOffset + 3] = alphabet[(inBuff) & 0x3f];
220 return destination;
221 case 2:
222 destination[destOffset] = alphabet[(inBuff >>> 18)];
223 destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
224 destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
225 destination[destOffset + 3] = EQUALS_SIGN;
226 return destination;
227 case 1:
228 destination[destOffset] = alphabet[(inBuff >>> 18)];
229 destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
230 destination[destOffset + 2] = EQUALS_SIGN;
231 destination[destOffset + 3] = EQUALS_SIGN;
232 return destination;
233 default:
234 return destination;
235 } // end switch
236 } // end encode3to4
237
238 /**
239 * Encodes a byte array into Base64 notation.
240 * Equivalent to calling
241 * {@code encodeBytes(source, 0, source.length)}
242 *
243 * @param source The data to convert
244 * @since 1.4
245 */
246 public static String encode(byte[] source) {
247 return encode(source, 0, source.length, ALPHABET, true);
248 }
249
250 /**
251 * Encodes a byte array into web safe Base64 notation.
252 *
253 * @param source The data to convert
254 * @param doPadding is {@code true} to pad result with '=' chars
255 * if it does not fall on 3 byte boundaries
256 */
257 public static String encodeWebSafe(byte[] source, boolean doPadding) {
258 return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding);
259 }
260
261 /**
262 * Encodes a byte array into Base64 notation.
263 *
264 * @param source the data to convert
265 * @param off offset in array where conversion should begin
266 * @param len length of data to convert
267 * @param alphabet the encoding alphabet
268 * @param doPadding is {@code true} to pad result with '=' chars
269 * if it does not fall on 3 byte boundaries
270 * @since 1.4
271 */
272 public static String encode(byte[] source, int off, int len, byte[] alphabet,
273 boolean doPadding) {
274 byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE);
275 int outLen = outBuff.length;
276
277 // If doPadding is false, set length to truncate '='
278 // padding characters
279 while (doPadding == false && outLen > 0) {
280 if (outBuff[outLen - 1] != '=') {
281 break;
282 }
283 outLen -= 1;
284 }
285
286 return new String(outBuff, 0, outLen);
287 }
288
289 /**
290 * Encodes a byte array into Base64 notation.
291 *
292 * @param source the data to convert
293 * @param off offset in array where conversion should begin
294 * @param len length of data to convert
295 * @param alphabet is the encoding alphabet
296 * @param maxLineLength maximum length of one line.
297 * @return the BASE64-encoded byte array
298 */
299 public static byte[] encode(byte[] source, int off, int len, byte[] alphabet,
300 int maxLineLength) {
301 int lenDiv3 = (len + 2) / 3; // ceil(len / 3)
302 int len43 = lenDiv3 * 4;
303 byte[] outBuff = new byte[len43 // Main 4:3
304 + (len43 / maxLineLength)]; // New lines
305
306 int d = 0;
307 int e = 0;
308 int len2 = len - 2;
309 int lineLength = 0;
310 for (; d < len2; d += 3, e += 4) {
311
312 // The following block of code is the same as
313 // encode3to4( source, d + off, 3, outBuff, e, alphabet );
314 // but inlined for faster encoding (~20% improvement)
315 int inBuff =
316 ((source[d + off] << 24) >>> 8)
317 | ((source[d + 1 + off] << 24) >>> 16)
318 | ((source[d + 2 + off] << 24) >>> 24);
319 outBuff[e] = alphabet[(inBuff >>> 18)];
320 outBuff[e + 1] = alphabet[(inBuff >>> 12) & 0x3f];
321 outBuff[e + 2] = alphabet[(inBuff >>> 6) & 0x3f];
322 outBuff[e + 3] = alphabet[(inBuff) & 0x3f];
323
324 lineLength += 4;
325 if (lineLength == maxLineLength) {
326 outBuff[e + 4] = NEW_LINE;
327 e++;
328 lineLength = 0;
329 } // end if: end of line
330 } // end for: each piece of array
331
332 if (d < len) {
333 encode3to4(source, d + off, len - d, outBuff, e, alphabet);
334
335 lineLength += 4;
336 if (lineLength == maxLineLength) {
337 // Add a last newline
338 outBuff[e + 4] = NEW_LINE;
339 e++;
340 }
341 e += 4;
342 }
343
344 assert (e == outBuff.length);
345 return outBuff;
346 }
347
348
349 /* ******** D E C O D I N G M E T H O D S ******** */
350
351
352 /**
353 * Decodes four bytes from array <var>source</var>
354 * and writes the resulting bytes (up to three of them)
355 * to <var>destination</var>.
356 * The source and destination arrays can be manipulated
357 * anywhere along their length by specifying
358 * <var>srcOffset</var> and <var>destOffset</var>.
359 * This method does not check to make sure your arrays
360 * are large enough to accommodate <var>srcOffset</var> + 4 for
361 * the <var>source</var> array or <var>destOffset</var> + 3 for
362 * the <var>destination</var> array.
363 * This method returns the actual number of bytes that
364 * were converted from the Base64 encoding.
365 *
366 *
367 * @param source the array to convert
368 * @param srcOffset the index where conversion begins
369 * @param destination the array to hold the conversion
370 * @param destOffset the index where output will be put
371 * @param decodabet the decodabet for decoding Base64 content
372 * @return the number of decoded bytes converted
373 * @since 1.3
374 */
375 private static int decode4to3(byte[] source, int srcOffset,
376 byte[] destination, int destOffset, byte[] decodabet) {
377 // Example: Dk==
378 if (source[srcOffset + 2] == EQUALS_SIGN) {
379 int outBuff =
380 ((decodabet[source[srcOffset]] << 24) >>> 6)
381 | ((decodabet[source[srcOffset + 1]] << 24) >>> 12);
382
383 destination[destOffset] = (byte) (outBuff >>> 16);
384 return 1;
385 } else if (source[srcOffset + 3] == EQUALS_SIGN) {
386 // Example: DkL=
387 int outBuff =
388 ((decodabet[source[srcOffset]] << 24) >>> 6)
389 | ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
390 | ((decodabet[source[srcOffset + 2]] << 24) >>> 18);
391
392 destination[destOffset] = (byte) (outBuff >>> 16);
393 destination[destOffset + 1] = (byte) (outBuff >>> 8);
394 return 2;
395 } else {
396 // Example: DkLE
397 int outBuff =
398 ((decodabet[source[srcOffset]] << 24) >>> 6)
399 | ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
400 | ((decodabet[source[srcOffset + 2]] << 24) >>> 18)
401 | ((decodabet[source[srcOffset + 3]] << 24) >>> 24);
402
403 destination[destOffset] = (byte) (outBuff >> 16);
404 destination[destOffset + 1] = (byte) (outBuff >> 8);
405 destination[destOffset + 2] = (byte) (outBuff);
406 return 3;
407 }
408 } // end decodeToBytes
409
410
411 /**
412 * Decodes data from Base64 notation.
413 *
414 * @param s the string to decode (decoded in default encoding)
415 * @return the decoded data
416 * @since 1.4
417 */
418 public static byte[] decode(String s) throws Base64DecoderException {
419 byte[] bytes = s.getBytes();
420 return decode(bytes, 0, bytes.length);
421 }
422
423 /**
424 * Decodes data from web safe Base64 notation.
425 * Web safe encoding uses '-' instead of '+', '_' instead of '/'
426 *
427 * @param s the string to decode (decoded in default encoding)
428 * @return the decoded data
429 */
430 public static byte[] decodeWebSafe(String s) throws Base64DecoderException {
431 byte[] bytes = s.getBytes();
432 return decodeWebSafe(bytes, 0, bytes.length);
433 }
434
435 /**
436 * Decodes Base64 content in byte array format and returns
437 * the decoded byte array.
438 *
439 * @param source The Base64 encoded data
440 * @return decoded data
441 * @since 1.3
442 * @throws Base64DecoderException
443 */
444 public static byte[] decode(byte[] source) throws Base64DecoderException {
445 return decode(source, 0, source.length);
446 }
447
448 /**
449 * Decodes web safe Base64 content in byte array format and returns
450 * the decoded data.
451 * Web safe encoding uses '-' instead of '+', '_' instead of '/'
452 *
453 * @param source the string to decode (decoded in default encoding)
454 * @return the decoded data
455 */
456 public static byte[] decodeWebSafe(byte[] source)
457 throws Base64DecoderException {
458 return decodeWebSafe(source, 0, source.length);
459 }
460
461 /**
462 * Decodes Base64 content in byte array format and returns
463 * the decoded byte array.
464 *
465 * @param source the Base64 encoded data
466 * @param off the offset of where to begin decoding
467 * @param len the length of characters to decode
468 * @return decoded data
469 * @since 1.3
470 * @throws Base64DecoderException
471 */
472 public static byte[] decode(byte[] source, int off, int len)
473 throws Base64DecoderException {
474 return decode(source, off, len, DECODABET);
475 }
476
477 /**
478 * Decodes web safe Base64 content in byte array format and returns
479 * the decoded byte array.
480 * Web safe encoding uses '-' instead of '+', '_' instead of '/'
481 *
482 * @param source the Base64 encoded data
483 * @param off the offset of where to begin decoding
484 * @param len the length of characters to decode
485 * @return decoded data
486 */
487 public static byte[] decodeWebSafe(byte[] source, int off, int len)
488 throws Base64DecoderException {
489 return decode(source, off, len, WEBSAFE_DECODABET);
490 }
491
492 /**
493 * Decodes Base64 content using the supplied decodabet and returns
494 * the decoded byte array.
495 *
496 * @param source the Base64 encoded data
497 * @param off the offset of where to begin decoding
498 * @param len the length of characters to decode
499 * @param decodabet the decodabet for decoding Base64 content
500 * @return decoded data
501 */
502 public static byte[] decode(byte[] source, int off, int len, byte[] decodabet)
503 throws Base64DecoderException {
504 int len34 = len * 3 / 4;
505 byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output
506 int outBuffPosn = 0;
507
508 byte[] b4 = new byte[4];
509 int b4Posn = 0;
510 int i = 0;
511 byte sbiCrop = 0;
512 byte sbiDecode = 0;
513 for (i = 0; i < len; i++) {
514 sbiCrop = (byte) (source[i + off] & 0x7f); // Only the low seven bits
515 sbiDecode = decodabet[sbiCrop];
516
517 if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better
518 if (sbiDecode >= EQUALS_SIGN_ENC) {
519 // An equals sign (for padding) must not occur at position 0 or 1
520 // and must be the last byte[s] in the encoded value
521 if (sbiCrop == EQUALS_SIGN) {
522 int bytesLeft = len - i;
523 byte lastByte = (byte) (source[len - 1 + off] & 0x7f);
524 if (b4Posn == 0 || b4Posn == 1) {
525 throw new Base64DecoderException(
526 "invalid padding byte '=' at byte offset " + i);
527 } else if ((b4Posn == 3 && bytesLeft > 2)
528 || (b4Posn == 4 && bytesLeft > 1)) {
529 throw new Base64DecoderException(
530 "padding byte '=' falsely signals end of encoded value "
531 + "at offset " + i);
532 } else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) {
533 throw new Base64DecoderException(
534 "encoded value has invalid trailing byte");
535 }
536 break;
537 }
538
539 b4[b4Posn++] = sbiCrop;
540 if (b4Posn == 4) {
541 outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
542 b4Posn = 0;
543 }
544 }
545 } else {
546 throw new Base64DecoderException("Bad Base64 input character at " + i
547 + ": " + source[i + off] + "(decimal)");
548 }
549 }
550
551 // Because web safe encoding allows non padding base64 encodes, we
552 // need to pad the rest of the b4 buffer with equal signs when
553 // b4Posn != 0. There can be at most 2 equal signs at the end of
554 // four characters, so the b4 buffer must have two or three
555 // characters. This also catches the case where the input is
556 // padded with EQUALS_SIGN
557 if (b4Posn != 0) {
558 if (b4Posn == 1) {
559 throw new Base64DecoderException("single trailing character at offset "
560 + (len - 1));
561 }
562 b4[b4Posn++] = EQUALS_SIGN;
563 outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
564 }
565
566 byte[] out = new byte[outBuffPosn];
567 System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
568 return out;
569 }
570 }

  ViewVC Help
Powered by ViewVC 1.1.20