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, null);
 112             failNpeExpected();
 113         } catch (NullPointerException npe) {}
 114 
 115 
 116         try {
 117             Channels.newReader(null, null);
 118             failNpeExpected();
 119         } catch (NullPointerException npe) {}
 120 
 121         try {
 122             Channels.newWriter((WritableByteChannel)null,
 123                                Charset.defaultCharset().newEncoder(),
 124                                -1);
 125             failNpeExpected();
 126         } catch (NullPointerException npe) {}
 127 
 128         try {
 129             Channels.newWriter(null, null, -1);
 130             failNpeExpected();
 131         } catch (NullPointerException npe) {}
 132 
 133         try {
 134             Channels.newWriter(wbc, null, -1);
 135             failNpeExpected();
 136         } catch (NullPointerException npe) {}
 137 
 138         try {
 139             Channels.newWriter((WritableByteChannel)null,
 140                                Charset.defaultCharset().name());
 141             failNpeExpected();
 142         } catch (NullPointerException npe) {}
 143 
 144         try {
 145             Channels.newWriter(wbc, null);
 146             failNpeExpected();
 147         } catch (NullPointerException npe) {}
 148 
 149         try {
 150             Channels.newWriter(null, null);
 151             failNpeExpected();
 152         } catch (NullPointerException npe) {}
 153 
 154 
 155         try {
 156             blah = File.createTempFile("blah", null);
 157 
 158             testNewOutputStream(blah);
 159             readAndCheck(blah);
 160             blah.delete();
 161 
 162             writeOut(blah, ITERATIONS);
 163             testNewInputStream(blah);
 164             blah.delete();
 165 
 166             testNewChannelOut(blah);
 167             readAndCheck(blah);
 168             blah.delete();
 169 
 170             testNewChannelWriteAfterClose(blah);
 171 
 172             testNewChannelReadAfterClose(blah);
 173             blah.delete();
 174 
 175             writeOut(blah, ITERATIONS);
 176             testNewChannelIn(blah);
 177             test4481572(blah);
 178             blah.delete();
 179 
 180             testNewWriter(blah);
 181             readAndCheck(blah);
 182             blah.delete();
 183 
 184             writeOut(blah, ITERATIONS);
 185             testNewReader(blah);
 186 
 187         } finally {
 188             blah.delete();
 189         }
 190     }
 191 
 192     private static void readAndCheck(File blah) throws Exception {
 193         FileInputStream fis = new FileInputStream(blah);
 194         int messageSize = message.length() * ITERATIONS * 3 + 1;
 195         byte bb[] = new byte[messageSize];
 196         int bytesRead = 0;
 197         int totalRead = 0;
 198         while (bytesRead != -1) {
 199             totalRead += bytesRead;
 200             bytesRead = fis.read(bb, totalRead, messageSize - totalRead);
 201         }
 202         String result = new String(bb, 0, totalRead, encoding);
 203         int len = message.length();
 204         for (int i=0; i<ITERATIONS; i++) {
 205             String segment = result.substring(i++ * len, i * len);
 206             if (!segment.equals(message))
 207                 throw new RuntimeException("Test failed");
 208         }
 209         fis.close();
 210     }
 211 
 212     private static void writeOut(File blah, int limit) throws Exception {
 213         FileOutputStream fos = new FileOutputStream(blah);
 214         for (int i=0; i<limit; i++)
 215             fos.write(message.getBytes(encoding));
 216         fos.close();
 217     }
 218 
 219     private static void testNewOutputStream(File blah) throws Exception {
 220         FileOutputStream fos = new FileOutputStream(blah);
 221         FileChannel fc = fos.getChannel();
 222         WritableByteChannel wbc = (WritableByteChannel)fc;
 223         OutputStream os = Channels.newOutputStream(wbc);
 224         for (int i=0; i<ITERATIONS; i++)
 225             os.write(message.getBytes(encoding));
 226         os.close();
 227         fos.close();
 228     }
 229 
 230     private static void testNewInputStream(File blah) throws Exception {
 231         FileInputStream fis = new FileInputStream(blah);
 232         FileChannel fc = fis.getChannel();
 233         InputStream is = Channels.newInputStream(fc);
 234         int messageSize = message.length() * ITERATIONS * 3 + 1;
 235         byte bb[] = new byte[messageSize];
 236 
 237         int bytesRead = 0;
 238         int totalRead = 0;
 239         while (bytesRead != -1) {
 240             totalRead += bytesRead;
 241             long rem = Math.min(fc.size() - totalRead, (long)Integer.MAX_VALUE);
 242             if (is.available() != (int)rem)
 243                 throw new RuntimeException("available not useful or not maximally useful");
 244             bytesRead = is.read(bb, totalRead, messageSize - totalRead);
 245         }
 246         if (is.available() != 0)
 247            throw new RuntimeException("available() should return 0 at EOF");
 248 
 249         String result = new String(bb, 0, totalRead, encoding);
 250         int len = message.length();
 251         for (int i=0; i<ITERATIONS; i++) {
 252             String segment = result.substring(i++ * len, i * len);
 253             if (!segment.equals(message))
 254                 throw new RuntimeException("Test failed");
 255         }
 256         is.close();
 257         fis.close();
 258     }
 259 
 260     private static void testNewChannelOut(File blah) throws Exception {
 261         ExtendedFileOutputStream fos = new ExtendedFileOutputStream(blah);
 262         WritableByteChannel wbc = Channels.newChannel(fos);
 263 
 264         for (int i=0; i<ITERATIONS; i++)
 265             wbc.write(ByteBuffer.wrap(message.getBytes(encoding)));
 266         wbc.close();
 267         fos.close();
 268     }
 269 
 270     private static void testNewChannelIn(File blah) throws Exception {
 271         ExtendedFileInputStream fis = new ExtendedFileInputStream(blah);
 272         ReadableByteChannel rbc = Channels.newChannel(fis);
 273 
 274         int messageSize = message.length() * ITERATIONS * 3;
 275         byte data[] = new byte[messageSize+1];
 276         ByteBuffer bb = ByteBuffer.wrap(data);
 277 
 278         int bytesRead = 0;
 279         int totalRead = 0;
 280         while (bytesRead != -1) {
 281             totalRead += bytesRead;
 282             bytesRead = rbc.read(bb);
 283         }
 284 
 285         String result = new String(data, 0, totalRead, encoding);
 286         int len = message.length();
 287         for (int i=0; i<ITERATIONS; i++) {
 288             String segment = result.substring(i++ * len, i * len);
 289             if (!segment.equals(message))
 290                 throw new RuntimeException("Test failed");
 291         }
 292         rbc.close();
 293         fis.close();
 294     }
 295 
 296     private static void testNewChannelWriteAfterClose(File blah)
 297         throws Exception {
 298         try (ExtendedFileOutputStream fos =
 299             new ExtendedFileOutputStream(blah)) {
 300             WritableByteChannel wbc = Channels.newChannel(fos);
 301 
 302             wbc.close();
 303             try {
 304                 wbc.write(ByteBuffer.allocate(0));
 305                 throw new RuntimeException
 306                     ("No ClosedChannelException on WritableByteChannel::write");
 307             } catch (ClosedChannelException expected) {
 308             }
 309         }
 310     }
 311 
 312     private static void testNewChannelReadAfterClose(File blah)
 313         throws Exception {
 314         try (ExtendedFileInputStream fis = new ExtendedFileInputStream(blah)) {
 315             ReadableByteChannel rbc = Channels.newChannel(fis);
 316 
 317             rbc.close();
 318             try {
 319                 rbc.read(ByteBuffer.allocate(0));
 320                 throw new RuntimeException
 321                     ("No ClosedChannelException on ReadableByteChannel::read");
 322             } catch (ClosedChannelException expected) {
 323             }
 324         }
 325     }
 326 
 327     // Causes BufferOverflowException if bug 4481572 is present.
 328     private static void test4481572(File blah) throws Exception {
 329         ExtendedFileInputStream fis = new ExtendedFileInputStream(blah);
 330         ReadableByteChannel rbc = Channels.newChannel(fis);
 331 
 332         byte data[] = new byte[9000];
 333         ByteBuffer bb = ByteBuffer.wrap(data);
 334 
 335         int bytesRead = 1;
 336         int totalRead = 0;
 337         while (bytesRead > 0) {
 338             totalRead += bytesRead;
 339             bytesRead = rbc.read(bb);
 340         }
 341         rbc.close();
 342         fis.close();
 343     }
 344 
 345     private static void testNewWriter(File blah) throws Exception {
 346         FileOutputStream fos = new FileOutputStream(blah);
 347         WritableByteChannel wbc = (WritableByteChannel)fos.getChannel();
 348         Writer w = Channels.newWriter(wbc, encoding);
 349         char data[] = new char[40];
 350         message.getChars(0, message.length(), data, 0);
 351         for (int i=0; i<ITERATIONS; i++)
 352             w.write(data, 0, message.length());
 353         w.flush();
 354         w.close();
 355         fos.close();
 356     }
 357 
 358     private static void testNewReader(File blah) throws Exception {
 359         FileInputStream fis = new FileInputStream(blah);
 360         ReadableByteChannel rbc = (ReadableByteChannel)fis.getChannel();
 361         Reader r = Channels.newReader(rbc, encoding);
 362 
 363         int messageSize = message.length() * ITERATIONS;
 364         char data[] = new char[messageSize];
 365 
 366         int totalRead = 0;
 367         int charsRead = 0;
 368         while (totalRead < messageSize) {
 369             totalRead += charsRead;
 370             charsRead = r.read(data, totalRead, messageSize - totalRead);
 371         }
 372         String result = new String(data, 0, totalRead);
 373         int len = message.length();
 374         for (int i=0; i<ITERATIONS; i++) {
 375             String segment = result.substring(i++ * len, i * len);
 376             if (!segment.equals(message))
 377                 throw new RuntimeException("Test failed");
 378         }
 379         r.close();
 380         fis.close();
 381     }
 382 }
 383 
 384 class ExtendedFileInputStream extends java.io.FileInputStream {
 385     ExtendedFileInputStream(File file) throws FileNotFoundException {
 386         super(file);
 387     }
 388 }
 389 
 390 class ExtendedFileOutputStream extends java.io.FileOutputStream {
 391     ExtendedFileOutputStream(File file) throws FileNotFoundException {
 392         super(file);
 393     }
 394 }