1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.io.input;
19
20 import static org.apache.commons.io.IOUtils.EOF;
21 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertNull;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.CharArrayReader;
29 import java.io.IOException;
30 import java.io.InputStreamReader;
31 import java.io.PipedReader;
32 import java.io.Reader;
33 import java.io.StringReader;
34 import java.util.function.Supplier;
35
36 import org.apache.commons.io.IOUtils;
37 import org.junit.jupiter.api.AfterEach;
38 import org.junit.jupiter.api.Test;
39
40
41
42
43
44
45
46 class UnsynchronizedBufferedReaderTest {
47
48 private UnsynchronizedBufferedReader br;
49
50 private final String testString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\n"
51 + "Test_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\n"
52 + "Test_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\n"
53 + "Test_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\n"
54 + "Test_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\n"
55 + "Test_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\n"
56 + "Test_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\n"
57 + "Test_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\n"
58 + "Test_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\n"
59 + "Test_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\n"
60 + "Test_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\n"
61 + "Test_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\n"
62 + "Test_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\n"
63 + "Test_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\n"
64 + "Test_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\n"
65 + "Test_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\n"
66 + "Test_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\n"
67 + "Test_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\n"
68 + "Test_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\n"
69 + "Test_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\n"
70 + "Test_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\n"
71 + "Test_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\n"
72 + "Test_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\n"
73 + "Test_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\n"
74 + "Test_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\n"
75 + "Test_java_util_tm\nTest_java_util_Vector\n";
76
77
78
79
80 @AfterEach
81 protected void afterEach() {
82 IOUtils.closeQuietly(br);
83 }
84
85 private void assertLines(final String input, final String... lines) throws IOException {
86 assertReadLines(input, lines);
87 assertPeek(input, lines);
88 }
89
90 private void assertPeek(final String input, final String... lines) throws IOException {
91 try (UnsynchronizedBufferedReader bufferedReader = new UnsynchronizedBufferedReader(new StringReader(input))) {
92 for (final String line : lines) {
93
94 final char[] bufAFull = new char[line.length()];
95 assertEquals(bufAFull.length, bufferedReader.peek(bufAFull));
96 assertArrayEquals(line.toCharArray(), bufAFull);
97 if (!line.isEmpty()) {
98
99 assertEquals(line.charAt(0), bufferedReader.peek());
100
101 for (int peekLen = 0; peekLen < line.length(); peekLen++) {
102 assertPeekArray(bufferedReader, peekLen, line);
103 }
104 }
105
106 assertEquals(line, bufferedReader.readLine());
107 }
108 assertNull(bufferedReader.readLine());
109 }
110 }
111
112 private void assertPeekArray(final UnsynchronizedBufferedReader bufferedReader, final int peekLen, final String line) throws IOException {
113 final char[] expectedBuf = new char[peekLen];
114 final int srcPeekLen = Math.min(peekLen, line.length());
115 line.getChars(0, srcPeekLen, expectedBuf, 0);
116 final char[] actualBuf = new char[peekLen];
117 final Supplier<String> msg = () -> String.format("len=%,d, line='%s'", peekLen, line);
118 assertEquals(actualBuf.length, bufferedReader.peek(actualBuf), msg);
119 assertArrayEquals(expectedBuf, actualBuf, msg);
120 }
121
122 private void assertReadLines(final String input, final String... lines) throws IOException {
123 try (UnsynchronizedBufferedReader bufferedReader = new UnsynchronizedBufferedReader(new StringReader(input))) {
124 for (final String line : lines) {
125 assertEquals(line, bufferedReader.readLine());
126 }
127 assertNull(bufferedReader.readLine());
128 }
129 }
130
131
132
133
134
135
136 @Test
137 void testClose() throws IOException {
138
139 br = new UnsynchronizedBufferedReader(new StringReader(testString));
140 br.close();
141 assertThrows(IOException.class, br::read);
142 }
143
144 @Test
145 void testEmptyInput() throws Exception {
146 try (UnsynchronizedBufferedReader br = new UnsynchronizedBufferedReader(new StringReader(""))) {
147 assertEquals(EOF, br.read());
148 assertEquals(EOF, br.peek());
149 assertNull(br.readLine());
150 assertEquals(0, br.read(new char[10], 0, 0));
151 }
152 }
153
154
155
156
157
158
159 @Test
160 void testMark() throws IOException {
161
162 char[] buf = null;
163 br = new UnsynchronizedBufferedReader(new StringReader(testString));
164 br.skip(500);
165 br.mark(1000);
166 br.skip(250);
167 br.reset();
168 buf = new char[testString.length()];
169 br.read(buf, 0, 500);
170 assertTrue(testString.substring(500, 1000).equals(new String(buf, 0, 500)));
171
172 br = new UnsynchronizedBufferedReader(new StringReader(testString), 800);
173 br.skip(500);
174 br.mark(250);
175 br.read(buf, 0, 1000);
176 assertThrows(IOException.class, br::reset);
177
178 final char[] chars = new char[256];
179 for (int i = 0; i < 256; i++) {
180 chars[i] = (char) i;
181 }
182
183 try (Reader in = new UnsynchronizedBufferedReader(new StringReader(new String(chars)), 12)) {
184 in.skip(6);
185 in.mark(14);
186 in.read(new char[14], 0, 14);
187 in.reset();
188 assertTrue(in.read() == (char) 6 && in.read() == (char) 7);
189 }
190 try (Reader in = new UnsynchronizedBufferedReader(new StringReader(new String(chars)), 12)) {
191 in.skip(6);
192 in.mark(8);
193 in.skip(7);
194 in.reset();
195 assertTrue(in.read() == (char) 6 && in.read() == (char) 7);
196 }
197 try (UnsynchronizedBufferedReader br = new UnsynchronizedBufferedReader(new StringReader("01234"), 2)) {
198 br.mark(3);
199 final char[] carray = new char[3];
200 final int result = br.read(carray);
201 assertEquals(3, result);
202 assertEquals('0', carray[0]);
203 assertEquals('1', carray[1]);
204 assertEquals('2', carray[2]);
205 assertEquals('3', br.read());
206 }
207 try (UnsynchronizedBufferedReader br = new UnsynchronizedBufferedReader(new StringReader("01234"), 2)) {
208 br.mark(3);
209 final char[] carray = new char[4];
210 final int result = br.read(carray);
211 assertEquals(4, result);
212 assertEquals('0', carray[0]);
213 assertEquals('1', carray[1]);
214 assertEquals('2', carray[2]);
215 assertEquals('3', carray[3]);
216 assertEquals('4', br.read());
217 assertEquals(-1, br.read());
218 }
219 try (UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new StringReader("01234"))) {
220 reader.mark(Integer.MAX_VALUE);
221 reader.read();
222 }
223 }
224
225
226
227
228 @Test
229 void testMarkSupported() {
230
231 br = new UnsynchronizedBufferedReader(new StringReader(testString));
232 assertTrue(br.markSupported());
233 }
234
235
236
237
238
239
240 @Test
241 void testPeek() throws IOException {
242
243 br = new UnsynchronizedBufferedReader(new StringReader(testString));
244 final int p = br.peek();
245 assertEquals(testString.charAt(0), p);
246 final int r = br.read();
247 assertEquals(testString.charAt(0), r);
248 br = new UnsynchronizedBufferedReader(new StringReader(new String(new char[] { '\u8765' })));
249 assertEquals(br.peek(), '\u8765');
250 assertEquals(br.read(), '\u8765');
251
252 final char[] chars = new char[256];
253 for (int i = 0; i < 256; i++) {
254 chars[i] = (char) i;
255 }
256 try (UnsynchronizedBufferedReader in = new UnsynchronizedBufferedReader(new StringReader(new String(chars)), 12)) {
257 assertEquals(0, in.peek());
258 assertEquals(0, in.read());
259 final char[] buf = new char[14];
260 in.read(buf, 0, 14);
261 assertTrue(new String(buf).equals(new String(chars, 1, 14)));
262 assertEquals(15, in.peek());
263 assertEquals(15, in.read());
264 }
265
266
267 try (UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new CharArrayReader(new char[5], 1, 0), 2)) {
268 assertEquals(reader.peek(), -1);
269 assertEquals(reader.read(), -1);
270 }
271 }
272
273
274
275
276
277
278 @Test
279 void testPeekArray() throws IOException {
280
281 final char[] peekBuf1 = new char[1];
282 br = new UnsynchronizedBufferedReader(new StringReader(testString));
283 assertEquals(peekBuf1.length, br.peek(peekBuf1));
284 assertEquals(testString.charAt(0), peekBuf1[0]);
285 final int r = br.read();
286 assertEquals(testString.charAt(0), r);
287 br = new UnsynchronizedBufferedReader(new StringReader(new String(new char[] { '\u8765' })));
288 assertEquals(peekBuf1.length, br.peek(peekBuf1));
289 assertEquals(peekBuf1[0], '\u8765');
290 assertEquals(br.read(), '\u8765');
291
292 final char[] chars = new char[256];
293 for (int i = 0; i < 256; i++) {
294 chars[i] = (char) i;
295 }
296 try (UnsynchronizedBufferedReader in = new UnsynchronizedBufferedReader(new StringReader(new String(chars)), 12)) {
297 assertEquals(peekBuf1.length, in.peek(peekBuf1));
298 assertEquals(peekBuf1[0], 0);
299 assertEquals(0, in.read());
300 final char[] peekBuf14 = new char[14];
301 assertEquals(peekBuf14.length, in.peek(peekBuf14));
302 assertTrue(new String(peekBuf14).equals(new String(chars, 1, 14)));
303 final char[] buf = new char[14];
304 in.read(buf, 0, 14);
305 assertTrue(new String(buf).equals(new String(chars, 1, 14)));
306 assertEquals(peekBuf1.length, in.peek(peekBuf1));
307 assertEquals(15, peekBuf1[0]);
308 assertEquals(15, in.read());
309 }
310
311
312 try (UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new CharArrayReader(new char[5], 1, 0), 2)) {
313 assertEquals(reader.peek(), -1);
314 assertEquals(reader.read(), -1);
315 }
316 }
317
318
319
320
321
322
323 @Test
324 void testRead() throws IOException {
325
326 br = new UnsynchronizedBufferedReader(new StringReader(testString));
327 final int r = br.read();
328 assertEquals(testString.charAt(0), r);
329 br = new UnsynchronizedBufferedReader(new StringReader(new String(new char[] { '\u8765' })));
330 assertEquals(br.read(), '\u8765');
331
332 final char[] chars = new char[256];
333 for (int i = 0; i < 256; i++) {
334 chars[i] = (char) i;
335 }
336 try (Reader in = new UnsynchronizedBufferedReader(new StringReader(new String(chars)), 12)) {
337 assertEquals(0, in.read());
338 final char[] buf = new char[14];
339 in.read(buf, 0, 14);
340 assertTrue(new String(buf).equals(new String(chars, 1, 14)));
341 assertEquals(15, in.read());
342 }
343
344
345 try (Reader reader = new UnsynchronizedBufferedReader(new CharArrayReader(new char[5], 1, 0), 2)) {
346 assertEquals(reader.read(), -1);
347 }
348 }
349
350 @Test
351 void testReadArray_HARMONY_54() throws IOException {
352
353 final char[] ch = {};
354 @SuppressWarnings("resource")
355 final UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new CharArrayReader(ch));
356
357 assertThrows(NullPointerException.class, () -> reader.read(null, 1, 0));
358
359
360
361 reader.close();
362 assertThrows(IOException.class, () -> reader.read(null, 1, 0));
363
364
365
366 assertThrows(IOException.class, () -> reader.read(ch, 0, 42));
367 }
368
369 @Test
370 void testReadArray_HARMONY_831() throws IOException {
371
372 try (Reader reader = new UnsynchronizedBufferedReader(new PipedReader(), 9)) {
373 assertThrows(IndexOutOfBoundsException.class, () -> reader.read(new char[] {}, 7, 0));
374 }
375 }
376
377
378
379
380
381
382 @Test
383 void testReadArray1() throws IOException {
384 final char[] ca = new char[2];
385 try (UnsynchronizedBufferedReader toRet = new UnsynchronizedBufferedReader(new InputStreamReader(new ByteArrayInputStream(new byte[0])))) {
386
387 assertThrows(NullPointerException.class, () -> toRet.read(null, 1, 0));
388 assertThrows(IndexOutOfBoundsException.class, () -> toRet.read(ca, 1, 5));
389
390 assertEquals(0, toRet.read(ca, 0, 0));
391 toRet.close();
392
393
394
395 assertThrows(IOException.class, () -> toRet.read(null, 1, 0));
396 assertThrows(IOException.class, () -> toRet.read(ca, 1, 5));
397 assertThrows(IOException.class, () -> toRet.read(ca, 0, 0));
398 }
399 }
400
401 @Test
402 void testReadArray2() throws IOException {
403 final char[] ca = new char[2];
404
405 try (UnsynchronizedBufferedReader toRet2 = new UnsynchronizedBufferedReader(new InputStreamReader(new ByteArrayInputStream(new byte[2])))) {
406 assertEquals(2, toRet2.read(ca, 0, 2));
407 assertEquals(-1, toRet2.read(ca, 0, 2));
408 assertEquals(0, toRet2.read(ca, 0, 0));
409 }
410 }
411
412 @Test
413 void testReadArray3() throws IOException {
414
415 final char[] buf = new char[testString.length()];
416 br = new UnsynchronizedBufferedReader(new StringReader(testString));
417 br.read(buf, 50, 500);
418 assertTrue(new String(buf, 50, 500).equals(testString.substring(0, 500)));
419 }
420
421 @Test
422 void testReadArray4() throws IOException {
423 try (UnsynchronizedBufferedReader bufin = new UnsynchronizedBufferedReader(new Reader() {
424 int size = 2;
425 int pos;
426
427 char[] contents = new char[size];
428
429 @Override
430 public void close() throws IOException {
431
432 }
433
434 @Override
435 public int read() throws IOException {
436 if (pos >= size) {
437 throw new IOException("Read past end of data");
438 }
439 return contents[pos++];
440 }
441
442 @Override
443 public int read(final char[] buf, final int off, final int len) throws IOException {
444 if (pos >= size) {
445 throw new IOException("Read past end of data");
446 }
447 int toRead = len;
448 if (toRead > size - pos) {
449 toRead = size - pos;
450 }
451 System.arraycopy(contents, pos, buf, off, toRead);
452 pos += toRead;
453 return toRead;
454 }
455
456 @Override
457 public boolean ready() throws IOException {
458 return size - pos > 0;
459 }
460 })) {
461 bufin.read();
462 final int result = bufin.read(new char[2], 0, 2);
463 assertEquals(result, 1);
464 }
465 }
466
467
468
469
470
471
472 @Test
473 void testReadArrayException() throws IOException {
474 br = new UnsynchronizedBufferedReader(new StringReader(testString));
475 final char[] nullCharArray = null;
476 final char[] charArray = testString.toCharArray();
477 assertThrows(NullPointerException.class, () -> br.read(nullCharArray, -1, 0));
478 assertThrows(NullPointerException.class, () -> br.read(nullCharArray, 0, -1));
479 assertThrows(NullPointerException.class, () -> br.read(nullCharArray, 1, 1));
480 assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, -1, 0));
481 assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, 0, -1));
482 assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, charArray.length, 1));
483
484 br.read(charArray, 0, 0);
485 br.read(charArray, 0, charArray.length);
486 br.read(charArray, charArray.length, 0);
487
488 assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, charArray.length + 1, 0));
489 assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, charArray.length + 1, 1));
490
491 br.close();
492
493 assertThrows(IOException.class, () -> br.read(nullCharArray, -1, -1));
494 assertThrows(IOException.class, () -> br.read(charArray, -1, 0));
495 assertThrows(IOException.class, () -> br.read(charArray, 0, -1));
496 }
497
498
499
500
501
502
503 @Test
504 void testReadLine() throws IOException {
505
506 br = new UnsynchronizedBufferedReader(new StringReader(testString));
507 final String r = br.readLine();
508 assertEquals("Test_All_Tests", r);
509 }
510
511
512
513
514
515
516
517 @Test
518 void testReadLineIgnoresEbcdic85Characters() throws IOException {
519 assertLines("A\u0085B", "A\u0085B");
520 }
521
522 @Test
523 void testReadLineSeparators() throws IOException {
524 assertLines("A\nB\nC", "A", "B", "C");
525 assertLines("A\rB\rC", "A", "B", "C");
526 assertLines("A\r\nB\r\nC", "A", "B", "C");
527 assertLines("A\n\rB\n\rC", "A", "", "B", "", "C");
528 assertLines("A\n\nB\n\nC", "A", "", "B", "", "C");
529 assertLines("A\r\rB\r\rC", "A", "", "B", "", "C");
530 assertLines("A\n\n", "A", "");
531 assertLines("A\n\r", "A", "");
532 assertLines("A\r\r", "A", "");
533 assertLines("A\r\n", "A");
534 assertLines("A\r\n\r\n", "A", "");
535 }
536
537
538
539
540
541
542 @Test
543 void testReady() throws IOException {
544
545 br = new UnsynchronizedBufferedReader(new StringReader(testString));
546 assertTrue(br.ready());
547 }
548
549
550
551
552
553
554 @Test
555 void testReset() throws IOException {
556
557 br = new UnsynchronizedBufferedReader(new StringReader(testString));
558 br.skip(500);
559 br.mark(900);
560 br.skip(500);
561 br.reset();
562 final char[] buf = new char[testString.length()];
563 br.read(buf, 0, 500);
564 assertTrue(testString.substring(500, 1000).equals(new String(buf, 0, 500)));
565 br = new UnsynchronizedBufferedReader(new StringReader(testString));
566 br.skip(500);
567 assertThrows(IOException.class, br::reset);
568 }
569
570 @Test
571 void testReset_IOException() throws Exception {
572 final int[] expected = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', -1 };
573 br = new UnsynchronizedBufferedReader(new StringReader("1234567890"), 9);
574 br.mark(9);
575 for (int i = 0; i < 11; i++) {
576 assertEquals(expected[i], br.read());
577 }
578 assertThrows(IOException.class, br::reset);
579 for (int i = 0; i < 11; i++) {
580 assertEquals(-1, br.read());
581 }
582
583 br = new UnsynchronizedBufferedReader(new StringReader("1234567890"));
584 br.mark(10);
585 for (int i = 0; i < 10; i++) {
586 assertEquals(expected[i], br.read());
587 }
588 br.reset();
589 for (int i = 0; i < 11; i++) {
590 assertEquals(expected[i], br.read());
591 }
592 }
593
594
595
596
597
598
599 @Test
600 void testSkip() throws IOException {
601
602 br = new UnsynchronizedBufferedReader(new StringReader(testString));
603 br.skip(500);
604 final char[] buf = new char[testString.length()];
605 br.read(buf, 0, 500);
606 assertTrue(testString.substring(500, 1000).equals(new String(buf, 0, 500)));
607 }
608 }