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 */ 25 package sun.io; 26 27 public 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 } | 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 */ 25 package sun.io; 26 27 import sun.nio.cs.Surrogate; 28 import sun.nio.cs.ext.DoubleByte; 29 import static sun.nio.cs.CharsetMapping.*; 30 31 public abstract class CharToByteDBCS_ASCII extends CharToByteConverter 32 { 33 34 private char highHalfZoneCode; 35 private byte[] outputByte = new byte[2]; 36 37 private DoubleByte.Encoder enc; 38 39 public CharToByteDBCS_ASCII(DoubleByte.Encoder enc) { 40 super(); 41 this.enc = enc; 42 } 43 44 int encodeChar(char c) { 45 return enc.encodeChar(c); 46 } 47 48 /** 49 * flush out any residual data and reset the buffer state 50 */ 51 public int flush(byte [] output, int outStart, int outEnd) 52 throws MalformedInputException, ConversionBufferFullException 53 { 54 55 if (highHalfZoneCode != 0) { 56 reset(); 57 badInputLength = 0; 58 throw new MalformedInputException(); 59 } 60 61 reset(); 62 return 0; 63 } 64 65 /** 66 * Character conversion 67 */ 68 public int convert(char[] input, int inOff, int inEnd, 69 byte[] output, int outOff, int outEnd) 70 throws UnknownCharacterException, MalformedInputException, 71 ConversionBufferFullException 72 { 73 char inputChar; 74 int inputSize; 75 76 byteOff = outOff; 77 charOff = inOff; 78 79 while(charOff < inEnd) { 80 int index; 81 int theBytes; 82 int spaceNeeded; 83 84 if (highHalfZoneCode == 0) { 85 inputChar = input[charOff]; 86 inputSize = 1; 87 } else { 88 inputChar = highHalfZoneCode; 89 inputSize = 0; 90 highHalfZoneCode = 0; 91 } 92 93 // Is this a high surrogate? 94 if (Surrogate.isHigh(inputChar)) { 95 // Is this the last character of the input? 96 if (charOff + inputSize >= inEnd) { 97 highHalfZoneCode = inputChar; 98 charOff += inputSize; 99 break; 100 } 101 102 // Is there a low surrogate following? 103 inputChar = input[charOff + inputSize]; 104 if (Surrogate.isLow(inputChar)) { 105 // We have a valid surrogate pair. Too bad we don't do 106 // surrogates. Is substitution enabled? 107 if (subMode) { 108 if (subBytes.length == 1) { 109 outputByte[0] = 0x00; 110 outputByte[1] = subBytes[0]; 111 } 112 else { 113 outputByte[0] = subBytes[0]; 114 outputByte[1] = subBytes[1]; 115 } 116 inputSize++; 117 } else { 118 badInputLength = 2; 119 throw new UnknownCharacterException(); 120 } 121 } else { 122 // We have a malformed surrogate pair 123 badInputLength = 1; 124 throw new MalformedInputException(); 125 } 126 } 127 // Is this an unaccompanied low surrogate? 128 else if (Surrogate.isLow(inputChar)) { 129 badInputLength = 1; 130 throw new MalformedInputException(); 131 } else { 132 133 // We have a valid character, get the bytes for it 134 theBytes = encodeChar(inputChar); 135 if (theBytes == UNMAPPABLE_ENCODING) { 136 // if there was no mapping - look for substitution characters 137 if (subMode) { 138 if (subBytes.length == 1) { 139 outputByte[0] = 0x00; 140 outputByte[1] = subBytes[0]; 141 } else { 142 outputByte[0] = subBytes[0]; 143 outputByte[1] = subBytes[1]; 144 } 145 } else { 146 badInputLength = 1; 147 throw new UnknownCharacterException(); 148 } 149 } else { 150 outputByte[0] = (byte)(theBytes >>8); 151 outputByte[1] = (byte)theBytes; 152 } 153 } 154 if (outputByte[0] == 0x00) 155 spaceNeeded = 1; 156 else 157 spaceNeeded = 2; 158 159 if (byteOff + spaceNeeded > outEnd) 160 throw new ConversionBufferFullException(); 161 162 if (spaceNeeded == 1) 163 output[byteOff++] = outputByte[1]; 164 else { 165 output[byteOff++] = outputByte[0]; 166 output[byteOff++] = outputByte[1]; 167 } 168 169 charOff += inputSize; 170 } 171 return byteOff - outOff; 172 } 173 174 /** 175 * Resets converter to its initial state. 176 */ 177 public void reset() { 178 charOff = byteOff = 0; 179 highHalfZoneCode = 0; 180 } 181 182 /** 183 * Returns the maximum number of bytes needed to convert a char. 184 */ 185 public int getMaxBytesPerChar() { 186 return 2; 187 } 188 189 /** 190 * Returns true if the given character can be converted to the 191 * target character encoding. 192 */ 193 public boolean canConvert(char c) { 194 return encodeChar(c) != UNMAPPABLE_ENCODING; 195 } 196 } |