--- old/src/java.desktop/unix/classes/sun/awt/motif/X11GBK.java 2015-02-19 16:13:12.117548392 -0800 +++ new/src/java.desktop/unix/classes/sun/awt/motif/X11GBK.java 2015-02-19 16:13:12.009548395 -0800 @@ -25,11 +25,15 @@ package sun.awt.motif; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; import java.nio.charset.*; -import sun.nio.cs.ext.*; -import static sun.nio.cs.CharsetMapping.*; +import static sun.awt.motif.DoubleByte.*; public class X11GBK extends Charset { + + private static Charset gbk = Charset.forName("GBK"); + public X11GBK () { super("X11GBK", null); } @@ -37,19 +41,23 @@ return new Encoder(this); } public CharsetDecoder newDecoder() { - return new GBK().newDecoder(); + return gbk.newDecoder(); } public boolean contains(Charset cs) { return cs instanceof X11GBK; } - private class Encoder extends DoubleByte.Encoder { + static class Encoder extends CharsetEncoder { - private DoubleByte.Encoder enc = (DoubleByte.Encoder)new GBK().newEncoder(); + static final int MAX_SINGLEBYTE = 0xff; + static private CharsetEncoder enc = gbk.newEncoder(); Encoder(Charset cs) { - super(cs, (char[])null, (char[])null); + super(cs, enc.averageBytesPerChar(), enc.maxBytesPerChar(), + enc.replacement()); + enc.onMalformedInput(CodingErrorAction.REPORT); + enc.onUnmappableCharacter(CodingErrorAction.REPORT); } public boolean canEncode(char ch){ @@ -58,9 +66,67 @@ } public int encodeChar(char ch) { - if (ch < 0x80) + if (ch < 0x80) { + return UNMAPPABLE_ENCODING; + } + char[] buf = new char[1]; + buf[0] = ch; + ByteBuffer bb = null; + CharBuffer cb = CharBuffer.wrap(buf); + boolean mapped = false; + try { + bb = enc.encode(cb); + mapped = true; + } catch (CharacterCodingException cce) { + } + if (mapped && bb != null) { + int ret = UNMAPPABLE_ENCODING; + if (bb.remaining() == 1) { + ret = bb.get() & 0xff; + } else if (bb.remaining() > 1) { + ret = ((bb.get() & 0xff) << 8) | (bb.get() & 0xff); + } + return ret; + } else { return UNMAPPABLE_ENCODING; - return enc.encodeChar(ch); + } + } + + private SurrogateParser sgp; + protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) { + int mark = src.position(); + try { + while (src.hasRemaining()) { + char c = src.get(); + int bb = encodeChar(c); + if (bb == UNMAPPABLE_ENCODING) { + if (Character.isSurrogate(c)) { + if (sgp == null) { + sgp = new SurrogateParser(); + } + if (sgp.parse(c, src) < 0) + return sgp.error(); + return sgp.unmappableResult(); + } + return CoderResult.unmappableForLength(1); + } + if (bb > MAX_SINGLEBYTE) { // DoubleByte + if (dst.remaining() < 2) + return CoderResult.OVERFLOW; + dst.put((byte)(bb >> 8)); + dst.put((byte)(bb)); + } else { + if (dst.remaining() < 1) + return CoderResult.OVERFLOW; + dst.put((byte)bb); + } + mark++; + } + return CoderResult.UNDERFLOW; + } finally { + src.position(mark); + } + } } }