src/java.desktop/unix/classes/sun/awt/motif/X11GBK.java

Print this page

        

@@ -23,44 +23,110 @@
  * questions.
  */
 
 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);
     }
     public CharsetEncoder newEncoder() {
         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){
             if (ch < 0x80) return false;
             return enc.canEncode(ch);
         }
 
         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);
+            }
+
         }
     }
 }