Path: blob/master/test/jdk/sun/nio/cs/OLD/DoubleByteEncoder.java
41155 views
/*1* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26*/272829import java.nio.ByteBuffer;30import java.nio.CharBuffer;31import java.nio.charset.Charset;32import java.nio.charset.CharsetEncoder;33import java.nio.charset.CoderResult;34import sun.nio.cs.Surrogate;3536public abstract class DoubleByteEncoder37extends CharsetEncoder38{3940private short index1[];41private String index2[];4243private final Surrogate.Parser sgp = new Surrogate.Parser();4445protected DoubleByteEncoder(Charset cs,46short[] index1, String[] index2)47{48super(cs, 2.0f, 2.0f);49this.index1 = index1;50this.index2 = index2;51}5253protected DoubleByteEncoder(Charset cs,54short[] index1, String[] index2,55float avg, float max)56{57super(cs, avg, max);58this.index1 = index1;59this.index2 = index2;60}6162protected DoubleByteEncoder(Charset cs,63short[] index1, String[] index2, byte[] repl)64{65super(cs, 2.0f, 2.0f, repl);66this.index1 = index1;67this.index2 = index2;68}697071protected DoubleByteEncoder(Charset cs,72short[] index1, String[] index2,73byte[] repl, float avg, float max)74{75super(cs, avg, max,repl);76this.index1 = index1;77this.index2 = index2;78}7980public boolean canEncode(char c) {81return (encodeSingle(c) != -1 ||82encodeDouble(c) != 0);83}8485private CoderResult encodeArrayLoop(CharBuffer src, ByteBuffer dst) {86char[] sa = src.array();87int sp = src.arrayOffset() + src.position();88int sl = src.arrayOffset() + src.limit();89byte[] da = dst.array();90int dp = dst.arrayOffset() + dst.position();91int dl = dst.arrayOffset() + dst.limit();9293try {94while (sp < sl) {95char c = sa[sp];96if (Character.isSurrogate(c)) {97if (sgp.parse(c, sa, sp, sl) < 0)98return sgp.error();99if (sl - sp < 2)100return CoderResult.UNDERFLOW;101char c2 = sa[sp + 1];102103byte[] outputBytes = new byte[2];104outputBytes = encodeSurrogate(c, c2);105106if (outputBytes == null) {107return sgp.unmappableResult();108}109else {110if (dl - dp < 2)111return CoderResult.OVERFLOW;112da[dp++] = outputBytes[0];113da[dp++] = outputBytes[1];114sp += 2;115continue;116}117}118if (c >= '\uFFFE')119return CoderResult.unmappableForLength(1);120121int b = encodeSingle(c);122if (b != -1) { // Single Byte123if (dl - dp < 1)124return CoderResult.OVERFLOW;125da[dp++] = (byte)b;126sp++;127continue;128}129130int ncode = encodeDouble(c);131if (ncode != 0 && c != '\u0000' ) {132if (dl - dp < 2)133return CoderResult.OVERFLOW;134da[dp++] = (byte) ((ncode & 0xff00) >> 8);135da[dp++] = (byte) (ncode & 0xff);136sp++;137continue;138}139return CoderResult.unmappableForLength(1);140}141return CoderResult.UNDERFLOW;142} finally {143src.position(sp - src.arrayOffset());144dst.position(dp - dst.arrayOffset());145}146}147148private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {149int mark = src.position();150151try {152while (src.hasRemaining()) {153char c = src.get();154if (Character.isSurrogate(c)) {155int surr;156if ((surr = sgp.parse(c, src)) < 0)157return sgp.error();158char c2 = Surrogate.low(surr);159byte[] outputBytes = new byte[2];160outputBytes = encodeSurrogate(c, c2);161162if (outputBytes == null) {163return sgp.unmappableResult();164} else {165if (dst.remaining() < 2)166return CoderResult.OVERFLOW;167mark += 2;168dst.put(outputBytes[0]);169dst.put(outputBytes[1]);170continue;171}172}173if (c >= '\uFFFE')174return CoderResult.unmappableForLength(1);175int b = encodeSingle(c);176177if (b != -1) { // Single-byte character178if (dst.remaining() < 1)179return CoderResult.OVERFLOW;180mark++;181dst.put((byte)b);182continue;183}184// Double Byte character185186int ncode = encodeDouble(c);187if (ncode != 0 && c != '\u0000') {188if (dst.remaining() < 2)189return CoderResult.OVERFLOW;190mark++;191dst.put((byte) ((ncode & 0xff00) >> 8));192dst.put((byte) ncode);193continue;194}195return CoderResult.unmappableForLength(1);196}197198return CoderResult.UNDERFLOW;199} finally {200src.position(mark);201}202}203204protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {205if (true && src.hasArray() && dst.hasArray())206return encodeArrayLoop(src, dst);207else208return encodeBufferLoop(src, dst);209}210211/*212* Can be changed by subclass213*/214protected int encodeDouble(char ch) {215int offset = index1[((ch & 0xff00) >> 8 )] << 8;216return index2[offset >> 12].charAt((offset & 0xfff) + (ch & 0xff));217}218219/*220* Can be changed by subclass221*/222protected int encodeSingle(char inputChar) {223if (inputChar < 0x80)224return (byte)inputChar;225else226return -1;227}228229/**230* Protected method which should be overridden by concrete DBCS231* CharsetEncoder classes which included supplementary characters232* within their mapping coverage.233* null return value indicates surrogate values could not be234* handled or encoded.235*/236protected byte[] encodeSurrogate(char highSurrogate, char lowSurrogate) {237return null;238}239}240241242