DBCS_IBM_ASCII_Encoder.java revision 2362
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This code is free software; you can redistribute it and/or modify it
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * under the terms of the GNU General Public License version 2 only, as
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * published by the Free Software Foundation. Oracle designates this
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * particular file as subject to the "Classpath" exception as provided
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * by Oracle in the LICENSE file that accompanied this code.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This code is distributed in the hope that it will be useful, but WITHOUT
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * version 2 for more details (a copy is included in the LICENSE file that
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * accompanied this code).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * You should have received a copy of the GNU General Public License version
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 2 along with this work; if not, write to the Free Software Foundation,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * or visit www.oracle.com if you need additional information or have any
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * questions.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowimport java.nio.ByteBuffer;
4bff34e37def8a90f9194d81bc345c52ba20086athurlowimport java.nio.CharBuffer;
4bff34e37def8a90f9194d81bc345c52ba20086athurlowimport java.nio.charset.Charset;
4bff34e37def8a90f9194d81bc345c52ba20086athurlowimport java.nio.charset.CharsetEncoder;
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gdimport java.nio.charset.CoderResult;
de8c4a14ec9a49bad5e62b2cfa6c1ba21de1c708Erik Nordmarkimport sun.nio.cs.Surrogate;
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd
3ce9ce383e93f64f4baed13c5a0a28d7a5f1b71eBayard Bell/**
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd * An abstract base class for subclasses which encodes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * IBM double byte host encodings such as ibm code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * pages 942,943,948, etc.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowabstract class DBCS_IBM_ASCII_Encoder extends CharsetEncoder
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow protected static final char REPLACE_CHAR='\uFFFD';
4bff34e37def8a90f9194d81bc345c52ba20086athurlow private byte b1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow private byte b2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow protected short index1[];
4bff34e37def8a90f9194d81bc345c52ba20086athurlow protected String index2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow protected String index2a;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow protected int mask1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow protected int mask2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow protected int shift;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow private final Surrogate.Parser sgp = new Surrogate.Parser();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow protected DBCS_IBM_ASCII_Encoder(Charset cs) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow super(cs, 2.0f, 2.0f);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /**
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Returns true if the given character can be converted to the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * target character encoding.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow public boolean canEncode(char ch) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int index;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int theBytes;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow index = index1[((ch & mask1) >> shift)] + (ch & mask2);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (index < 15000)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow theBytes = (int)(index2.charAt(index));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow theBytes = (int)(index2a.charAt(index-15000));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (theBytes != 0)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (true);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // only return true if input char was unicode null - all others are
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // undefined
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return( ch == '\u0000');
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow private CoderResult encodeArrayLoop(CharBuffer src, ByteBuffer dst) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char[] sa = src.array();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int sp = src.arrayOffset() + src.position();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int sl = src.arrayOffset() + src.limit();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow byte[] da = dst.array();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int dp = dst.arrayOffset() + dst.position();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int dl = dst.arrayOffset() + dst.limit();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int outputSize = 0; // size of output
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow try {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while (sp < sl) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int index;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int theBytes;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char c = sa[sp];
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross if (Surrogate.is(c)) {
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross if (sgp.parse(c, sa, sp, sl) < 0)
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross return sgp.error();
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross return sgp.unmappableResult();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (c >= '\uFFFE')
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return CoderResult.unmappableForLength(1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow index = index1[((c & mask1) >> shift)]
4bff34e37def8a90f9194d81bc345c52ba20086athurlow + (c & mask2);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (index < 15000)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow theBytes = (int)(index2.charAt(index));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow theBytes = (int)(index2a.charAt(index-15000));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow b1 = (byte)((theBytes & 0x0000ff00)>>8);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow b2 = (byte)(theBytes & 0x000000ff);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (b1 == 0x00 && b2 == 0x00
4bff34e37def8a90f9194d81bc345c52ba20086athurlow && c != '\u0000') {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return CoderResult.unmappableForLength(1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (b1 == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (dl - dp < 1)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return CoderResult.OVERFLOW;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow da[dp++] = (byte) b2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } else {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (dl - dp < 2)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return CoderResult.OVERFLOW;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow da[dp++] = (byte) b1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow da[dp++] = (byte) b2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow sp++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return CoderResult.UNDERFLOW;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } finally {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow src.position(sp - src.arrayOffset());
4bff34e37def8a90f9194d81bc345c52ba20086athurlow dst.position(dp - dst.arrayOffset());
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int mark = src.position();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int outputSize = 0; // size of output
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow try {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while (src.hasRemaining()) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int index;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int theBytes;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char c = src.get();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (Surrogate.is(c)) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (sgp.parse(c, src) < 0)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return sgp.error();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return sgp.unmappableResult();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (c >= '\uFFFE')
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return CoderResult.unmappableForLength(1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow index = index1[((c & mask1) >> shift)]
4bff34e37def8a90f9194d81bc345c52ba20086athurlow + (c & mask2);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (index < 15000)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow theBytes = (int)(index2.charAt(index));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow theBytes = (int)(index2a.charAt(index-15000));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow b1 = (byte)((theBytes & 0x0000ff00)>>8);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow b2 = (byte)(theBytes & 0x000000ff);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (b1 == 0x00 && b2 == 0x00
4bff34e37def8a90f9194d81bc345c52ba20086athurlow && c != '\u0000') {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return CoderResult.unmappableForLength(1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (b1 == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (dst.remaining() < 1)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return CoderResult.OVERFLOW;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow dst.put((byte) b2);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } else {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (dst.remaining() < 2)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return CoderResult.OVERFLOW;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow dst.put((byte) b1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow dst.put((byte) b2);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mark++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return CoderResult.UNDERFLOW;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } finally {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow src.position(mark);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (true && src.hasArray() && dst.hasArray())
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return encodeArrayLoop(src, dst);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return encodeBufferLoop(src, dst);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow