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