1 /* 2 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package test.java.io.InputStream; 24 25 import java.io.ByteArrayInputStream; 26 import java.io.FilterInputStream; 27 import java.io.IOException; 28 import java.io.InputStream; 29 import java.util.Arrays; 30 import java.util.Random; 31 import org.testng.annotations.Test; 32 33 /* 34 * @test 35 * @bug 8080835 8139206 36 * @library /test/lib 37 * @build jdk.test.lib.RandomFactory 38 * @run main ReadNBytes 39 * @summary Basic test for InputStream.readNBytes 40 * @key randomness 41 */ 42 43 public class ReadNBytes { 44 45 private static Random generator = new Random(); 46 47 @Test testReadNBytes()48 public void testReadNBytes() throws IOException { 49 test(new byte[]{1, 2, 3}); 50 test(createRandomBytes(1024)); 51 for (int shift : new int[] {13, 15, 17}) { 52 for (int offset : new int[] {-1, 0, 1}) { 53 test(createRandomBytes((1 << shift) + offset)); 54 } 55 } 56 57 test(-1); 58 test(0); 59 for (int shift : new int[] {13, 15, 17}) { 60 for (int offset : new int[] {-1, 0, 1}) { 61 test((1 << shift) + offset); 62 } 63 } 64 } 65 test(byte[] inputBytes)66 static void test(byte[] inputBytes) throws IOException { 67 int length = inputBytes.length; 68 WrapperInputStream in = new WrapperInputStream(new ByteArrayInputStream(inputBytes)); 69 byte[] readBytes = new byte[(length / 2) + 1]; 70 int nread = in.readNBytes(readBytes, 0, readBytes.length); 71 72 int x; 73 byte[] tmp; 74 check(nread == readBytes.length, 75 "Expected number of bytes read: " + readBytes.length + ", got: " + nread); 76 check(Arrays.equals((tmp = Arrays.copyOf(inputBytes, nread)), readBytes), 77 "Expected[" + tmp + "], got:[" + readBytes + "]"); 78 check(!in.isClosed(), "Stream unexpectedly closed"); 79 80 // Read again 81 nread = in.readNBytes(readBytes, 0, readBytes.length); 82 83 check(nread == length - readBytes.length, 84 "Expected number of bytes read: " + (length - readBytes.length) + ", got: " + nread); 85 check(Arrays.equals((tmp = Arrays.copyOfRange(inputBytes, readBytes.length, length)), 86 Arrays.copyOf(readBytes, nread)), 87 "Expected[" + tmp + "], got:[" + readBytes + "]"); 88 // Expect end of stream 89 check((x = in.read()) == -1, 90 "Expected end of stream from read(), got " + x); 91 check((x = in.read(tmp)) == -1, 92 "Expected end of stream from read(byte[]), got " + x); 93 check((x = in.read(tmp, 0, tmp.length)) == -1, 94 "Expected end of stream from read(byte[], int, int), got " + x); 95 check((x = in.readNBytes(tmp, 0, tmp.length)) == 0, 96 "Expected end of stream, 0, from readNBytes(byte[], int, int), got " + x); 97 check(!in.isClosed(), "Stream unexpectedly closed"); 98 } 99 test(int max)100 static void test(int max) throws IOException { 101 byte[] inputBytes = max <= 0 ? new byte[0] : createRandomBytes(max); 102 WrapperInputStream in = 103 new WrapperInputStream(new ByteArrayInputStream(inputBytes)); 104 105 if (max < 0) { 106 try { 107 in.readNBytes(max); 108 check(false, "Expected IllegalArgumentException not thrown"); 109 } catch (IllegalArgumentException iae) { 110 return; 111 } 112 } else if (max == 0) { 113 int x; 114 check((x = in.readNBytes(max).length) == 0, 115 "Expected zero bytes, got " + x); 116 return; 117 } 118 119 int off = Math.toIntExact(in.skip(generator.nextInt(max/2))); 120 int len = generator.nextInt(max - 1 - off); 121 byte[] readBytes = in.readNBytes(len); 122 check(readBytes.length == len, 123 "Expected " + len + " bytes, got " + readBytes.length); 124 check(Arrays.equals(Arrays.copyOfRange(inputBytes, off, off + len), readBytes), 125 "Expected[" + Arrays.copyOfRange(inputBytes, off, off + len) + 126 "], got:[" + readBytes + "]"); 127 128 int remaining = max - (off + len); 129 readBytes = in.readNBytes(remaining); 130 check(readBytes.length == remaining, 131 "Expected " + remaining + "bytes, got " + readBytes.length); 132 check(Arrays.equals(Arrays.copyOfRange(inputBytes, off + len, max), 133 readBytes), 134 "Expected[" + Arrays.copyOfRange(inputBytes, off + len, max) + 135 "], got:[" + readBytes + "]"); 136 137 check(!in.isClosed(), "Stream unexpectedly closed"); 138 } 139 createRandomBytes(int size)140 static byte[] createRandomBytes(int size) { 141 byte[] bytes = new byte[size]; 142 generator.nextBytes(bytes); 143 return bytes; 144 } 145 check(boolean cond, Object ... failedArgs)146 static void check(boolean cond, Object ... failedArgs) { 147 if (cond) 148 return; 149 StringBuilder sb = new StringBuilder(); 150 for (Object o : failedArgs) 151 sb.append(o); 152 throw new RuntimeException(sb.toString()); 153 } 154 155 156 static class WrapperInputStream extends FilterInputStream { 157 private boolean closed; WrapperInputStream(InputStream in)158 WrapperInputStream(InputStream in) { super(in); } close()159 @Override public void close() throws IOException { closed = true; in.close(); } isClosed()160 boolean isClosed() { return closed; } 161 } 162 }