src/share/classes/sun/nio/cs/SingleByte.java

Print this page

        

@@ -30,10 +30,11 @@
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
+import java.util.Arrays;
 import static sun.nio.cs.CharsetMapping.*;
 
 public class SingleByte
 {
     private static final CoderResult withResult(CoderResult cr,

@@ -43,11 +44,12 @@
         src.position(sp - src.arrayOffset());
         dst.position(dp - dst.arrayOffset());
         return cr;
     }
 
-    public static class Decoder extends CharsetDecoder {
+    final public static class Decoder extends CharsetDecoder
+                                      implements ArrayDecoder {
         private final char[] b2c;
 
         public Decoder(Charset cs, char[] b2c) {
             super(cs, 1.0f, 1.0f);
             this.b2c = b2c;

@@ -106,13 +108,33 @@
         }
 
         private final char decode(int b) {
             return b2c[b + 128];
         }
+
+        private char repl = '\uFFFD';
+        protected void implReplaceWith(String newReplacement) {
+            repl = newReplacement.charAt(0);
     }
 
-    public static class Encoder extends CharsetEncoder {
+        public int decode(byte[] src, int sp, int len, char[] dst) {
+            if (len > dst.length) 
+                len = dst.length;
+            int dp = 0;
+            while (dp < len) {
+                dst[dp] = decode(src[sp++]);
+                if (dst[dp] == UNMAPPABLE_DECODING) {
+                    dst[dp] = repl;
+                }
+                dp++;
+            }
+            return dp;
+        }
+    }
+
+    final public static class Encoder extends CharsetEncoder
+                                      implements ArrayEncoder {
         private Surrogate.Parser sgp;
         private final char[] c2b;
         private final char[] c2bIndex;
 
         public Encoder(Charset cs, char[] c2b, char[] c2bIndex) {

@@ -123,10 +145,15 @@
 
         public boolean canEncode(char c) {
             return encode(c) != UNMAPPABLE_ENCODING;
         }
 
+        public boolean isLegalReplacement(byte[] repl) {
+            return ((repl.length == 1 && repl[0] == (byte)'?') ||
+                    super.isLegalReplacement(repl));
+        }
+
         private CoderResult encodeArrayLoop(CharBuffer src, ByteBuffer dst) {
             char[] sa = src.array();
             int sp = src.arrayOffset() + src.position();
             int sl = src.arrayOffset() + src.limit();
 

@@ -198,11 +225,39 @@
             char index = c2bIndex[ch >> 8];
             if (index == UNMAPPABLE_ENCODING)
                 return UNMAPPABLE_ENCODING;
             return c2b[index + (ch & 0xff)];
         }
+
+        private byte repl = (byte)'?';
+        protected void implReplaceWith(byte[] newReplacement) {
+            repl = newReplacement[0];
     }
+
+        public int encode(char[] src, int sp, int len, byte[] dst) {
+            int dp = 0;
+            int sl = sp + Math.min(len, dst.length);
+            while (sp < sl) {
+                char c = src[sp++];
+                int b = encode(c);
+                if (b != UNMAPPABLE_ENCODING) {
+                    dst[dp++] = (byte)b;
+                    continue;
+                }
+                if (Surrogate.isHigh(c) && sp < sl &&
+                    Surrogate.isLow(src[sp])) {
+                    if (len > dst.length) {
+                        sl++;
+                        len--;
+                    }
+                    sp++;
+                }
+                dst[dp++] = repl;
+            }
+            return dp;
+        }
+    }
 
     // init the c2b and c2bIndex tables from b2c.
     public static void initC2B(char[] b2c, char[] c2bNR,
                                char[] c2b, char[] c2bIndex) {
         for (int i = 0; i < c2bIndex.length; i++)