1 /*
   2  * Copyright (c) 2006, 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 /**
  25  * @test
  26  * @bug 4679743
  27  * @summary Test basic functionality of DeflaterInputStream and InflaterOutputStream
  28  * @key randomness
  29  */
  30 
  31 import java.io.*;
  32 import java.util.*;
  33 import java.util.zip.*;
  34 
  35 public class DeflateIn_InflateOut {
  36     private static byte[] data = new byte[1024 * 1024];
  37 
  38     private static ByteArrayInputStream bais;
  39     private static DeflaterInputStream dis;
  40 
  41     private static ByteArrayOutputStream baos;
  42     private static InflaterOutputStream ios;
  43 
  44     private static void reset() {
  45         new Random(new Date().getTime()).nextBytes(data);
  46 
  47         bais = new ByteArrayInputStream(data);
  48         dis = new DeflaterInputStream(bais);
  49 
  50         baos = new ByteArrayOutputStream();
  51         ios = new InflaterOutputStream(baos);
  52     }
  53 
  54     /** Check byte arrays read/write. */
  55     private static void ArrayReadWrite() throws Throwable {
  56         byte[] buf = new byte[512];
  57 
  58         reset();
  59         check(dis.available() == 1);
  60         for (;;) {
  61             int len = dis.read(buf, 0, buf.length);
  62             if (len < 0) {
  63                 break;
  64             } else {
  65                 ios.write(buf, 0, len);
  66             }
  67         }
  68         check(dis.available() == 0);
  69         ios.close();
  70         check(Arrays.equals(data, baos.toByteArray()));
  71     }
  72 
  73     /** Check byte arrays read, single byte write */
  74     private static void ArrayReadByteWrite() throws Throwable {
  75         byte[] buf = new byte[512];
  76 
  77         reset();
  78         for (;;) {
  79             int len = dis.read(buf, 0, buf.length);
  80             if (len <= 0) {
  81                 break;
  82             } else {
  83                 for (int i = 0; i < len; i++) {
  84                     byte x = (byte) (buf[i] & 0xff);
  85                     ios.write(x);
  86                 }
  87             }
  88         }
  89         check(dis.available() == 0);
  90         ios.close();
  91         check(Arrays.equals(data, baos.toByteArray()));
  92     }
  93 
  94     /** Check single byte read, byte array write.
  95      * <p>
  96      * Note that this test relies on the vaule from DeflaterInputStream.read()
  97      * to determine when to stop reading.
  98      */
  99     private static void ByteReadArrayWrite() throws Throwable {
 100         byte[] buf = new byte[8192];
 101         int off = 0;
 102 
 103         reset();
 104         int datum = dis.read();
 105         while (datum != -1) {
 106             if (off == 8192) {
 107                 ios.write(buf, 0, off);
 108                 off = 0;
 109             }
 110             buf[off++] = (byte) (datum & 0xff);
 111             datum = dis.read();
 112         }
 113         if (off > 0) {
 114             ios.write(buf, 0, off);
 115         }
 116         ios.close();
 117         check(Arrays.equals(data, baos.toByteArray()));
 118     }
 119 
 120     /** Check single byte read/write.
 121      * <p>
 122      * Note that this test relies on DeflaterInputStream.available() to
 123      * determine when to stop reading.
 124      */
 125     private static void ByteReadByteWrite() throws Throwable {
 126         byte[] buf = new byte[512];
 127         boolean reachEOF = false;
 128 
 129         reset();
 130         while (dis.available() == 1) {
 131             int datum = dis.read();
 132             if (datum == -1) {
 133                 reachEOF = true;
 134             } else {
 135                 if (datum < 0 || datum > 255) {
 136                     fail("datum out of range: " + datum);
 137                 }
 138                 ios.write(datum);
 139             }
 140         }
 141         dis.close();
 142         ios.close();
 143         check(data[0] == baos.toByteArray()[0]);
 144     }
 145 
 146     /** Check skip(). */
 147     private static void SkipBytes() throws Throwable {
 148         byte[] buf = new byte[512];
 149         int numReadable = 0;
 150 
 151         // Count number of bytes that are read
 152         reset();
 153         check(dis.available() == 1);
 154         for (;;) {
 155             int count = dis.read(buf, 0, buf.length);
 156             if (count < 0) {
 157                 break;
 158             } else {
 159                 numReadable += count;
 160             }
 161         }
 162         check(dis.available() == 0);
 163 
 164         // Verify that skipping the first several bytes works.
 165         reset();
 166         int numNotSkipped = 0;
 167         int numSkipBytes = 2053; // arbitrarily chosen prime
 168         check(dis.skip(numSkipBytes) == numSkipBytes);
 169         for (int i = 0; ; i++) {
 170             int count = dis.read(buf, 0, buf.length);
 171             if (count < 0) {
 172                 break;
 173             } else {
 174                 numNotSkipped += count;
 175             }
 176         }
 177         check(numNotSkipped + numSkipBytes == numReadable);
 178 
 179         // Verify that skipping some bytes mid-stream works.
 180         reset();
 181         numNotSkipped = 0;
 182         numSkipBytes = 8887; // arbitrarily chosen prime
 183         for (int i = 0; ; i++) {
 184             if (i == 13) { // Arbitrarily chosen
 185                 check(dis.skip(numSkipBytes) == numSkipBytes);
 186             } else {
 187                 int count = dis.read(buf, 0, buf.length);
 188                 if (count < 0) {
 189                     break;
 190                 } else {
 191                     numNotSkipped += count;
 192                 }
 193             }
 194         }
 195         check(numNotSkipped + numSkipBytes == numReadable);
 196 
 197         // Verify that skipping the last N bytes works.
 198         reset();
 199         numNotSkipped = 0;
 200         numSkipBytes = 6449; // arbitrarily chosen prime
 201         for (int i = 0; ; i++) {
 202             if (numNotSkipped + numSkipBytes > numReadable) {
 203                 numSkipBytes = numReadable - numNotSkipped;
 204                 check(dis.skip(numSkipBytes) == numSkipBytes);
 205                 check(dis.read(buf, 0, buf.length) == -1);
 206                 check(dis.available() == 0);
 207             } else {
 208                 int count = dis.read(buf, 0, buf.length);
 209                 if (count < 0) {
 210                     break;
 211                 } else {
 212                     numNotSkipped += count;
 213                 }
 214             }
 215         }
 216         check(numNotSkipped + numSkipBytes == numReadable);
 217     }
 218 
 219 
 220     public static void realMain(String[] args) throws Throwable {
 221         ArrayReadWrite();
 222 
 223         ArrayReadByteWrite();
 224 
 225         ByteReadArrayWrite();
 226 
 227         ByteReadByteWrite();
 228 
 229         SkipBytes();
 230     }
 231 
 232     //--------------------- Infrastructure ---------------------------
 233     static volatile int passed = 0, failed = 0;
 234     static void pass() {passed++;}
 235     static void fail() {failed++; Thread.dumpStack();}
 236     static void fail(String msg) {System.out.println(msg); fail();}
 237     static void unexpected(Throwable t) {failed++; t.printStackTrace();}
 238     static void check(boolean cond) {if (cond) pass(); else fail();}
 239     static void equal(Object x, Object y) {
 240         if (x == null ? y == null : x.equals(y)) pass();
 241         else fail(x + " not equal to " + y);}
 242     public static void main(String[] args) throws Throwable {
 243         try {realMain(args);} catch (Throwable t) {unexpected(t);}
 244         System.out.println("\nPassed = " + passed + " failed = " + failed);
 245         if (failed > 0) throw new AssertionError("Some tests failed");}
 246 }