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