src/java.base/share/classes/sun/nio/cs/DoubleByte.java
Print this page
@@ -113,10 +113,11 @@
{
final char[][] b2c;
final char[] b2cSB;
final int b2Min;
final int b2Max;
+ final boolean isASCIICompatible;
// for SimpleEUC override
protected CoderResult crMalformedOrUnderFlow(int b) {
return CoderResult.UNDERFLOW;
}
@@ -130,20 +131,27 @@
return CoderResult.unmappableForLength(2);
}
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) {
byte[] sa = src.array();
int sp = src.arrayOffset() + src.position();
@@ -213,10 +221,11 @@
return decodeArrayLoop(src, dst);
else
return decodeBufferLoop(src, dst);
}
+ @Override
public int decode(byte[] src, int sp, int len, char[] dst) {
int dp = 0;
int sl = sp + len;
char repl = replacement().charAt(0);
while (sp < sl) {
@@ -241,10 +250,15 @@
dst[dp++] = c;
}
return dp;
}
+ @Override
+ public boolean isASCIICompatible() {
+ return isASCIICompatible;
+ }
+
public void implReset() {
super.implReset();
}
public CoderResult implFlush(CharBuffer out) {
@@ -272,12 +286,18 @@
private static final int SO = 0x0e;
private static final int SI = 0x0f;
private int currentState;
public Decoder_EBCDIC(Charset cs,
+ 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);
+ super(cs, b2c, b2cSB, b2Min, b2Max, false);
}
public void implReset() {
currentState = SBCS;
}
@@ -401,10 +421,11 @@
} finally {
src.position(mark);
}
}
+ @Override
public int decode(byte[] src, int sp, int len, char[] dst) {
int dp = 0;
int sl = sp + len;
currentState = SBCS;
char repl = replacement().charAt(0);
@@ -449,12 +470,17 @@
static final char[] b2cSB_UNMAPPABLE;
static {
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);
}
}
// EUC_SIMPLE
// The only thing we need to "override" is to check SS2/SS3 and
@@ -462,12 +488,13 @@
public static class Decoder_EUC_SIM extends Decoder {
private final int SS2 = 0x8E;
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
protected CoderResult crMalformedOrUnderFlow(int b) {
if (b == SS2 || b == SS3 )
@@ -479,10 +506,11 @@
if (b1 == SS2 || b1 == SS3 )
return CoderResult.malformedForLength(1);
return CoderResult.unmappableForLength(2);
}
+ @Override
public int decode(byte[] src, int sp, int len, char[] dst) {
int dp = 0;
int sl = sp + len;
char repl = replacement().charAt(0);
while (sp < sl) {
@@ -513,21 +541,29 @@
{
protected final int MAX_SINGLEBYTE = 0xff;
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) {
return encodeChar(c) != UNMAPPABLE_ENCODING;
}
@@ -622,10 +658,11 @@
protected byte[] repl = replacement();
protected void implReplaceWith(byte[] newReplacement) {
repl = newReplacement;
}
+ @Override
public int encode(char[] src, int sp, int len, byte[] dst) {
int dp = 0;
int sl = sp + len;
int dl = dst.length;
while (sp < sl) {
@@ -645,15 +682,73 @@
dst[dp++] = (byte)(bb >> 8);
dst[dp++] = (byte)bb;
} 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)];
}
// init the c2b and c2bIndex tables from b2c.
@@ -739,35 +834,36 @@
}
}
}
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) {
int bb = super.encodeChar(ch);
if (bb <= MAX_SINGLEBYTE)
return UNMAPPABLE_ENCODING;
return bb;
}
}
-
-
public static class Encoder_EBCDIC extends Encoder {
static final int SBCS = 0;
static final int DBCS = 1;
static final byte SO = 0x0e;
static final byte SI = 0x0f;
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() {
currentState = SBCS;
}
@@ -876,10 +972,11 @@
} finally {
src.position(mark);
}
}
+ @Override
public int encode(char[] src, int sp, int len, byte[] dst) {
int dp = 0;
int sl = sp + len;
while (sp < sl) {
char c = src[sp++];
@@ -915,15 +1012,91 @@
currentState = SBCS;
dst[dp++] = SI;
}
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);
}
}
}