blob: e58267bb3f55770bb9cb8b0d39dd74b6094d071a [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package sun.io;
26
27public abstract class CharToByteDBCS_ASCII extends CharToByteConverter
28{
29
30 private char highHalfZoneCode;
31 private byte[] outputByte = new byte[2];
32
33 protected short index1[];
34 protected String index2;
35 protected String index2a;
36 protected int mask1;
37 protected int mask2;
38 protected int shift;
39
40 /**
41 * flush out any residual data and reset the buffer state
42 */
43 public int flush(byte [] output, int outStart, int outEnd)
44 throws MalformedInputException, ConversionBufferFullException
45 {
46
47 if (highHalfZoneCode != 0) {
48 reset();
49 badInputLength = 0;
50 throw new MalformedInputException();
51 }
52
53 reset();
54 return 0;
55 }
56
57 /**
58 * Character conversion
59 */
60 public int convert(char[] input, int inOff, int inEnd,
61 byte[] output, int outOff, int outEnd)
62 throws UnknownCharacterException, MalformedInputException,
63 ConversionBufferFullException
64 {
65 char inputChar;
66 int inputSize;
67
68 byteOff = outOff;
69 charOff = inOff;
70
71 while(charOff < inEnd) {
72
73 int index;
74 int theBytes;
75 int spaceNeeded;
76
77 if (highHalfZoneCode == 0) {
78 inputChar = input[charOff];
79 inputSize = 1;
80 } else {
81 inputChar = highHalfZoneCode;
82 inputSize = 0;
83 highHalfZoneCode = 0;
84 }
85
86
87 // Is this a high surrogate?
88 if(inputChar >= '\ud800' && inputChar <= '\udbff') {
89 // Is this the last character of the input?
90 if (charOff + inputSize >= inEnd) {
91 highHalfZoneCode = inputChar;
92 charOff += inputSize;
93 break;
94 }
95
96 // Is there a low surrogate following?
97 inputChar = input[charOff + inputSize];
98 if (inputChar >= '\udc00' && inputChar <= '\udfff') {
99
100 // We have a valid surrogate pair. Too bad we don't do
101 // surrogates. Is substitution enabled?
102 if (subMode) {
103 if (subBytes.length == 1) {
104 outputByte[0] = 0x00;
105 outputByte[1] = subBytes[0];
106 }
107 else {
108 outputByte[0] = subBytes[0];
109 outputByte[1] = subBytes[1];
110 }
111
112 inputSize++;
113 } else {
114 badInputLength = 2;
115 throw new UnknownCharacterException();
116 }
117 } else {
118
119 // We have a malformed surrogate pair
120 badInputLength = 1;
121 throw new MalformedInputException();
122 }
123 }
124
125 // Is this an unaccompanied low surrogate?
126 else
127 if (inputChar >= '\uDC00' && inputChar <= '\uDFFF') {
128 badInputLength = 1;
129 throw new MalformedInputException();
130 } else {
131
132 // We have a valid character, get the bytes for it
133 index = index1[((inputChar & mask1) >> shift)] + (inputChar & mask2);
134 if (index < 15000)
135 theBytes = (int)(index2.charAt(index));
136 else
137 theBytes = (int)(index2a.charAt(index-15000));
138 outputByte[0] = (byte)((theBytes & 0x0000ff00)>>8);
139 outputByte[1] = (byte)(theBytes & 0x000000ff);
140 }
141
142 // if there was no mapping - look for substitution characters
143 if (outputByte[0] == 0x00 && outputByte[1] == 0x00
144 && inputChar != '\u0000')
145 {
146 if (subMode) {
147 if (subBytes.length == 1) {
148 outputByte[0] = 0x00;
149 outputByte[1] = subBytes[0];
150 } else {
151 outputByte[0] = subBytes[0];
152 outputByte[1] = subBytes[1];
153 }
154 } else {
155 badInputLength = 1;
156 throw new UnknownCharacterException();
157 }
158 }
159
160 if (outputByte[0] == 0x00)
161 spaceNeeded = 1;
162 else
163 spaceNeeded = 2;
164
165 if (byteOff + spaceNeeded > outEnd)
166 throw new ConversionBufferFullException();
167
168 if (spaceNeeded == 1)
169 output[byteOff++] = outputByte[1];
170 else {
171 output[byteOff++] = outputByte[0];
172 output[byteOff++] = outputByte[1];
173 }
174
175 charOff += inputSize;
176 }
177
178 return byteOff - outOff;
179 }
180
181 /**
182 * Resets converter to its initial state.
183 */
184 public void reset() {
185 charOff = byteOff = 0;
186 highHalfZoneCode = 0;
187 }
188
189 /**
190 * Returns the maximum number of bytes needed to convert a char.
191 */
192 public int getMaxBytesPerChar() {
193 return 2;
194 }
195
196
197 /**
198 * Returns true if the given character can be converted to the
199 * target character encoding.
200 */
201 public boolean canConvert(char ch) {
202 int index;
203 int theBytes;
204
205 index = index1[((ch & mask1) >> shift)] + (ch & mask2);
206 if (index < 15000)
207 theBytes = (int)(index2.charAt(index));
208 else
209 theBytes = (int)(index2a.charAt(index-15000));
210
211 if (theBytes != 0)
212 return (true);
213
214 // only return true if input char was unicode null - all others are
215 // undefined
216 return( ch == '\u0000');
217
218 }
219
220}