--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/io/CharToByteEUC.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,256 @@
+/*
+ * Copyright 1997 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.io;
+
+public abstract class CharToByteEUC extends CharToByteConverter
+{
+
+ private char highHalfZoneCode;
+ private byte[] outputByte;
+
+ protected short index1[];
+ protected String index2;
+ protected String index2a;
+ protected String index2b;
+ protected String index2c;
+ protected int mask1;
+ protected int mask2;
+ protected int shift;
+
+ private byte[] workByte = new byte[4];
+
+ /**
+ * flush out any residual data and reset the buffer state
+ */
+ public int flush(byte [] output, int outStart, int outEnd)
+ throws MalformedInputException, ConversionBufferFullException
+ {
+
+ if (highHalfZoneCode != 0) {
+ reset();
+ badInputLength = 0;
+ throw new MalformedInputException();
+ }
+
+ reset();
+ return 0;
+ }
+
+ /**
+ * Character conversion
+ */
+ public int convert(char[] input, int inOff, int inEnd,
+ byte[] output, int outOff, int outEnd)
+ throws UnknownCharacterException, MalformedInputException,
+ ConversionBufferFullException
+ {
+ char inputChar;
+ int inputSize;
+
+ byteOff = outOff;
+ charOff = inOff;
+
+ while(charOff < inEnd) {
+
+ outputByte = workByte;
+
+ int index;
+ int theBytes;
+ int spaceNeeded;
+ boolean allZeroes = true;
+ int i;
+
+
+ if (highHalfZoneCode == 0) {
+ inputChar = input[charOff];
+ inputSize = 1;
+ } else {
+ inputChar = highHalfZoneCode;
+ inputSize = 0;
+ highHalfZoneCode = 0;
+ }
+
+
+ // Is this a high surrogate?
+ if(inputChar >= '\ud800' && inputChar <= '\udbff') {
+ // Is this the last character of the input?
+ if (charOff + inputSize >= inEnd) {
+ highHalfZoneCode = inputChar;
+ charOff += inputSize;
+ break;
+ }
+
+ // Is there a low surrogate following?
+ inputChar = input[charOff + inputSize];
+ if (inputChar >= '\udc00' && inputChar <= '\udfff') {
+
+ // We have a valid surrogate pair. Too bad we don't do
+ // surrogates. Is substitution enabled?
+ if (subMode) {
+ outputByte = subBytes;
+ inputSize++;
+ } else {
+ badInputLength = 2;
+ throw new UnknownCharacterException();
+ }
+ } else {
+
+ // We have a malformed surrogate pair
+ badInputLength = 1;
+ throw new MalformedInputException();
+ }
+ }
+
+ // Is this an unaccompanied low surrogate?
+ else
+ if (inputChar >= '\uDC00' && inputChar <= '\uDFFF') {
+ badInputLength = 1;
+ throw new MalformedInputException();
+ } else {
+
+ String theChars;
+ char aChar;
+
+ // We have a valid character, get the bytes for it
+ index = index1[((inputChar & mask1) >> shift)] + (inputChar & mask2);
+
+ if (index < 7500)
+ theChars = index2;
+ else
+ if (index < 15000) {
+ index = index - 7500;
+ theChars = index2a;
+ }
+ else
+ if (index < 22500){
+ index = index - 15000;
+ theChars = index2b;
+ }
+ else {
+ index = index - 22500;
+ theChars = index2c;
+ }
+
+ aChar = theChars.charAt(2*index);
+ outputByte[0] = (byte)((aChar & 0xff00)>>8);
+ outputByte[1] = (byte)(aChar & 0x00ff);
+ aChar = theChars.charAt(2*index + 1);
+ outputByte[2] = (byte)((aChar & 0xff00)>>8);
+ outputByte[3] = (byte)(aChar & 0x00ff);
+ }
+
+ // if there was no mapping - look for substitution characters
+
+ for (i = 0; i < outputByte.length; i++) {
+ if (outputByte[i] != 0x00) {
+ allZeroes = false;
+ break;
+ }
+ }
+
+ if (allZeroes && inputChar != '\u0000')
+ {
+ if (subMode) {
+ outputByte = subBytes;
+ } else {
+ badInputLength = 1;
+ throw new UnknownCharacterException();
+ }
+ }
+
+ int oindex = 0;
+ for (spaceNeeded = outputByte.length; spaceNeeded > 1; spaceNeeded--){
+ if (outputByte[oindex++] != 0x00 )
+ break;
+ }
+
+ if (byteOff + spaceNeeded > outEnd)
+ throw new ConversionBufferFullException();
+
+
+ for (i = outputByte.length - spaceNeeded; i < outputByte.length; i++) {
+ output[byteOff++] = outputByte[i];
+ }
+
+ charOff += inputSize;
+ }
+
+ return byteOff - outOff;
+ }
+
+ /**
+ * Resets converter to its initial state.
+ */
+ public void reset() {
+ charOff = byteOff = 0;
+ highHalfZoneCode = 0;
+ }
+
+ /**
+ * Returns the maximum number of bytes needed to convert a char.
+ */
+ public int getMaxBytesPerChar() {
+ return 2;
+ }
+
+
+ /**
+ * Returns true if the given character can be converted to the
+ * target character encoding.
+ */
+ public boolean canConvert(char ch) {
+ int index;
+ String theChars;
+
+ index = index1[((ch & mask1) >> shift)] + (ch & mask2);
+
+ if (index < 7500)
+ theChars = index2;
+ else
+ if (index < 15000) {
+ index = index - 7500;
+ theChars = index2a;
+ }
+ else
+ if (index < 22500){
+ index = index - 15000;
+ theChars = index2b;
+ }
+ else {
+ index = index - 22500;
+ theChars = index2c;
+ }
+
+ if (theChars.charAt(2*index) != '\u0000' ||
+ theChars.charAt(2*index + 1) != '\u0000')
+ return (true);
+
+ // only return true if input char was unicode null - all others are
+ // undefined
+ return( ch == '\u0000');
+
+ }
+
+}