< prev index next >

src/java.base/share/classes/java/lang/StringCoding.java

Print this page

        

@@ -34,10 +34,12 @@
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CharacterCodingException;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
 import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
 import java.nio.charset.UnsupportedCharsetException;
 import java.util.Arrays;
 import jdk.internal.HotSpotIntrinsicCandidate;
 import sun.nio.cs.HistoricallyNamedCharset;
 import sun.nio.cs.ArrayDecoder;

@@ -605,11 +607,11 @@
             int ret = implEncodeISOArray(val, sp, dst, dp, len);
             sp = sp + ret;
             dp = dp + ret;
             if (ret != len) {
                 if (!doReplace) {
-                    throwMalformed(sp, 1);
+                    throwUnmappable(sp, 1);
                 }
                 char c = StringUTF16.getChar(val, sp++);
                 if (Character.isHighSurrogate(c) && sp < sl &&
                     Character.isLowSurrogate(StringUTF16.getChar(val, sp))) {
                     sp++;

@@ -677,20 +679,31 @@
         assert false;
         return -1;
     }
 
     private static void throwMalformed(int off, int nb) {
-        throw new IllegalArgumentException("malformed input off : " + off +
-                                           ", length : " + nb);
+        String msg = "malformed input off : " + off + ", length : " + nb;
+        throw new IllegalArgumentException(msg, new MalformedInputException(nb));
     }
 
     private static void throwMalformed(byte[] val) {
         int dp = 0;
         while (dp < val.length && val[dp] >=0) { dp++; }
         throwMalformed(dp, 1);
     }
 
+    private static void throwUnmappable(int off, int nb) {
+        String msg = "malformed input off : " + off + ", length : " + nb;
+        throw new IllegalArgumentException(msg, new UnmappableCharacterException(nb));
+    }
+
+    private static void throwUnmappable(byte[] val) {
+        int dp = 0;
+        while (dp < val.length && val[dp] >=0) { dp++; }
+        throwUnmappable(dp, 1);
+    }
+
     private static char repl = '\ufffd';
 
     private static Result decodeUTF8(byte[] src, int sp, int len, boolean doReplace) {
         // ascii-bais, which has a relative impact to the non-ascii-only bytes
         if (COMPACT_STRINGS && !hasNegatives(src, sp, len))

@@ -917,11 +930,11 @@
                 }
                 if (uc < 0) {
                     if (doReplace) {
                         dst[dp++] = '?';
                     } else {
-                        throwMalformed(sp - 1, 1); // or 2, does not matter here
+                        throwUnmappable(sp - 1, 1); // or 2, does not matter here
                     }
                 } else {
                     dst[dp++] = (byte)(0xf0 | ((uc >> 18)));
                     dst[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f));
                     dst[dp++] = (byte)(0x80 | ((uc >>  6) & 0x3f));

@@ -970,11 +983,23 @@
         if (COMPACT_STRINGS)
            return new String(src, LATIN1);
         return new String(StringLatin1.inflate(src, 0, src.length), UTF16);
     }
 
-    static String newStringNoRepl(byte[] src, Charset cs) {
+    static String newStringNoRepl(byte[] src, Charset cs) throws CharacterCodingException {
+        try {
+            return newStringNoRepl1(src, cs);
+        } catch (IllegalArgumentException e) {
+            Throwable cause = e.getCause();
+            if (cause != null && cause instanceof MalformedInputException) {
+                throw (MalformedInputException)cause;
+            }
+            throw new UnmappableCharacterException(1);
+        }
+    }
+
+    static String newStringNoRepl1(byte[] src, Charset cs) {
         if (cs == UTF_8) {
             if (COMPACT_STRINGS && isASCII(src))
                 return new String(src, LATIN1);
             Result ret = decodeUTF8_0(src, 0, src.length, false);
             return new String(ret.value, ret.coder);

@@ -1023,11 +1048,23 @@
     }
 
     /*
      * Throws iae, instead of replacing, if unmappable.
      */
-    static byte[] getBytesNoRepl(String s, Charset cs) {
+    static byte[] getBytesNoRepl(String s, Charset cs) throws CharacterCodingException {
+        try {
+            return getBytesNoRepl1(s, cs);
+        } catch (IllegalArgumentException e) {
+            Throwable cause = e.getCause();
+            if (cause != null && cause instanceof UnmappableCharacterException) {
+                throw (UnmappableCharacterException)cause;
+            }
+            throw new UnmappableCharacterException(1);
+        }
+    }
+
+    static byte[] getBytesNoRepl1(String s, Charset cs) {
         byte[] val = s.value();
         byte coder = s.coder();
         if (cs == UTF_8) {
             if (isASCII(val)) {
                 return val;

@@ -1043,11 +1080,11 @@
         if (cs == US_ASCII) {
             if (coder == LATIN1) {
                 if (isASCII(val)) {
                     return val;
                 } else {
-                    throwMalformed(val);
+                    throwUnmappable(val);
                 }
             }
         }
         CharsetEncoder ce = cs.newEncoder();
         // fastpath for ascii compatible

@@ -1081,10 +1118,10 @@
                 cr.throwException();
             cr = ce.flush(bb);
             if (!cr.isUnderflow())
                 cr.throwException();
         } catch (CharacterCodingException x) {
-            throw new Error(x);
+            throw new IllegalArgumentException(x);
         }
         return safeTrim(ba, bb.position(), isTrusted);
     }
 }
< prev index next >