< 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 >