14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.util;
27
28 import java.io.FilterOutputStream;
29 import java.io.InputStream;
30 import java.io.IOException;
31 import java.io.OutputStream;
32 import java.nio.ByteBuffer;
33 import java.nio.charset.StandardCharsets;
34
35 /**
36 * This class consists exclusively of static methods for obtaining
37 * encoders and decoders for the Base64 encoding scheme. The
38 * implementation of this class supports the following types of Base64
39 * as specified in
40 * <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a> and
41 * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>.
42 *
43 * <ul>
44 * <li><a id="basic"><b>Basic</b></a>
45 * <p> Uses "The Base64 Alphabet" as specified in Table 1 of
46 * RFC 4648 and RFC 2045 for encoding and decoding operation.
47 * The encoder does not add any line feed (line separator)
48 * character. The decoder rejects data that contains characters
49 * outside the base64 alphabet.</p></li>
50 *
51 * <li><a id="url"><b>URL and Filename safe</b></a>
52 * <p> Uses the "URL and Filename safe Base64 Alphabet" as specified
53 * in Table 2 of RFC 4648 for encoding and decoding. The
373 }
374
375 /**
376 * Returns an encoder instance that encodes equivalently to this one,
377 * but without adding any padding character at the end of the encoded
378 * byte data.
379 *
380 * <p> The encoding scheme of this encoder instance is unaffected by
381 * this invocation. The returned encoder instance should be used for
382 * non-padding encoding operation.
383 *
384 * @return an equivalent encoder that encodes without adding any
385 * padding character at the end
386 */
387 public Encoder withoutPadding() {
388 if (!doPadding)
389 return this;
390 return new Encoder(isURL, newline, linemax, false);
391 }
392
393 private int encode0(byte[] src, int off, int end, byte[] dst) {
394 char[] base64 = isURL ? toBase64URL : toBase64;
395 int sp = off;
396 int slen = (end - off) / 3 * 3;
397 int sl = off + slen;
398 if (linemax > 0 && slen > linemax / 4 * 3)
399 slen = linemax / 4 * 3;
400 int dp = 0;
401 while (sp < sl) {
402 int sl0 = Math.min(sp + slen, sl);
403 for (int sp0 = sp, dp0 = dp ; sp0 < sl0; ) {
404 int bits = (src[sp0++] & 0xff) << 16 |
405 (src[sp0++] & 0xff) << 8 |
406 (src[sp0++] & 0xff);
407 dst[dp0++] = (byte)base64[(bits >>> 18) & 0x3f];
408 dst[dp0++] = (byte)base64[(bits >>> 12) & 0x3f];
409 dst[dp0++] = (byte)base64[(bits >>> 6) & 0x3f];
410 dst[dp0++] = (byte)base64[bits & 0x3f];
411 }
412 int dlen = (sl0 - sp) / 3 * 4;
413 dp += dlen;
414 sp = sl0;
415 if (dlen == linemax && sp < end) {
416 for (byte b : newline){
417 dst[dp++] = b;
418 }
419 }
420 }
421 if (sp < end) { // 1 or 2 leftover bytes
422 int b0 = src[sp++] & 0xff;
423 dst[dp++] = (byte)base64[b0 >> 2];
424 if (sp == end) {
425 dst[dp++] = (byte)base64[(b0 << 4) & 0x3f];
426 if (doPadding) {
427 dst[dp++] = '=';
428 dst[dp++] = '=';
429 }
430 } else {
431 int b1 = src[sp++] & 0xff;
|
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.util;
27
28 import java.io.FilterOutputStream;
29 import java.io.InputStream;
30 import java.io.IOException;
31 import java.io.OutputStream;
32 import java.nio.ByteBuffer;
33 import java.nio.charset.StandardCharsets;
34 import jdk.internal.HotSpotIntrinsicCandidate;
35
36 /**
37 * This class consists exclusively of static methods for obtaining
38 * encoders and decoders for the Base64 encoding scheme. The
39 * implementation of this class supports the following types of Base64
40 * as specified in
41 * <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a> and
42 * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>.
43 *
44 * <ul>
45 * <li><a id="basic"><b>Basic</b></a>
46 * <p> Uses "The Base64 Alphabet" as specified in Table 1 of
47 * RFC 4648 and RFC 2045 for encoding and decoding operation.
48 * The encoder does not add any line feed (line separator)
49 * character. The decoder rejects data that contains characters
50 * outside the base64 alphabet.</p></li>
51 *
52 * <li><a id="url"><b>URL and Filename safe</b></a>
53 * <p> Uses the "URL and Filename safe Base64 Alphabet" as specified
54 * in Table 2 of RFC 4648 for encoding and decoding. The
374 }
375
376 /**
377 * Returns an encoder instance that encodes equivalently to this one,
378 * but without adding any padding character at the end of the encoded
379 * byte data.
380 *
381 * <p> The encoding scheme of this encoder instance is unaffected by
382 * this invocation. The returned encoder instance should be used for
383 * non-padding encoding operation.
384 *
385 * @return an equivalent encoder that encodes without adding any
386 * padding character at the end
387 */
388 public Encoder withoutPadding() {
389 if (!doPadding)
390 return this;
391 return new Encoder(isURL, newline, linemax, false);
392 }
393
394 void generateImplEncode(byte[] src, int sp, int sl, byte[] dst, int dp) {
395 if (sp > sl)
396 throw new ArrayIndexOutOfBoundsException(
397 "Start offset " + sp + ", End offset " +sl);
398 implEncode(src, sp, sl, dst, dp, isURL);
399 }
400
401 @HotSpotIntrinsicCandidate
402 private void implEncode(byte[] src, int sp, int sl, byte[] dst, int dp, boolean isURL) {
403 char[] base64 = isURL ? toBase64URL : toBase64;
404 for (int sp0 = sp, dp0 = dp ; sp0 < sl; ) {
405 int bits = (src[sp0++] & 0xff) << 16 |
406 (src[sp0++] & 0xff) << 8 |
407 (src[sp0++] & 0xff);
408 dst[dp0++] = (byte)base64[(bits >>> 18) & 0x3f];
409 dst[dp0++] = (byte)base64[(bits >>> 12) & 0x3f];
410 dst[dp0++] = (byte)base64[(bits >>> 6) & 0x3f];
411 dst[dp0++] = (byte)base64[bits & 0x3f];
412 }
413 }
414 private int encode0(byte[] src, int off, int end, byte[] dst) {
415 char[] base64 = isURL ? toBase64URL : toBase64;
416 int sp = off;
417 int slen = (end - off) / 3 * 3;
418 int sl = off + slen;
419 if (linemax > 0 && slen > linemax / 4 * 3)
420 slen = linemax / 4 * 3;
421 int dp = 0;
422 while (sp < sl) {
423 int sl0 = Math.min(sp + slen, sl);
424 generateImplEncode(src, sp, sl0, dst, dp);
425 int dlen = (sl0 - sp) / 3 * 4;
426 dp += dlen;
427 sp = sl0;
428 if (dlen == linemax && sp < end) {
429 for (byte b : newline){
430 dst[dp++] = b;
431 }
432 }
433 }
434 if (sp < end) { // 1 or 2 leftover bytes
435 int b0 = src[sp++] & 0xff;
436 dst[dp++] = (byte)base64[b0 >> 2];
437 if (sp == end) {
438 dst[dp++] = (byte)base64[(b0 << 4) & 0x3f];
439 if (doPadding) {
440 dst[dp++] = '=';
441 dst[dp++] = '=';
442 }
443 } else {
444 int b1 = src[sp++] & 0xff;
|