8035302: Eliminate dependency on jdk.charsets from 2D font code

Reviewed-by: mchung, alanb, sherman, serb
This commit is contained in:
Phil Race 2015-04-13 17:06:04 -07:00
parent 609fc7915d
commit e630663bbb
36 changed files with 57 additions and 2772 deletions

View File

@ -24,10 +24,12 @@
*/
package sun.awt;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.IOException;;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.StandardCharsets;
import sun.nio.cs.HistoricallyNamedCharset;
public class FontDescriptor implements Cloneable {
@ -49,11 +51,15 @@ public class FontDescriptor implements Cloneable {
this.exclusionRanges = exclusionRanges;
this.useUnicode = false;
Charset cs = encoder.charset();
if (cs instanceof HistoricallyNamedCharset)
this.charsetName = ((HistoricallyNamedCharset)cs).historicalName();
else
this.charsetName = cs.name();
// The following looks odd but its the only public way to get the
// historical name if one exists and the canonical name otherwise.
try {
ByteArrayInputStream bais = new ByteArrayInputStream(new byte[8]);
InputStreamReader isr = new InputStreamReader(bais, cs);
this.charsetName = isr.getEncoding();
isr.close();
} catch (IOException ioe) {
}
}
public String getNativeName() {

View File

@ -378,12 +378,8 @@ public final class FontUtilities {
* Suggested usage is something like :
* FontUIResource fuir;
* Font desktopFont = getDesktopFont(..);
* // NOTE even if fontSupportsDefaultEncoding returns true because
* // you get Tahoma and are running in an English locale, you may
* // still want to just call getCompositeFontUIResource() anyway
* // as only then will you get fallback fonts - eg for CJK.
* if (FontManager.fontSupportsDefaultEncoding(desktopFont)) {
* fuir = new FontUIResource(..);
* fuir = new FontUIResource(desktopFont);
* } else {
* fuir = FontManager.getCompositeFontUIResource(desktopFont);
* }

View File

@ -567,36 +567,6 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE {
}
}
/**
* This method is provided for internal and exclusive use by Swing.
*
* @param font representing a physical font.
* @return true if the underlying font is a TrueType or OpenType font
* that claims to support the Microsoft Windows encoding corresponding to
* the default file.encoding property of this JRE instance.
* This narrow value is useful for Swing to decide if the font is useful
* for the Windows Look and Feel, or, if a composite font should be
* used instead.
* The information used to make the decision is obtained from
* the ulCodePageRange fields in the font.
* A caller can use isLogicalFont(Font) in this class before calling
* this method and would not need to call this method if that
* returns true.
*/
// static boolean fontSupportsDefaultEncoding(Font font) {
// String encoding =
// (String) java.security.AccessController.doPrivileged(
// new sun.security.action.GetPropertyAction("file.encoding"));
// if (encoding == null || font == null) {
// return false;
// }
// encoding = encoding.toLowerCase(Locale.ENGLISH);
// return FontManager.fontSupportsEncoding(font, encoding);
// }
public Font2DHandle getNewComposite(String family, int style,
Font2DHandle handle) {

View File

@ -23,13 +23,12 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import java.nio.charset.*;
import sun.nio.cs.*;
import sun.nio.cs.ext.*;
public abstract class X11CNS11643 extends Charset {
private final int plane;

View File

@ -24,7 +24,7 @@
*/
package sun.awt.motif;
package sun.font;
public class X11CNS11643P1 extends X11CNS11643 {
public X11CNS11643P1() {

View File

@ -23,7 +23,7 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
public class X11CNS11643P2 extends X11CNS11643 {
public X11CNS11643P2() {

View File

@ -23,7 +23,7 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
public class X11CNS11643P3 extends X11CNS11643 {
public X11CNS11643P3() {

View File

@ -40,7 +40,7 @@ import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.plaf.FontUIResource;
import sun.awt.motif.MFontConfiguration;
import sun.font.MFontConfiguration;
import sun.font.CompositeFont;
import sun.font.FontManager;
import sun.font.SunFontManager;

View File

@ -43,7 +43,7 @@ import java.net.UnknownHostException;
import java.util.*;
import sun.awt.motif.MFontConfiguration;
import sun.font.MFontConfiguration;
import sun.font.FcFontConfiguration;
import sun.font.Font2D;
import sun.font.FontManager;

View File

@ -1,109 +0,0 @@
/*
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt.motif;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.*;
import sun.nio.cs.*;
import sun.nio.cs.ext.*;
import static sun.nio.cs.CharsetMapping.*;
public class X11JIS0201 extends Charset {
private static Charset jis0201 = new JIS_X_0201();
private static SingleByte.Encoder enc =
(SingleByte.Encoder)jis0201.newEncoder();
public X11JIS0201 () {
super("X11JIS0201", null);
}
public CharsetEncoder newEncoder() {
return new Encoder(this);
}
public CharsetDecoder newDecoder() {
return jis0201.newDecoder();
}
public boolean contains(Charset cs) {
return cs instanceof X11JIS0201;
}
private class Encoder extends CharsetEncoder {
public Encoder(Charset cs) {
super(cs, 1.0f, 1.0f);
}
public boolean canEncode(char c){
if ((c >= 0xff61 && c <= 0xff9f)
|| c == 0x203e
|| c == 0xa5) {
return true;
}
return false;
}
private Surrogate.Parser sgp;
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
char[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
byte[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
CoderResult cr = CoderResult.UNDERFLOW;
if ((dl - dp) < (sl - sp)) {
sl = sp + (dl - dp);
cr = CoderResult.OVERFLOW;
}
try {
while (sp < sl) {
char c = sa[sp];
int b = enc.encode(c);
if (b == UNMAPPABLE_ENCODING) {
if (Character.isSurrogate(c)) {
if (sgp == null)
sgp = new Surrogate.Parser();
if (sgp.parse(c, sa, sp, sl) >= 0)
return CoderResult.unmappableForLength(2);
}
return CoderResult.unmappableForLength(1);
}
da[dp++] = (byte)b;
sp++;
}
return cr;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
}
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt.motif;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.*;
import sun.nio.cs.ext.*;
public class X11JIS0208 extends Charset {
private static Charset jis0208 = new JIS_X_0208();
public X11JIS0208 () {
super("X11JIS0208", null);
}
public CharsetEncoder newEncoder() {
return jis0208.newEncoder();
}
public CharsetDecoder newDecoder() {
return jis0208.newDecoder();
}
public boolean contains(Charset cs) {
return cs instanceof X11JIS0208;
}
}

View File

@ -1,49 +0,0 @@
/*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt.motif;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.*;
import sun.nio.cs.ext.*;
public class X11JIS0212 extends Charset {
private static Charset jis0212 = new JIS_X_0212();
public X11JIS0212 () {
super("X11JIS0212", null);
}
public CharsetEncoder newEncoder() {
return jis0212.newEncoder();
}
public CharsetDecoder newDecoder() {
return jis0212.newDecoder();
}
public boolean contains(Charset cs) {
return cs instanceof X11JIS0212;
}
}

View File

@ -26,7 +26,7 @@
/*
*/
package sun.nio.cs.ext;
package sun.font;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;

View File

@ -23,7 +23,7 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
import sun.awt.FontConfiguration;
import sun.awt.X11FontManager;
@ -235,7 +235,7 @@ public class MFontConfiguration extends FontConfiguration {
String xlfdEncoding = awtFontName.substring(beginIndex);
if (xlfdEncoding.indexOf("fontspecific") > 0) {
if (awtFontName.indexOf("dingbats") > 0) {
return "sun.awt.motif.X11Dingbats";
return "sun.font.X11Dingbats";
} else if (awtFontName.indexOf("symbol") > 0) {
return "sun.awt.Symbol";
}
@ -303,28 +303,28 @@ public class MFontConfiguration extends FontConfiguration {
encodingMap.put("iso8859-9", "ISO-8859-9");
encodingMap.put("iso8859-13", "ISO-8859-13");
encodingMap.put("iso8859-15", "ISO-8859-15");
encodingMap.put("gb2312.1980-0", "sun.awt.motif.X11GB2312");
encodingMap.put("gb2312.1980-0", "sun.font.X11GB2312");
if (osName == null) {
// use standard converter on Solaris
encodingMap.put("gbk-0", "GBK");
} else {
encodingMap.put("gbk-0", "sun.awt.motif.X11GBK");
encodingMap.put("gbk-0", "sun.font.X11GBK");
}
encodingMap.put("gb18030.2000-0", "sun.awt.motif.X11GB18030_0");
encodingMap.put("gb18030.2000-1", "sun.awt.motif.X11GB18030_1");
encodingMap.put("cns11643-1", "sun.awt.motif.X11CNS11643P1");
encodingMap.put("cns11643-2", "sun.awt.motif.X11CNS11643P2");
encodingMap.put("cns11643-3", "sun.awt.motif.X11CNS11643P3");
encodingMap.put("gb18030.2000-0", "sun.font.X11GB18030_0");
encodingMap.put("gb18030.2000-1", "sun.font.X11GB18030_1");
encodingMap.put("cns11643-1", "sun.font.X11CNS11643P1");
encodingMap.put("cns11643-2", "sun.font.X11CNS11643P2");
encodingMap.put("cns11643-3", "sun.font.X11CNS11643P3");
encodingMap.put("big5-1", "Big5");
encodingMap.put("big5-0", "Big5");
encodingMap.put("hkscs-1", "Big5-HKSCS");
encodingMap.put("ansi-1251", "windows-1251");
encodingMap.put("koi8-r", "KOI8-R");
encodingMap.put("jisx0201.1976-0", "sun.awt.motif.X11JIS0201");
encodingMap.put("jisx0208.1983-0", "sun.awt.motif.X11JIS0208");
encodingMap.put("jisx0212.1990-0", "sun.awt.motif.X11JIS0212");
encodingMap.put("ksc5601.1987-0", "sun.awt.motif.X11KSC5601");
encodingMap.put("ksc5601.1992-3", "sun.awt.motif.X11Johab");
encodingMap.put("jisx0201.1976-0", "JIS0201");
encodingMap.put("jisx0208.1983-0", "JIS0208");
encodingMap.put("jisx0212.1990-0", "JIS0212");
encodingMap.put("ksc5601.1987-0", "sun.font.X11KSC5601");
encodingMap.put("ksc5601.1992-3", "sun.font.X11Johab");
encodingMap.put("tis620.2533-0", "TIS-620");
encodingMap.put("iso10646-1", "UTF-16BE");
}

View File

@ -23,7 +23,7 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;

View File

@ -23,12 +23,11 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.ext.DoubleByteEncoder;
public class X11GB18030_0 extends Charset {
public X11GB18030_0 () {

View File

@ -23,12 +23,11 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.ext.DoubleByteEncoder;
public class X11GB18030_1 extends Charset {
public X11GB18030_1 () {

View File

@ -23,13 +23,12 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import java.nio.charset.*;
import sun.nio.cs.*;
import sun.nio.cs.ext.*;
import static sun.nio.cs.CharsetMapping.*;
public class X11GB2312 extends Charset {

View File

@ -23,11 +23,10 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
import java.nio.charset.*;
import sun.nio.cs.*;
import sun.nio.cs.ext.*;
import static sun.nio.cs.CharsetMapping.*;
public class X11GBK extends Charset {

View File

@ -23,12 +23,11 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.ext.DoubleByteEncoder;
public class X11Johab extends Charset {
public X11Johab () {

View File

@ -23,13 +23,12 @@
* questions.
*/
package sun.awt.motif;
package sun.font;
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import java.nio.charset.*;
import sun.nio.cs.*;
import sun.nio.cs.ext.*;
import static sun.nio.cs.CharsetMapping.*;
public class X11KSC5601 extends Charset {

View File

@ -24,12 +24,11 @@
*/
package sun.awt.motif;
package sun.font;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.ext.DoubleByteEncoder;
public class X11SunUnicode_0 extends Charset {
public X11SunUnicode_0 () {

View File

@ -69,7 +69,7 @@ class XMap {
boolean addAscii = false;
boolean lowPartOnly = false;
if (encoding.equals("dingbats")) {
jclass = "sun.awt.motif.X11Dingbats";
jclass = "sun.font.X11Dingbats";
minU = 0x2701;
maxU = 0x27be;
} else if (encoding.equals("symbol")){
@ -81,10 +81,10 @@ class XMap {
} else if (encoding.equals("iso8859-2")) {
jclass = "ISO8859_2";
} else if (encoding.equals("jisx0208.1983-0")) {
jclass = "sun.awt.motif.X11JIS0208";
jclass = "JIS0208";
nBytes = DOUBLE_BYTE;
} else if (encoding.equals("jisx0201.1976-0")) {
jclass = "sun.awt.motif.X11JIS0201";
jclass = "JIS0201";
// this is mapping the latin supplement range 128->255 which
// doesn't exist in JIS0201. This needs examination.
// it was also overwriting a couple of the mappings of
@ -94,7 +94,7 @@ class XMap {
addAscii = true;
lowPartOnly = true;
} else if (encoding.equals("jisx0212.1990-0")) {
jclass = "sun.awt.motif.X11JIS0212";
jclass = "JIS0212";
nBytes = DOUBLE_BYTE;
} else if (encoding.equals("iso8859-4")) {
jclass = "ISO8859_4";
@ -117,25 +117,25 @@ class XMap {
} else if (encoding.equals("iso8859-15")) {
jclass = "ISO8859_15";
} else if (encoding.equals("ksc5601.1987-0")) {
jclass ="sun.awt.motif.X11KSC5601";
jclass ="sun.font.X11KSC5601";
nBytes = DOUBLE_BYTE;
} else if (encoding.equals( "ksc5601.1992-3")) {
jclass ="sun.awt.motif.X11Johab";
jclass ="sun.font.X11Johab";
nBytes = DOUBLE_BYTE;
} else if (encoding.equals( "ksc5601.1987-1")) {
jclass ="EUC_KR";
nBytes = DOUBLE_BYTE;
} else if (encoding.equals( "cns11643-1")) {
jclass = "sun.awt.motif.X11CNS11643P1";
jclass = "sun.font.X11CNS11643P1";
nBytes = DOUBLE_BYTE;
} else if (encoding.equals("cns11643-2")) {
jclass = "sun.awt.motif.X11CNS11643P2";
jclass = "sun.font.X11CNS11643P2";
nBytes = DOUBLE_BYTE;
} else if (encoding.equals("cns11643-3")) {
jclass = "sun.awt.motif.X11CNS11643P3";
jclass = "sun.font.X11CNS11643P3";
nBytes = DOUBLE_BYTE;
} else if (encoding.equals("gb2312.1980-0")) {
jclass = "sun.awt.motif.X11GB2312";
jclass = "sun.font.X11GB2312";
nBytes = DOUBLE_BYTE;
} else if (encoding.indexOf("big5") >= 0) {
jclass = "Big5";
@ -144,19 +144,19 @@ class XMap {
} else if (encoding.equals("tis620.2533-0")) {
jclass = "TIS620";
} else if (encoding.equals("gbk-0")) {
jclass = "sun.awt.motif.X11GBK";
jclass = "sun.font.X11GBK";
nBytes = DOUBLE_BYTE;
} else if (encoding.indexOf("sun.unicode-0") >= 0) {
jclass = "sun.awt.motif.X11SunUnicode_0";
jclass = "sun.font.X11SunUnicode_0";
nBytes = DOUBLE_BYTE;
} else if (encoding.indexOf("gb18030.2000-1") >= 0) {
jclass = "sun.awt.motif.X11GB18030_1";
jclass = "sun.font.X11GB18030_1";
nBytes = DOUBLE_BYTE;
} else if (encoding.indexOf( "gb18030.2000-0") >= 0) {
jclass = "sun.awt.motif.X11GB18030_0";
jclass = "sun.font.X11GB18030_0";
nBytes = DOUBLE_BYTE;
} else if (encoding.indexOf("hkscs") >= 0) {
jclass = "sun.awt.HKSCS";
jclass = "MS950_HKSCS_XP";
nBytes = DOUBLE_BYTE;
}
return new XMap(jclass, minU, maxU, nBytes, addAscii, lowPartOnly);

View File

@ -1,49 +0,0 @@
/*
* Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.cs.ext;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetDecoder;
public class COMPOUND_TEXT extends Charset {
public COMPOUND_TEXT () {
super("x-COMPOUND_TEXT",
ExtendedCharsets.aliasesFor("x-COMPOUND_TEXT"));
}
public CharsetEncoder newEncoder() {
return new COMPOUND_TEXT_Encoder(this);
}
public CharsetDecoder newDecoder() {
return new COMPOUND_TEXT_Decoder(this);
}
public boolean contains(Charset cs) {
return cs instanceof COMPOUND_TEXT;
}
}

View File

@ -1,714 +0,0 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.cs.ext;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.*;
/**
* An algorithmic conversion from COMPOUND_TEXT to Unicode.
*/
public class COMPOUND_TEXT_Decoder extends CharsetDecoder {
private static final int NORMAL_BYTES = 0;
private static final int NONSTANDARD_BYTES = 1;
private static final int VERSION_SEQUENCE_V = 2;
private static final int VERSION_SEQUENCE_TERM = 3;
private static final int ESCAPE_SEQUENCE = 4;
private static final int CHARSET_NGIIF = 5;
private static final int CHARSET_NLIIF = 6;
private static final int CHARSET_NLIF = 7;
private static final int CHARSET_NRIIF = 8;
private static final int CHARSET_NRIF = 9;
private static final int CHARSET_NONSTANDARD_FOML = 10;
private static final int CHARSET_NONSTANDARD_OML = 11;
private static final int CHARSET_NONSTANDARD_ML = 12;
private static final int CHARSET_NONSTANDARD_L = 13;
private static final int CHARSET_NONSTANDARD = 14;
private static final int CHARSET_LIIF = 15;
private static final int CHARSET_LIF = 16;
private static final int CHARSET_RIIF = 17;
private static final int CHARSET_RIF = 18;
private static final int CONTROL_SEQUENCE_PIF = 19;
private static final int CONTROL_SEQUENCE_IF = 20;
private static final int EXTENSION_ML = 21;
private static final int EXTENSION_L = 22;
private static final int EXTENSION = 23;
private static final int ESCAPE_SEQUENCE_OTHER = 24;
private static final String ERR_LATIN1 = "ISO8859_1 unsupported";
private static final String ERR_ILLSTATE = "Illegal state";
private static final String ERR_ESCBYTE =
"Illegal byte in 0x1B escape sequence";
private static final String ERR_ENCODINGBYTE =
"Illegal byte in non-standard character set name";
private static final String ERR_CTRLBYTE =
"Illegal byte in 0x9B control sequence";
private static final String ERR_CTRLPI =
"P following I in 0x9B control sequence";
private static final String ERR_VERSTART =
"Versioning escape sequence can only appear at start of byte stream";
private static final String ERR_VERMANDATORY =
"Cannot parse mandatory extensions";
private static final String ERR_ENCODING = "Unknown encoding: ";
private static final String ERR_FLUSH =
"Escape sequence, control sequence, or ML extension not terminated";
private int state = NORMAL_BYTES ;
private int ext_count, ext_offset;
private boolean versionSequenceAllowed = true;
private byte[] byteBuf = new byte[1];
private ByteBuffer inBB = ByteBuffer.allocate(16);
private ByteArrayOutputStream queue = new ByteArrayOutputStream(),
encodingQueue = new ByteArrayOutputStream();
private CharsetDecoder glDecoder, grDecoder, nonStandardDecoder,
lastDecoder;
private boolean glHigh = false, grHigh = true;
public COMPOUND_TEXT_Decoder(Charset cs) {
super(cs, 1.0f, 1.0f);
try {
// Initial state in ISO 2022 designates Latin-1 charset.
glDecoder = Charset.forName("ASCII").newDecoder();
grDecoder = Charset.forName("ISO8859_1").newDecoder();
} catch (IllegalArgumentException e) {
error(ERR_LATIN1);
}
initDecoder(glDecoder);
initDecoder(grDecoder);
}
protected CoderResult decodeLoop(ByteBuffer src, CharBuffer des) {
CoderResult cr = CoderResult.UNDERFLOW;
byte[] input = src.array();
int inOff = src.arrayOffset() + src.position();
int inEnd = src.arrayOffset() + src.limit();
try {
while (inOff < inEnd && cr.isUnderflow()) {
// Byte parsing is done with shorts instead of bytes because
// Java bytes are signed, while COMPOUND_TEXT bytes are not. If
// we used the Java byte type, the > and < tests during parsing
// would not work correctly.
cr = handleByte((short)(input[inOff] & 0xFF), des);
inOff++;
}
return cr;
} finally {
src.position(inOff - src.arrayOffset());
}
}
private CoderResult handleByte(short newByte, CharBuffer cb) {
CoderResult cr = CoderResult.UNDERFLOW;
switch (state) {
case NORMAL_BYTES:
cr= normalBytes(newByte, cb);
break;
case NONSTANDARD_BYTES:
cr = nonStandardBytes(newByte, cb);
break;
case VERSION_SEQUENCE_V:
case VERSION_SEQUENCE_TERM:
cr = versionSequence(newByte);
break;
case ESCAPE_SEQUENCE:
cr = escapeSequence(newByte);
break;
case CHARSET_NGIIF:
cr = charset94N(newByte);
break;
case CHARSET_NLIIF:
case CHARSET_NLIF:
cr = charset94NL(newByte, cb);
break;
case CHARSET_NRIIF:
case CHARSET_NRIF:
cr = charset94NR(newByte, cb);
break;
case CHARSET_NONSTANDARD_FOML:
case CHARSET_NONSTANDARD_OML:
case CHARSET_NONSTANDARD_ML:
case CHARSET_NONSTANDARD_L:
case CHARSET_NONSTANDARD:
cr = charsetNonStandard(newByte, cb);
break;
case CHARSET_LIIF:
case CHARSET_LIF:
cr = charset9496L(newByte, cb);
break;
case CHARSET_RIIF:
case CHARSET_RIF:
cr = charset9496R(newByte, cb);
break;
case CONTROL_SEQUENCE_PIF:
case CONTROL_SEQUENCE_IF:
cr = controlSequence(newByte);
break;
case EXTENSION_ML:
case EXTENSION_L:
case EXTENSION:
cr = extension(newByte);
break;
case ESCAPE_SEQUENCE_OTHER:
cr = escapeSequenceOther(newByte);
break;
default:
error(ERR_ILLSTATE);
}
return cr;
}
private CoderResult normalBytes(short newByte, CharBuffer cb) {
CoderResult cr = CoderResult.UNDERFLOW;
if ((newByte >= 0x00 && newByte <= 0x1F) || // C0
(newByte >= 0x80 && newByte <= 0x9F)) { // C1
char newChar;
switch (newByte) {
case 0x1B:
state = ESCAPE_SEQUENCE;
queue.write(newByte);
return cr;
case 0x9B:
state = CONTROL_SEQUENCE_PIF;
versionSequenceAllowed = false;
queue.write(newByte);
return cr;
case 0x09:
versionSequenceAllowed = false;
newChar = '\t';
break;
case 0x0A:
versionSequenceAllowed = false;
newChar = '\n';
break;
default:
versionSequenceAllowed = false;
return cr;
}
if (!cb.hasRemaining())
return CoderResult.OVERFLOW;
else
cb.put(newChar);
} else {
CharsetDecoder decoder;
boolean high;
versionSequenceAllowed = false;
if (newByte >= 0x20 && newByte <= 0x7F) {
decoder = glDecoder;
high = glHigh;
} else /* if (newByte >= 0xA0 && newByte <= 0xFF) */ {
decoder = grDecoder;
high = grHigh;
}
if (lastDecoder != null && decoder != lastDecoder) {
cr = flushDecoder(lastDecoder, cb);
}
lastDecoder = decoder;
if (decoder != null) {
byte b = (byte)newByte;
if (high) {
b |= 0x80;
} else {
b &= 0x7F;
}
inBB.put(b);
inBB.flip();
cr = decoder.decode(inBB, cb, false);
if (!inBB.hasRemaining() || cr.isMalformed()) {
inBB.clear();
} else {
int pos = inBB.limit();
inBB.clear();
inBB.position(pos);
}
} else if (cb.remaining() < replacement().length()) {
cb.put(replacement());
} else {
return CoderResult.OVERFLOW;
}
}
return cr;
}
private CoderResult nonStandardBytes(short newByte, CharBuffer cb)
{
CoderResult cr = CoderResult.UNDERFLOW;
if (nonStandardDecoder != null) {
//byteBuf[0] = (byte)newByte;
inBB.put((byte)newByte);
inBB.flip();
cr = nonStandardDecoder.decode(inBB, cb, false);
if (!inBB.hasRemaining()) {
inBB.clear();
} else {
int pos = inBB.limit();
inBB.clear();
inBB.position(pos);
}
} else if (cb.remaining() < replacement().length()) {
cb.put(replacement());
} else {
return CoderResult.OVERFLOW;
}
ext_offset++;
if (ext_offset >= ext_count) {
ext_offset = ext_count = 0;
state = NORMAL_BYTES;
cr = flushDecoder(nonStandardDecoder, cb);
nonStandardDecoder = null;
}
return cr;
}
private CoderResult escapeSequence(short newByte) {
switch (newByte) {
case 0x23:
state = VERSION_SEQUENCE_V;
break;
case 0x24:
state = CHARSET_NGIIF;
versionSequenceAllowed = false;
break;
case 0x25:
state = CHARSET_NONSTANDARD_FOML;
versionSequenceAllowed = false;
break;
case 0x28:
state = CHARSET_LIIF;
versionSequenceAllowed = false;
break;
case 0x29:
case 0x2D:
state = CHARSET_RIIF;
versionSequenceAllowed = false;
break;
default:
// escapeSequenceOther will write to queue if appropriate
return escapeSequenceOther(newByte);
}
queue.write(newByte);
return CoderResult.UNDERFLOW;
}
/**
* Test for unknown, but valid, escape sequences.
*/
private CoderResult escapeSequenceOther(short newByte) {
if (newByte >= 0x20 && newByte <= 0x2F) {
// {I}
state = ESCAPE_SEQUENCE_OTHER;
versionSequenceAllowed = false;
queue.write(newByte);
} else if (newByte >= 0x30 && newByte <= 0x7E) {
// F -- end of sequence
state = NORMAL_BYTES;
versionSequenceAllowed = false;
queue.reset();
} else {
return malformedInput(ERR_ESCBYTE);
}
return CoderResult.UNDERFLOW;
}
/**
* Parses directionality, as well as unknown, but valid, control sequences.
*/
private CoderResult controlSequence(short newByte) {
if (newByte >= 0x30 && newByte <= 0x3F) {
// {P}
if (state == CONTROL_SEQUENCE_IF) {
// P no longer allowed
return malformedInput(ERR_CTRLPI);
}
queue.write(newByte);
} else if (newByte >= 0x20 && newByte <= 0x2F) {
// {I}
state = CONTROL_SEQUENCE_IF;
queue.write(newByte);
} else if (newByte >= 0x40 && newByte <= 0x7E) {
// F -- end of sequence
state = NORMAL_BYTES;
queue.reset();
} else {
return malformedInput(ERR_CTRLBYTE);
}
return CoderResult.UNDERFLOW;
}
private CoderResult versionSequence(short newByte) {
if (state == VERSION_SEQUENCE_V) {
if (newByte >= 0x20 && newByte <= 0x2F) {
state = VERSION_SEQUENCE_TERM;
queue.write(newByte);
} else {
return escapeSequenceOther(newByte);
}
} else /* if (state == VERSION_SEQUENCE_TERM) */ {
switch (newByte) {
case 0x30:
if (!versionSequenceAllowed) {
return malformedInput(ERR_VERSTART);
}
// OK to ignore extensions
versionSequenceAllowed = false;
state = NORMAL_BYTES;
queue.reset();
break;
case 0x31:
return malformedInput((versionSequenceAllowed)
? ERR_VERMANDATORY : ERR_VERSTART);
default:
return escapeSequenceOther(newByte);
}
}
return CoderResult.UNDERFLOW;
}
private CoderResult charset94N(short newByte) {
switch (newByte) {
case 0x28:
state = CHARSET_NLIIF;
break;
case 0x29:
state = CHARSET_NRIIF;
break;
default:
// escapeSequenceOther will write byte if appropriate
return escapeSequenceOther(newByte);
}
queue.write(newByte);
return CoderResult.UNDERFLOW;
}
private CoderResult charset94NL(short newByte, CharBuffer cb) {
if (newByte >= 0x21 &&
newByte <= (state == CHARSET_NLIIF ? 0x23 : 0x2F)) {
// {I}
state = CHARSET_NLIF;
queue.write(newByte);
} else if (newByte >= 0x40 && newByte <= 0x7E) {
// F
return switchDecoder(newByte, cb);
} else {
return escapeSequenceOther(newByte);
}
return CoderResult.UNDERFLOW;
}
private CoderResult charset94NR(short newByte, CharBuffer cb)
{
if (newByte >= 0x21 &&
newByte <= (state == CHARSET_NRIIF ? 0x23 : 0x2F)) {
// {I}
state = CHARSET_NRIF;
queue.write(newByte);
} else if (newByte >= 0x40 && newByte <= 0x7E) {
// F
return switchDecoder(newByte, cb);
} else {
return escapeSequenceOther(newByte);
}
return CoderResult.UNDERFLOW;
}
private CoderResult charset9496L(short newByte, CharBuffer cb) {
if (newByte >= 0x21 &&
newByte <= (state == CHARSET_LIIF ? 0x23 : 0x2F)) {
// {I}
state = CHARSET_LIF;
queue.write(newByte);
return CoderResult.UNDERFLOW;
} else if (newByte >= 0x40 && newByte <= 0x7E) {
// F
return switchDecoder(newByte, cb);
} else {
return escapeSequenceOther(newByte);
}
}
private CoderResult charset9496R(short newByte, CharBuffer cb) {
if (newByte >= 0x21 &&
newByte <= (state == CHARSET_RIIF ? 0x23 : 0x2F)) {
// {I}
state = CHARSET_RIF;
queue.write(newByte);
return CoderResult.UNDERFLOW;
} else if (newByte >= 0x40 && newByte <= 0x7E) {
// F
return switchDecoder(newByte, cb);
} else {
return escapeSequenceOther(newByte);
}
}
private CoderResult charsetNonStandard(short newByte, CharBuffer cb) {
switch (state) {
case CHARSET_NONSTANDARD_FOML:
if (newByte == 0x2F) {
state = CHARSET_NONSTANDARD_OML;
queue.write(newByte);
} else {
return escapeSequenceOther(newByte);
}
break;
case CHARSET_NONSTANDARD_OML:
if (newByte >= 0x30 && newByte <= 0x34) {
state = CHARSET_NONSTANDARD_ML;
queue.write(newByte);
} else if (newByte >= 0x35 && newByte <= 0x3F) {
state = EXTENSION_ML;
queue.write(newByte);
} else {
return escapeSequenceOther(newByte);
}
break;
case CHARSET_NONSTANDARD_ML:
ext_count = (newByte & 0x7F) * 0x80;
state = CHARSET_NONSTANDARD_L;
break;
case CHARSET_NONSTANDARD_L:
ext_count = ext_count + (newByte & 0x7F);
state = (ext_count > 0) ? CHARSET_NONSTANDARD : NORMAL_BYTES;
break;
case CHARSET_NONSTANDARD:
if (newByte == 0x3F || newByte == 0x2A) {
queue.reset(); // In this case, only current byte is bad.
return malformedInput(ERR_ENCODINGBYTE);
}
ext_offset++;
if (ext_offset >= ext_count) {
ext_offset = ext_count = 0;
state = NORMAL_BYTES;
queue.reset();
encodingQueue.reset();
} else if (newByte == 0x02) {
// encoding name terminator
return switchDecoder((short)0, cb);
} else {
encodingQueue.write(newByte);
}
break;
default:
error(ERR_ILLSTATE);
}
return CoderResult.UNDERFLOW;
}
private CoderResult extension(short newByte) {
switch (state) {
case EXTENSION_ML:
ext_count = (newByte & 0x7F) * 0x80;
state = EXTENSION_L;
break;
case EXTENSION_L:
ext_count = ext_count + (newByte & 0x7F);
state = (ext_count > 0) ? EXTENSION : NORMAL_BYTES;
break;
case EXTENSION:
// Consume 'count' bytes. Don't bother putting them on the queue.
// There may be too many and we can't do anything with them anyway.
ext_offset++;
if (ext_offset >= ext_count) {
ext_offset = ext_count = 0;
state = NORMAL_BYTES;
queue.reset();
}
break;
default:
error(ERR_ILLSTATE);
}
return CoderResult.UNDERFLOW;
}
/**
* Preconditions:
* 1. 'queue' contains ControlSequence.escSequence
* 2. 'encodingQueue' contains ControlSequence.encoding
*/
private CoderResult switchDecoder(short lastByte, CharBuffer cb) {
CoderResult cr = CoderResult.UNDERFLOW;
CharsetDecoder decoder = null;
boolean high = false;
byte[] escSequence;
byte[] encoding = null;
if (lastByte != 0) {
queue.write(lastByte);
}
escSequence = queue.toByteArray();
queue.reset();
if (state == CHARSET_NONSTANDARD) {
encoding = encodingQueue.toByteArray();
encodingQueue.reset();
decoder = CompoundTextSupport.
getNonStandardDecoder(escSequence, encoding);
} else {
decoder = CompoundTextSupport.getStandardDecoder(escSequence);
high = CompoundTextSupport.getHighBit(escSequence);
}
if (decoder != null) {
initDecoder(decoder);
} else if (unmappableCharacterAction() == CodingErrorAction.REPORT) {
int badInputLength = 1;
if (encoding != null) {
badInputLength = encoding.length;
} else if (escSequence.length > 0) {
badInputLength = escSequence.length;
}
return CoderResult.unmappableForLength(badInputLength);
}
if (state == CHARSET_NLIIF || state == CHARSET_NLIF ||
state == CHARSET_LIIF || state == CHARSET_LIF)
{
if (lastDecoder == glDecoder) {
cr = flushDecoder(glDecoder, cb);
}
glDecoder = lastDecoder = decoder;
glHigh = high;
state = NORMAL_BYTES;
} else if (state == CHARSET_NRIIF || state == CHARSET_NRIF ||
state == CHARSET_RIIF || state == CHARSET_RIF) {
if (lastDecoder == grDecoder) {
cr = flushDecoder(grDecoder, cb);
}
grDecoder = lastDecoder = decoder;
grHigh = high;
state = NORMAL_BYTES;
} else if (state == CHARSET_NONSTANDARD) {
if (lastDecoder != null) {
cr = flushDecoder(lastDecoder, cb);
lastDecoder = null;
}
nonStandardDecoder = decoder;
state = NONSTANDARD_BYTES;
} else {
error(ERR_ILLSTATE);
}
return cr;
}
private ByteBuffer fbb= ByteBuffer.allocate(0);
private CoderResult flushDecoder(CharsetDecoder dec, CharBuffer cb) {
dec.decode(fbb, cb, true);
CoderResult cr = dec.flush(cb);
dec.reset(); //reuse
return cr;
}
private CoderResult malformedInput(String msg) {
int badInputLength = queue.size() + 1 /* current byte */ ;
queue.reset();
//TBD: nowhere to put the msg in CoderResult
return CoderResult.malformedForLength(badInputLength);
}
private void error(String msg) {
// For now, throw InternalError. Convert to 'assert' keyword later.
throw new InternalError(msg);
}
protected CoderResult implFlush(CharBuffer out) {
CoderResult cr = CoderResult.UNDERFLOW;
if (lastDecoder != null)
cr = flushDecoder(lastDecoder, out);
if (state != NORMAL_BYTES)
//TBD message ERR_FLUSH;
cr = CoderResult.malformedForLength(0);
reset();
return cr;
}
/**
* Resets the decoder.
* Call this method to reset the decoder to its initial state
*/
protected void implReset() {
state = NORMAL_BYTES;
ext_count = ext_offset = 0;
versionSequenceAllowed = true;
queue.reset();
encodingQueue.reset();
nonStandardDecoder = lastDecoder = null;
glHigh = false;
grHigh = true;
try {
// Initial state in ISO 2022 designates Latin-1 charset.
glDecoder = Charset.forName("ASCII").newDecoder();
grDecoder = Charset.forName("ISO8859_1").newDecoder();
} catch (IllegalArgumentException e) {
error(ERR_LATIN1);
}
initDecoder(glDecoder);
initDecoder(grDecoder);
}
protected void implOnMalformedInput(CodingErrorAction newAction) {
if (glDecoder != null)
glDecoder.onMalformedInput(newAction);
if (grDecoder != null)
grDecoder.onMalformedInput(newAction);
if (nonStandardDecoder != null)
nonStandardDecoder.onMalformedInput(newAction);
}
protected void implOnUnmappableCharacter(CodingErrorAction newAction) {
if (glDecoder != null)
glDecoder.onUnmappableCharacter(newAction);
if (grDecoder != null)
grDecoder.onUnmappableCharacter(newAction);
if (nonStandardDecoder != null)
nonStandardDecoder.onUnmappableCharacter(newAction);
}
protected void implReplaceWith(String newReplacement) {
if (glDecoder != null)
glDecoder.replaceWith(newReplacement);
if (grDecoder != null)
grDecoder.replaceWith(newReplacement);
if (nonStandardDecoder != null)
nonStandardDecoder.replaceWith(newReplacement);
}
private void initDecoder(CharsetDecoder dec) {
dec.onUnmappableCharacter(CodingErrorAction.REPLACE)
.replaceWith(replacement());
}
}

View File

@ -1,349 +0,0 @@
/*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.cs.ext;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class COMPOUND_TEXT_Encoder extends CharsetEncoder {
/**
* NOTE: The following four static variables should be used *only* for
* testing whether a encoder can encode a specific character. They
* cannot be used for actual encoding because they are shared across all
* COMPOUND_TEXT encoders and may be stateful.
*/
private static final Map<String,CharsetEncoder> encodingToEncoderMap =
Collections.synchronizedMap(new HashMap<String,CharsetEncoder>(21, 1.0f));
private static final CharsetEncoder latin1Encoder;
private static final CharsetEncoder defaultEncoder;
private static final boolean defaultEncodingSupported;
static {
CharsetEncoder encoder = Charset.defaultCharset().newEncoder();
String encoding = encoder.charset().name();
if ("ISO8859_1".equals(encoding)) {
latin1Encoder = encoder;
defaultEncoder = encoder;
defaultEncodingSupported = true;
} else {
try {
latin1Encoder =
Charset.forName("ISO8859_1").newEncoder();
} catch (IllegalArgumentException e) {
throw new ExceptionInInitializerError
("ISO8859_1 unsupported");
}
defaultEncoder = encoder;
defaultEncodingSupported = CompoundTextSupport.getEncodings().
contains(defaultEncoder.charset().name());
}
}
private CharsetEncoder encoder;
private char[] charBuf = new char[1];
private CharBuffer charbuf = CharBuffer.wrap(charBuf);
private ByteArrayOutputStream nonStandardCharsetBuffer;
private byte[] byteBuf;
private ByteBuffer bytebuf;
private int numNonStandardChars, nonStandardEncodingLen;
public COMPOUND_TEXT_Encoder(Charset cs) {
super(cs,
(float)(CompoundTextSupport.MAX_CONTROL_SEQUENCE_LEN + 2),
(float)(CompoundTextSupport.MAX_CONTROL_SEQUENCE_LEN + 2));
try {
encoder = Charset.forName("ISO8859_1").newEncoder();
} catch (IllegalArgumentException cannotHappen) {}
initEncoder(encoder);
}
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer des) {
CoderResult cr = CoderResult.UNDERFLOW;
char[] input = src.array();
int inOff = src.arrayOffset() + src.position();
int inEnd = src.arrayOffset() + src.limit();
try {
while (inOff < inEnd && cr.isUnderflow()) {
charBuf[0] = input[inOff];
if (charBuf[0] <= '\u0008' ||
(charBuf[0] >= '\u000B' && charBuf[0] <= '\u001F') ||
(charBuf[0] >= '\u0080' && charBuf[0] <= '\u009F')) {
// The compound text specification only permits the octets
// 0x09, 0x0A, 0x1B, and 0x9B in C0 and C1. Of these, 1B and
// 9B must also be removed because they initiate control
// sequences.
charBuf[0] = '?';
}
CharsetEncoder enc = getEncoder(charBuf[0]);
//System.out.println("char=" + charBuf[0] + ", enc=" + enc);
if (enc == null) {
if (unmappableCharacterAction()
== CodingErrorAction.REPORT) {
charBuf[0] = '?';
enc = latin1Encoder;
} else {
return CoderResult.unmappableForLength(1);
}
}
if (enc != encoder) {
if (nonStandardCharsetBuffer != null) {
cr = flushNonStandardCharsetBuffer(des);
} else {
//cr= encoder.flush(des);
flushEncoder(encoder, des);
}
if (!cr.isUnderflow())
return cr;
byte[] escSequence = CompoundTextSupport.
getEscapeSequence(enc.charset().name());
if (escSequence == null) {
throw new InternalError("Unknown encoding: " +
enc.charset().name());
} else if (escSequence[1] == (byte)0x25 &&
escSequence[2] == (byte)0x2F) {
initNonStandardCharsetBuffer(enc, escSequence);
} else if (des.remaining() >= escSequence.length) {
des.put(escSequence, 0, escSequence.length);
} else {
return CoderResult.OVERFLOW;
}
encoder = enc;
continue;
}
charbuf.rewind();
if (nonStandardCharsetBuffer == null) {
cr = encoder.encode(charbuf, des, false);
} else {
bytebuf.clear();
cr = encoder.encode(charbuf, bytebuf, false);
bytebuf.flip();
nonStandardCharsetBuffer.write(byteBuf,
0, bytebuf.limit());
numNonStandardChars++;
}
inOff++;
}
return cr;
} finally {
src.position(inOff - src.arrayOffset());
}
}
protected CoderResult implFlush(ByteBuffer out) {
CoderResult cr = (nonStandardCharsetBuffer != null)
? flushNonStandardCharsetBuffer(out)
//: encoder.flush(out);
: flushEncoder(encoder, out);
reset();
return cr;
}
private void initNonStandardCharsetBuffer(CharsetEncoder c,
byte[] escSequence)
{
nonStandardCharsetBuffer = new ByteArrayOutputStream();
byteBuf = new byte[(int)c.maxBytesPerChar()];
bytebuf = ByteBuffer.wrap(byteBuf);
nonStandardCharsetBuffer.write(escSequence, 0, escSequence.length);
nonStandardCharsetBuffer.write(0); // M placeholder
nonStandardCharsetBuffer.write(0); // L placeholder
byte[] encoding = CompoundTextSupport.
getEncoding(c.charset().name());
if (encoding == null) {
throw new InternalError
("Unknown encoding: " + encoder.charset().name());
}
nonStandardCharsetBuffer.write(encoding, 0, encoding.length);
nonStandardCharsetBuffer.write(0x02); // divider
nonStandardEncodingLen = encoding.length + 1;
}
private CoderResult flushNonStandardCharsetBuffer(ByteBuffer out) {
if (numNonStandardChars > 0) {
byte[] flushBuf = new byte[(int)encoder.maxBytesPerChar() *
numNonStandardChars];
ByteBuffer bb = ByteBuffer.wrap(flushBuf);
flushEncoder(encoder, bb);
bb.flip();
nonStandardCharsetBuffer.write(flushBuf, 0, bb.limit());
numNonStandardChars = 0;
}
int numBytes = nonStandardCharsetBuffer.size();
int nonStandardBytesOff = 6 + nonStandardEncodingLen;
if (out.remaining() < (numBytes - nonStandardBytesOff) +
nonStandardBytesOff * (((numBytes - nonStandardBytesOff) /
((1 << 14) - 1)) + 1))
{
return CoderResult.OVERFLOW;
}
byte[] nonStandardBytes =
nonStandardCharsetBuffer.toByteArray();
// The non-standard charset header only supports 2^14-1 bytes of data.
// If we have more than that, we have to repeat the header.
do {
out.put((byte)0x1B);
out.put((byte)0x25);
out.put((byte)0x2F);
out.put(nonStandardBytes[3]);
int toWrite = Math.min(numBytes - nonStandardBytesOff,
(1 << 14) - 1 - nonStandardEncodingLen);
out.put((byte)
(((toWrite + nonStandardEncodingLen) / 0x80) | 0x80)); // M
out.put((byte)
(((toWrite + nonStandardEncodingLen) % 0x80) | 0x80)); // L
out.put(nonStandardBytes, 6, nonStandardEncodingLen);
out.put(nonStandardBytes, nonStandardBytesOff, toWrite);
nonStandardBytesOff += toWrite;
} while (nonStandardBytesOff < numBytes);
nonStandardCharsetBuffer = null;
byteBuf = null;
nonStandardEncodingLen = 0;
return CoderResult.UNDERFLOW;
}
/**
* Resets the encoder.
* Call this method to reset the encoder to its initial state
*/
protected void implReset() {
numNonStandardChars = nonStandardEncodingLen = 0;
nonStandardCharsetBuffer = null;
byteBuf = null;
try {
encoder = Charset.forName("ISO8859_1").newEncoder();
} catch (IllegalArgumentException cannotHappen) {
}
initEncoder(encoder);
}
/**
* Return whether a character is mappable or not
* @return true if a character is mappable
*/
public boolean canEncode(char ch) {
return getEncoder(ch) != null;
}
protected void implOnMalformedInput(CodingErrorAction newAction) {
encoder.onUnmappableCharacter(newAction);
}
protected void implOnUnmappableCharacter(CodingErrorAction newAction) {
encoder.onUnmappableCharacter(newAction);
}
protected void implReplaceWith(byte[] newReplacement) {
if (encoder != null)
encoder.replaceWith(newReplacement);
}
/**
* Try to figure out which CharsetEncoder to use for conversion
* of the specified Unicode character. The target character encoding
* of the returned encoder is approved to be used with Compound Text.
*
* @param ch Unicode character
* @return CharsetEncoder to convert the given character
*/
private CharsetEncoder getEncoder(char ch) {
// 1. Try the current encoder.
if (encoder.canEncode(ch)) {
return encoder;
}
// 2. Try the default encoder.
if (defaultEncodingSupported && defaultEncoder.canEncode(ch)) {
CharsetEncoder retval = null;
try {
retval = defaultEncoder.charset().newEncoder();
} catch (UnsupportedOperationException cannotHappen) {
}
initEncoder(retval);
return retval;
}
// 3. Try ISO8859-1.
if (latin1Encoder.canEncode(ch)) {
CharsetEncoder retval = null;
try {
retval = latin1Encoder.charset().newEncoder();
} catch (UnsupportedOperationException cannotHappen) {}
initEncoder(retval);
return retval;
}
// 4. Brute force search of all supported encodings.
for (String encoding : CompoundTextSupport.getEncodings())
{
CharsetEncoder enc = encodingToEncoderMap.get(encoding);
if (enc == null) {
enc = CompoundTextSupport.getEncoder(encoding);
if (enc == null) {
throw new InternalError("Unsupported encoding: " +
encoding);
}
encodingToEncoderMap.put(encoding, enc);
}
if (enc.canEncode(ch)) {
CharsetEncoder retval = CompoundTextSupport.getEncoder(encoding);
initEncoder(retval);
return retval;
}
}
return null;
}
private void initEncoder(CharsetEncoder enc) {
try {
enc.onUnmappableCharacter(CodingErrorAction.REPLACE)
.replaceWith(replacement());
} catch (IllegalArgumentException x) {}
}
private CharBuffer fcb= CharBuffer.allocate(0);
private CoderResult flushEncoder(CharsetEncoder enc, ByteBuffer bb) {
enc.encode(fcb, bb, true);
return enc.flush(bb);
}
}

View File

@ -1,548 +0,0 @@
/*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.cs.ext;
import java.util.Collections;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.nio.charset.*;
final class CompoundTextSupport {
private static final class ControlSequence {
final int hash;
final byte[] escSequence;
final byte[] encoding;
ControlSequence(byte[] escSequence) {
this(escSequence, null);
}
ControlSequence(byte[] escSequence, byte[] encoding) {
if (escSequence == null) {
throw new NullPointerException();
}
this.escSequence = escSequence;
this.encoding = encoding;
int hash = 0;
int length = escSequence.length;
for (int i = 0; i < escSequence.length; i++) {
hash += (((int)escSequence[i]) & 0xff) << (i % 4);
}
if (encoding != null) {
for (int i = 0; i < encoding.length; i++) {
hash += (((int)encoding[i]) & 0xff) << (i % 4);
}
length += 2 /* M L */ + encoding.length + 1 /* 0x02 */;
}
this.hash = hash;
if (MAX_CONTROL_SEQUENCE_LEN < length) {
MAX_CONTROL_SEQUENCE_LEN = length;
}
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof ControlSequence)) {
return false;
}
ControlSequence rhs = (ControlSequence)obj;
if (escSequence != rhs.escSequence) {
if (escSequence.length != rhs.escSequence.length) {
return false;
}
for (int i = 0; i < escSequence.length; i++) {
if (escSequence[i] != rhs.escSequence[i]) {
return false;
}
}
}
if (encoding != rhs.encoding) {
if (encoding == null || rhs.encoding == null ||
encoding.length != rhs.encoding.length)
{
return false;
}
for (int i = 0; i < encoding.length; i++) {
if (encoding[i] != rhs.encoding[i]) {
return false;
}
}
}
return true;
}
public int hashCode() {
return hash;
}
ControlSequence concatenate(ControlSequence rhs) {
if (encoding != null) {
throw new IllegalArgumentException
("cannot concatenate to a non-standard charset escape " +
"sequence");
}
int len = escSequence.length + rhs.escSequence.length;
byte[] newEscSequence = new byte[len];
System.arraycopy(escSequence, 0, newEscSequence, 0,
escSequence.length);
System.arraycopy(rhs.escSequence, 0, newEscSequence,
escSequence.length, rhs.escSequence.length);
return new ControlSequence(newEscSequence, rhs.encoding);
}
}
static int MAX_CONTROL_SEQUENCE_LEN;
/**
* Maps a GL or GR escape sequence to an encoding.
*/
private static final Map<ControlSequence, String> sequenceToEncodingMap;
/**
* Indicates whether a particular encoding wants the high bit turned on
* or off.
*/
private static final Map<ControlSequence, Boolean> highBitsMap;
/**
* Maps an encoding to an escape sequence. Rather than manage two
* converters in CharToByteCOMPOUND_TEXT, we output escape sequences which
* modify both GL and GR if necessary. This makes the output slightly less
* efficient, but our code much simpler.
*/
private static final Map<String, ControlSequence> encodingToSequenceMap;
/**
* The keys of 'encodingToSequenceMap', sorted in preferential order.
*/
private static final List<String> encodings;
static {
HashMap<ControlSequence, String> tSequenceToEncodingMap =
new HashMap<>(33, 1.0f);
HashMap<ControlSequence, Boolean> tHighBitsMap =
new HashMap<>(31, 1.0f);
HashMap<String, ControlSequence> tEncodingToSequenceMap =
new HashMap<>(21, 1.0f);
ArrayList<String> tEncodings = new ArrayList<>(21);
if (!(isEncodingSupported("US-ASCII") &&
isEncodingSupported("ISO-8859-1")))
{
throw new ExceptionInInitializerError
("US-ASCII and ISO-8859-1 unsupported");
}
ControlSequence leftAscii = // high bit off, leave off
new ControlSequence(new byte[] { 0x1B, 0x28, 0x42 });
tSequenceToEncodingMap.put(leftAscii, "US-ASCII");
tHighBitsMap.put(leftAscii, Boolean.FALSE);
{
ControlSequence rightAscii = // high bit on, turn off
new ControlSequence(new byte[] { 0x1B, 0x29, 0x42 });
tSequenceToEncodingMap.put(rightAscii, "US-ASCII");
tHighBitsMap.put(rightAscii, Boolean.FALSE);
}
{
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x41 });
tSequenceToEncodingMap.put(rightHalf, "ISO-8859-1");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("ISO-8859-1", fullSet);
tEncodings.add("ISO-8859-1");
}
if (isEncodingSupported("ISO-8859-2")) {
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x42 });
tSequenceToEncodingMap.put(rightHalf, "ISO-8859-2");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("ISO-8859-2", fullSet);
tEncodings.add("ISO-8859-2");
}
if (isEncodingSupported("ISO-8859-3")) {
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x43 });
tSequenceToEncodingMap.put(rightHalf, "ISO-8859-3");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("ISO-8859-3", fullSet);
tEncodings.add("ISO-8859-3");
}
if (isEncodingSupported("ISO-8859-4")) {
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x44 });
tSequenceToEncodingMap.put(rightHalf, "ISO-8859-4");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("ISO-8859-4", fullSet);
tEncodings.add("ISO-8859-4");
}
if (isEncodingSupported("ISO-8859-5")) {
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x4C });
tSequenceToEncodingMap.put(rightHalf, "ISO-8859-5");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("ISO-8859-5", fullSet);
tEncodings.add("ISO-8859-5");
}
if (isEncodingSupported("ISO-8859-6")) {
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x47 });
tSequenceToEncodingMap.put(rightHalf, "ISO-8859-6");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("ISO-8859-6", fullSet);
tEncodings.add("ISO-8859-6");
}
if (isEncodingSupported("ISO-8859-7")) {
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x46 });
tSequenceToEncodingMap.put(rightHalf, "ISO-8859-7");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("ISO-8859-7", fullSet);
tEncodings.add("ISO-8859-7");
}
if (isEncodingSupported("ISO-8859-8")) {
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x48 });
tSequenceToEncodingMap.put(rightHalf, "ISO-8859-8");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("ISO-8859-8", fullSet);
tEncodings.add("ISO-8859-8");
}
if (isEncodingSupported("ISO-8859-9")) {
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x4D });
tSequenceToEncodingMap.put(rightHalf, "ISO-8859-9");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("ISO-8859-9", fullSet);
tEncodings.add("ISO-8859-9");
}
if (isEncodingSupported("JIS_X0201")) {
ControlSequence glLeft = // high bit off, leave off
new ControlSequence(new byte[] { 0x1B, 0x28, 0x4A });
ControlSequence glRight = // high bit off, turn on
new ControlSequence(new byte[] { 0x1B, 0x28, 0x49 });
ControlSequence grLeft = // high bit on, turn off
new ControlSequence(new byte[] { 0x1B, 0x29, 0x4A });
ControlSequence grRight = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x29, 0x49 });
tSequenceToEncodingMap.put(glLeft, "JIS_X0201");
tSequenceToEncodingMap.put(glRight, "JIS_X0201");
tSequenceToEncodingMap.put(grLeft, "JIS_X0201");
tSequenceToEncodingMap.put(grRight, "JIS_X0201");
tHighBitsMap.put(glLeft, Boolean.FALSE);
tHighBitsMap.put(glRight, Boolean.TRUE);
tHighBitsMap.put(grLeft, Boolean.FALSE);
tHighBitsMap.put(grRight, Boolean.TRUE);
ControlSequence fullSet = glLeft.concatenate(grRight);
tEncodingToSequenceMap.put("JIS_X0201", fullSet);
tEncodings.add("JIS_X0201");
}
if (isEncodingSupported("X11GB2312")) {
ControlSequence leftHalf = // high bit off, leave off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x28, 0x41 });
ControlSequence rightHalf = // high bit on, turn off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x29, 0x41 });
tSequenceToEncodingMap.put(leftHalf, "X11GB2312");
tSequenceToEncodingMap.put(rightHalf, "X11GB2312");
tHighBitsMap.put(leftHalf, Boolean.FALSE);
tHighBitsMap.put(rightHalf, Boolean.FALSE);
tEncodingToSequenceMap.put("X11GB2312", leftHalf);
tEncodings.add("X11GB2312");
}
if (isEncodingSupported("x-JIS0208")) {
ControlSequence leftHalf = // high bit off, leave off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x28, 0x42 });
ControlSequence rightHalf = // high bit on, turn off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x29, 0x42 });
tSequenceToEncodingMap.put(leftHalf, "x-JIS0208");
tSequenceToEncodingMap.put(rightHalf, "x-JIS0208");
tHighBitsMap.put(leftHalf, Boolean.FALSE);
tHighBitsMap.put(rightHalf, Boolean.FALSE);
tEncodingToSequenceMap.put("x-JIS0208", leftHalf);
tEncodings.add("x-JIS0208");
}
if (isEncodingSupported("X11KSC5601")) {
ControlSequence leftHalf = // high bit off, leave off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x28, 0x43 });
ControlSequence rightHalf = // high bit on, turn off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x29, 0x43 });
tSequenceToEncodingMap.put(leftHalf, "X11KSC5601");
tSequenceToEncodingMap.put(rightHalf, "X11KSC5601");
tHighBitsMap.put(leftHalf, Boolean.FALSE);
tHighBitsMap.put(rightHalf, Boolean.FALSE);
tEncodingToSequenceMap.put("X11KSC5601", leftHalf);
tEncodings.add("X11KSC5601");
}
// Encodings not listed in Compound Text Encoding spec
// Esc seq: -b
if (isEncodingSupported("ISO-8859-15")) {
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x62 });
tSequenceToEncodingMap.put(rightHalf, "ISO-8859-15");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("ISO-8859-15", fullSet);
tEncodings.add("ISO-8859-15");
}
// Esc seq: -T
if (isEncodingSupported("TIS-620")) {
ControlSequence rightHalf = // high bit on, leave on
new ControlSequence(new byte[] { 0x1B, 0x2D, 0x54 });
tSequenceToEncodingMap.put(rightHalf, "TIS-620");
tHighBitsMap.put(rightHalf, Boolean.TRUE);
ControlSequence fullSet = leftAscii.concatenate(rightHalf);
tEncodingToSequenceMap.put("TIS-620", fullSet);
tEncodings.add("TIS-620");
}
if (isEncodingSupported("JIS_X0212-1990")) {
ControlSequence leftHalf = // high bit off, leave off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x28, 0x44 });
ControlSequence rightHalf = // high bit on, turn off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x29, 0x44 });
tSequenceToEncodingMap.put(leftHalf, "JIS_X0212-1990");
tSequenceToEncodingMap.put(rightHalf, "JIS_X0212-1990");
tHighBitsMap.put(leftHalf, Boolean.FALSE);
tHighBitsMap.put(rightHalf, Boolean.FALSE);
tEncodingToSequenceMap.put("JIS_X0212-1990", leftHalf);
tEncodings.add("JIS_X0212-1990");
}
if (isEncodingSupported("X11CNS11643P1")) {
ControlSequence leftHalf = // high bit off, leave off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x28, 0x47 });
ControlSequence rightHalf = // high bit on, turn off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x29, 0x47 });
tSequenceToEncodingMap.put(leftHalf, "X11CNS11643P1");
tSequenceToEncodingMap.put(rightHalf, "X11CNS11643P1");
tHighBitsMap.put(leftHalf, Boolean.FALSE);
tHighBitsMap.put(rightHalf, Boolean.FALSE);
tEncodingToSequenceMap.put("X11CNS11643P1", leftHalf);
tEncodings.add("X11CNS11643P1");
}
if (isEncodingSupported("X11CNS11643P2")) {
ControlSequence leftHalf = // high bit off, leave off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x28, 0x48 });
ControlSequence rightHalf = // high bit on, turn off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x29, 0x48 });
tSequenceToEncodingMap.put(leftHalf, "X11CNS11643P2");
tSequenceToEncodingMap.put(rightHalf, "X11CNS11643P2");
tHighBitsMap.put(leftHalf, Boolean.FALSE);
tHighBitsMap.put(rightHalf, Boolean.FALSE);
tEncodingToSequenceMap.put("X11CNS11643P2", leftHalf);
tEncodings.add("X11CNS11643P2");
}
if (isEncodingSupported("X11CNS11643P3")) {
ControlSequence leftHalf = // high bit off, leave off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x28, 0x49 });
ControlSequence rightHalf = // high bit on, turn off
new ControlSequence(new byte[] { 0x1B, 0x24, 0x29, 0x49 });
tSequenceToEncodingMap.put(leftHalf, "X11CNS11643P3");
tSequenceToEncodingMap.put(rightHalf, "X11CNS11643P3");
tHighBitsMap.put(leftHalf, Boolean.FALSE);
tHighBitsMap.put(rightHalf, Boolean.FALSE);
tEncodingToSequenceMap.put("X11CNS11643P3", leftHalf);
tEncodings.add("X11CNS11643P3");
}
// Esc seq: %/2??SUN-KSC5601.1992-3
if (isEncodingSupported("x-Johab")) {
// 0x32 looks wrong. It's copied from the Sun X11 Compound Text
// support code. It implies that all Johab characters comprise two
// octets, which isn't true. Johab supports the ASCII/KS-Roman
// characters from 0x21-0x7E with single-byte representations.
ControlSequence johab = new ControlSequence(
new byte[] { 0x1b, 0x25, 0x2f, 0x32 },
new byte[] { 0x53, 0x55, 0x4e, 0x2d, 0x4b, 0x53, 0x43, 0x35,
0x36, 0x30, 0x31, 0x2e, 0x31, 0x39, 0x39, 0x32,
0x2d, 0x33 });
tSequenceToEncodingMap.put(johab, "x-Johab");
tEncodingToSequenceMap.put("x-Johab", johab);
tEncodings.add("x-Johab");
}
// Esc seq: %/2??SUN-BIG5-1
if (isEncodingSupported("Big5")) {
// 0x32 looks wrong. It's copied from the Sun X11 Compound Text
// support code. It implies that all Big5 characters comprise two
// octets, which isn't true. Big5 supports the ASCII/CNS-Roman
// characters from 0x21-0x7E with single-byte representations.
ControlSequence big5 = new ControlSequence(
new byte[] { 0x1b, 0x25, 0x2f, 0x32 },
new byte[] { 0x53, 0x55, 0x4e, 0x2d, 0x42, 0x49, 0x47, 0x35,
0x2d, 0x31 });
tSequenceToEncodingMap.put(big5, "Big5");
tEncodingToSequenceMap.put("Big5", big5);
tEncodings.add("Big5");
}
sequenceToEncodingMap =
Collections.unmodifiableMap(tSequenceToEncodingMap);
highBitsMap = Collections.unmodifiableMap(tHighBitsMap);
encodingToSequenceMap =
Collections.unmodifiableMap(tEncodingToSequenceMap);
encodings = Collections.unmodifiableList(tEncodings);
}
private static boolean isEncodingSupported(String encoding) {
try {
if (Charset.isSupported(encoding))
return true;
} catch (IllegalArgumentException x) { }
return (getDecoder(encoding) != null &&
getEncoder(encoding) != null);
}
// For Decoder
static CharsetDecoder getStandardDecoder(byte[] escSequence) {
return getNonStandardDecoder(escSequence, null);
}
static boolean getHighBit(byte[] escSequence) {
Boolean bool = highBitsMap.get(new ControlSequence(escSequence));
return (bool == Boolean.TRUE);
}
static CharsetDecoder getNonStandardDecoder(byte[] escSequence,
byte[] encoding) {
return getDecoder(sequenceToEncodingMap.get
(new ControlSequence(escSequence, encoding)));
}
static CharsetDecoder getDecoder(String enc) {
if (enc == null) {
return null;
}
Charset cs = null;
try {
cs = Charset.forName(enc);
} catch (IllegalArgumentException e) {
Class<?> cls;
try {
cls = Class.forName("sun.awt.motif." + enc);
} catch (ClassNotFoundException ee) {
return null;
}
try {
cs = (Charset)cls.newInstance();
} catch (InstantiationException ee) {
return null;
} catch (IllegalAccessException ee) {
return null;
}
}
try {
return cs.newDecoder();
} catch (UnsupportedOperationException e) {}
return null;
}
// For Encoder
static byte[] getEscapeSequence(String encoding) {
ControlSequence seq = encodingToSequenceMap.get(encoding);
if (seq != null) {
return seq.escSequence;
}
return null;
}
static byte[] getEncoding(String encoding) {
ControlSequence seq = encodingToSequenceMap.get(encoding);
if (seq != null) {
return seq.encoding;
}
return null;
}
static List<String> getEncodings() {
return encodings;
}
static CharsetEncoder getEncoder(String enc) {
if (enc == null) {
return null;
}
Charset cs = null;
try {
cs = Charset.forName(enc);
} catch (IllegalArgumentException e) {
Class<?> cls;
try {
cls = Class.forName("sun.awt.motif." + enc);
} catch (ClassNotFoundException ee) {
return null;
}
try {
cs = (Charset)cls.newInstance();
} catch (InstantiationException ee) {
return null;
} catch (IllegalAccessException ee) {
return null;
}
}
try {
return cs.newEncoder();
} catch (Throwable e) {}
return null;
}
// Not an instantiable class
private CompoundTextSupport() {}
}

View File

@ -1,134 +0,0 @@
/*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import java.nio.charset.*;
import sun.nio.cs.ext.EUC_CN;
public class X11GB2312_OLD extends Charset {
public X11GB2312_OLD () {
super("X11GB2312-OLD", null);
}
public CharsetEncoder newEncoder() {
return new Encoder(this);
}
public CharsetDecoder newDecoder() {
return new Decoder(this);
}
public boolean contains(Charset cs) {
return cs instanceof X11GB2312_OLD;
}
private class Encoder extends EUC_CN_OLD.Encoder {
public Encoder(Charset cs) {
super(cs);
}
public boolean canEncode(char c) {
if (c <= 0x7F) {
return false;
}
return super.canEncode(c);
}
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
char[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
byte[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
try {
while (sp < sl) {
char c = sa[sp];
if (c <= '\u007f')
return CoderResult.unmappableForLength(1);
int ncode = encodeDouble(c);
if (ncode != 0 && c != '\u0000' ) {
da[dp++] = (byte) ((ncode >> 8) & 0x7f);
da[dp++] = (byte) (ncode & 0x7f);
sp++;
continue;
}
return CoderResult.unmappableForLength(1);
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
public boolean isLegalReplacement(byte[] repl) {
return true;
}
}
private class Decoder extends EUC_CN_OLD.Decoder {
public Decoder(Charset cs) {
super(cs);
}
protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
byte[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
assert (sp <= sl);
sp = (sp <= sl ? sp : sl);
char[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
assert (dp <= dl);
dp = (dp <= dl ? dp : dl);
try {
while (sp < sl) {
if ( sl - sp < 2) {
return CoderResult.UNDERFLOW;
}
int b1 = sa[sp] & 0xFF | 0x80;
int b2 = sa[sp + 1] & 0xFF | 0x80;
char c = decodeDouble(b1, b2);
if (c == replacement().charAt(0)) {
return CoderResult.unmappableForLength(2);
}
if (dl - dp < 1)
return CoderResult.OVERFLOW;
da[dp++] = c;
sp +=2;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
}
}

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.ext.GBK;
public class X11GBK_OLD extends Charset {
public X11GBK_OLD () {
super("X11GBK-OLD", null);
}
public CharsetEncoder newEncoder() {
return new Encoder(this);
}
public CharsetDecoder newDecoder() {
return new GBK_OLD.Decoder(this);
}
public boolean contains(Charset cs) {
return cs instanceof X11GBK_OLD;
}
private class Encoder extends GBK_OLD.Encoder {
public Encoder(Charset cs) {
super(cs);
}
public boolean canEncode(char ch){
if (ch < 0x80) return false;
return super.canEncode(ch);
}
}
}

View File

@ -1,133 +0,0 @@
/*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import java.nio.charset.*;
import sun.nio.cs.ext.EUC_KR;
public class X11KSC5601_OLD extends Charset {
public X11KSC5601_OLD () {
super("X11KSC5601-OLD", null);
}
public CharsetEncoder newEncoder() {
return new Encoder(this);
}
public CharsetDecoder newDecoder() {
return new Decoder(this);
}
public boolean contains(Charset cs) {
return cs instanceof X11KSC5601_OLD;
}
private class Encoder extends EUC_KR_OLD.Encoder {
public Encoder(Charset cs) {
super(cs);
}
public boolean canEncode(char c) {
if (c <= 0x7F) {
return false;
}
return super.canEncode(c);
}
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
char[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
byte[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
try {
while (sp < sl) {
char c = sa[sp];
if (c <= '\u007f')
return CoderResult.unmappableForLength(1);
int ncode = encodeDouble(c);
if (ncode != 0 && c != '\u0000' ) {
da[dp++] = (byte) ((ncode >> 8) & 0x7f);
da[dp++] = (byte) (ncode & 0x7f);
sp++;
continue;
}
return CoderResult.unmappableForLength(1);
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
public boolean isLegalReplacement(byte[] repl) {
return true;
}
}
private class Decoder extends EUC_KR_OLD.Decoder {
public Decoder(Charset cs) {
super(cs);
}
protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
byte[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
assert (sp <= sl);
sp = (sp <= sl ? sp : sl);
char[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
assert (dp <= dl);
dp = (dp <= dl ? dp : dl);
try {
while (sp < sl) {
if ( sl - sp < 2) {
return CoderResult.UNDERFLOW;
}
int b1 = sa[sp] & 0xFF | 0x80;
int b2 = sa[sp + 1] & 0xFF | 0x80;
char c = decodeDouble(b1, b2);
if (c == replacement().charAt(0)) {
return CoderResult.unmappableForLength(2);
}
if (dl - dp < 1)
return CoderResult.OVERFLOW;
da[dp++] = c;
sp +=2;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
}
}

View File

@ -1,144 +0,0 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6831794
* @summary Test X11CNS charset
*/
import java.nio.charset.*;
import java.nio.*;
import java.util.*;
public class TestX11CNS {
static char[] decode(byte[] bb, Charset cs)
throws Exception {
CharsetDecoder dec = cs.newDecoder();
ByteBuffer bbf = ByteBuffer.wrap(bb);
CharBuffer cbf = CharBuffer.allocate(bb.length);
CoderResult cr = dec.decode(bbf, cbf, true);
if (cr != CoderResult.UNDERFLOW) {
System.out.println("DEC-----------------");
int pos = bbf.position();
System.out.printf(" cr=%s, bbf.pos=%d, bb[pos]=%x,%x,%x,%x%n",
cr.toString(), pos,
bb[pos++]&0xff, bb[pos++]&0xff,bb[pos++]&0xff, bb[pos++]&0xff);
throw new RuntimeException("Decoding err: " + cs.name());
}
char[] cc = new char[cbf.position()];
cbf.flip(); cbf.get(cc);
return cc;
}
static byte[] encode(char[] cc, Charset cs)
throws Exception {
ByteBuffer bbf = ByteBuffer.allocate(cc.length * 4);
CharBuffer cbf = CharBuffer.wrap(cc);
CharsetEncoder enc = cs.newEncoder();
CoderResult cr = enc.encode(cbf, bbf, true);
if (cr != CoderResult.UNDERFLOW) {
System.out.println("ENC-----------------");
int pos = cbf.position();
System.out.printf(" cr=%s, cbf.pos=%d, cc[pos]=%x%n",
cr.toString(), pos, cc[pos]&0xffff);
throw new RuntimeException("Encoding err: " + cs.name());
}
byte[] bb = new byte[bbf.position()];
bbf.flip(); bbf.get(bb);
return bb;
}
static char[] getChars(Charset newCS, Charset oldCS) {
CharsetEncoder enc = oldCS.newEncoder();
CharsetEncoder encNew = newCS.newEncoder();
char[] cc = new char[0x10000];
int pos = 0;
int i = 0;
while (i < 0x10000) {
if (i == 0x4ea0 || i == 0x51ab || i == 0x52f9) {
i++;continue;
}
if (enc.canEncode((char)i) != encNew.canEncode((char)i)) {
System.out.printf(" Err i=%x%n", i);
//throw new RuntimeException("canEncode() err!");
}
if (enc.canEncode((char)i)) {
cc[pos++] = (char)i;
}
i++;
}
return Arrays.copyOf(cc, pos);
}
static void compare(Charset newCS, Charset oldCS) throws Exception {
if (newCS == null)
return; // does not exist on this platform
char[] cc = getChars(newCS, oldCS);
System.out.printf(" Diff <%s> <%s>...%n", newCS.name(), oldCS.name());
byte[] bb1 = encode(cc, newCS);
byte[] bb2 = encode(cc, oldCS);
if (!Arrays.equals(bb1, bb2)) {
System.out.printf(" encoding failed!%n");
}
char[] cc1 = decode(bb1, newCS);
char[] cc2 = decode(bb1, oldCS);
if (!Arrays.equals(cc1, cc2)) {
for (int i = 0; i < cc1.length; i++) {
if (cc1[i] != cc2[i]) {
System.out.printf("i=%d, cc1=%x cc2=%x, bb=<%x%x>%n",
i,
cc1[i]&0xffff, cc2[i]&0xffff,
bb1[i*2]&0xff, bb1[i*2+1]&0xff);
}
}
System.out.printf(" decoding failed%n");
}
}
private static Charset getCharset(String czName)
throws Exception {
try {
return (Charset)Class.forName(czName).newInstance();
} catch (ClassNotFoundException e){}
return null; // does not exist
}
public static void main(String[] args) throws Exception {
compare(getCharset("sun.awt.motif.X11CNS11643P1"),
new X11CNS11643P1());
compare(getCharset("sun.awt.motif.X11CNS11643P2"),
new X11CNS11643P2());
compare(getCharset("sun.awt.motif.X11CNS11643P3"),
new X11CNS11643P3());
}
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4195325
* @summary name() should return "X11JIS0201"
*
*/
import java.nio.charset.*;
public class TestX11JIS0201 {
public static void main(String args[])
throws Exception
{
test();
}
private static void test()
throws Exception
{
Class cl = null;
try {
cl = Class.forName("sun.awt.motif.X11JIS0201");
} catch (Exception e){
return;
}
Charset cs = (Charset)cl.newInstance();
if (! cs.name().equals("X11JIS0201")){
throw new Exception("X11JIS0201 does not work correctly");
}
CharsetEncoder enc = cs.newEncoder();
char[] cc = new char[0xffff];
for (char c = 0; c < 0xffff; c++) {
cc[c] = c;
if (enc.canEncode(c) !=
((c >= 0xff61 && c <= 0xff9f) || c == 0x203e || c == 0xa5)) {
throw new RuntimeException("x11jis0201 canEncod() failed!");
}
}
String s = new String(cc);
byte[] bb_x11 = s.getBytes(cs);
byte[] bb = s.getBytes("jis0201");
if (!java.util.Arrays.equals(bb, bb_x11)) {
throw new RuntimeException("x11jis0201 encoding failed");
}
}
}

View File

@ -1,188 +0,0 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import java.nio.charset.*;
import sun.nio.cs.*;
import sun.nio.cs.ext.*;
public abstract class X11CNS11643 extends Charset {
private final int plane;
public X11CNS11643 (int plane, String name) {
super(name, null);
switch (plane) {
case 1:
this.plane = 0; // CS1
break;
case 2:
case 3:
this.plane = plane;
break;
default:
throw new IllegalArgumentException
("Only planes 1, 2, and 3 supported");
}
}
public CharsetEncoder newEncoder() {
return new Encoder(this, plane);
}
public CharsetDecoder newDecoder() {
return new Decoder(this, plane);
}
public boolean contains(Charset cs) {
return cs instanceof X11CNS11643;
}
private class Encoder extends EUC_TW_OLD.Encoder {
private int plane;
public Encoder(Charset cs, int plane) {
super(cs);
this.plane = plane;
}
public boolean canEncode(char c) {
if (c <= 0x7F) {
return false;
}
int p = getNative(c) >> 16;
if (p == 1 && plane == 0 ||
p == 2 && plane == 2 ||
p == 3 && plane == 3)
return true;
return false;
}
public boolean isLegalReplacement(byte[] repl) {
return true;
}
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
char[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
byte[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
try {
while (sp < sl) {
char c = sa[sp];
if (c >= '\uFFFE' || c <= '\u007f')
return CoderResult.unmappableForLength(1);
int cns = getNative(c);
int p = cns >> 16;
if (p == 1 && plane == 0 ||
p == 2 && plane == 2 ||
p == 3 && plane == 3) {
if (dl - dp < 2)
return CoderResult.OVERFLOW;
da[dp++] = (byte) ((cns >> 8) & 0x7f);
da[dp++] = (byte) (cns & 0x7f);
sp++;
continue;
}
return CoderResult.unmappableForLength(1);
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
}
private class Decoder extends EUC_TW_OLD.Decoder {
private String table;
protected Decoder(Charset cs, int plane) {
super(cs);
switch (plane) {
case 0:
table = unicodeCNS1;
break;
case 2:
table = unicodeCNS2;
break;
case 3:
table = unicodeCNS3;
break;
default:
throw new IllegalArgumentException
("Only planes 1, 2, and 3 supported");
}
}
//we only work on array backed buffer.
protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
byte[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
assert (sp <= sl);
sp = (sp <= sl ? sp : sl);
char[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
assert (dp <= dl);
dp = (dp <= dl ? dp : dl);
try {
while (sp < sl) {
if ( sl - sp < 2) {
return CoderResult.UNDERFLOW;
}
byte b1 = sa[sp];
byte b2 = sa[sp + 1];
char c = replacement().charAt(0);
if (table == unicodeCNS3) {
char[] cc = convToSurrogate((byte)(b1 | 0x80),
(byte)(b2 | 0x80),
table);
if (cc != null && cc[0] == '\u0000')
c = cc[1];
} else {
c = convToUnicode((byte)(b1 | 0x80),
(byte)(b2 | 0x80),
table);
}
if (c == replacement().charAt(0)
//to keep the compatibility with b2cX11CNS11643
/*|| c == '\u0000'*/) {
return CoderResult.unmappableForLength(2);
}
if (dl - dp < 1)
return CoderResult.OVERFLOW;
da[dp++] = c;
sp +=2;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class X11CNS11643P1 extends X11CNS11643 {
public X11CNS11643P1() {
super(1, "X11CNS11643P1");
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class X11CNS11643P2 extends X11CNS11643 {
public X11CNS11643P2() {
super(2, "X11CNS11643P2");
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class X11CNS11643P3 extends X11CNS11643 {
public X11CNS11643P3() {
super(3, "X11CNS11643P3");
}
}