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
351
352
353
354
355 @Test
356 void testReadArray() throws IOException {
357 final char[] ca = new char[2];
358 try (UnsynchronizedBufferedReader toRet = new UnsynchronizedBufferedReader(new InputStreamReader(new ByteArrayInputStream(new byte[0])))) {
359
360 assertThrows(NullPointerException.class, () -> toRet.read(null, 1, 0));
361 toRet.close();
362 assertThrows(IOException.class, () -> toRet.read(null, 1, 0));
363
364 assertThrows(IOException.class, () -> toRet.read(ca, 0, 0));
365
366
367
368
369
370 assertThrows(IOException.class, () -> toRet.read(ca, 1, 5));
371 }
372
373 try (UnsynchronizedBufferedReader toRet2 = new UnsynchronizedBufferedReader(new InputStreamReader(new ByteArrayInputStream(new byte[2])))) {
374 assertEquals(2, toRet2.read(ca, 0, 2));
375 assertEquals(-1, toRet2.read(ca, 0, 2));
376 assertEquals(0, toRet2.read(ca, 0, 0));
377 }
378
379
380 final char[] buf = new char[testString.length()];
381 br = new UnsynchronizedBufferedReader(new StringReader(testString));
382 br.read(buf, 50, 500);
383 assertTrue(new String(buf, 50, 500).equals(testString.substring(0, 500)));
384
385 try (UnsynchronizedBufferedReader bufin = new UnsynchronizedBufferedReader(new Reader() {
386 int size = 2;
387 int pos;
388
389 char[] contents = new char[size];
390
391 @Override
392 public void close() throws IOException {
393
394 }
395
396 @Override
397 public int read() throws IOException {
398 if (pos >= size) {
399 throw new IOException("Read past end of data");
400 }
401 return contents[pos++];
402 }
403
404 @Override
405 public int read(final char[] buf, final int off, final int len) throws IOException {
406 if (pos >= size) {
407 throw new IOException("Read past end of data");
408 }
409 int toRead = len;
410 if (toRead > size - pos) {
411 toRead = size - pos;
412 }
413 System.arraycopy(contents, pos, buf, off, toRead);
414 pos += toRead;
415 return toRead;
416 }
417
418 @Override
419 public boolean ready() throws IOException {
420 return size - pos > 0;
421 }
422 })) {
423 bufin.read();
424 final int result = bufin.read(new char[2], 0, 2);
425 assertEquals(result, 1);
426 }
427
428 try (Reader reader = new UnsynchronizedBufferedReader(new PipedReader(), 9)) {
429 assertThrows(IndexOutOfBoundsException.class, () -> reader.read(new char[] {}, 7, 0));
430 }
431
432
433 final char[] ch = {};
434 @SuppressWarnings("resource")
435 final UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new CharArrayReader(ch));
436
437 assertThrows(NullPointerException.class, () -> reader.read(null, 1, 0));
438
439
440
441 reader.close();
442 assertThrows(IOException.class, () -> reader.read(null, 1, 0));
443
444
445
446 assertThrows(IOException.class, () -> reader.read(ch, 0, 42));
447 }
448
449
450
451
452
453
454 @Test
455 void testReadArrayException() throws IOException {
456 br = new UnsynchronizedBufferedReader(new StringReader(testString));
457 final char[] nullCharArray = null;
458 final char[] charArray = testString.toCharArray();
459 assertThrows(IndexOutOfBoundsException.class, () -> br.read(nullCharArray, -1, -1));
460 assertThrows(IndexOutOfBoundsException.class, () -> br.read(nullCharArray, -1, 0));
461 assertThrows(NullPointerException.class, () -> br.read(nullCharArray, 0, -1));
462 assertThrows(NullPointerException.class, () -> br.read(nullCharArray, 0, 0));
463 assertThrows(NullPointerException.class, () -> br.read(nullCharArray, 0, 1));
464 assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, -1, -1));
465 assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, -1, 0));
466
467 br.read(charArray, 0, 0);
468 br.read(charArray, 0, charArray.length);
469 br.read(charArray, charArray.length, 0);
470
471 assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, charArray.length + 1, 0));
472 assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, charArray.length + 1, 1));
473
474 br.close();
475
476 assertThrows(IOException.class, () -> br.read(nullCharArray, -1, -1));
477 assertThrows(IOException.class, () -> br.read(charArray, -1, 0));
478 assertThrows(IOException.class, () -> br.read(charArray, 0, -1));
479 }
480
481
482
483
484
485
486 @Test
487 void testReadLine() throws IOException {
488
489 br = new UnsynchronizedBufferedReader(new StringReader(testString));
490 final String r = br.readLine();
491 assertEquals("Test_All_Tests", r);
492 }
493
494
495
496
497
498
499
500 @Test
501 void testReadLineIgnoresEbcdic85Characters() throws IOException {
502 assertLines("A\u0085B", "A\u0085B");
503 }
504
505 @Test
506 void testReadLineSeparators() throws IOException {
507 assertLines("A\nB\nC", "A", "B", "C");
508 assertLines("A\rB\rC", "A", "B", "C");
509 assertLines("A\r\nB\r\nC", "A", "B", "C");
510 assertLines("A\n\rB\n\rC", "A", "", "B", "", "C");
511 assertLines("A\n\nB\n\nC", "A", "", "B", "", "C");
512 assertLines("A\r\rB\r\rC", "A", "", "B", "", "C");
513 assertLines("A\n\n", "A", "");
514 assertLines("A\n\r", "A", "");
515 assertLines("A\r\r", "A", "");
516 assertLines("A\r\n", "A");
517 assertLines("A\r\n\r\n", "A", "");
518 }
519
520
521
522
523
524
525 @Test
526 void testReady() throws IOException {
527
528 br = new UnsynchronizedBufferedReader(new StringReader(testString));
529 assertTrue(br.ready());
530 }
531
532
533
534
535
536
537 @Test
538 void testReset() throws IOException {
539
540 br = new UnsynchronizedBufferedReader(new StringReader(testString));
541 br.skip(500);
542 br.mark(900);
543 br.skip(500);
544 br.reset();
545 final char[] buf = new char[testString.length()];
546 br.read(buf, 0, 500);
547 assertTrue(testString.substring(500, 1000).equals(new String(buf, 0, 500)));
548 br = new UnsynchronizedBufferedReader(new StringReader(testString));
549 br.skip(500);
550 assertThrows(IOException.class, br::reset);
551 }
552
553 @Test
554 void testReset_IOException() throws Exception {
555 final int[] expected = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', -1 };
556 br = new UnsynchronizedBufferedReader(new StringReader("1234567890"), 9);
557 br.mark(9);
558 for (int i = 0; i < 11; i++) {
559 assertEquals(expected[i], br.read());
560 }
561 assertThrows(IOException.class, br::reset);
562 for (int i = 0; i < 11; i++) {
563 assertEquals(-1, br.read());
564 }
565
566 br = new UnsynchronizedBufferedReader(new StringReader("1234567890"));
567 br.mark(10);
568 for (int i = 0; i < 10; i++) {
569 assertEquals(expected[i], br.read());
570 }
571 br.reset();
572 for (int i = 0; i < 11; i++) {
573 assertEquals(expected[i], br.read());
574 }
575 }
576
577
578
579
580
581
582 @Test
583 void testSkip() throws IOException {
584
585 br = new UnsynchronizedBufferedReader(new StringReader(testString));
586 br.skip(500);
587 final char[] buf = new char[testString.length()];
588 br.read(buf, 0, 500);
589 assertTrue(testString.substring(500, 1000).equals(new String(buf, 0, 500)));
590 }
591 }