1 /*
   2  * Copyright (c) 2001, 2017, 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 
  24 /* @test
  25  * @bug 4417152 4481572 6248930 6725399 6884800
  26  * @summary Test Channels basic functionality
  27  */
  28 
  29 import java.io.*;
  30 import java.nio.*;
  31 import java.nio.charset.*;
  32 import java.nio.channels.*;
  33 
  34 
  35 public class Basic {
  36 
  37     static String message;
  38 
  39     static String encoding;
  40 
  41     static File blah;
  42 
  43     static int ITERATIONS = 500;
  44 
  45     public static void main(String[] args) throws Exception {
  46         message = "ascii data for a test";
  47         encoding = "ISO-8859-1";
  48         test();
  49         message = "\ucafe\ubabe\ucafe\ubabe\ucafe\ubabe";
  50         encoding = "UTF-8";
  51         test();
  52     }
  53 
  54     static void failNpeExpected() {
  55         throw new RuntimeException("Did not get the expected NullPointerException.");
  56     }
  57 
  58     private static void test() throws Exception {
  59         //Test if methods of Channels throw NPE with null argument(s)
  60         try {
  61             Channels.newInputStream((ReadableByteChannel)null);
  62             failNpeExpected();
  63         } catch (NullPointerException npe) {}
  64 
  65         try {
  66             Channels.newOutputStream((WritableByteChannel)null);
  67             failNpeExpected();
  68         } catch (NullPointerException npe) {}
  69 
  70         try {
  71             ReadableByteChannel channel = Channels.newChannel((InputStream)null);
  72             failNpeExpected();
  73         } catch (NullPointerException ne) {}  // OK. As expected.
  74 
  75         try {
  76             WritableByteChannel channel = Channels.newChannel((OutputStream)null);
  77             failNpeExpected();
  78         } catch (NullPointerException ne) {}  // OK. As expected.
  79 
  80         WritableByteChannel wbc = new WritableByteChannel() {
  81             public int write(ByteBuffer src) { return 0; }
  82             public void close() throws IOException { }
  83             public boolean isOpen() { return true; }
  84         };
  85 
  86         ReadableByteChannel rbc = new ReadableByteChannel() {
  87             public int read(ByteBuffer dst) { return 0; }
  88             public void close() {}
  89             public boolean isOpen() { return true; }
  90         };
  91 
  92         try {
  93             Channels.newReader((ReadableByteChannel)null,
  94                                Charset.defaultCharset().newDecoder(),
  95                                -1);
  96             failNpeExpected();
  97         } catch (NullPointerException npe) {}
  98 
  99         try {
 100             Channels.newReader(rbc, (CharsetDecoder)null, -1);
 101             failNpeExpected();
 102         } catch (NullPointerException npe) {}
 103 
 104         try {
 105             Channels.newReader((ReadableByteChannel)null,
 106                                Charset.defaultCharset().name());
 107             failNpeExpected();
 108         } catch (NullPointerException npe) {}
 109 
 110         try {
 111             Channels.newReader(rbc, (String)null);
 112             failNpeExpected();
 113         } catch (NullPointerException npe) {}
 114 
 115 
 116         try {
 117             Channels.newReader(null, (String)null);
 118             failNpeExpected();
 119         } catch (NullPointerException npe) {}
 120 
 121         try {
 122             Channels.newReader(rbc, (Charset)null);
 123             failNpeExpected();
 124         } catch (NullPointerException npe) {}
 125 
 126 
 127         try {
 128             Channels.newReader(null, (Charset)null);
 129             failNpeExpected();
 130         } catch (NullPointerException npe) {}
 131 
 132         try {
 133             Channels.newWriter((WritableByteChannel)null,
 134                                Charset.defaultCharset().newEncoder(),
 135                                -1);
 136             failNpeExpected();
 137         } catch (NullPointerException npe) {}
 138 
 139         try {
 140             Channels.newWriter(null, null, -1);
 141             failNpeExpected();
 142         } catch (NullPointerException npe) {}
 143 
 144         try {
 145             Channels.newWriter(wbc, null, -1);
 146             failNpeExpected();
 147         } catch (NullPointerException npe) {}
 148 
 149         try {
 150             Channels.newWriter((WritableByteChannel)null,
 151                                Charset.defaultCharset().name());
 152             failNpeExpected();
 153         } catch (NullPointerException npe) {}
 154 
 155         try {
 156             Channels.newWriter(wbc, (String)null);
 157             failNpeExpected();
 158         } catch (NullPointerException npe) {}
 159 
 160         try {
 161             Channels.newWriter(null, (String)null);
 162             failNpeExpected();
 163         } catch (NullPointerException npe) {}
 164 
 165         try {
 166             Channels.newWriter(wbc, (Charset)null);
 167             failNpeExpected();
 168         } catch (NullPointerException npe) {}
 169 
 170         try {
 171             Channels.newWriter(null, (Charset)null);
 172             failNpeExpected();
 173         } catch (NullPointerException npe) {}
 174 
 175         try {
 176             blah = File.createTempFile("blah", null);
 177 
 178             testNewOutputStream(blah);
 179             readAndCheck(blah);
 180             blah.delete();
 181 
 182             writeOut(blah, ITERATIONS);
 183             testNewInputStream(blah);
 184             blah.delete();
 185 
 186             testNewChannelOut(blah);
 187             readAndCheck(blah);
 188             blah.delete();
 189 
 190             testNewChannelWriteAfterClose(blah);
 191 
 192             testNewChannelReadAfterClose(blah);
 193             blah.delete();
 194 
 195             writeOut(blah, ITERATIONS);
 196             testNewChannelIn(blah);
 197             test4481572(blah);
 198             blah.delete();
 199 
 200             testNewWriter(blah);
 201             readAndCheck(blah);
 202             blah.delete();
 203 
 204             writeOut(blah, ITERATIONS);
 205             testNewReader(blah);
 206 
 207         } finally {
 208             blah.delete();
 209         }
 210     }
 211 
 212     private static void readAndCheck(File blah) throws Exception {
 213         FileInputStream fis = new FileInputStream(blah);
 214         int messageSize = message.length() * ITERATIONS * 3 + 1;
 215         byte bb[] = new byte[messageSize];
 216         int bytesRead = 0;
 217         int totalRead = 0;
 218         while (bytesRead != -1) {
 219             totalRead += bytesRead;
 220             bytesRead = fis.read(bb, totalRead, messageSize - totalRead);
 221         }
 222         String result = new String(bb, 0, totalRead, encoding);
 223         int len = message.length();
 224         for (int i=0; i<ITERATIONS; i++) {
 225             String segment = result.substring(i++ * len, i * len);
 226             if (!segment.equals(message))
 227                 throw new RuntimeException("Test failed");
 228         }
 229         fis.close();
 230     }
 231 
 232     private static void writeOut(File blah, int limit) throws Exception {
 233         FileOutputStream fos = new FileOutputStream(blah);
 234         for (int i=0; i<limit; i++)
 235             fos.write(message.getBytes(encoding));
 236         fos.close();
 237     }
 238 
 239     private static void testNewOutputStream(File blah) throws Exception {
 240         FileOutputStream fos = new FileOutputStream(blah);
 241         FileChannel fc = fos.getChannel();
 242         WritableByteChannel wbc = (WritableByteChannel)fc;
 243         OutputStream os = Channels.newOutputStream(wbc);
 244         for (int i=0; i<ITERATIONS; i++)
 245             os.write(message.getBytes(encoding));
 246         os.close();
 247         fos.close();
 248     }
 249 
 250     private static void testNewInputStream(File blah) throws Exception {
 251         FileInputStream fis = new FileInputStream(blah);
 252         FileChannel fc = fis.getChannel();
 253         InputStream is = Channels.newInputStream(fc);
 254         int messageSize = message.length() * ITERATIONS * 3 + 1;
 255         byte bb[] = new byte[messageSize];
 256 
 257         int bytesRead = 0;
 258         int totalRead = 0;
 259         while (bytesRead != -1) {
 260             totalRead += bytesRead;
 261             long rem = Math.min(fc.size() - totalRead, (long)Integer.MAX_VALUE);
 262             if (is.available() != (int)rem)
 263                 throw new RuntimeException("available not useful or not maximally useful");
 264             bytesRead = is.read(bb, totalRead, messageSize - totalRead);
 265         }
 266         if (is.available() != 0)
 267            throw new RuntimeException("available() should return 0 at EOF");
 268 
 269         String result = new String(bb, 0, totalRead, encoding);
 270         int len = message.length();
 271         for (int i=0; i<ITERATIONS; i++) {
 272             String segment = result.substring(i++ * len, i * len);
 273             if (!segment.equals(message))
 274                 throw new RuntimeException("Test failed");
 275         }
 276         is.close();
 277         fis.close();
 278     }
 279 
 280     private static void testNewChannelOut(File blah) throws Exception {
 281         ExtendedFileOutputStream fos = new ExtendedFileOutputStream(blah);
 282         WritableByteChannel wbc = Channels.newChannel(fos);
 283 
 284         for (int i=0; i<ITERATIONS; i++)
 285             wbc.write(ByteBuffer.wrap(message.getBytes(encoding)));
 286         wbc.close();
 287         fos.close();
 288     }
 289 
 290     private static void testNewChannelIn(File blah) throws Exception {
 291         ExtendedFileInputStream fis = new ExtendedFileInputStream(blah);
 292         ReadableByteChannel rbc = Channels.newChannel(fis);
 293 
 294         int messageSize = message.length() * ITERATIONS * 3;
 295         byte data[] = new byte[messageSize+1];
 296         ByteBuffer bb = ByteBuffer.wrap(data);
 297 
 298         int bytesRead = 0;
 299         int totalRead = 0;
 300         while (bytesRead != -1) {
 301             totalRead += bytesRead;
 302             bytesRead = rbc.read(bb);
 303         }
 304 
 305         String result = new String(data, 0, totalRead, encoding);
 306         int len = message.length();
 307         for (int i=0; i<ITERATIONS; i++) {
 308             String segment = result.substring(i++ * len, i * len);
 309             if (!segment.equals(message))
 310                 throw new RuntimeException("Test failed");
 311         }
 312         rbc.close();
 313         fis.close();
 314     }
 315 
 316     private static void testNewChannelWriteAfterClose(File blah)
 317         throws Exception {
 318         try (ExtendedFileOutputStream fos =
 319             new ExtendedFileOutputStream(blah)) {
 320             WritableByteChannel wbc = Channels.newChannel(fos);
 321 
 322             wbc.close();
 323             try {
 324                 wbc.write(ByteBuffer.allocate(0));
 325                 throw new RuntimeException
 326                     ("No ClosedChannelException on WritableByteChannel::write");
 327             } catch (ClosedChannelException expected) {
 328             }
 329         }
 330     }
 331 
 332     private static void testNewChannelReadAfterClose(File blah)
 333         throws Exception {
 334         try (ExtendedFileInputStream fis = new ExtendedFileInputStream(blah)) {
 335             ReadableByteChannel rbc = Channels.newChannel(fis);
 336 
 337             rbc.close();
 338             try {
 339                 rbc.read(ByteBuffer.allocate(0));
 340                 throw new RuntimeException
 341                     ("No ClosedChannelException on ReadableByteChannel::read");
 342             } catch (ClosedChannelException expected) {
 343             }
 344         }
 345     }
 346 
 347     // Causes BufferOverflowException if bug 4481572 is present.
 348     private static void test4481572(File blah) throws Exception {
 349         ExtendedFileInputStream fis = new ExtendedFileInputStream(blah);
 350         ReadableByteChannel rbc = Channels.newChannel(fis);
 351 
 352         byte data[] = new byte[9000];
 353         ByteBuffer bb = ByteBuffer.wrap(data);
 354 
 355         int bytesRead = 1;
 356         int totalRead = 0;
 357         while (bytesRead > 0) {
 358             totalRead += bytesRead;
 359             bytesRead = rbc.read(bb);
 360         }
 361         rbc.close();
 362         fis.close();
 363     }
 364 
 365     private static void testNewWriter(File blah) throws Exception {
 366         FileOutputStream fos = new FileOutputStream(blah);
 367         WritableByteChannel wbc = (WritableByteChannel)fos.getChannel();
 368         Writer w = Channels.newWriter(wbc, encoding);
 369         char data[] = new char[40];
 370         message.getChars(0, message.length(), data, 0);
 371         for (int i=0; i<ITERATIONS; i++)
 372             w.write(data, 0, message.length());
 373         w.flush();
 374         w.close();
 375         fos.close();
 376     }
 377 
 378     private static void testNewReader(File blah) throws Exception {
 379         FileInputStream fis = new FileInputStream(blah);
 380         ReadableByteChannel rbc = (ReadableByteChannel)fis.getChannel();
 381         Reader r = Channels.newReader(rbc, encoding);
 382 
 383         int messageSize = message.length() * ITERATIONS;
 384         char data[] = new char[messageSize];
 385 
 386         int totalRead = 0;
 387         int charsRead = 0;
 388         while (totalRead < messageSize) {
 389             totalRead += charsRead;
 390             charsRead = r.read(data, totalRead, messageSize - totalRead);
 391         }
 392         String result = new String(data, 0, totalRead);
 393         int len = message.length();
 394         for (int i=0; i<ITERATIONS; i++) {
 395             String segment = result.substring(i++ * len, i * len);
 396             if (!segment.equals(message))
 397                 throw new RuntimeException("Test failed");
 398         }
 399         r.close();
 400         fis.close();
 401     }
 402 }
 403 
 404 class ExtendedFileInputStream extends java.io.FileInputStream {
 405     ExtendedFileInputStream(File file) throws FileNotFoundException {
 406         super(file);
 407     }
 408 }
 409 
 410 class ExtendedFileOutputStream extends java.io.FileOutputStream {
 411     ExtendedFileOutputStream(File file) throws FileNotFoundException {
 412         super(file);
 413     }
 414 }