blob: 879bf4e31bb8907a538fc9f94424fcffc8d9d8b5 [file] [log] [blame]
The Android Open Source Project0eec4642012-04-01 00:00:00 -07001/*
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 tests.api.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.UnsupportedEncodingException;
28import java.nio.charset.Charset;
29import java.nio.charset.CharsetDecoder;
30import java.nio.charset.CodingErrorAction;
31import java.nio.charset.MalformedInputException;
32import java.util.Arrays;
33
34import tests.support.Support_ASimpleInputStream;
35
36import junit.framework.TestCase;
37import dalvik.annotation.TestLevel;
38import dalvik.annotation.TestTargetClass;
39import dalvik.annotation.TestTargetNew;
40import dalvik.annotation.TestTargets;
41
42/**
43 *
44 */
45@TestTargetClass(InputStreamReader.class)
46public class InputStreamReaderTest extends TestCase {
47
48 private final String source = "This is a test message with Unicode character. \u4e2d\u56fd is China's name in Chinese";
49
50 private InputStream in;
51
52 private InputStreamReader reader;
53
54 private InputStreamReader is;
55
56 private InputStream fis;
57
58 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";
59
60 static class LimitedByteArrayInputStream extends ByteArrayInputStream {
61
62 // A ByteArrayInputStream that only returns a single byte per read
63 byte[] bytes;
64
65 int count;
66
67 public LimitedByteArrayInputStream(int type) {
68 super(new byte[0]);
69 switch (type) {
70 case 0:
71 bytes = new byte[] { 0x61, 0x72 };
72 break;
73 case 1:
74 bytes = new byte[] { (byte) 0xff, (byte) 0xfe, 0x61, 0x72 };
75 break;
76 case 2:
77 bytes = new byte[] { '\u001b', '$', 'B', '6', 'e', 'B', 'h',
78 '\u001b', '(', 'B' };
79 break;
80 }
81 count = bytes.length;
82 }
83
84 public int read() {
85 if (count == 0)
86 return -1;
87 count--;
88 return bytes[bytes.length - count];
89 }
90
91 public int read(byte[] buffer, int offset, int length) {
92 if (count == 0)
93 return -1;
94 if (length == 0)
95 return 0;
96 buffer[offset] = bytes[bytes.length - count];
97 count--;
98 return 1;
99 }
100
101 public int available() {
102 return count;
103 }
104 }
105
106 /*
107 * @see TestCase#setUp()
108 */
109 protected void setUp() throws Exception {
110 super.setUp();
111
112 try {
113 in = new ByteArrayInputStream(source.getBytes("UTF-8"));
114 reader = new InputStreamReader(in, "UTF-8");
115
116 ByteArrayOutputStream bos = new ByteArrayOutputStream();
117 OutputStreamWriter osw = new OutputStreamWriter(bos);
118 char[] buf = new char[fileString.length()];
119 fileString.getChars(0, fileString.length(), buf, 0);
120 osw.write(buf);
121 osw.close();
122 fis = new ByteArrayInputStream(bos.toByteArray());
123 is = new InputStreamReader(fis);
124 } catch (Exception e) {
125 fail("Exception during setUp : " + e.getMessage());
126 }
127 }
128
129 /*
130 * @see TestCase#tearDown()
131 */
132 protected void tearDown() throws Exception {
133 try {
134 in.close();
135 is.close();
136 fis.close();
137 } catch (IOException e) {
138 }
139
140 super.tearDown();
141 }
142
143 /*
144 * Class under test for int read()
145 */
146 @TestTargetNew(
147 level = TestLevel.PARTIAL_COMPLETE,
148 notes = "IOException checking missed.",
149 method = "read",
150 args = {}
151 )
152 public void testRead() throws IOException {
153 assertEquals('T', (char) reader.read());
154 assertEquals('h', (char) reader.read());
155 assertEquals('i', (char) reader.read());
156 assertEquals('s', (char) reader.read());
157 assertEquals(' ', (char) reader.read());
158 reader.read(new char[source.length() - 5], 0, source.length() - 5);
159 assertEquals(-1, reader.read());
160 }
161
162 /*
163 * Class under test for int read()
164 * Regression for Harmony-411
165 */
166 @TestTargetNew(
167 level = TestLevel.PARTIAL_COMPLETE,
168 notes = "IOException checking missed.",
169 method = "read",
170 args = {}
171 )
172
173 public void testRead1() throws IOException {
174 // if the decoder is constructed by InputStreamReader itself, the decoder's
175 // default error action is REPLACE
176 InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(
177 new byte[] { -32, -96 }), "UTF-8");
178 assertEquals("read() return incorrect value", 65533, isr.read());
179
180 InputStreamReader isr2 = new InputStreamReader(new ByteArrayInputStream(
181 new byte[] { -32, -96 }), Charset.forName("UTF-8"));
182 assertEquals("read() return incorrect value", 65533, isr2.read());
183
184 // if the decoder is passed in, keep its status intacted
185 CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
186 decoder.onMalformedInput(CodingErrorAction.REPORT);
187 InputStreamReader isr3 = new InputStreamReader(new ByteArrayInputStream(
188 new byte[] { -32, -96 }), decoder);
189 try{
190 isr3.read();
191 fail("Should throw MalformedInputException");
192 }catch(MalformedInputException e){
193 //expected
194 }
195
196 CharsetDecoder decoder2 = Charset.forName("UTF-8").newDecoder();
197 decoder2.onMalformedInput(CodingErrorAction.IGNORE);
198 InputStreamReader isr4 = new InputStreamReader(new ByteArrayInputStream(
199 new byte[] { -32, -96 }), decoder2);
200 assertEquals("read() return incorrect value", -1, isr4.read());
201
202 CharsetDecoder decoder3 = Charset.forName("UTF-8").newDecoder();
203 decoder3.onMalformedInput(CodingErrorAction.REPLACE);
204 InputStreamReader isr5 = new InputStreamReader(new ByteArrayInputStream(
205 new byte[] { -32, -96 }), decoder3);
206 assertEquals("read() return incorrect value", 65533, isr5.read());
207 }
208
209 /*
210 * Class under test for int read(char[], int, int)
211 */
212 @TestTargetNew(
213 level = TestLevel.PARTIAL_COMPLETE,
214 notes = "IOException checking missed.",
215 method = "read",
216 args = {char[].class, int.class, int.class}
217 )
218 public void testReadcharArrayintint() throws IOException {
219 try {
220 reader.read(new char[3], -1, 0);
221 fail("Should throw IndexOutOfBoundsException");
222 } catch (IndexOutOfBoundsException e) {
223 //expected
224 }
225 try {
226 reader.read(new char[3], 0, -1);
227 fail("Should throw IndexOutOfBoundsException");
228 } catch (IndexOutOfBoundsException e) {
229 //expected
230 }
231 try {
232 reader.read(new char[3], 4, 0);
233 fail("Should throw IndexOutOfBoundsException");
234 } catch (IndexOutOfBoundsException e) {
235 //expected
236 }
237 try {
238 reader.read(new char[3], 3, 1);
239 fail("Should throw IndexOutOfBoundsException");
240 } catch (IndexOutOfBoundsException e) {
241 //expected
242 }
243 try {
244 reader.read(new char[3], 1, 3);
245 fail("Should throw IndexOutOfBoundsException");
246 } catch (IndexOutOfBoundsException e) {
247 //expected
248 }
249 try {
250 reader.read(new char[3], 0, 4);
251 fail("Should throw IndexOutOfBoundsException");
252 } catch (IndexOutOfBoundsException e) {
253 //expected
254 }
255
256 try {
257 reader.read(null, 0, 0);
258 fail("Should throw NullPointerException");
259 } catch (NullPointerException e) {
260 //expected
261 }
262
263 assertEquals(0, reader.read(new char[3], 3, 0));
264 char[] chars = new char[source.length()];
265 assertEquals(0, reader.read(chars, 0, 0));
266 assertEquals(0, chars[0]);
267 assertEquals(3, reader.read(chars, 0, 3));
268 assertEquals(5, reader.read(chars, 3, 5));
269 assertEquals(source.length() - 8, reader.read(chars, 8,
270 chars.length - 8));
271 assertTrue(Arrays.equals(chars, source.toCharArray()));
272 assertEquals(-1, reader.read(chars, 0, chars.length));
273 assertTrue(Arrays.equals(chars, source.toCharArray()));
274 }
275 @TestTargetNew(
276 level = TestLevel.PARTIAL_COMPLETE,
277 notes = "IOException checking missed.",
278 method = "read",
279 args = {char[].class, int.class, int.class}
280 )
281 public void testReadcharArrayintint2() throws IOException {
282 char[] chars = new char[source.length()];
283 assertEquals(source.length() - 3, reader.read(chars, 0,
284 chars.length - 3));
285 assertEquals(3, reader.read(chars, 0, 10));
286 }
287 @TestTargetNew(
288 level = TestLevel.PARTIAL_COMPLETE,
289 notes = "IOException checking missed.",
290 method = "ready",
291 args = {}
292 )
293 public void testReady() throws IOException {
294 assertTrue(reader.ready());
295 reader.read(new char[source.length()]);
296 assertFalse(reader.ready());
297 }
298 @TestTargetNew(
299 level = TestLevel.PARTIAL_COMPLETE,
300 notes = "IOException checking missed.",
301 method = "read",
302 args = {}
303 )
304 public void testSpecialCharsetReading() throws Exception {
305 reader.close();
306 in = this.getClass().getClassLoader().getResourceAsStream(
307 "tests/api/java/io/testfile-utf8.txt");
308 reader = new InputStreamReader(in, "utf-8");
309 int c;
310 StringBuffer sb = new StringBuffer();
311 while ((c = reader.read()) != -1) {
312 sb.append((char) c);
313 }
314 // delete BOM
315 assertEquals(source, sb.deleteCharAt(0).toString());
316
317 sb.setLength(0);
318 reader.close();
319 in = this.getClass().getClassLoader().getResourceAsStream(
320 "tests/api/java/io/testfile.txt");
321 reader = new InputStreamReader(in, "GB2312");
322
323 while ((c = reader.read()) != -1) {
324 sb.append((char) c);
325 }
326 assertEquals(source, sb.toString());
327 }
328
329 @TestTargets({
330 @TestTargetNew(
331 level = TestLevel.PARTIAL_COMPLETE,
332 notes = "IOException checking.",
333 method = "read",
334 args = {}
335 ),
336 @TestTargetNew(
337 level = TestLevel.PARTIAL_COMPLETE,
338 notes = "IOException checking.",
339 method = "ready",
340 args = {}
341 )
342 })
343 public void testAfterClose() throws IOException {
344 reader.close();
345 in = new BufferedInputStream(this.getClass().getClassLoader()
346 .getResourceAsStream("tests/api/java/io/testfile-utf8.txt"));
347 reader = new InputStreamReader(in, "utf-8");
348 in.close();
349 try {
350 int count = reader.read(new char[1]);
351 fail("count:" + count);
352 } catch (IOException e) {
353 }
354 try {
355 reader.read();
356 fail();
357 } catch (IOException e) {
358 }
359
360 assertFalse(reader.ready());
361 Charset cs = Charset.forName("utf-8");
362 assertEquals(cs, Charset.forName(reader.getEncoding()));
363 reader.close();
364 }
365
366 /*
367 * Class under test for void InputStreamReader(InputStream)
368 */
369 @TestTargetNew(
370 level = TestLevel.COMPLETE,
371 notes = "",
372 method = "InputStreamReader",
373 args = {java.io.InputStream.class}
374 )
375 public void testInputStreamReaderInputStream() throws IOException {
376 try {
377 reader = new InputStreamReader(null);
378 fail();
379 } catch (NullPointerException e) {
380 }
381 InputStreamReader reader2 = new InputStreamReader(in);
382 reader2.close();
383 }
384
385 /*
386 * Class under test for void InputStreamReader(InputStream, String)
387 */
388 @TestTargetNew(
389 level = TestLevel.COMPLETE,
390 notes = "",
391 method = "InputStreamReader",
392 args = {java.io.InputStream.class, java.lang.String.class}
393 )
394 public void testInputStreamReaderInputStreamString() throws IOException {
395 try {
396 reader = new InputStreamReader(null, "utf-8");
397 fail();
398 } catch (NullPointerException e) {
399 }
400 try {
401 reader = new InputStreamReader(in, (String) null);
402 fail();
403 } catch (NullPointerException e) {
404 }
405 try {
406 reader = new InputStreamReader(in, "");
407 fail();
408 } catch (UnsupportedEncodingException e) {
409 }
410 try {
411 reader = new InputStreamReader(in, "badname");
412 fail();
413 } catch (UnsupportedEncodingException e) {
414 }
415 InputStreamReader reader2 = new InputStreamReader(in, "utf-8");
416 assertEquals(Charset.forName(reader2.getEncoding()), Charset
417 .forName("utf-8"));
418 reader2.close();
419 reader2 = new InputStreamReader(in, "utf8");
420 assertEquals(Charset.forName(reader2.getEncoding()), Charset
421 .forName("utf-8"));
422 reader2.close();
423 }
424
425 /*
426 * Class under test for void InputStreamReader(InputStream, CharsetDecoder)
427 */
428 @TestTargetNew(
429 level = TestLevel.COMPLETE,
430 notes = "",
431 method = "InputStreamReader",
432 args = {java.io.InputStream.class, java.nio.charset.CharsetDecoder.class}
433 )
434 public void testInputStreamReaderInputStreamCharsetDecoder()
435 throws Exception {
436 CharsetDecoder decoder = Charset.forName("utf-8").newDecoder();
437 try {
438 reader = new InputStreamReader(null, decoder);
439 fail();
440 } catch (NullPointerException e) {
441 }
442 try {
443 reader = new InputStreamReader(in, (CharsetDecoder) null);
444 fail();
445 } catch (NullPointerException e) {
446 }
447 InputStreamReader reader2 = new InputStreamReader(in, decoder);
448 assertEquals(Charset.forName(reader2.getEncoding()), decoder.charset());
449 reader2.close();
450 }
451
452 /*
453 * Class under test for void InputStreamReader(InputStream, Charset)
454 */
455 @TestTargetNew(
456 level = TestLevel.COMPLETE,
457 notes = "",
458 method = "InputStreamReader",
459 args = {java.io.InputStream.class, java.nio.charset.Charset.class}
460 )
461 public void testInputStreamReaderInputStreamCharset() throws IOException {
462 Charset cs = Charset.forName("utf-8");
463 try {
464 reader = new InputStreamReader(null, cs);
465 fail();
466 } catch (NullPointerException e) {
467 }
468 try {
469 reader = new InputStreamReader(in, (Charset) null);
470 fail();
471 } catch (NullPointerException e) {
472 }
473 InputStreamReader reader2 = new InputStreamReader(in, cs);
474 assertEquals(Charset.forName(reader2.getEncoding()), cs);
475 reader2.close();
476 }
477 @TestTargetNew(
478 level = TestLevel.PARTIAL_COMPLETE,
479 notes = "",
480 method = "read",
481 args = {char[].class, int.class, int.class}
482 )
483 public void testInputStreamReaderSuccessiveReads() throws IOException {
484 byte[] data = new byte[8192 * 2];
485 Arrays.fill(data, (byte) 116); // 116 = ISO-8859-1 value for 't'
486 ByteArrayInputStream bis = new ByteArrayInputStream(data);
487 InputStreamReader isr = new InputStreamReader(bis, "ISO-8859-1");
488
489 // One less than the InputStreamReader.BUFFER_SIZE
490 char[] buf = new char[8191];
491 int bytesRead = isr.read(buf, 0, buf.length);
492 if (bytesRead == -1) {
493 throw new RuntimeException();
494 }
495 bytesRead = isr.read(buf, 0, buf.length);
496 if (bytesRead == -1) {
497 throw new RuntimeException();
498 }
499 }
500
501 /**
502 * @tests java.io.InputStreamReader#InputStreamReader(java.io.InputStream)
503 */
504 @TestTargetNew(
505 level = TestLevel.COMPLETE,
506 notes = "See setUp.",
507 method = "InputStreamReader",
508 args = {java.io.InputStream.class}
509 )
510 public void test_ConstructorLjava_io_InputStream() {
511 // Test for method java.io.InputStreamReader(java.io.InputStream)
512 assertTrue("Used to test other methods", true);
513 }
514
515 /**
516 * @tests java.io.InputStreamReader#InputStreamReader(java.io.InputStream,
517 * java.lang.String)
518 */
519 @TestTargetNew(
520 level = TestLevel.COMPLETE,
521 notes = "Verifies InputStreamReader(java.io.InputStream) constructor.",
522 method = "InputStreamReader",
523 args = {java.io.InputStream.class}
524 )
525 public void test_ConstructorLjava_io_InputStreamLjava_lang_String() {
526 // Test for method java.io.InputStreamReader(java.io.InputStream,
527 // java.lang.String)
528 try {
529 is = new InputStreamReader(fis, "8859_1");
530 } catch (UnsupportedEncodingException e) {
531 fail("Unable to create input stream : " + e.getMessage());
532 }
533
534 try {
535 is = new InputStreamReader(fis, "Bogus");
536 } catch (UnsupportedEncodingException e) {
537 return;
538 }
539 fail("Failed to throw Unsupported Encoding exception");
540 }
541
542 /**
543 * @tests java.io.InputStreamReader#close()
544 */
545 @TestTargetNew(
546 level = TestLevel.PARTIAL_COMPLETE,
547 method = "close",
548 args = {}
549 )
550 public void test_close() {
551 // Test for method void java.io.InputStreamReader.close()
552 try {
553 is.close();
554 } catch (IOException e) {
555 fail("Failed to close reader : " + e.getMessage());
556 }
557 try {
558 is.read();
559 fail("Test 1: IOException expected.");
560 } catch (IOException e) {
561 // Exception means read failed due to close
562 }
563
564 is = new InputStreamReader(new Support_ASimpleInputStream(true));
565 try {
566 is.read();
567 fail("Test 2: IOException expected.");
568 } catch (IOException e) {
569 // Expected.
570 }
571
572 }
573
574 @TestTargetNew(
575 level = TestLevel.PARTIAL_COMPLETE,
576 method = "close",
577 args = {}
578 )
579 public void testClose() throws IOException {
580 reader.close();
581 try {
582 reader.ready();
583 fail("Should throw IOException");
584 } catch (IOException e) {
585 }
586 reader.close();
587 }
588
589 /**
590 * @tests java.io.InputStreamReader#getEncoding()
591 */
592 @TestTargetNew(
593 level = TestLevel.COMPLETE,
594 notes = "Verifies getEncoding() method.",
595 method = "getEncoding",
596 args = {}
597 )
598 public void test_getEncoding() {
599 // Test for method java.lang.String
600 // java.io.InputStreamReader.getEncoding()
601 try {
602 is = new InputStreamReader(fis, "8859_1");
603 } catch (UnsupportedEncodingException e) {
604 assertEquals("Returned incorrect encoding",
605 "8859_1", is.getEncoding());
606 }
607 }
608
609 /**
610 * @tests java.io.InputStreamReader#read()
611 */
612 @TestTargetNew(
613 level = TestLevel.PARTIAL_COMPLETE,
614 notes = "",
615 method = "read",
616 args = {}
617 )
618 public void test_read() throws IOException{
619 // Test for method int java.io.InputStreamReader.read()
620 try {
621 int c = is.read();
622 assertTrue("returned incorrect char", (char) c == fileString
623 .charAt(0));
624 InputStreamReader reader = new InputStreamReader(
625 new ByteArrayInputStream(new byte[] { (byte) 0xe8,
626 (byte) 0x9d, (byte) 0xa5 }), "UTF8");
627 assertTrue("wrong double byte char", reader.read() == '\u8765');
628 } catch (IOException e) {
629 fail("Exception during read test : " + e.getMessage());
630 }
631
632 // Regression for HARMONY-166
633 InputStream in;
634 InputStreamReader reader;
635
636 in = new LimitedByteArrayInputStream(0);
637 reader = new InputStreamReader(in, "UTF-16BE");
638 assertEquals("Incorrect byte UTF-16BE", '\u6172', reader.read());
639
640 in = new LimitedByteArrayInputStream(0);
641 reader = new InputStreamReader(in, "UTF-16LE");
642 assertEquals("Incorrect byte UTF-16BE", '\u7261', reader.read());
643
644 in = new LimitedByteArrayInputStream(1);
645 reader = new InputStreamReader(in, "UTF-16");
646 assertEquals("Incorrect byte UTF-16BE", '\u7261', reader.read());
647
648 in = new LimitedByteArrayInputStream(2);
649 reader = new InputStreamReader(in, "ISO2022JP");
650 assertEquals("Incorrect byte ISO2022JP 1", '\u4e5d', reader.read());
651 assertEquals("Incorrect byte ISO2022JP 2", '\u7b2c', reader.read());
652 }
653
654 /**
655 * @tests java.io.InputStreamReader#read(char[], int, int)
656 */
657 @TestTargetNew(
658 level = TestLevel.PARTIAL_COMPLETE,
659 notes = "",
660 method = "read",
661 args = {char[].class, int.class, int.class}
662 )
663 public void test_read$CII() {
664 // Test for method int java.io.InputStreamReader.read(char [], int, int)
665 try {
666 char[] rbuf = new char[100];
667 char[] sbuf = new char[100];
668 fileString.getChars(0, 100, sbuf, 0);
669 is.read(rbuf, 0, 100);
670 for (int i = 0; i < rbuf.length; i++)
671 assertTrue("returned incorrect chars", rbuf[i] == sbuf[i]);
672 } catch (IOException e) {
673 fail("Exception during read test : " + e.getMessage());
674 }
675 }
676
677 /**
678 * @tests java.io.InputStreamReader#ready()
679 */
680 @TestTargetNew(
681 level = TestLevel.PARTIAL_COMPLETE,
682 notes = "[No verification for empty buffer]",
683 method = "ready",
684 args = {}
685 )
686 public void test_ready() {
687 // Test for method boolean java.io.InputStreamReader.ready()
688 try {
689 assertTrue("Ready test failed", is.ready());
690 is.read();
691 assertTrue("More chars, but not ready", is.ready());
692 } catch (IOException e) {
693 fail("Exception during ready test : " + e.getMessage());
694 }
695 }
696
697 /**
698 * Test for regression of a bug that dropped characters when
699 * multibyte encodings spanned buffer boundaries.
700 */
701 @TestTargetNew(
702 level = TestLevel.PARTIAL_COMPLETE,
703 notes = "",
704 method = "read",
705 args = {}
706 )
707 public void test_readWhenCharacterSpansBuffer() {
708 final byte[] suffix = {
709 (byte) 0x93, (byte) 0xa1, (byte) 0x8c, (byte) 0xb4,
710 (byte) 0x97, (byte) 0x43, (byte) 0x88, (byte) 0xea,
711 (byte) 0x98, (byte) 0x59
712 };
713 final char[] decodedSuffix = {
714 (char) 0x85e4, (char) 0x539f, (char) 0x4f51, (char) 0x4e00,
715 (char) 0x90ce
716 };
717 final int prefixLength = 8189;
718
719 byte[] bytes = new byte[prefixLength + 10];
720 Arrays.fill(bytes, (byte) ' ');
721 System.arraycopy(suffix, 0, bytes, prefixLength, suffix.length);
722 ByteArrayInputStream is = new ByteArrayInputStream(bytes);
723
724 try {
725 InputStreamReader isr = new InputStreamReader(is, "SHIFT_JIS");
726 char[] chars = new char[8192];
727 int at = 0;
728
729 for (;;) {
730 int amt = isr.read(chars);
731 if (amt <= 0) {
732 break;
733 }
734
735 for (int i = 0; i < amt; i++) {
736 char c = chars[i];
737 if (at < prefixLength) {
738 if (c != ' ') {
739 fail("Found bad prefix character " +
740 (int) c + " at " + at);
741 }
742 } else {
743 char decoded = decodedSuffix[at - prefixLength];
744 if (c != decoded) {
745 fail("Found mismatched character " +
746 (int) c + " at " + at);
747 }
748 }
749 at++;
750 }
751 }
752 } catch (IOException ex) {
753 throw new RuntimeException("unexpected exception", ex);
754 }
755 }
756}