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

Print this page




 603                 } else {
 604                     int b1 = src[sp++] & 0xff;
 605                     dst[dp++] = (byte)base64[(b0 << 4) & 0x3f | (b1 >> 4)];
 606                     dst[dp++] = (byte)base64[(b1 << 2) & 0x3f];
 607                     dst[dp++] = '=';
 608                 }
 609             }
 610             return dp;
 611         }
 612     }
 613 
 614     /**
 615      * This class implements a decoder for decoding byte data using the
 616      * Base64 encoding scheme as specified in RFC 4648 and RFC 2045.
 617      *
 618      * <p> The Base64 padding character {@code '='} is accepted and
 619      * interpreted as the end of the encoded byte data, but is not
 620      * required. So if the final unit of the encoded byte data only has
 621      * two or three Base64 characters (without the corresponding padding
 622      * character(s) padded), they are decoded as if followed by padding
 623      * character(s).



 624      *
 625      * <p> Instances of {@link Decoder} class are safe for use by
 626      * multiple concurrent threads.
 627      *
 628      * <p> Unless otherwise noted, passing a {@code null} argument to
 629      * a method of this class will cause a
 630      * {@link java.lang.NullPointerException NullPointerException} to
 631      * be thrown.
 632      *
 633      * @see     Encoder
 634      * @since   1.8
 635      */
 636     public static class Decoder {
 637 
 638         private final boolean isURL;
 639         private final boolean isMIME;
 640 
 641         private Decoder(boolean isURL, boolean isMIME) {
 642             this.isURL = isURL;
 643             this.isMIME = isMIME;


1017                 mark = sp;
1018                 return dp - dp0;
1019             } finally {
1020                 src.position(mark);
1021                 dst.position(dp);
1022             }
1023         }
1024 
1025         private int outLength(byte[] src, int sp, int sl) {
1026             int[] base64 = isURL ? fromBase64URL : fromBase64;
1027             int paddings = 0;
1028             int len = sl - sp;
1029             if (len == 0)
1030                 return 0;
1031             if (len < 2) {
1032                 if (isMIME && base64[0] == -1)
1033                     return 0;
1034                 throw new IllegalArgumentException(
1035                     "Input byte[] should at least have 2 bytes for base64 bytes");
1036             }
1037             if (src[sl - 1] == '=') {
1038                 paddings++;
1039                 if (src[sl - 2] == '=')
1040                     paddings++;
1041             }
1042             if (isMIME) {
1043                 // scan all bytes to fill out all non-alphabet. a performance
1044                 // trade-off of pre-scan or Arrays.copyOf
1045                 int n = 0;
1046                 while (sp < sl) {
1047                     int b = src[sp++] & 0xff;
1048                     if (b == '=')

1049                         break;

1050                     if ((b = base64[b]) == -1)
1051                         n++;
1052                 }
1053                 len -= n;






1054             }
1055             if (paddings == 0 && (len & 0x3) !=  0)
1056                 paddings = 4 - (len & 0x3);
1057             return 3 * ((len + 3) / 4) - paddings;
1058         }
1059 
1060         private int decode0(byte[] src, int sp, int sl, byte[] dst) {
1061             int[] base64 = isURL ? fromBase64URL : fromBase64;
1062             int dp = 0;
1063             int bits = 0;
1064             int shiftto = 18;       // pos of first byte of 4-byte atom
1065             while (sp < sl) {
1066                 int b = src[sp++] & 0xff;
1067                 if ((b = base64[b]) < 0) {
1068                     if (b == -2) {     // padding byte '='
1069                         // xx=   shiftto==6&&sp==sl missing last =
1070                         // xx=y  shiftto==6 last is not =
1071                         // =     shiftto==18 unnecessary padding
1072                         // x=    shiftto==12 be taken care later
1073                         //       together with single x, invalid anyway




 603                 } else {
 604                     int b1 = src[sp++] & 0xff;
 605                     dst[dp++] = (byte)base64[(b0 << 4) & 0x3f | (b1 >> 4)];
 606                     dst[dp++] = (byte)base64[(b1 << 2) & 0x3f];
 607                     dst[dp++] = '=';
 608                 }
 609             }
 610             return dp;
 611         }
 612     }
 613 
 614     /**
 615      * This class implements a decoder for decoding byte data using the
 616      * Base64 encoding scheme as specified in RFC 4648 and RFC 2045.
 617      *
 618      * <p> The Base64 padding character {@code '='} is accepted and
 619      * interpreted as the end of the encoded byte data, but is not
 620      * required. So if the final unit of the encoded byte data only has
 621      * two or three Base64 characters (without the corresponding padding
 622      * character(s) padded), they are decoded as if followed by padding
 623      * character(s). If there is padding character present in the
 624      * final unit, the correct number of padding character(s) must be
 625      * present, otherwise {@code IllegalArgumentException} is thrown
 626      * during decoding.
 627      *
 628      * <p> Instances of {@link Decoder} class are safe for use by
 629      * multiple concurrent threads.
 630      *
 631      * <p> Unless otherwise noted, passing a {@code null} argument to
 632      * a method of this class will cause a
 633      * {@link java.lang.NullPointerException NullPointerException} to
 634      * be thrown.
 635      *
 636      * @see     Encoder
 637      * @since   1.8
 638      */
 639     public static class Decoder {
 640 
 641         private final boolean isURL;
 642         private final boolean isMIME;
 643 
 644         private Decoder(boolean isURL, boolean isMIME) {
 645             this.isURL = isURL;
 646             this.isMIME = isMIME;


1020                 mark = sp;
1021                 return dp - dp0;
1022             } finally {
1023                 src.position(mark);
1024                 dst.position(dp);
1025             }
1026         }
1027 
1028         private int outLength(byte[] src, int sp, int sl) {
1029             int[] base64 = isURL ? fromBase64URL : fromBase64;
1030             int paddings = 0;
1031             int len = sl - sp;
1032             if (len == 0)
1033                 return 0;
1034             if (len < 2) {
1035                 if (isMIME && base64[0] == -1)
1036                     return 0;
1037                 throw new IllegalArgumentException(
1038                     "Input byte[] should at least have 2 bytes for base64 bytes");
1039             }





1040             if (isMIME) {
1041                 // scan all bytes to fill out all non-alphabet. a performance
1042                 // trade-off of pre-scan or Arrays.copyOf
1043                 int n = 0;
1044                 while (sp < sl) {
1045                     int b = src[sp++] & 0xff;
1046                     if (b == '=') {
1047                         len -= (sl - sp + 1);
1048                         break;
1049                     }
1050                     if ((b = base64[b]) == -1)
1051                         n++;
1052                 }
1053                 len -= n;
1054             } else {
1055                 if (src[sl - 1] == '=') {
1056                     paddings++;
1057                     if (src[sl - 2] == '=')
1058                         paddings++;
1059                 }
1060             }
1061             if (paddings == 0 && (len & 0x3) !=  0)
1062                 paddings = 4 - (len & 0x3);
1063             return 3 * ((len + 3) / 4) - paddings;
1064         }
1065 
1066         private int decode0(byte[] src, int sp, int sl, byte[] dst) {
1067             int[] base64 = isURL ? fromBase64URL : fromBase64;
1068             int dp = 0;
1069             int bits = 0;
1070             int shiftto = 18;       // pos of first byte of 4-byte atom
1071             while (sp < sl) {
1072                 int b = src[sp++] & 0xff;
1073                 if ((b = base64[b]) < 0) {
1074                     if (b == -2) {     // padding byte '='
1075                         // xx=   shiftto==6&&sp==sl missing last =
1076                         // xx=y  shiftto==6 last is not =
1077                         // =     shiftto==18 unnecessary padding
1078                         // x=    shiftto==12 be taken care later
1079                         //       together with single x, invalid anyway