1 21 22 package org.apache.derby.impl.jdbc; 23 24 import java.io.InputStream ; 25 import java.io.Reader ; 26 import java.io.IOException ; 27 import java.io.UTFDataFormatException ; 28 import java.io.EOFException ; 29 import java.sql.SQLException ; 30 31 33 public final class UTF8Reader extends Reader 34 { 35 36 private InputStream in; 37 private final long utfLen; private long utfCount; private long readerCharCount; private long maxFieldSize; 42 private char[] buffer = new char[8 * 1024]; 43 private int charactersInBuffer; private int readPositionInBuffer; 45 46 private boolean noMoreReads; 47 48 private ConnectionChild parent; 51 52 public UTF8Reader( 53 InputStream in, 54 long maxFieldSize, 55 ConnectionChild parent, 56 Object synchronization) 57 throws IOException 58 { 59 super(synchronization); 60 61 this.in = in; 62 this.maxFieldSize = maxFieldSize; 63 this.parent = parent; 64 65 synchronized (lock) { 66 this.utfLen = readUnsignedShort(); 67 } 68 } 69 70 73 public int read() throws IOException 74 { 75 synchronized (lock) { 76 77 if (noMoreReads) 79 throw new IOException (); 80 81 if (readPositionInBuffer >= charactersInBuffer) { 82 if (fillBuffer()) { 83 return -1; 84 } 85 readPositionInBuffer = 0; 86 } 87 88 return buffer[readPositionInBuffer++]; 89 } 90 } 91 92 public int read(char[] cbuf, int off, int len) throws IOException 93 { 94 synchronized (lock) { 95 if (noMoreReads) 97 throw new IOException (); 98 99 if (readPositionInBuffer >= charactersInBuffer) { 100 if (fillBuffer()) { 101 return -1; 102 } 103 readPositionInBuffer = 0; 104 } 105 106 int remainingInBuffer = charactersInBuffer - readPositionInBuffer; 107 108 if (len > remainingInBuffer) 109 len = remainingInBuffer; 110 111 System.arraycopy(buffer, readPositionInBuffer, cbuf, off, len); 112 readPositionInBuffer += len; 113 114 return len; 115 } 116 } 117 118 public long skip(long len) throws IOException { 119 synchronized (lock) { 120 if (noMoreReads) 122 throw new IOException (); 123 124 if (readPositionInBuffer >= charactersInBuffer) { 125 if (fillBuffer()) { 127 return -1; 128 } 129 readPositionInBuffer = 0; 130 } 131 132 int remainingInBuffer = charactersInBuffer - readPositionInBuffer; 133 134 if (len > remainingInBuffer) 135 len = remainingInBuffer; 136 137 readPositionInBuffer += len; 138 139 return len; 140 } 141 142 } 143 144 public void close() 145 { 146 synchronized (lock) { 147 closeIn(); 148 parent = null; 149 noMoreReads = true; 150 } 151 } 152 153 156 157 public int readInto(StringBuffer sb, int len) throws IOException { 158 159 synchronized (lock) { 160 if (readPositionInBuffer >= charactersInBuffer) { 161 if (fillBuffer()) { 162 return -1; 163 } 164 readPositionInBuffer = 0; 165 } 166 167 int remainingInBuffer = charactersInBuffer - readPositionInBuffer; 168 169 if (len > remainingInBuffer) 170 len = remainingInBuffer; 171 sb.append(buffer, readPositionInBuffer, len); 172 173 readPositionInBuffer += len; 174 175 return len; 176 } 177 } 178 int readAsciiInto(byte[] abuf, int off, int len) throws IOException { 179 180 synchronized (lock) { 181 if (readPositionInBuffer >= charactersInBuffer) { 182 if (fillBuffer()) { 183 return -1; 184 } 185 readPositionInBuffer = 0; 186 } 187 188 int remainingInBuffer = charactersInBuffer - readPositionInBuffer; 189 190 if (len > remainingInBuffer) 191 len = remainingInBuffer; 192 193 char[] lbuffer = buffer; 194 for (int i = 0; i < len; i++) { 195 char c = lbuffer[readPositionInBuffer + i]; 196 byte cb; 197 if (c <= 255) 198 cb = (byte) c; 199 else 200 cb = (byte) '?'; 202 abuf[off + i] = cb; 203 } 204 205 readPositionInBuffer += len; 206 207 return len; 208 } 209 } 210 211 214 215 216 private void closeIn() { 217 if (in != null) { 218 try { 219 in.close(); 220 } catch (IOException ioe) { 221 } finally { 222 in = null; 223 } 224 } 225 } 226 private IOException utfFormatException(String s) { 227 noMoreReads = true; 228 closeIn(); 229 return new UTFDataFormatException (s); 230 } 231 232 private IOException utfFormatException() { 233 noMoreReads = true; 234 closeIn(); 235 return new UTFDataFormatException (); 236 } 237 238 241 private boolean fillBuffer() throws IOException 242 { 243 if (in == null) 244 return true; 245 246 charactersInBuffer = 0; 247 248 try { 249 try { 250 251 parent.setupContextStack(); 252 253 readChars: 254 while ( 255 (charactersInBuffer < buffer.length) && 256 ((utfCount < utfLen) || (utfLen == 0)) && 257 ((maxFieldSize == 0) || (readerCharCount < maxFieldSize)) 258 ) 259 { 260 int c = in.read(); 261 if (c == -1) { 262 if (utfLen == 0) { 263 closeIn(); 264 break readChars; 265 } 266 throw utfFormatException(); 267 } 268 269 int finalChar; 270 switch (c >> 4) { 271 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 272 utfCount++; 274 finalChar = c; 275 break; 276 277 case 12: case 13: 278 { 279 utfCount += 2; 281 int char2 = in.read(); 282 if (char2 == -1) 283 throw utfFormatException(); 284 285 if ((char2 & 0xC0) != 0x80) 286 throw utfFormatException(); 287 finalChar = (((c & 0x1F) << 6) | (char2 & 0x3F)); 288 break; 289 } 290 291 case 14: 292 { 293 utfCount += 3; 295 int char2 = in.read(); 296 int char3 = in.read(); 297 if (char2 == -1 || char3 == -1) 298 throw utfFormatException(); 299 300 if ((c == 0xE0) && (char2 == 0) && (char3 == 0)) 301 { 302 if (utfLen == 0) { 303 closeIn(); 307 break readChars; 308 } 309 throw utfFormatException(); 310 } 311 312 if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) 313 throw utfFormatException(); 314 315 finalChar = (((c & 0x0F) << 12) | 316 ((char2 & 0x3F) << 6) | 317 ((char3 & 0x3F) << 0)); 318 } 319 break; 320 321 default: 322 throw utfFormatException(); 324 } 325 326 buffer[charactersInBuffer++] = (char) finalChar; 327 readerCharCount++; 328 } 329 if (utfLen != 0 && utfCount > utfLen) 330 throw utfFormatException("utfCount " + utfCount + " utfLen " + utfLen); 331 332 if (charactersInBuffer != 0) 333 return false; 334 335 closeIn(); 336 return true; 337 } finally { 338 parent.restoreContextStack(); 339 } 340 } catch (SQLException sqle) { 341 throw new IOException (sqle.getSQLState() + ":" + sqle.getMessage()); 342 } 343 } 344 345 346 private final int readUnsignedShort() throws IOException { 348 int ch1 = in.read(); 349 int ch2 = in.read(); 350 if ((ch1 | ch2) < 0) 351 throw new EOFException (); 352 353 return (ch1 << 8) + (ch2 << 0); 354 } 355 } 356 | Popular Tags |