1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package org.apache.harmony.tests.java.io; 19 20import junit.framework.TestCase; 21import java.io.BufferedInputStream; 22import java.io.ByteArrayInputStream; 23import java.io.ByteArrayOutputStream; 24import java.io.IOException; 25import java.io.InputStream; 26import java.io.InputStreamReader; 27import java.io.OutputStreamWriter; 28import java.io.UnsupportedEncodingException; 29import java.nio.charset.Charset; 30import java.nio.charset.CharsetDecoder; 31import java.nio.charset.CodingErrorAction; 32import java.nio.charset.MalformedInputException; 33import java.util.Arrays; 34 35public class InputStreamReaderTest extends TestCase { 36 37 static class LimitedByteArrayInputStream extends ByteArrayInputStream { 38 39 // A ByteArrayInputStream that only returns a single byte per read 40 byte[] bytes; 41 42 int count; 43 44 public LimitedByteArrayInputStream(int type) { 45 super(new byte[0]); 46 switch (type) { 47 case 0: 48 bytes = new byte[] { 0x61, 0x72 }; 49 break; 50 case 1: 51 bytes = new byte[] { (byte) 0xff, (byte) 0xfe, 0x61, 0x72 }; 52 break; 53 case 2: 54 bytes = new byte[] { '\u001b', '$', 'B', '6', 'e', 'B', 'h', 55 '\u001b', '(', 'B' }; 56 break; 57 } 58 count = bytes.length; 59 } 60 61 @Override 62 public int available() { 63 return count; 64 } 65 66 @Override 67 public int read() { 68 if (count == 0) { 69 return -1; 70 } 71 count--; 72 return bytes[bytes.length - count]; 73 } 74 75 @Override 76 public int read(byte[] buffer, int offset, int length) { 77 if (count == 0) { 78 return -1; 79 } 80 if (length == 0) { 81 return 0; 82 } 83 buffer[offset] = bytes[bytes.length - count]; 84 count--; 85 return 1; 86 } 87 } 88 89 public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\n"; 90 91 private InputStream fis; 92 93 private InputStream in; 94 95 private InputStreamReader is; 96 97 private InputStreamReader reader; 98 99 private final String source = "This is a test message with Unicode character. \u4e2d\u56fd is China's name in Chinese"; 100 101 /* 102 * @see TestCase#setUp() 103 */ 104 @Override 105 protected void setUp() throws Exception { 106 super.setUp(); 107 108 in = new ByteArrayInputStream(source.getBytes("UTF-8")); 109 reader = new InputStreamReader(in, "UTF-8"); 110 111 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 112 OutputStreamWriter osw = new OutputStreamWriter(bos); 113 char[] buf = new char[fileString.length()]; 114 fileString.getChars(0, fileString.length(), buf, 0); 115 osw.write(buf); 116 osw.close(); 117 fis = new ByteArrayInputStream(bos.toByteArray()); 118 is = new InputStreamReader(fis); 119 } 120 121 /* 122 * @see TestCase#tearDown() 123 */ 124 @Override 125 protected void tearDown() throws Exception { 126 try { 127 in.close(); 128 is.close(); 129 fis.close(); 130 } catch (IOException e) { 131 // Ignored 132 } 133 134 super.tearDown(); 135 } 136 137 /** 138 * java.io.InputStreamReader#close() 139 */ 140 public void test_close() throws IOException { 141 is.close(); 142 try { 143 is.read(); 144 fail("Should throw IOException"); 145 } catch (IOException e) { 146 // Expected 147 } 148 149 reader.close(); 150 try { 151 reader.ready(); 152 fail("Should throw IOException"); 153 } catch (IOException e) { 154 // Expected 155 } 156 157 // Should be a no-op 158 reader.close(); 159 160 // Tests after reader closed 161 in = new BufferedInputStream( 162 this 163 .getClass() 164 .getClassLoader() 165 .getResourceAsStream( 166 "org/apache/harmony/luni/tests/java/io/testfile-utf8.txt")); 167 reader = new InputStreamReader(in, "utf-8"); 168 in.close(); 169 try { 170 int count = reader.read(new char[1]); 171 fail("count:" + count); 172 } catch (IOException e) { 173 // Expected 174 } 175 try { 176 reader.read(); 177 fail(); 178 } catch (IOException e) { 179 // Expected 180 } 181 182 assertFalse(reader.ready()); 183 Charset cs = Charset.forName("utf-8"); 184 assertEquals(cs, Charset.forName(reader.getEncoding())); 185 } 186 187 /** 188 * java.io.InputStreamReader#InputStreamReader(java.io.InputStream) 189 */ 190 public void test_ConstructorLjava_io_InputStream() throws IOException { 191 try { 192 reader = new InputStreamReader(null); 193 fail(); 194 } catch (NullPointerException e) { 195 // Expected 196 } 197 InputStreamReader reader2 = new InputStreamReader(in); 198 reader2.close(); 199 } 200 201 /** 202 * java.io.InputStreamReader#InputStreamReader(java.io.InputStream, 203 *java.lang.String) 204 */ 205 public void test_ConstructorLjava_io_InputStreamLjava_lang_String() 206 throws IOException { 207 is = new InputStreamReader(fis, "8859_1"); 208 209 try { 210 is = new InputStreamReader(fis, "Bogus"); 211 fail("Failed to throw Unsupported Encoding exception"); 212 } catch (UnsupportedEncodingException e) { 213 assertNotNull(e.getMessage()); 214 } 215 216 try { 217 reader = new InputStreamReader(null, "utf-8"); 218 fail(); 219 } catch (NullPointerException e) { 220 // Expected 221 } 222 try { 223 reader = new InputStreamReader(in, (String) null); 224 fail(); 225 } catch (NullPointerException e) { 226 // Expected 227 } 228 try { 229 reader = new InputStreamReader(in, ""); 230 fail(); 231 } catch (UnsupportedEncodingException e) { 232 // Expected 233 } 234 try { 235 reader = new InputStreamReader(in, "badname"); 236 fail(); 237 } catch (UnsupportedEncodingException e) { 238 // Expected 239 } 240 InputStreamReader reader2 = new InputStreamReader(in, "utf-8"); 241 assertEquals(Charset.forName(reader2.getEncoding()), Charset 242 .forName("utf-8")); 243 reader2.close(); 244 reader2 = new InputStreamReader(in, "utf8"); 245 assertEquals(Charset.forName(reader2.getEncoding()), Charset 246 .forName("utf-8")); 247 reader2.close(); 248 } 249 250 /** 251 * java.io.InputStreamReader(java.io.InputStream, 252 *java.nio.charset.Charset) 253 */ 254 public void test_ConstructorLjava_io_InputStreamLjava_nio_charset_Charset() 255 throws IOException { 256 Charset cs = Charset.forName("utf-8"); 257 try { 258 reader = new InputStreamReader(null, cs); 259 fail(); 260 } catch (NullPointerException e) { 261 // Expected 262 } 263 try { 264 reader = new InputStreamReader(in, (Charset) null); 265 fail(); 266 } catch (NullPointerException e) { 267 // Expected 268 } 269 InputStreamReader reader2 = new InputStreamReader(in, cs); 270 assertEquals(Charset.forName(reader2.getEncoding()), cs); 271 reader2.close(); 272 } 273 274 /** 275 * java.io.InputStreamReader(java.io.InputStream, 276 *java.nio.charset.CharsetDecoder) 277 */ 278 public void test_ConstructorLjava_io_InputStreamLjava_nio_charset_CharsetDecoder() 279 throws IOException { 280 CharsetDecoder decoder = Charset.forName("utf-8").newDecoder(); 281 try { 282 reader = new InputStreamReader(null, decoder); 283 fail(); 284 } catch (NullPointerException e) { 285 // Expected 286 } 287 try { 288 reader = new InputStreamReader(in, (CharsetDecoder) null); 289 fail(); 290 } catch (NullPointerException e) { 291 // Expected 292 } 293 InputStreamReader reader2 = new InputStreamReader(in, decoder); 294 assertEquals(Charset.forName(reader2.getEncoding()), decoder.charset()); 295 reader2.close(); 296 } 297 298 /** 299 * Unlike the RI, we return a canonical encoding name and not something 300 * java specific. 301 */ 302 public void test_getEncoding() throws IOException { 303 InputStreamReader isr = new InputStreamReader(fis, "8859_1"); 304 assertEquals("ISO-8859-1", isr.getEncoding()); 305 306 isr = new InputStreamReader(fis, "ISO-8859-1"); 307 assertEquals("ISO-8859-1", isr.getEncoding()); 308 309 byte b[] = new byte[5]; 310 isr = new InputStreamReader(new ByteArrayInputStream(b), "UTF-16BE"); 311 isr.close(); 312 assertNull(isr.getEncoding()); 313 314 try { 315 isr = new InputStreamReader(System.in, "UTF-16BE"); 316 } catch (UnsupportedEncodingException e) { 317 // Ignored 318 } 319 assertEquals("UTF-16BE", isr.getEncoding()); 320 } 321 322 /** 323 * java.io.InputStreamReader#read() 324 */ 325 public void test_read() throws IOException { 326 assertEquals('T', (char) reader.read()); 327 assertEquals('h', (char) reader.read()); 328 assertEquals('i', (char) reader.read()); 329 assertEquals('s', (char) reader.read()); 330 assertEquals(' ', (char) reader.read()); 331 reader.read(new char[source.length() - 5], 0, source.length() - 5); 332 assertEquals(-1, reader.read()); 333 334 int c = is.read(); 335 assertTrue("returned incorrect char", (char) c == fileString.charAt(0)); 336 InputStreamReader reader = new InputStreamReader( 337 new ByteArrayInputStream(new byte[] { (byte) 0xe8, (byte) 0x9d, 338 (byte) 0xa5 }), "UTF8"); 339 assertTrue("wrong double byte char", reader.read() == '\u8765'); 340 341 // Regression for HARMONY-166 342 InputStream in; 343 344 in = new LimitedByteArrayInputStream(0); 345 reader = new InputStreamReader(in, "UTF-16BE"); 346 assertEquals("Incorrect byte UTF-16BE", '\u6172', reader.read()); 347 348 in = new LimitedByteArrayInputStream(0); 349 reader = new InputStreamReader(in, "UTF-16LE"); 350 assertEquals("Incorrect byte UTF-16BE", '\u7261', reader.read()); 351 352 in = new LimitedByteArrayInputStream(1); 353 reader = new InputStreamReader(in, "UTF-16"); 354 assertEquals("Incorrect byte UTF-16BE", '\u7261', reader.read()); 355 356 /* 357 * Temporarily commented out due to lack of ISO2022 support in ICU4J 3.8 358 * in = new LimitedByteArrayInputStream(2); reader = new 359 * InputStreamReader(in, "ISO2022JP"); assertEquals("Incorrect byte 360 * ISO2022JP 1", '\u4e5d', reader.read()); assertEquals("Incorrect byte 361 * ISO2022JP 2", '\u7b2c', reader.read()); 362 */ 363 } 364 365 /* 366 * Class under test for int read() Regression for Harmony-411 367 */ 368 public void test_read_1() throws IOException { 369 // if the decoder is constructed by InputStreamReader itself, the 370 // decoder's default error action is REPLACE 371 InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream( 372 new byte[] { -32, -96 }), "UTF-8"); 373 assertEquals("read() return incorrect value", 65533, isr.read()); 374 375 InputStreamReader isr2 = new InputStreamReader( 376 new ByteArrayInputStream(new byte[] { -32, -96 }), Charset 377 .forName("UTF-8")); 378 assertEquals("read() return incorrect value", 65533, isr2.read()); 379 380 // if the decoder is passed in, keep its status intact 381 CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder(); 382 decoder.onMalformedInput(CodingErrorAction.REPORT); 383 InputStreamReader isr3 = new InputStreamReader( 384 new ByteArrayInputStream(new byte[] { -32, -96 }), decoder); 385 try { 386 isr3.read(); 387 fail("Should throw MalformedInputException"); 388 } catch (MalformedInputException e) { 389 // expected 390 } 391 392 CharsetDecoder decoder2 = Charset.forName("UTF-8").newDecoder(); 393 decoder2.onMalformedInput(CodingErrorAction.IGNORE); 394 InputStreamReader isr4 = new InputStreamReader( 395 new ByteArrayInputStream(new byte[] { -32, -96 }), decoder2); 396 assertEquals("read() return incorrect value", -1, isr4.read()); 397 398 CharsetDecoder decoder3 = Charset.forName("UTF-8").newDecoder(); 399 decoder3.onMalformedInput(CodingErrorAction.REPLACE); 400 InputStreamReader isr5 = new InputStreamReader( 401 new ByteArrayInputStream(new byte[] { -32, -96 }), decoder3); 402 assertEquals("read() return incorrect value", 65533, isr5.read()); 403 } 404 405 public void test_read_specialCharset() throws IOException { 406 reader.close(); 407 in = this.getClass().getClassLoader().getResourceAsStream( 408 "tests/api/java/io/testfile-utf8.txt"); 409 reader = new InputStreamReader(in, "utf-8"); 410 int c; 411 StringBuffer sb = new StringBuffer(); 412 while ((c = reader.read()) != -1) { 413 sb.append((char) c); 414 } 415 // delete BOM 416 assertEquals(source, sb.deleteCharAt(0).toString()); 417 418 sb.setLength(0); 419 reader.close(); 420 in = this.getClass().getClassLoader().getResourceAsStream( 421 "tests/api/java/io/testfile.txt"); 422 423 reader = new InputStreamReader(in, "gb18030"); 424 while ((c = reader.read()) != -1) { 425 sb.append((char) c); 426 } 427 assertEquals(source, sb.toString()); 428 } 429 430 /** 431 * java.io.InputStreamReader#read(char[], int, int) 432 */ 433 public void test_read$CII() throws IOException { 434 char[] rbuf = new char[100]; 435 char[] sbuf = new char[100]; 436 fileString.getChars(0, 100, sbuf, 0); 437 is.read(rbuf, 0, 100); 438 for (int i = 0; i < rbuf.length; i++) { 439 assertTrue("returned incorrect chars", rbuf[i] == sbuf[i]); 440 } 441 442 // Test successive reads 443 byte[] data = new byte[8192 * 2]; 444 Arrays.fill(data, (byte) 116); // 116 = ISO-8859-1 value for 't' 445 ByteArrayInputStream bis = new ByteArrayInputStream(data); 446 InputStreamReader isr = new InputStreamReader(bis, "ISO-8859-1"); 447 448 // One less than the InputStreamReader.BUFFER_SIZE 449 char[] buf = new char[8191]; 450 int bytesRead = isr.read(buf, 0, buf.length); 451 assertFalse(-1 == bytesRead); 452 bytesRead = isr.read(buf, 0, buf.length); 453 assertFalse(-1 == bytesRead); 454 455 bis = new ByteArrayInputStream(source.getBytes("UTF-8")); 456 isr = new InputStreamReader(in, "UTF-8"); 457 char[] chars = new char[source.length()]; 458 assertEquals(source.length() - 3, isr.read(chars, 0, chars.length - 3)); 459 assertEquals(3, isr.read(chars, 0, 10)); 460 } 461 462 /* 463 * Class under test for int read(char[], int, int) 464 */ 465 public void test_read$CII_1() throws IOException { 466 try { 467 reader.read(null, -1, 1); 468 fail(); 469 } catch (NullPointerException expected) { 470 } catch (IndexOutOfBoundsException expected) { 471 } 472 473 try { 474 reader.read(null, 0, -1); 475 fail("Should throw NullPointerException"); 476 } catch (NullPointerException e) { 477 } catch (IndexOutOfBoundsException expected) { 478 } 479 480 try { 481 reader.read(null, 0, 1); 482 fail(); 483 } catch (NullPointerException e) { 484 // Expected 485 } 486 try { 487 reader.read(new char[3], -1, 1); 488 fail(); 489 } catch (IndexOutOfBoundsException e) { 490 // Expected 491 } 492 try { 493 reader.read(new char[3], 0, -1); 494 fail(); 495 } catch (IndexOutOfBoundsException e) { 496 // Expected 497 } 498 try { 499 reader.read(new char[3], 1, 3); 500 fail(); 501 } catch (IndexOutOfBoundsException e) { 502 // Expected 503 } 504 assertEquals(0, reader.read(new char[3], 3, 0)); 505 char[] chars = new char[source.length()]; 506 assertEquals(0, reader.read(chars, 0, 0)); 507 assertEquals(0, chars[0]); 508 assertEquals(3, reader.read(chars, 0, 3)); 509 assertEquals(5, reader.read(chars, 3, 5)); 510 assertEquals(source.length() - 8, reader.read(chars, 8, 511 chars.length - 8)); 512 assertTrue(Arrays.equals(chars, source.toCharArray())); 513 assertEquals(-1, reader.read(chars, 0, chars.length)); 514 assertTrue(Arrays.equals(chars, source.toCharArray())); 515 } 516 517 /** 518 * java.io.InputStreamReader#ready() 519 */ 520 public void test_ready() throws IOException { 521 assertTrue("Ready test failed", is.ready()); 522 is.read(); 523 assertTrue("More chars, but not ready", is.ready()); 524 525 assertTrue(reader.ready()); 526 reader.read(new char[source.length()]); 527 assertFalse(reader.ready()); 528 } 529} 530