001: /*
002: * @(#)CharToByteASCII.java 1.16 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.io;
029:
030: public class CharToByteASCII extends CharToByteConverter {
031:
032: // Return the character set ID
033: public String getCharacterEncoding() {
034: return "ASCII";
035: }
036:
037: private char highHalfZoneCode;
038:
039: public int flush(byte[] output, int outStart, int outEnd)
040: throws MalformedInputException {
041: if (highHalfZoneCode != 0) {
042: highHalfZoneCode = 0;
043: throw new MalformedInputException(
044: "String ends with <High Half Zone code> of UTF16");
045: }
046: byteOff = charOff = 0;
047: return 0;
048: }
049:
050: /*
051: * Character conversion
052: */
053: public int convert(char[] input, int inOff, int inEnd,
054: byte[] output, int outOff, int outEnd)
055: throws MalformedInputException, UnknownCharacterException,
056: ConversionBufferFullException {
057: char inputChar; // Input character to be converted
058: int outputSize; // Size of output
059:
060: // Record beginning offsets
061: charOff = inOff;
062: byteOff = outOff;
063:
064: if (highHalfZoneCode != 0) {
065: inputChar = highHalfZoneCode;
066: highHalfZoneCode = 0;
067: if (input[inOff] >= 0xdc00 && input[inOff] <= 0xdfff) {
068: // This is legal UTF16 sequence.
069: badInputLength = 1;
070: throw new UnknownCharacterException();
071: } else {
072: // This is illegal UTF16 sequence.
073: badInputLength = 0;
074: throw new MalformedInputException(
075: "Previous converted string ends with "
076: + "<High Half Zone Code> of UTF16 "
077: + ", but this string is not begin with <Low Half Zone>");
078: }
079: }
080:
081: // Loop until we hit the end of the input
082: while (charOff < inEnd) {
083: // Get the input character
084: inputChar = input[charOff];
085:
086: // Is this character mappable?
087: if (inputChar <= '\u007F') {
088: if (byteOff + 1 > outEnd)
089: throw new ConversionBufferFullException();
090:
091: output[byteOff++] = (byte) inputChar;
092: charOff += 1;
093:
094: }
095: // Is this a high surrogate?
096: else if (inputChar >= '\uD800' && inputChar <= '\uDBFF') {
097: // Is this the last character in the input?
098: if (charOff + 1 == inEnd) {
099: highHalfZoneCode = inputChar;
100: break;
101: }
102:
103: // Is there a low surrogate following?
104: inputChar = input[charOff + 1];
105: if (inputChar >= '\uDC00' && inputChar <= '\uDFFF') {
106: // We have a valid surrogate pair. Too bad we don't map
107: // surrogates. Is substitution enabled?
108: if (subMode) {
109: outputSize = subBytes.length;
110:
111: if (byteOff + outputSize > outEnd)
112: throw new ConversionBufferFullException();
113:
114: System.arraycopy(subBytes, 0, output, byteOff,
115: outputSize);
116: byteOff += outputSize;
117: charOff += 2;
118:
119: } else {
120: badInputLength = 2;
121: throw new UnknownCharacterException();
122: }
123: } else {
124: // We have a malformed surrogate pair
125: badInputLength = 1;
126: throw new MalformedInputException();
127: }
128: }
129: // Is this an unaccompanied low surrogate?
130: else if (inputChar >= '\uDC00' && inputChar <= '\uDFFF') {
131: badInputLength = 1;
132: throw new MalformedInputException();
133: }
134: // Unmappable and not part of a surrogate
135: else {
136: // Is substitution enabled?
137: if (subMode) {
138: outputSize = subBytes.length;
139:
140: if (byteOff + outputSize > outEnd)
141: throw new ConversionBufferFullException();
142:
143: System.arraycopy(subBytes, 0, output, byteOff,
144: outputSize);
145: byteOff += outputSize;
146: charOff += 1;
147:
148: } else {
149: badInputLength = 1;
150: throw new UnknownCharacterException();
151: }
152: }
153:
154: }
155:
156: // Return the length written to the output buffer
157: return byteOff - outOff;
158: }
159:
160: // Determine if a character is mappable or not
161: public boolean canConvert(char ch) {
162: return (ch <= '\u007F');
163: }
164:
165: // Reset the converter
166: public void reset() {
167: byteOff = charOff = 0;
168: highHalfZoneCode = 0;
169: }
170:
171: /**
172: * returns the maximum number of bytes needed to convert a char
173: */
174: public int getMaxBytesPerChar() {
175: return 1;
176: }
177: }
|