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 } |