< prev index next >

src/java.base/share/classes/java/util/Base64.java

Print this page




  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;


< prev index next >