src/share/classes/sun/nio/cs/ext/EUC_JP_LINUX.java

Print this page




   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  */
  28 
  29 package sun.nio.cs.ext;
  30 
  31 import java.nio.ByteBuffer;
  32 import java.nio.CharBuffer;
  33 import java.nio.charset.Charset;
  34 import java.nio.charset.CharsetDecoder;
  35 import java.nio.charset.CharsetEncoder;
  36 import java.nio.charset.CoderResult;
  37 import sun.nio.cs.HistoricallyNamedCharset;
  38 import sun.nio.cs.Surrogate;
  39 
  40 public class EUC_JP_LINUX
  41     extends Charset
  42     implements HistoricallyNamedCharset
  43 {
  44     public EUC_JP_LINUX() {
  45         super("x-euc-jp-linux", ExtendedCharsets.aliasesFor("x-euc-jp-linux"));
  46     }
  47 
  48     public String historicalName() {
  49         return "EUC_JP_LINUX";
  50     }
  51 
  52     public boolean contains(Charset cs) {
  53         return ((cs instanceof JIS_X_0201)
  54                || (cs.name().equals("US-ASCII"))
  55                || (cs instanceof EUC_JP_LINUX));
  56     }
  57 
  58     public CharsetDecoder newDecoder() {
  59         return new Decoder(this);
  60     }
  61 
  62     public CharsetEncoder newEncoder() {
  63         return new Encoder(this);
  64     }
  65 
  66     private static class Decoder extends CharsetDecoder {
  67         JIS_X_0201.Decoder decoderJ0201;
  68         protected final char REPLACE_CHAR='\uFFFD';
  69 
  70         private static final int start = 0xa1;
  71         private static final int end = 0xfe;
  72         private static final short[] jis0208Index1 =
  73             JIS_X_0208_Decoder.getIndex1();
  74         private static final String[] jis0208Index2 =
  75             JIS_X_0208_Decoder.getIndex2();
  76 
  77         private Decoder(Charset cs) {
  78             super(cs, 1.0f, 1.0f);
  79             decoderJ0201 = new JIS_X_0201.Decoder(cs);
  80         }
  81 
  82         protected char convSingleByte(int b) {
  83             if (b < 0 || b > 0x7f)
  84                 return REPLACE_CHAR;
  85             return decoderJ0201.decode(b);
  86         }
  87 
  88         protected char decodeDouble(int byte1, int byte2) {
  89             if (byte1 == 0x8e) {
  90                 return decoderJ0201.decode(byte2 - 256);
  91             }
  92 
  93             if (((byte1 < 0) || (byte1 > jis0208Index1.length))
  94                 || ((byte2 < start) || (byte2 > end)))
  95                 return REPLACE_CHAR;
  96 
  97             int n = (jis0208Index1[byte1 - 0x80] & 0xf) * (end - start + 1)
  98                     + (byte2 - start);
  99             return jis0208Index2[jis0208Index1[byte1 - 0x80] >> 4].charAt(n);
 100         }
 101 
 102         private CoderResult decodeArrayLoop(ByteBuffer src,
 103                                             CharBuffer dst)
 104         {
 105             byte[] sa = src.array();
 106             int sp = src.arrayOffset() + src.position();
 107             int sl = src.arrayOffset() + src.limit();
 108             assert (sp <= sl);
 109             sp = (sp <= sl ? sp : sl);
 110 
 111             char[] da = dst.array();
 112             int dp = dst.arrayOffset() + dst.position();
 113             int dl = dst.arrayOffset() + dst.limit();
 114             assert (dp <= dl);
 115             dp = (dp <= dl ? dp : dl);
 116 
 117             int b1 = 0, b2 = 0;
 118             int inputSize = 0;
 119             char outputChar = REPLACE_CHAR; // U+FFFD;
 120 
 121             try {
 122                 while (sp < sl) {
 123                     b1 = sa[sp] & 0xff;
 124                     inputSize = 1;
 125                     if ((b1 & 0x80) == 0) {
 126                         outputChar = (char)b1;
 127                     }
 128                     else {      // Multibyte char
 129                         if ((b1 & 0xff) == 0x8f) {   // JIS0212
 130                             if (sp + 3 > sl)
 131                                return CoderResult.UNDERFLOW;
 132                             inputSize = 3;
 133                             return CoderResult.unmappableForLength(inputSize); // substitute
 134                         } else {
 135                           // JIS0208
 136                             if (sp + 2 > sl)
 137                                return CoderResult.UNDERFLOW;
 138                             b2 = sa[sp + 1] & 0xff;
 139                             inputSize = 2;
 140                             outputChar = decodeDouble(b1, b2);
 141                         }
 142                     }
 143                     if (outputChar == REPLACE_CHAR) { // can't be decoded
 144                         return CoderResult.unmappableForLength(inputSize);
 145                     }
 146                     if (dp + 1 > dl)
 147                         return CoderResult.OVERFLOW;
 148                     da[dp++] = outputChar;
 149                     sp += inputSize;
 150                 }
 151                 return CoderResult.UNDERFLOW;
 152             } finally {
 153                 src.position(sp - src.arrayOffset());
 154                 dst.position(dp - dst.arrayOffset());
 155             }
 156         }
 157 
 158         private CoderResult decodeBufferLoop(ByteBuffer src,
 159                                              CharBuffer dst)
 160         {
 161             int mark = src.position();
 162             char outputChar = REPLACE_CHAR; // U+FFFD;
 163 
 164             try {
 165                 while (src.hasRemaining()) {
 166                     int b1 = src.get() & 0xff;
 167                     int inputSize = 1;
 168 
 169                     if ((b1 & 0x80) == 0) {
 170                         outputChar = (char)b1;
 171                     } else {    // Multibyte char
 172 
 173                         if ((b1 & 0xff) == 0x8f) { // JIS0212 not supported
 174                             if (src.remaining() < 2)
 175                                 return CoderResult.UNDERFLOW;
 176                             return CoderResult.unmappableForLength(3);
 177                         } else {
 178                             // JIS0208
 179                             if (src.remaining() < 1)
 180                                 return CoderResult.UNDERFLOW;
 181                             int b2 = src.get() & 0xff;
 182                             inputSize++;
 183                             outputChar = decodeDouble(b1, b2);
 184                         }
 185                     }
 186 
 187                     if (outputChar == REPLACE_CHAR)
 188                         return CoderResult.unmappableForLength(inputSize);
 189                     if (dst.remaining() < 1)
 190                         return CoderResult.OVERFLOW;
 191                     dst.put(outputChar);
 192                     mark += inputSize;
 193                 }
 194                 return CoderResult.UNDERFLOW;
 195             } finally {
 196                 src.position(mark);
 197             }
 198         }
 199 
 200         protected CoderResult decodeLoop(ByteBuffer src,
 201                                          CharBuffer dst)
 202         {
 203             if (src.hasArray() && dst.hasArray())
 204                 return decodeArrayLoop(src, dst);
 205             else
 206                 return decodeBufferLoop(src, dst);
 207         }
 208     }
 209 
 210 
 211     private static class Encoder extends CharsetEncoder {
 212 
 213         JIS_X_0201.Encoder encoderJ0201;
 214 
 215         private final Surrogate.Parser sgp = new Surrogate.Parser();
 216         private static final short[] jis0208Index1 =
 217             JIS_X_0208_Encoder.getIndex1();
 218         private static final String[] jis0208Index2 =
 219             JIS_X_0208_Encoder.getIndex2();
 220 
 221         private Encoder(Charset cs) {
 222             super(cs, 2.0f, 2.0f);
 223             encoderJ0201 = new JIS_X_0201.Encoder(cs);
 224         }
 225 
 226         public boolean canEncode(char c) {
 227             byte[]  encodedBytes = new byte[2];
 228 
 229             if (encodeSingle(c, encodedBytes) == 0) { //doublebyte
 230                 if (encodeDouble(c) == 0)
 231                     return false;
 232             }
 233             return true;
 234         }
 235 
 236         protected int encodeSingle(char inputChar, byte[] outputByte) {
 237             byte b;
 238 
 239             if (inputChar == 0) {
 240                 outputByte[0] = (byte)0;
 241                 return 1;
 242             }
 243 
 244             if ((b = encoderJ0201.encode(inputChar)) == 0)
 245                 return 0;
 246 
 247             if (b > 0 && b < 128) {
 248                 outputByte[0] = b;
 249                 return 1;
 250             }
 251             outputByte[0] = (byte)0x8e;
 252             outputByte[1] = b;
 253             return 2;
 254         }
 255 
 256         protected int encodeDouble(char ch) {
 257             int offset = jis0208Index1[((ch & 0xff00) >> 8 )] << 8;
 258             int r = jis0208Index2[offset >> 12].charAt((offset & 0xfff) + (ch & 0xff));
 259             if (r != 0)
 260                 return r + 0x8080;
 261             return r;
 262         }
 263 
 264         private CoderResult encodeArrayLoop(CharBuffer src,
 265                                             ByteBuffer dst)
 266         {
 267             char[] sa = src.array();
 268             int sp = src.arrayOffset() + src.position();
 269             int sl = src.arrayOffset() + src.limit();
 270             assert (sp <= sl);
 271             sp = (sp <= sl ? sp : sl);
 272             byte[] da = dst.array();
 273             int dp = dst.arrayOffset() + dst.position();
 274             int dl = dst.arrayOffset() + dst.limit();
 275             assert (dp <= dl);
 276             dp = (dp <= dl ? dp : dl);
 277 
 278             final byte[]  outputByte = new byte[2];
 279 
 280             try {
 281                 while (sp < sl) {
 282                     char c = sa[sp];
 283 
 284                     if (Character.isSurrogate(c)) {
 285                         if (sgp.parse(c, sa, sp, sl) < 0)
 286                             return sgp.error();
 287                         return sgp.unmappableResult();
 288                     }
 289 
 290                     int outputSize = encodeSingle(c, outputByte);
 291                     if (outputSize == 0) { // DoubleByte
 292                         int ncode = encodeDouble(c);
 293                         if (ncode != 0 && ((ncode & 0xFF0000) == 0)) {
 294                                 outputByte[0] = (byte) ((ncode & 0xff00) >> 8);
 295                                 outputByte[1] = (byte) (ncode & 0xff);
 296                                 outputSize = 2;
 297                         } else {
 298                                 return CoderResult.unmappableForLength(1);
 299                         }
 300                     }
 301 
 302                     if (dl - dp < outputSize)
 303                         return CoderResult.OVERFLOW;
 304                     // Put the byte in the output buffer
 305                     for (int i = 0; i < outputSize; i++) {
 306                         da[dp++] = outputByte[i];
 307                     }
 308                     sp++;
 309                 }
 310                 return CoderResult.UNDERFLOW;
 311             } finally {
 312                 src.position(sp - src.arrayOffset());
 313                 dst.position(dp - dst.arrayOffset());
 314             }
 315         }
 316 
 317         private CoderResult encodeBufferLoop(CharBuffer src,
 318                                              ByteBuffer dst)
 319         {
 320             final byte[]  outputByte = new byte[4];
 321             int mark = src.position();
 322 
 323             try {
 324                 while (src.hasRemaining()) {
 325                     char c = src.get();
 326                     if (Character.isSurrogate(c)) {
 327                         if (sgp.parse(c, src) < 0)
 328                             return sgp.error();
 329                         return sgp.unmappableResult();
 330                     }
 331 
 332                     int outputSize = encodeSingle(c, outputByte);
 333                     if (outputSize == 0) { // DoubleByte
 334                         int ncode = encodeDouble(c);
 335                         if (ncode != 0 ) {
 336                             if ((ncode & 0xFF0000) == 0) {
 337                                 outputByte[0] = (byte) ((ncode & 0xff00) >> 8);
 338                                 outputByte[1] = (byte) (ncode & 0xff);
 339                                 outputSize = 2;
 340                             }
 341                         } else {
 342                                 return CoderResult.unmappableForLength(1);
 343                         }
 344                     }
 345 
 346                     if (dst.remaining() < outputSize)
 347                         return CoderResult.OVERFLOW;
 348 
 349                     // Put the byte in the output buffer
 350                     for (int i = 0; i < outputSize; i++) {
 351                         dst.put(outputByte[i]);
 352                     }
 353                     mark++;
 354                 }
 355                 return CoderResult.UNDERFLOW;
 356             } finally {
 357                 src.position(mark);
 358             }
 359         }
 360 
 361         protected CoderResult encodeLoop(CharBuffer src,
 362                                          ByteBuffer dst)
 363         {
 364             if (src.hasArray() && dst.hasArray())
 365                 return encodeArrayLoop(src, dst);
 366             else
 367                 return encodeBufferLoop(src, dst);
 368         }
 369     }
 370 }


   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 



  26 package sun.nio.cs.ext;
  27 
  28 import java.nio.ByteBuffer;
  29 import java.nio.CharBuffer;
  30 import java.nio.charset.Charset;
  31 import java.nio.charset.CharsetDecoder;
  32 import java.nio.charset.CharsetEncoder;
  33 import java.nio.charset.CoderResult;
  34 import sun.nio.cs.HistoricallyNamedCharset;

  35 
  36 public class EUC_JP_LINUX
  37     extends Charset
  38     implements HistoricallyNamedCharset
  39 {
  40     public EUC_JP_LINUX() {
  41         super("x-euc-jp-linux", ExtendedCharsets.aliasesFor("x-euc-jp-linux"));
  42     }
  43 
  44     public String historicalName() {
  45         return "EUC_JP_LINUX";
  46     }
  47 
  48     public boolean contains(Charset cs) {
  49         return ((cs instanceof JIS_X_0201)
  50                || (cs.name().equals("US-ASCII"))
  51                || (cs instanceof EUC_JP_LINUX));
  52     }
  53 
  54     public CharsetDecoder newDecoder() {
  55         return new Decoder(this);
  56     }
  57 
  58     public CharsetEncoder newEncoder() {
  59         return new Encoder(this);
  60     }
  61 
  62     private static class Decoder extends EUC_JP.Decoder {










  63         private Decoder(Charset cs) {
  64             super(cs, 1.0f, 1.0f, DEC0201, DEC0208, null);












































































  65         }
  66     }
  67 
  68     private static class Encoder extends EUC_JP.Encoder {






























































  69         private Encoder(Charset cs) {
  70             super(cs, 2.0f, 2.0f, ENC0201, ENC0208, null);

















































































































































  71         }
  72     }
  73 }