1 /* 2 * Copyright (c) 2000, 2017, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * 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 35 public class US_ASCII 36 extends Charset 37 implements HistoricallyNamedCharset 38 { 39 public static final US_ASCII INSTANCE = new US_ASCII(); 40 41 public US_ASCII() { 42 super("US-ASCII", StandardCharsets.aliases_US_ASCII()); 43 } 44 45 public String historicalName() { 46 return "ASCII"; 47 } 48 49 public boolean contains(Charset cs) { 50 return (cs instanceof US_ASCII); 51 } 52 53 public CharsetDecoder newDecoder() { 54 return new Decoder(this); 55 } 56 57 public CharsetEncoder newEncoder() { 58 return new Encoder(this); 59 } 60 61 private static class Decoder extends CharsetDecoder { 62 63 private Decoder(Charset cs) { 64 super(cs, 1.0f, 1.0f); 65 } 66 67 private CoderResult decodeArrayLoop(ByteBuffer src, 68 CharBuffer dst) 69 { 70 byte[] sa = src.array(); 71 int sp = src.arrayOffset() + src.position(); 72 int sl = src.arrayOffset() + src.limit(); 73 assert (sp <= sl); 74 sp = (sp <= sl ? sp : sl); 75 char[] da = dst.array(); 76 int dp = dst.arrayOffset() + dst.position(); 77 int dl = dst.arrayOffset() + dst.limit(); 78 assert (dp <= dl); 79 dp = (dp <= dl ? dp : dl); 80 81 try { 82 83 if((dl-dp) >= (sl-sp)) { 84 85 int n = decodeASCII(sa, sp, sl-sp, da, dp); 86 sp = sp + n; 87 dp = dp + n; 88 if (sp<sl) 89 return CoderResult.malformedForLength(1); 90 return CoderResult.UNDERFLOW; 91 } 92 else { 93 int n = decodeASCII(sa, sp, dl-dp, da, dp); 94 sp = sp + n; 95 dp = dp + n; 96 if (dp<dl) 97 return CoderResult.malformedForLength(1); 98 return CoderResult.OVERFLOW; 99 } 100 } finally { 101 src.position(sp - src.arrayOffset()); 102 dst.position(dp - dst.arrayOffset()); 103 } 104 } 105 106 private CoderResult decodeBufferLoop(ByteBuffer src, 107 CharBuffer dst) 108 { 109 int mark = src.position(); 110 try { 111 while (src.hasRemaining()) { 112 byte b = src.get(); 113 if (b >= 0) { 114 if (!dst.hasRemaining()) 115 return CoderResult.OVERFLOW; 116 dst.put((char)b); 117 mark++; 118 continue; 119 } 120 return CoderResult.malformedForLength(1); 121 } 122 return CoderResult.UNDERFLOW; 123 } finally { 124 src.position(mark); 125 } 126 } 127 128 protected CoderResult decodeLoop(ByteBuffer src, 129 CharBuffer dst) 130 { 131 if (src.hasArray() && dst.hasArray()) 132 return decodeArrayLoop(src, dst); 133 else 134 return decodeBufferLoop(src, dst); 135 } 136 137 public final int decodeASCII(byte[] src, int sp, int len, char[] dst, int dp) { 138 int n = 0; 139 while (n < len) 140 { 141 byte b = src[sp++]; 142 143 if (b >= 0){ 144 145 dst[dp++] = (char)b; 146 n++; 147 continue; 148 } 149 break; 150 151 } 152 153 return n; 154 } 155 } 156 157 private static class Encoder extends CharsetEncoder { 158 159 private Encoder(Charset cs) { 160 super(cs, 1.0f, 1.0f); 161 } 162 163 public boolean canEncode(char c) { 164 return c < 0x80; 165 } 166 167 public boolean isLegalReplacement(byte[] repl) { 168 return (repl.length == 1 && repl[0] >= 0) || 169 super.isLegalReplacement(repl); 170 } 171 172 private final Surrogate.Parser sgp = new Surrogate.Parser(); 173 private CoderResult encodeArrayLoop(CharBuffer src, 174 ByteBuffer dst) 175 { 176 char[] sa = src.array(); 177 int sp = src.arrayOffset() + src.position(); 178 int sl = src.arrayOffset() + src.limit(); 179 assert (sp <= sl); 180 sp = (sp <= sl ? sp : sl); 181 byte[] da = dst.array(); 182 int dp = dst.arrayOffset() + dst.position(); 183 int dl = dst.arrayOffset() + dst.limit(); 184 assert (dp <= dl); 185 dp = (dp <= dl ? dp : dl); 186 187 try { 188 if((dl-dp) >= (sl-sp)) { 189 190 int n = encodeASCII(sa,sp,sl-sp,da,dp); 191 sp = sp+n; 192 dp = dp+n; 193 194 if (sp<sl) 195 { 196 char c = sa[sp]; 197 if (sgp.parse(c, sa, sp, sl) < 0) { 198 return sgp.error(); 199 } 200 else return sgp.unmappableResult(); 201 } 202 203 return CoderResult.UNDERFLOW; 204 } 205 else { 206 int n = encodeASCII(sa,sp,dl-dp,da,dp); 207 sp = sp+n; 208 dp = dp+n; 209 if (dp<dl) 210 { 211 char c = sa[sp]; 212 if (sgp.parse(c, sa, sp, sl) < 0) { 213 return sgp.error(); 214 } 215 else return sgp.unmappableResult(); 216 } 217 return CoderResult.OVERFLOW; 218 } 219 } finally { 220 src.position(sp - src.arrayOffset()); 221 dst.position(dp - dst.arrayOffset()); 222 } 223 } 224 225 private CoderResult encodeBufferLoop(CharBuffer src, 226 ByteBuffer dst) 227 { 228 int mark = src.position(); 229 try { 230 while (src.hasRemaining()) { 231 char c = src.get(); 232 if (c < 0x80) { 233 if (!dst.hasRemaining()) 234 return CoderResult.OVERFLOW; 235 dst.put((byte)c); 236 mark++; 237 continue; 238 } 239 if (sgp.parse(c, src) < 0) 240 return sgp.error(); 241 return sgp.unmappableResult(); 242 } 243 return CoderResult.UNDERFLOW; 244 } finally { 245 src.position(mark); 246 } 247 } 248 249 protected CoderResult encodeLoop(CharBuffer src, 250 ByteBuffer dst) 251 { 252 if (src.hasArray() && dst.hasArray()) 253 return encodeArrayLoop(src, dst); 254 else 255 return encodeBufferLoop(src, dst); 256 } 257 258 public final int encodeASCII(char[] src, int sp, int len, byte[] dst, int dp) { 259 int n = 0; 260 while (n < len) { 261 char c = src[sp++]; 262 if (c < 0x80) { 263 dst[dp++] = (byte)c; 264 n++; 265 continue; 266 } 267 break; 268 } 269 return n; 270 } 271 } 272 }