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