UnicodeEncoder.java revision 2362
2N/A/*
2N/A * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
2N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2N/A *
2N/A * This code is free software; you can redistribute it and/or modify it
2N/A * under the terms of the GNU General Public License version 2 only, as
2N/A * published by the Free Software Foundation. Oracle designates this
2N/A * particular file as subject to the "Classpath" exception as provided
2N/A * by Oracle in the LICENSE file that accompanied this code.
2N/A *
2N/A * This code is distributed in the hope that it will be useful, but WITHOUT
2N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2N/A * version 2 for more details (a copy is included in the LICENSE file that
2N/A * accompanied this code).
2N/A *
2N/A * You should have received a copy of the GNU General Public License version
2N/A * 2 along with this work; if not, write to the Free Software Foundation,
2N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2N/A *
2N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2N/A * or visit www.oracle.com if you need additional information or have any
2N/A * questions.
2N/A */
2N/A
2N/Apackage sun.nio.cs;
2N/A
2N/Aimport java.nio.*;
2N/Aimport java.nio.charset.*;
2N/A
2N/A/**
2N/A * Base class for different flavors of UTF-16 encoders
2N/A */
2N/Apublic abstract class UnicodeEncoder extends CharsetEncoder {
2N/A
2N/A protected static final char BYTE_ORDER_MARK = '\uFEFF';
2N/A protected static final char REVERSED_MARK = '\uFFFE';
2N/A
2N/A protected static final int BIG = 0;
2N/A protected static final int LITTLE = 1;
2N/A
2N/A private int byteOrder; /* Byte order in use */
2N/A private boolean usesMark; /* Write an initial BOM */
2N/A private boolean needsMark;
2N/A
2N/A protected UnicodeEncoder(Charset cs, int bo, boolean m) {
2N/A super(cs, 2.0f,
2N/A // Four bytes max if you need a BOM
2N/A m ? 4.0f : 2.0f,
2N/A // Replacement depends upon byte order
2N/A ((bo == BIG)
2N/A ? new byte[] { (byte)0xff, (byte)0xfd }
2N/A : new byte[] { (byte)0xfd, (byte)0xff }));
2N/A usesMark = needsMark = m;
2N/A byteOrder = bo;
2N/A }
2N/A
2N/A private void put(char c, ByteBuffer dst) {
2N/A if (byteOrder == BIG) {
2N/A dst.put((byte)(c >> 8));
2N/A dst.put((byte)(c & 0xff));
2N/A } else {
2N/A dst.put((byte)(c & 0xff));
2N/A dst.put((byte)(c >> 8));
2N/A }
2N/A }
2N/A
2N/A private final Surrogate.Parser sgp = new Surrogate.Parser();
2N/A
2N/A protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
2N/A int mark = src.position();
2N/A
2N/A if (needsMark) {
2N/A if (dst.remaining() < 2)
2N/A return CoderResult.OVERFLOW;
2N/A put(BYTE_ORDER_MARK, dst);
2N/A needsMark = false;
2N/A }
2N/A
2N/A try {
2N/A while (src.hasRemaining()) {
2N/A char c = src.get();
2N/A if (!Character.isSurrogate(c)) {
2N/A if (dst.remaining() < 2)
2N/A return CoderResult.OVERFLOW;
2N/A mark++;
2N/A put(c, dst);
2N/A continue;
2N/A }
2N/A int d = sgp.parse(c, src);
2N/A if (d < 0)
2N/A return sgp.error();
2N/A if (dst.remaining() < 4)
2N/A return CoderResult.OVERFLOW;
2N/A mark += 2;
2N/A put(Surrogate.high(d), dst);
2N/A put(Surrogate.low(d), dst);
2N/A }
2N/A return CoderResult.UNDERFLOW;
2N/A } finally {
2N/A src.position(mark);
2N/A }
2N/A }
2N/A
2N/A protected void implReset() {
2N/A needsMark = usesMark;
2N/A }
2N/A
2N/A public boolean canEncode(char c) {
2N/A return ! Character.isSurrogate(c);
2N/A }
2N/A}
2N/A