1 /* 2 * Copyright 2000-2004 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 */ 25 26 package sun.nio.cs; 27 28 import java.nio.ByteBuffer; 29 import java.nio.CharBuffer; 30 import java.nio.charset.Charset; 31 import java.nio.charset.CharsetDecoder; 32 import java.nio.charset.CharsetEncoder; 33 import java.nio.charset.CoderResult; 34 import java.nio.charset.CharacterCodingException; 35 import java.nio.charset.MalformedInputException; 36 import java.nio.charset.UnmappableCharacterException; 37 38 39 public class US_ASCII 40 extends Charset 41 implements HistoricallyNamedCharset 42 { 43 44 public US_ASCII() { 45 super("US-ASCII", StandardCharsets.aliases_US_ASCII); 46 } 47 48 public String historicalName() { 49 return "ASCII"; 50 } 51 52 public boolean contains(Charset cs) { 53 return (cs instanceof US_ASCII); 54 } 55 56 public CharsetDecoder newDecoder() { 57 return new Decoder(this); 58 } 59 60 public CharsetEncoder newEncoder() { 61 return new Encoder(this); 62 } 63 64 private static class Decoder extends CharsetDecoder { 65 66 private Decoder(Charset cs) { 67 super(cs, 1.0f, 1.0f); 68 } 69 70 private CoderResult decodeArrayLoop(ByteBuffer src, 71 CharBuffer dst) 72 { 73 byte[] sa = src.array(); 74 int sp = src.arrayOffset() + src.position(); 75 int sl = src.arrayOffset() + src.limit(); 76 assert (sp <= sl); 77 sp = (sp <= sl ? sp : sl); 78 char[] da = dst.array(); 79 int dp = dst.arrayOffset() + dst.position(); 80 int dl = dst.arrayOffset() + dst.limit(); 81 assert (dp <= dl); 82 dp = (dp <= dl ? dp : dl); 83 84 try { 85 while (sp < sl) { 86 byte b = sa[sp]; 87 if (b >= 0) { 88 if (dp >= dl) 89 return CoderResult.OVERFLOW; 90 da[dp++] = (char)b; 91 sp++; 92 continue; 93 } 94 return CoderResult.malformedForLength(1); 95 } 96 return CoderResult.UNDERFLOW; 97 } finally { 98 src.position(sp - src.arrayOffset()); 99 dst.position(dp - dst.arrayOffset()); 100 } 101 } 102 103 private CoderResult decodeBufferLoop(ByteBuffer src, 104 CharBuffer dst) 105 { 106 int mark = src.position(); 107 try { 108 while (src.hasRemaining()) { 109 byte b = src.get(); 110 if (b >= 0) { 111 if (!dst.hasRemaining()) 112 return CoderResult.OVERFLOW; 113 dst.put((char)b); 114 mark++; 115 continue; 116 } 117 return CoderResult.malformedForLength(1); 118 } 119 return CoderResult.UNDERFLOW; 120 } finally { 121 src.position(mark); 122 } 123 } 124 125 protected CoderResult decodeLoop(ByteBuffer src, 126 CharBuffer dst) 127 { 128 if (src.hasArray() && dst.hasArray()) 129 return decodeArrayLoop(src, dst); 130 else 131 return decodeBufferLoop(src, dst); 132 } 133 134 } 135 136 private static class Encoder extends CharsetEncoder { 137 138 private Encoder(Charset cs) { 139 super(cs, 1.0f, 1.0f); 140 } 141 142 public boolean canEncode(char c) { 143 return c < 0x80; 144 } 145 146 private final Surrogate.Parser sgp = new Surrogate.Parser(); 147 148 private CoderResult encodeArrayLoop(CharBuffer src, 149 ByteBuffer dst) 150 { 151 char[] sa = src.array(); 152 int sp = src.arrayOffset() + src.position(); 153 int sl = src.arrayOffset() + src.limit(); 154 assert (sp <= sl); 155 sp = (sp <= sl ? sp : sl); 156 byte[] da = dst.array(); 157 int dp = dst.arrayOffset() + dst.position(); 158 int dl = dst.arrayOffset() + dst.limit(); 159 assert (dp <= dl); 160 dp = (dp <= dl ? dp : dl); 161 162 try { 163 while (sp < sl) { 164 char c = sa[sp]; 165 if (c < 0x80) { 166 if (dp >= dl) 167 return CoderResult.OVERFLOW; 168 da[dp] = (byte)c; 169 sp++; dp++; 170 continue; 171 } 172 if (sgp.parse(c, sa, sp, sl) < 0) 173 return sgp.error(); 174 return sgp.unmappableResult(); 175 } 176 return CoderResult.UNDERFLOW; 177 } finally { 178 src.position(sp - src.arrayOffset()); 179 dst.position(dp - dst.arrayOffset()); 180 } 181 } 182 183 private CoderResult encodeBufferLoop(CharBuffer src, 184 ByteBuffer dst) 185 { 186 int mark = src.position(); 187 try { 188 while (src.hasRemaining()) { 189 char c = src.get(); 190 if (c < 0x80) { 191 if (!dst.hasRemaining()) 192 return CoderResult.OVERFLOW; 193 dst.put((byte)c); 194 mark++; 195 continue; 196 } 197 if (sgp.parse(c, src) < 0) 198 return sgp.error(); 199 return sgp.unmappableResult(); 200 } 201 return CoderResult.UNDERFLOW; 202 } finally { 203 src.position(mark); 204 } 205 } 206 207 protected CoderResult encodeLoop(CharBuffer src, 208 ByteBuffer dst) 209 { 210 if (src.hasArray() && dst.hasArray()) 211 return encodeArrayLoop(src, dst); 212 else 213 return encodeBufferLoop(src, dst); 214 } 215 216 } 217 218 }