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