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