--- old/src/java.base/share/classes/sun/nio/cs/DoubleByte.java 2015-10-30 14:03:47.713319486 -0700 +++ new/src/java.base/share/classes/sun/nio/cs/DoubleByte.java 2015-10-30 14:03:47.469320408 -0700 @@ -115,6 +115,7 @@ final char[] b2cSB; final int b2Min; final int b2Max; + final boolean isASCIICompatible; // for SimpleEUC override protected CoderResult crMalformedOrUnderFlow(int b) { @@ -132,16 +133,23 @@ public Decoder(Charset cs, float avgcpb, float maxcpb, char[][] b2c, char[] b2cSB, - int b2Min, int b2Max) { + int b2Min, int b2Max, + boolean isASCIICompatible) { super(cs, avgcpb, maxcpb); this.b2c = b2c; this.b2cSB = b2cSB; this.b2Min = b2Min; this.b2Max = b2Max; + this.isASCIICompatible = isASCIICompatible; + } + + public Decoder(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max, + boolean isASCIICompatible) { + this(cs, 0.5f, 1.0f, b2c, b2cSB, b2Min, b2Max, isASCIICompatible); } public Decoder(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max) { - this(cs, 0.5f, 1.0f, b2c, b2cSB, b2Min, b2Max); + this(cs, 0.5f, 1.0f, b2c, b2cSB, b2Min, b2Max, false); } protected CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) { @@ -215,6 +223,7 @@ return decodeBufferLoop(src, dst); } + @Override public int decode(byte[] src, int sp, int len, char[] dst) { int dp = 0; int sl = sp + len; @@ -230,12 +239,12 @@ if (b2c[b1] == B2C_UNMAPPABLE || // isNotLeadingByte b2c[b2] != B2C_UNMAPPABLE || // isLeadingByte decodeSingle(b2) != UNMAPPABLE_DECODING) { - sp--; + sp--; } } } if (c == UNMAPPABLE_DECODING) { - c = repl; + c = repl; } } dst[dp++] = c; @@ -243,6 +252,11 @@ return dp; } + @Override + public boolean isASCIICompatible() { + return isASCIICompatible; + } + public void implReset() { super.implReset(); } @@ -274,8 +288,14 @@ private int currentState; public Decoder_EBCDIC(Charset cs, - char[][] b2c, char[] b2cSB, int b2Min, int b2Max) { - super(cs, b2c, b2cSB, b2Min, b2Max); + char[][] b2c, char[] b2cSB, int b2Min, int b2Max, + boolean isASCIICompatible) { + super(cs, b2c, b2cSB, b2Min, b2Max, isASCIICompatible); + } + + public Decoder_EBCDIC(Charset cs, + char[][] b2c, char[] b2cSB, int b2Min, int b2Max) { + super(cs, b2c, b2cSB, b2Min, b2Max, false); } public void implReset() { @@ -403,6 +423,7 @@ } } + @Override public int decode(byte[] src, int sp, int len, char[] dst) { int dp = 0; int sl = sp + len; @@ -451,8 +472,13 @@ b2cSB_UNMAPPABLE = new char[0x100]; Arrays.fill(b2cSB_UNMAPPABLE, UNMAPPABLE_DECODING); } + public Decoder_DBCSONLY(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max, + boolean isASCIICompatible) { + super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max, isASCIICompatible); + } + public Decoder_DBCSONLY(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max) { - super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max); + super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max, false); } } @@ -464,8 +490,9 @@ private final int SS3 = 0x8F; public Decoder_EUC_SIM(Charset cs, - char[][] b2c, char[] b2cSB, int b2Min, int b2Max) { - super(cs, b2c, b2cSB, b2Min, b2Max); + char[][] b2c, char[] b2cSB, int b2Min, int b2Max, + boolean isASCIICompatible) { + super(cs, b2c, b2cSB, b2Min, b2Max, isASCIICompatible); } // No support provided for G2/G3 for SimpleEUC @@ -481,6 +508,7 @@ return CoderResult.unmappableForLength(2); } + @Override public int decode(byte[] src, int sp, int len, char[] dst) { int dp = 0; int sl = sp + len; @@ -515,17 +543,25 @@ private final char[] c2b; private final char[] c2bIndex; protected Surrogate.Parser sgp; + final boolean isASCIICompatible; public Encoder(Charset cs, char[] c2b, char[] c2bIndex) { + this(cs, c2b, c2bIndex, false); + } + + public Encoder(Charset cs, char[] c2b, char[] c2bIndex, boolean isASCIICompatible) { super(cs, 2.0f, 2.0f); this.c2b = c2b; this.c2bIndex = c2bIndex; + this.isASCIICompatible = isASCIICompatible; } - public Encoder(Charset cs, float avg, float max, byte[] repl, char[] c2b, char[] c2bIndex) { + public Encoder(Charset cs, float avg, float max, byte[] repl, char[] c2b, char[] c2bIndex, + boolean isASCIICompatible) { super(cs, avg, max, repl); this.c2b = c2b; this.c2bIndex = c2bIndex; + this.isASCIICompatible = isASCIICompatible; } public boolean canEncode(char c) { @@ -624,6 +660,7 @@ repl = newReplacement; } + @Override public int encode(char[] src, int sp, int len, byte[] dst) { int dp = 0; int sl = sp + len; @@ -647,11 +684,69 @@ } else { // SingleByte dst[dp++] = (byte)bb; } + } + return dp; + } + + @Override + public int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) { + int dp = 0; + int sl = sp + len; + while (sp < sl) { + char c = (char)(src[sp++] & 0xff); + int bb = encodeChar(c); + if (bb == UNMAPPABLE_ENCODING) { + // no surrogate pair in latin1 string + dst[dp++] = repl[0]; + if (repl.length > 1) { + dst[dp++] = repl[1]; + } + continue; + } //else + if (bb > MAX_SINGLEBYTE) { // DoubleByte + dst[dp++] = (byte)(bb >> 8); + dst[dp++] = (byte)bb; + } else { // SingleByte + dst[dp++] = (byte)bb; + } } return dp; } + @Override + public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) { + int dp = 0; + int sl = sp + len; + while (sp < sl) { + char c = StringUTF16.getChar(src, sp++); + int bb = encodeChar(c); + if (bb == UNMAPPABLE_ENCODING) { + if (Character.isHighSurrogate(c) && sp < sl && + Character.isLowSurrogate(StringUTF16.getChar(src, sp))) { + sp++; + } + dst[dp++] = repl[0]; + if (repl.length > 1) { + dst[dp++] = repl[1]; + } + continue; + } //else + if (bb > MAX_SINGLEBYTE) { // DoubleByte + dst[dp++] = (byte)(bb >> 8); + dst[dp++] = (byte)bb; + } else { // SingleByte + dst[dp++] = (byte)bb; + } + } + return dp; + } + + @Override + public boolean isASCIICompatible() { + return isASCIICompatible; + } + public int encodeChar(char ch) { return c2b[c2bIndex[ch >> 8] + (ch & 0xff)]; } @@ -741,9 +836,11 @@ } public static class Encoder_DBCSONLY extends Encoder { + public Encoder_DBCSONLY(Charset cs, byte[] repl, - char[] c2b, char[] c2bIndex) { - super(cs, 2.0f, 2.0f, repl, c2b, c2bIndex); + char[] c2b, char[] c2bIndex, + boolean isASCIICompatible) { + super(cs, 2.0f, 2.0f, repl, c2b, c2bIndex, isASCIICompatible); } public int encodeChar(char ch) { @@ -754,8 +851,6 @@ } } - - public static class Encoder_EBCDIC extends Encoder { static final int SBCS = 0; static final int DBCS = 1; @@ -764,8 +859,9 @@ protected int currentState = SBCS; - public Encoder_EBCDIC(Charset cs, char[] c2b, char[] c2bIndex) { - super(cs, 4.0f, 5.0f, new byte[] {(byte)0x6f}, c2b, c2bIndex); + public Encoder_EBCDIC(Charset cs, char[] c2b, char[] c2bIndex, + boolean isASCIICompatible) { + super(cs, 4.0f, 5.0f, new byte[] {(byte)0x6f}, c2b, c2bIndex, isASCIICompatible); } protected void implReset() { @@ -878,6 +974,7 @@ } } + @Override public int encode(char[] src, int sp, int len, byte[] dst) { int dp = 0; int sl = sp + len; @@ -917,12 +1014,88 @@ } return dp; } + + @Override + public int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) { + int dp = 0; + int sl = sp + len; + while (sp < sl) { + char c = (char)(src[sp++] & 0xff); + int bb = encodeChar(c); + if (bb == UNMAPPABLE_ENCODING) { + // no surrogate pair in latin1 string + dst[dp++] = repl[0]; + if (repl.length > 1) + dst[dp++] = repl[1]; + continue; + } //else + if (bb > MAX_SINGLEBYTE) { // DoubleByte + if (currentState == SBCS) { + currentState = DBCS; + dst[dp++] = SO; + } + dst[dp++] = (byte)(bb >> 8); + dst[dp++] = (byte)bb; + } else { // SingleByte + if (currentState == DBCS) { + currentState = SBCS; + dst[dp++] = SI; + } + dst[dp++] = (byte)bb; + } + } + if (currentState == DBCS) { + currentState = SBCS; + dst[dp++] = SI; + } + return dp; + } + + @Override + public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) { + int dp = 0; + int sl = sp + len; + while (sp < sl) { + char c = StringUTF16.getChar(src, sp++); + int bb = encodeChar(c); + if (bb == UNMAPPABLE_ENCODING) { + if (Character.isHighSurrogate(c) && sp < sl && + Character.isLowSurrogate(StringUTF16.getChar(src, sp))) { + sp++; + } + dst[dp++] = repl[0]; + if (repl.length > 1) + dst[dp++] = repl[1]; + continue; + } //else + if (bb > MAX_SINGLEBYTE) { // DoubleByte + if (currentState == SBCS) { + currentState = DBCS; + dst[dp++] = SO; + } + dst[dp++] = (byte)(bb >> 8); + dst[dp++] = (byte)bb; + } else { // SingleByte + if (currentState == DBCS) { + currentState = SBCS; + dst[dp++] = SI; + } + dst[dp++] = (byte)bb; + } + } + if (currentState == DBCS) { + currentState = SBCS; + dst[dp++] = SI; + } + return dp; + } } // EUC_SIMPLE public static class Encoder_EUC_SIM extends Encoder { - public Encoder_EUC_SIM(Charset cs, char[] c2b, char[] c2bIndex) { - super(cs, c2b, c2bIndex); + public Encoder_EUC_SIM(Charset cs, char[] c2b, char[] c2bIndex, + boolean isASCIICompatible) { + super(cs, c2b, c2bIndex, isASCIICompatible); } }