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