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