Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/nio/cs/ext/ISO2022.java
38919 views
/*1* Copyright (c) 2002, 2010, 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*/2728package sun.nio.cs.ext;2930import java.nio.ByteBuffer;31import java.nio.CharBuffer;32import java.nio.charset.Charset;33import java.nio.charset.CharsetDecoder;34import java.nio.charset.CharsetEncoder;35import java.nio.charset.CoderResult;36import sun.nio.cs.Surrogate;3738abstract class ISO202239extends Charset40{4142private static final byte ISO_ESC = 0x1b;43private static final byte ISO_SI = 0x0f;44private static final byte ISO_SO = 0x0e;45private static final byte ISO_SS2_7 = 0x4e;46private static final byte ISO_SS3_7 = 0x4f;47private static final byte MSB = (byte)0x80;48private static final char REPLACE_CHAR = '\uFFFD';49private static final byte minDesignatorLength = 3;5051public ISO2022(String csname, String[] aliases) {52super(csname, aliases);53}5455public CharsetDecoder newDecoder() {56return new Decoder(this);57}5859public CharsetEncoder newEncoder() {60return new Encoder(this);61}6263protected static class Decoder extends CharsetDecoder {6465// Value to be filled by subclass66protected byte SODesig[][];67protected byte SS2Desig[][] = null;68protected byte SS3Desig[][] = null;6970protected CharsetDecoder SODecoder[];71protected CharsetDecoder SS2Decoder[] = null;72protected CharsetDecoder SS3Decoder[] = null;7374private static final byte SOFlag = 0;75private static final byte SS2Flag = 1;76private static final byte SS3Flag = 2;7778private int curSODes, curSS2Des, curSS3Des;79private boolean shiftout;80private CharsetDecoder tmpDecoder[];8182protected Decoder(Charset cs) {83super(cs, 1.0f, 1.0f);84}8586protected void implReset() {87curSODes = 0;88curSS2Des = 0;89curSS3Des = 0;90shiftout = false;91}9293private char decode(byte byte1, byte byte2, byte shiftFlag)94{95byte1 |= MSB;96byte2 |= MSB;9798byte[] tmpByte = { byte1,byte2 };99char[] tmpChar = new char[1];100int i = 0,101tmpIndex = 0;102103switch(shiftFlag) {104case SOFlag:105tmpIndex = curSODes;106tmpDecoder = SODecoder;107break;108case SS2Flag:109tmpIndex = curSS2Des;110tmpDecoder = SS2Decoder;111break;112case SS3Flag:113tmpIndex = curSS3Des;114tmpDecoder = SS3Decoder;115break;116}117118if (tmpDecoder != null) {119for(i = 0; i < tmpDecoder.length; i++) {120if(tmpIndex == i) {121try {122ByteBuffer bb = ByteBuffer.wrap(tmpByte,0,2);123CharBuffer cc = CharBuffer.wrap(tmpChar,0,1);124tmpDecoder[i].decode(bb, cc, true);125cc.flip();126return cc.get();127} catch (Exception e) {}128}129}130}131return REPLACE_CHAR;132}133134private int findDesig(byte[] in, int sp, int sl, byte[][] desigs) {135if (desigs == null) return -1;136int i = 0;137while (i < desigs.length) {138if (desigs[i] != null && sl - sp >= desigs[i].length) {139int j = 0;140while (j < desigs[i].length && in[sp+j] == desigs[i][j]) { j++; }141if (j == desigs[i].length)142return i;143}144i++;145}146return -1;147}148149private int findDesigBuf(ByteBuffer in, byte[][] desigs) {150if (desigs == null) return -1;151int i = 0;152while (i < desigs.length) {153if (desigs[i] != null && in.remaining() >= desigs[i].length) {154int j = 0;155in.mark();156while (j < desigs[i].length && in.get() == desigs[i][j]) { j++; }157if (j == desigs[i].length)158return i;159in.reset();160}161i++;162}163return -1;164}165166private CoderResult decodeArrayLoop(ByteBuffer src,167CharBuffer dst)168{169byte[] sa = src.array();170int sp = src.arrayOffset() + src.position();171int sl = src.arrayOffset() + src.limit();172assert (sp <= sl);173sp = (sp <= sl ? sp : sl);174175char[] da = dst.array();176int dp = dst.arrayOffset() + dst.position();177int dl = dst.arrayOffset() + dst.limit();178assert (dp <= dl);179dp = (dp <= dl ? dp : dl);180181int b1 = 0, b2 = 0, b3 = 0;182183try {184while (sp < sl) {185b1 = sa[sp] & 0xff;186int inputSize = 1;187switch (b1) {188case ISO_SO:189shiftout = true;190inputSize = 1;191break;192case ISO_SI:193shiftout = false;194inputSize = 1;195break;196case ISO_ESC:197if (sl - sp - 1 < minDesignatorLength)198return CoderResult.UNDERFLOW;199200int desig = findDesig(sa, sp + 1, sl, SODesig);201if (desig != -1) {202curSODes = desig;203inputSize = SODesig[desig].length + 1;204break;205}206desig = findDesig(sa, sp + 1, sl, SS2Desig);207if (desig != -1) {208curSS2Des = desig;209inputSize = SS2Desig[desig].length + 1;210break;211}212desig = findDesig(sa, sp + 1, sl, SS3Desig);213if (desig != -1) {214curSS3Des = desig;215inputSize = SS3Desig[desig].length + 1;216break;217}218if (sl - sp < 2)219return CoderResult.UNDERFLOW;220b1 = sa[sp + 1];221switch(b1) {222case ISO_SS2_7:223if (sl - sp < 4)224return CoderResult.UNDERFLOW;225b2 = sa[sp +2];226b3 = sa[sp +3];227if (dl - dp <1)228return CoderResult.OVERFLOW;229da[dp] = decode((byte)b2,230(byte)b3,231SS2Flag);232dp++;233inputSize = 4;234break;235case ISO_SS3_7:236if (sl - sp < 4)237return CoderResult.UNDERFLOW;238b2 = sa[sp + 2];239b3 = sa[sp + 3];240if (dl - dp <1)241return CoderResult.OVERFLOW;242da[dp] = decode((byte)b2,243(byte)b3,244SS3Flag);245dp++;246inputSize = 4;247break;248default:249return CoderResult.malformedForLength(2);250}251break;252default:253if (dl - dp < 1)254return CoderResult.OVERFLOW;255if (!shiftout) {256da[dp++]=(char)(sa[sp] & 0xff);257} else {258if (dl - dp < 1)259return CoderResult.OVERFLOW;260if (sl - sp < 2)261return CoderResult.UNDERFLOW;262b2 = sa[sp+1] & 0xff;263da[dp++] = decode((byte)b1,264(byte)b2,265SOFlag);266inputSize = 2;267}268break;269}270sp += inputSize;271}272return CoderResult.UNDERFLOW;273} finally {274src.position(sp - src.arrayOffset());275dst.position(dp - dst.arrayOffset());276}277}278279private CoderResult decodeBufferLoop(ByteBuffer src,280CharBuffer dst)281{282int mark = src.position();283int b1 = 0, b2 = 0, b3 = 0;284285try {286while (src.hasRemaining()) {287b1 = src.get();288int inputSize = 1;289switch (b1) {290case ISO_SO:291shiftout = true;292break;293case ISO_SI:294shiftout = false;295break;296case ISO_ESC:297if (src.remaining() < minDesignatorLength)298return CoderResult.UNDERFLOW;299300int desig = findDesigBuf(src, SODesig);301if (desig != -1) {302curSODes = desig;303inputSize = SODesig[desig].length + 1;304break;305}306desig = findDesigBuf(src, SS2Desig);307if (desig != -1) {308curSS2Des = desig;309inputSize = SS2Desig[desig].length + 1;310break;311}312desig = findDesigBuf(src, SS3Desig);313if (desig != -1) {314curSS3Des = desig;315inputSize = SS3Desig[desig].length + 1;316break;317}318319if (src.remaining() < 1)320return CoderResult.UNDERFLOW;321b1 = src.get();322switch(b1) {323case ISO_SS2_7:324if (src.remaining() < 2)325return CoderResult.UNDERFLOW;326b2 = src.get();327b3 = src.get();328if (dst.remaining() < 1)329return CoderResult.OVERFLOW;330dst.put(decode((byte)b2,331(byte)b3,332SS2Flag));333inputSize = 4;334break;335case ISO_SS3_7:336if (src.remaining() < 2)337return CoderResult.UNDERFLOW;338b2 = src.get();339b3 = src.get();340if (dst.remaining() < 1)341return CoderResult.OVERFLOW;342dst.put(decode((byte)b2,343(byte)b3,344SS3Flag));345inputSize = 4;346break;347default:348return CoderResult.malformedForLength(2);349}350break;351default:352if (dst.remaining() < 1)353return CoderResult.OVERFLOW;354if (!shiftout) {355dst.put((char)(b1 & 0xff));356} else {357if (dst.remaining() < 1)358return CoderResult.OVERFLOW;359if (src.remaining() < 1)360return CoderResult.UNDERFLOW;361b2 = src.get() & 0xff;362dst.put(decode((byte)b1,363(byte)b2,364SOFlag));365inputSize = 2;366}367break;368}369mark += inputSize;370}371return CoderResult.UNDERFLOW;372} catch (Exception e) { e.printStackTrace(); return CoderResult.OVERFLOW; }373finally {374src.position(mark);375}376}377378protected CoderResult decodeLoop(ByteBuffer src,379CharBuffer dst)380{381if (src.hasArray() && dst.hasArray())382return decodeArrayLoop(src, dst);383else384return decodeBufferLoop(src, dst);385}386}387388protected static class Encoder extends CharsetEncoder {389private final Surrogate.Parser sgp = new Surrogate.Parser();390public static final byte SS2 = (byte)0x8e;391public static final byte PLANE2 = (byte)0xA2;392public static final byte PLANE3 = (byte)0xA3;393private final byte MSB = (byte)0x80;394395protected final byte maximumDesignatorLength = 4;396397protected String SODesig,398SS2Desig = null,399SS3Desig = null;400401protected CharsetEncoder ISOEncoder;402403private boolean shiftout = false;404private boolean SODesDefined = false;405private boolean SS2DesDefined = false;406private boolean SS3DesDefined = false;407408private boolean newshiftout = false;409private boolean newSODesDefined = false;410private boolean newSS2DesDefined = false;411private boolean newSS3DesDefined = false;412413protected Encoder(Charset cs) {414super(cs, 4.0f, 8.0f);415}416417public boolean canEncode(char c) {418return (ISOEncoder.canEncode(c));419}420421protected void implReset() {422shiftout = false;423SODesDefined = false;424SS2DesDefined = false;425SS3DesDefined = false;426}427428private int unicodeToNative(char unicode, byte ebyte[])429{430int index = 0;431byte tmpByte[];432char convChar[] = {unicode};433byte convByte[] = new byte[4];434int converted;435436try{437CharBuffer cc = CharBuffer.wrap(convChar);438ByteBuffer bb = ByteBuffer.allocate(4);439ISOEncoder.encode(cc, bb, true);440bb.flip();441converted = bb.remaining();442bb.get(convByte,0,converted);443} catch(Exception e) {444return -1;445}446447if (converted == 2) {448if (!SODesDefined) {449newSODesDefined = true;450ebyte[0] = ISO_ESC;451tmpByte = SODesig.getBytes();452System.arraycopy(tmpByte,0,ebyte,1,tmpByte.length);453index = tmpByte.length+1;454}455if (!shiftout) {456newshiftout = true;457ebyte[index++] = ISO_SO;458}459ebyte[index++] = (byte)(convByte[0] & 0x7f);460ebyte[index++] = (byte)(convByte[1] & 0x7f);461} else {462if(convByte[0] == SS2) {463if (convByte[1] == PLANE2) {464if (!SS2DesDefined) {465newSS2DesDefined = true;466ebyte[0] = ISO_ESC;467tmpByte = SS2Desig.getBytes();468System.arraycopy(tmpByte, 0, ebyte, 1, tmpByte.length);469index = tmpByte.length+1;470}471ebyte[index++] = ISO_ESC;472ebyte[index++] = ISO_SS2_7;473ebyte[index++] = (byte)(convByte[2] & 0x7f);474ebyte[index++] = (byte)(convByte[3] & 0x7f);475} else if (convByte[1] == PLANE3) {476if(!SS3DesDefined){477newSS3DesDefined = true;478ebyte[0] = ISO_ESC;479tmpByte = SS3Desig.getBytes();480System.arraycopy(tmpByte, 0, ebyte, 1, tmpByte.length);481index = tmpByte.length+1;482}483ebyte[index++] = ISO_ESC;484ebyte[index++] = ISO_SS3_7;485ebyte[index++] = (byte)(convByte[2] & 0x7f);486ebyte[index++] = (byte)(convByte[3] & 0x7f);487}488}489}490return index;491}492493private CoderResult encodeArrayLoop(CharBuffer src,494ByteBuffer dst)495{496char[] sa = src.array();497int sp = src.arrayOffset() + src.position();498int sl = src.arrayOffset() + src.limit();499assert (sp <= sl);500sp = (sp <= sl ? sp : sl);501byte[] da = dst.array();502int dp = dst.arrayOffset() + dst.position();503int dl = dst.arrayOffset() + dst.limit();504assert (dp <= dl);505dp = (dp <= dl ? dp : dl);506507int outputSize = 0;508byte[] outputByte = new byte[8];509newshiftout = shiftout;510newSODesDefined = SODesDefined;511newSS2DesDefined = SS2DesDefined;512newSS3DesDefined = SS3DesDefined;513514try {515while (sp < sl) {516char c = sa[sp];517if (Character.isSurrogate(c)) {518if (sgp.parse(c, sa, sp, sl) < 0)519return sgp.error();520return sgp.unmappableResult();521}522523if (c < 0x80) { // ASCII524if (shiftout){525newshiftout = false;526outputSize = 2;527outputByte[0] = ISO_SI;528outputByte[1] = (byte)(c & 0x7f);529} else {530outputSize = 1;531outputByte[0] = (byte)(c & 0x7f);532}533if(sa[sp] == '\n'){534newSODesDefined = false;535newSS2DesDefined = false;536newSS3DesDefined = false;537}538} else {539outputSize = unicodeToNative(c, outputByte);540if (outputSize == 0) {541return CoderResult.unmappableForLength(1);542}543}544if (dl - dp < outputSize)545return CoderResult.OVERFLOW;546547for (int i = 0; i < outputSize; i++)548da[dp++] = outputByte[i];549sp++;550shiftout = newshiftout;551SODesDefined = newSODesDefined;552SS2DesDefined = newSS2DesDefined;553SS3DesDefined = newSS3DesDefined;554}555return CoderResult.UNDERFLOW;556} finally {557src.position(sp - src.arrayOffset());558dst.position(dp - dst.arrayOffset());559}560}561562563private CoderResult encodeBufferLoop(CharBuffer src,564ByteBuffer dst)565{566int outputSize = 0;567byte[] outputByte = new byte[8];568int inputSize = 0; // Size of input569newshiftout = shiftout;570newSODesDefined = SODesDefined;571newSS2DesDefined = SS2DesDefined;572newSS3DesDefined = SS3DesDefined;573int mark = src.position();574575try {576while (src.hasRemaining()) {577char inputChar = src.get();578if (Character.isSurrogate(inputChar)) {579if (sgp.parse(inputChar, src) < 0)580return sgp.error();581return sgp.unmappableResult();582}583if (inputChar < 0x80) { // ASCII584if (shiftout){585newshiftout = false;586outputSize = 2;587outputByte[0] = ISO_SI;588outputByte[1] = (byte)(inputChar & 0x7f);589} else {590outputSize = 1;591outputByte[0] = (byte)(inputChar & 0x7f);592}593if(inputChar == '\n'){594newSODesDefined = false;595newSS2DesDefined = false;596newSS3DesDefined = false;597}598} else {599outputSize = unicodeToNative(inputChar, outputByte);600if (outputSize == 0) {601return CoderResult.unmappableForLength(1);602}603}604605if (dst.remaining() < outputSize)606return CoderResult.OVERFLOW;607for (int i = 0; i < outputSize; i++)608dst.put(outputByte[i]);609mark++;610shiftout = newshiftout;611SODesDefined = newSODesDefined;612SS2DesDefined = newSS2DesDefined;613SS3DesDefined = newSS3DesDefined;614}615return CoderResult.UNDERFLOW;616} finally {617src.position(mark);618}619}620621protected CoderResult encodeLoop(CharBuffer src,622ByteBuffer dst)623{624if (src.hasArray() && dst.hasArray())625return encodeArrayLoop(src, dst);626else627return encodeBufferLoop(src, dst);628}629}630}631632633