• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.util;
18 
19 import android.annotation.UnsupportedAppUsage;
20 import java.io.UnsupportedEncodingException;
21 
22 /**
23  * Utilities for encoding and decoding the Base64 representation of
24  * binary data.  See RFCs <a
25  * href="http://www.ietf.org/rfc/rfc2045.txt">2045</a> and <a
26  * href="http://www.ietf.org/rfc/rfc3548.txt">3548</a>.
27  */
28 public class Base64 {
29     /**
30      * Default values for encoder/decoder flags.
31      */
32     public static final int DEFAULT = 0;
33 
34     /**
35      * Encoder flag bit to omit the padding '=' characters at the end
36      * of the output (if any).
37      */
38     public static final int NO_PADDING = 1;
39 
40     /**
41      * Encoder flag bit to omit all line terminators (i.e., the output
42      * will be on one long line).
43      */
44     public static final int NO_WRAP = 2;
45 
46     /**
47      * Encoder flag bit to indicate lines should be terminated with a
48      * CRLF pair instead of just an LF.  Has no effect if {@code
49      * NO_WRAP} is specified as well.
50      */
51     public static final int CRLF = 4;
52 
53     /**
54      * Encoder/decoder flag bit to indicate using the "URL and
55      * filename safe" variant of Base64 (see RFC 3548 section 4) where
56      * {@code -} and {@code _} are used in place of {@code +} and
57      * {@code /}.
58      */
59     public static final int URL_SAFE = 8;
60 
61     /**
62      * Flag to pass to {@link Base64OutputStream} to indicate that it
63      * should not close the output stream it is wrapping when it
64      * itself is closed.
65      */
66     public static final int NO_CLOSE = 16;
67 
68     //  --------------------------------------------------------
69     //  shared code
70     //  --------------------------------------------------------
71 
72     /* package */ static abstract class Coder {
73         public byte[] output;
74         public int op;
75 
76         /**
77          * Encode/decode another block of input data.  this.output is
78          * provided by the caller, and must be big enough to hold all
79          * the coded data.  On exit, this.opwill be set to the length
80          * of the coded data.
81          *
82          * @param finish true if this is the final call to process for
83          *        this object.  Will finalize the coder state and
84          *        include any final bytes in the output.
85          *
86          * @return true if the input so far is good; false if some
87          *         error has been detected in the input stream..
88          */
process(byte[] input, int offset, int len, boolean finish)89         public abstract boolean process(byte[] input, int offset, int len, boolean finish);
90 
91         /**
92          * @return the maximum number of bytes a call to process()
93          * could produce for the given number of input bytes.  This may
94          * be an overestimate.
95          */
maxOutputSize(int len)96         public abstract int maxOutputSize(int len);
97     }
98 
99     //  --------------------------------------------------------
100     //  decoding
101     //  --------------------------------------------------------
102 
103     /**
104      * Decode the Base64-encoded data in input and return the data in
105      * a new byte array.
106      *
107      * <p>The padding '=' characters at the end are considered optional, but
108      * if any are present, there must be the correct number of them.
109      *
110      * @param str    the input String to decode, which is converted to
111      *               bytes using the default charset
112      * @param flags  controls certain features of the decoded output.
113      *               Pass {@code DEFAULT} to decode standard Base64.
114      *
115      * @throws IllegalArgumentException if the input contains
116      * incorrect padding
117      */
decode(String str, int flags)118     public static byte[] decode(String str, int flags) {
119         return decode(str.getBytes(), flags);
120     }
121 
122     /**
123      * Decode the Base64-encoded data in input and return the data in
124      * a new byte array.
125      *
126      * <p>The padding '=' characters at the end are considered optional, but
127      * if any are present, there must be the correct number of them.
128      *
129      * @param input the input array to decode
130      * @param flags  controls certain features of the decoded output.
131      *               Pass {@code DEFAULT} to decode standard Base64.
132      *
133      * @throws IllegalArgumentException if the input contains
134      * incorrect padding
135      */
decode(byte[] input, int flags)136     public static byte[] decode(byte[] input, int flags) {
137         return decode(input, 0, input.length, flags);
138     }
139 
140     /**
141      * Decode the Base64-encoded data in input and return the data in
142      * a new byte array.
143      *
144      * <p>The padding '=' characters at the end are considered optional, but
145      * if any are present, there must be the correct number of them.
146      *
147      * @param input  the data to decode
148      * @param offset the position within the input array at which to start
149      * @param len    the number of bytes of input to decode
150      * @param flags  controls certain features of the decoded output.
151      *               Pass {@code DEFAULT} to decode standard Base64.
152      *
153      * @throws IllegalArgumentException if the input contains
154      * incorrect padding
155      */
decode(byte[] input, int offset, int len, int flags)156     public static byte[] decode(byte[] input, int offset, int len, int flags) {
157         // Allocate space for the most data the input could represent.
158         // (It could contain less if it contains whitespace, etc.)
159         Decoder decoder = new Decoder(flags, new byte[len*3/4]);
160 
161         if (!decoder.process(input, offset, len, true)) {
162             throw new IllegalArgumentException("bad base-64");
163         }
164 
165         // Maybe we got lucky and allocated exactly enough output space.
166         if (decoder.op == decoder.output.length) {
167             return decoder.output;
168         }
169 
170         // Need to shorten the array, so allocate a new one of the
171         // right size and copy.
172         byte[] temp = new byte[decoder.op];
173         System.arraycopy(decoder.output, 0, temp, 0, decoder.op);
174         return temp;
175     }
176 
177     /* package */ static class Decoder extends Coder {
178         /**
179          * Lookup table for turning bytes into their position in the
180          * Base64 alphabet.
181          */
182         private static final int DECODE[] = {
183             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
184             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
185             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
186             52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
187             -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
188             15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
189             -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
190             41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
191             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
192             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
193             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
194             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
195             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
196             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
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         };
200 
201         /**
202          * Decode lookup table for the "web safe" variant (RFC 3548
203          * sec. 4) where - and _ replace + and /.
204          */
205         private static final int DECODE_WEBSAFE[] = {
206             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
207             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
208             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
209             52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
210             -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
211             15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
212             -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
213             41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
214             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
215             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
216             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
217             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
218             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
219             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
220             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
221             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
222         };
223 
224         /** Non-data values in the DECODE arrays. */
225         private static final int SKIP = -1;
226         private static final int EQUALS = -2;
227 
228         /**
229          * States 0-3 are reading through the next input tuple.
230          * State 4 is having read one '=' and expecting exactly
231          * one more.
232          * State 5 is expecting no more data or padding characters
233          * in the input.
234          * State 6 is the error state; an error has been detected
235          * in the input and no future input can "fix" it.
236          */
237         private int state;   // state number (0 to 6)
238         private int value;
239 
240         final private int[] alphabet;
241 
Decoder(int flags, byte[] output)242         public Decoder(int flags, byte[] output) {
243             this.output = output;
244 
245             alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;
246             state = 0;
247             value = 0;
248         }
249 
250         /**
251          * @return an overestimate for the number of bytes {@code
252          * len} bytes could decode to.
253          */
maxOutputSize(int len)254         public int maxOutputSize(int len) {
255             return len * 3/4 + 10;
256         }
257 
258         /**
259          * Decode another block of input data.
260          *
261          * @return true if the state machine is still healthy.  false if
262          *         bad base-64 data has been detected in the input stream.
263          */
process(byte[] input, int offset, int len, boolean finish)264         public boolean process(byte[] input, int offset, int len, boolean finish) {
265             if (this.state == 6) return false;
266 
267             int p = offset;
268             len += offset;
269 
270             // Using local variables makes the decoder about 12%
271             // faster than if we manipulate the member variables in
272             // the loop.  (Even alphabet makes a measurable
273             // difference, which is somewhat surprising to me since
274             // the member variable is final.)
275             int state = this.state;
276             int value = this.value;
277             int op = 0;
278             final byte[] output = this.output;
279             final int[] alphabet = this.alphabet;
280 
281             while (p < len) {
282                 // Try the fast path:  we're starting a new tuple and the
283                 // next four bytes of the input stream are all data
284                 // bytes.  This corresponds to going through states
285                 // 0-1-2-3-0.  We expect to use this method for most of
286                 // the data.
287                 //
288                 // If any of the next four bytes of input are non-data
289                 // (whitespace, etc.), value will end up negative.  (All
290                 // the non-data values in decode are small negative
291                 // numbers, so shifting any of them up and or'ing them
292                 // together will result in a value with its top bit set.)
293                 //
294                 // You can remove this whole block and the output should
295                 // be the same, just slower.
296                 if (state == 0) {
297                     while (p+4 <= len &&
298                            (value = ((alphabet[input[p] & 0xff] << 18) |
299                                      (alphabet[input[p+1] & 0xff] << 12) |
300                                      (alphabet[input[p+2] & 0xff] << 6) |
301                                      (alphabet[input[p+3] & 0xff]))) >= 0) {
302                         output[op+2] = (byte) value;
303                         output[op+1] = (byte) (value >> 8);
304                         output[op] = (byte) (value >> 16);
305                         op += 3;
306                         p += 4;
307                     }
308                     if (p >= len) break;
309                 }
310 
311                 // The fast path isn't available -- either we've read a
312                 // partial tuple, or the next four input bytes aren't all
313                 // data, or whatever.  Fall back to the slower state
314                 // machine implementation.
315 
316                 int d = alphabet[input[p++] & 0xff];
317 
318                 switch (state) {
319                 case 0:
320                     if (d >= 0) {
321                         value = d;
322                         ++state;
323                     } else if (d != SKIP) {
324                         this.state = 6;
325                         return false;
326                     }
327                     break;
328 
329                 case 1:
330                     if (d >= 0) {
331                         value = (value << 6) | d;
332                         ++state;
333                     } else if (d != SKIP) {
334                         this.state = 6;
335                         return false;
336                     }
337                     break;
338 
339                 case 2:
340                     if (d >= 0) {
341                         value = (value << 6) | d;
342                         ++state;
343                     } else if (d == EQUALS) {
344                         // Emit the last (partial) output tuple;
345                         // expect exactly one more padding character.
346                         output[op++] = (byte) (value >> 4);
347                         state = 4;
348                     } else if (d != SKIP) {
349                         this.state = 6;
350                         return false;
351                     }
352                     break;
353 
354                 case 3:
355                     if (d >= 0) {
356                         // Emit the output triple and return to state 0.
357                         value = (value << 6) | d;
358                         output[op+2] = (byte) value;
359                         output[op+1] = (byte) (value >> 8);
360                         output[op] = (byte) (value >> 16);
361                         op += 3;
362                         state = 0;
363                     } else if (d == EQUALS) {
364                         // Emit the last (partial) output tuple;
365                         // expect no further data or padding characters.
366                         output[op+1] = (byte) (value >> 2);
367                         output[op] = (byte) (value >> 10);
368                         op += 2;
369                         state = 5;
370                     } else if (d != SKIP) {
371                         this.state = 6;
372                         return false;
373                     }
374                     break;
375 
376                 case 4:
377                     if (d == EQUALS) {
378                         ++state;
379                     } else if (d != SKIP) {
380                         this.state = 6;
381                         return false;
382                     }
383                     break;
384 
385                 case 5:
386                     if (d != SKIP) {
387                         this.state = 6;
388                         return false;
389                     }
390                     break;
391                 }
392             }
393 
394             if (!finish) {
395                 // We're out of input, but a future call could provide
396                 // more.
397                 this.state = state;
398                 this.value = value;
399                 this.op = op;
400                 return true;
401             }
402 
403             // Done reading input.  Now figure out where we are left in
404             // the state machine and finish up.
405 
406             switch (state) {
407             case 0:
408                 // Output length is a multiple of three.  Fine.
409                 break;
410             case 1:
411                 // Read one extra input byte, which isn't enough to
412                 // make another output byte.  Illegal.
413                 this.state = 6;
414                 return false;
415             case 2:
416                 // Read two extra input bytes, enough to emit 1 more
417                 // output byte.  Fine.
418                 output[op++] = (byte) (value >> 4);
419                 break;
420             case 3:
421                 // Read three extra input bytes, enough to emit 2 more
422                 // output bytes.  Fine.
423                 output[op++] = (byte) (value >> 10);
424                 output[op++] = (byte) (value >> 2);
425                 break;
426             case 4:
427                 // Read one padding '=' when we expected 2.  Illegal.
428                 this.state = 6;
429                 return false;
430             case 5:
431                 // Read all the padding '='s we expected and no more.
432                 // Fine.
433                 break;
434             }
435 
436             this.state = state;
437             this.op = op;
438             return true;
439         }
440     }
441 
442     //  --------------------------------------------------------
443     //  encoding
444     //  --------------------------------------------------------
445 
446     /**
447      * Base64-encode the given data and return a newly allocated
448      * String with the result.
449      *
450      * @param input  the data to encode
451      * @param flags  controls certain features of the encoded output.
452      *               Passing {@code DEFAULT} results in output that
453      *               adheres to RFC 2045.
454      */
encodeToString(byte[] input, int flags)455     public static String encodeToString(byte[] input, int flags) {
456         try {
457             return new String(encode(input, flags), "US-ASCII");
458         } catch (UnsupportedEncodingException e) {
459             // US-ASCII is guaranteed to be available.
460             throw new AssertionError(e);
461         }
462     }
463 
464     /**
465      * Base64-encode the given data and return a newly allocated
466      * String with the result.
467      *
468      * @param input  the data to encode
469      * @param offset the position within the input array at which to
470      *               start
471      * @param len    the number of bytes of input to encode
472      * @param flags  controls certain features of the encoded output.
473      *               Passing {@code DEFAULT} results in output that
474      *               adheres to RFC 2045.
475      */
encodeToString(byte[] input, int offset, int len, int flags)476     public static String encodeToString(byte[] input, int offset, int len, int flags) {
477         try {
478             return new String(encode(input, offset, len, flags), "US-ASCII");
479         } catch (UnsupportedEncodingException e) {
480             // US-ASCII is guaranteed to be available.
481             throw new AssertionError(e);
482         }
483     }
484 
485     /**
486      * Base64-encode the given data and return a newly allocated
487      * byte[] with the result.
488      *
489      * @param input  the data to encode
490      * @param flags  controls certain features of the encoded output.
491      *               Passing {@code DEFAULT} results in output that
492      *               adheres to RFC 2045.
493      */
encode(byte[] input, int flags)494     public static byte[] encode(byte[] input, int flags) {
495         return encode(input, 0, input.length, flags);
496     }
497 
498     /**
499      * Base64-encode the given data and return a newly allocated
500      * byte[] with the result.
501      *
502      * @param input  the data to encode
503      * @param offset the position within the input array at which to
504      *               start
505      * @param len    the number of bytes of input to encode
506      * @param flags  controls certain features of the encoded output.
507      *               Passing {@code DEFAULT} results in output that
508      *               adheres to RFC 2045.
509      */
encode(byte[] input, int offset, int len, int flags)510     public static byte[] encode(byte[] input, int offset, int len, int flags) {
511         Encoder encoder = new Encoder(flags, null);
512 
513         // Compute the exact length of the array we will produce.
514         int output_len = len / 3 * 4;
515 
516         // Account for the tail of the data and the padding bytes, if any.
517         if (encoder.do_padding) {
518             if (len % 3 > 0) {
519                 output_len += 4;
520             }
521         } else {
522             switch (len % 3) {
523                 case 0: break;
524                 case 1: output_len += 2; break;
525                 case 2: output_len += 3; break;
526             }
527         }
528 
529         // Account for the newlines, if any.
530         if (encoder.do_newline && len > 0) {
531             output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) *
532                 (encoder.do_cr ? 2 : 1);
533         }
534 
535         encoder.output = new byte[output_len];
536         encoder.process(input, offset, len, true);
537 
538         assert encoder.op == output_len;
539 
540         return encoder.output;
541     }
542 
543     /* package */ static class Encoder extends Coder {
544         /**
545          * Emit a new line every this many output tuples.  Corresponds to
546          * a 76-character line length (the maximum allowable according to
547          * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>).
548          */
549         public static final int LINE_GROUPS = 19;
550 
551         /**
552          * Lookup table for turning Base64 alphabet positions (6 bits)
553          * into output bytes.
554          */
555         private static final byte ENCODE[] = {
556             'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
557             'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
558             'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
559             'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
560         };
561 
562         /**
563          * Lookup table for turning Base64 alphabet positions (6 bits)
564          * into output bytes.
565          */
566         private static final byte ENCODE_WEBSAFE[] = {
567             'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
568             'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
569             'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
570             'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
571         };
572 
573         final private byte[] tail;
574         /* package */ int tailLen;
575         private int count;
576 
577         final public boolean do_padding;
578         final public boolean do_newline;
579         final public boolean do_cr;
580         final private byte[] alphabet;
581 
Encoder(int flags, byte[] output)582         public Encoder(int flags, byte[] output) {
583             this.output = output;
584 
585             do_padding = (flags & NO_PADDING) == 0;
586             do_newline = (flags & NO_WRAP) == 0;
587             do_cr = (flags & CRLF) != 0;
588             alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;
589 
590             tail = new byte[2];
591             tailLen = 0;
592 
593             count = do_newline ? LINE_GROUPS : -1;
594         }
595 
596         /**
597          * @return an overestimate for the number of bytes {@code
598          * len} bytes could encode to.
599          */
maxOutputSize(int len)600         public int maxOutputSize(int len) {
601             return len * 8/5 + 10;
602         }
603 
process(byte[] input, int offset, int len, boolean finish)604         public boolean process(byte[] input, int offset, int len, boolean finish) {
605             // Using local variables makes the encoder about 9% faster.
606             final byte[] alphabet = this.alphabet;
607             final byte[] output = this.output;
608             int op = 0;
609             int count = this.count;
610 
611             int p = offset;
612             len += offset;
613             int v = -1;
614 
615             // First we need to concatenate the tail of the previous call
616             // with any input bytes available now and see if we can empty
617             // the tail.
618 
619             switch (tailLen) {
620                 case 0:
621                     // There was no tail.
622                     break;
623 
624                 case 1:
625                     if (p+2 <= len) {
626                         // A 1-byte tail with at least 2 bytes of
627                         // input available now.
628                         v = ((tail[0] & 0xff) << 16) |
629                             ((input[p++] & 0xff) << 8) |
630                             (input[p++] & 0xff);
631                         tailLen = 0;
632                     };
633                     break;
634 
635                 case 2:
636                     if (p+1 <= len) {
637                         // A 2-byte tail with at least 1 byte of input.
638                         v = ((tail[0] & 0xff) << 16) |
639                             ((tail[1] & 0xff) << 8) |
640                             (input[p++] & 0xff);
641                         tailLen = 0;
642                     }
643                     break;
644             }
645 
646             if (v != -1) {
647                 output[op++] = alphabet[(v >> 18) & 0x3f];
648                 output[op++] = alphabet[(v >> 12) & 0x3f];
649                 output[op++] = alphabet[(v >> 6) & 0x3f];
650                 output[op++] = alphabet[v & 0x3f];
651                 if (--count == 0) {
652                     if (do_cr) output[op++] = '\r';
653                     output[op++] = '\n';
654                     count = LINE_GROUPS;
655                 }
656             }
657 
658             // At this point either there is no tail, or there are fewer
659             // than 3 bytes of input available.
660 
661             // The main loop, turning 3 input bytes into 4 output bytes on
662             // each iteration.
663             while (p+3 <= len) {
664                 v = ((input[p] & 0xff) << 16) |
665                     ((input[p+1] & 0xff) << 8) |
666                     (input[p+2] & 0xff);
667                 output[op] = alphabet[(v >> 18) & 0x3f];
668                 output[op+1] = alphabet[(v >> 12) & 0x3f];
669                 output[op+2] = alphabet[(v >> 6) & 0x3f];
670                 output[op+3] = alphabet[v & 0x3f];
671                 p += 3;
672                 op += 4;
673                 if (--count == 0) {
674                     if (do_cr) output[op++] = '\r';
675                     output[op++] = '\n';
676                     count = LINE_GROUPS;
677                 }
678             }
679 
680             if (finish) {
681                 // Finish up the tail of the input.  Note that we need to
682                 // consume any bytes in tail before any bytes
683                 // remaining in input; there should be at most two bytes
684                 // total.
685 
686                 if (p-tailLen == len-1) {
687                     int t = 0;
688                     v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;
689                     tailLen -= t;
690                     output[op++] = alphabet[(v >> 6) & 0x3f];
691                     output[op++] = alphabet[v & 0x3f];
692                     if (do_padding) {
693                         output[op++] = '=';
694                         output[op++] = '=';
695                     }
696                     if (do_newline) {
697                         if (do_cr) output[op++] = '\r';
698                         output[op++] = '\n';
699                     }
700                 } else if (p-tailLen == len-2) {
701                     int t = 0;
702                     v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |
703                         (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);
704                     tailLen -= t;
705                     output[op++] = alphabet[(v >> 12) & 0x3f];
706                     output[op++] = alphabet[(v >> 6) & 0x3f];
707                     output[op++] = alphabet[v & 0x3f];
708                     if (do_padding) {
709                         output[op++] = '=';
710                     }
711                     if (do_newline) {
712                         if (do_cr) output[op++] = '\r';
713                         output[op++] = '\n';
714                     }
715                 } else if (do_newline && op > 0 && count != LINE_GROUPS) {
716                     if (do_cr) output[op++] = '\r';
717                     output[op++] = '\n';
718                 }
719 
720                 assert tailLen == 0;
721                 assert p == len;
722             } else {
723                 // Save the leftovers in tail to be consumed on the next
724                 // call to encodeInternal.
725 
726                 if (p == len-1) {
727                     tail[tailLen++] = input[p];
728                 } else if (p == len-2) {
729                     tail[tailLen++] = input[p];
730                     tail[tailLen++] = input[p+1];
731                 }
732             }
733 
734             this.op = op;
735             this.count = count;
736 
737             return true;
738         }
739     }
740 
741     @UnsupportedAppUsage
Base64()742     private Base64() { }   // don't instantiate
743 }
744