test/jdk/java/util/zip/DeInflate.java

Print this page


   1 /*
   2  * Copyright (c) 2011, 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 /**
  25  * @test
  26  * @bug 7110149 8184306
  27  * @summary Test basic deflater & inflater functionality
  28  * @key randomness
  29  */
  30 
  31 import java.io.*;

  32 import java.util.*;
  33 import java.util.zip.*;
  34 


  35 public class DeInflate {
  36 



  37     static void checkStream(Deflater def, byte[] in, int len,
  38                             byte[] out1, byte[] out2, boolean nowrap)
  39         throws Throwable
  40     {
  41         Arrays.fill(out1, (byte)0);
  42         Arrays.fill(out2, (byte)0);
  43 
  44         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  45         try (DeflaterOutputStream defos = new DeflaterOutputStream(baos, def)) {
  46             defos.write(in, 0, len);
  47         }
  48         out1 = baos.toByteArray();
  49         int m = out1.length;
  50 
  51         Inflater inf = new Inflater(nowrap);
  52         inf.setInput(out1, 0, m);
  53         int n = inf.inflate(out2);
  54 
  55         if (n != len ||
  56             !Arrays.equals(Arrays.copyOf(in, len), Arrays.copyOf(out2, len)) ||
  57             inf.inflate(out2) != 0) {
  58             System.out.printf("m=%d, n=%d, len=%d, eq=%b%n",
  59                               m, n, len, Arrays.equals(in, out2));
  60             throw new RuntimeException("De/inflater failed:" + def);
  61         }
  62     }
  63 



















































  64     static void check(Deflater def, byte[] in, int len,
  65                       byte[] out1, byte[] out2, boolean nowrap)
  66         throws Throwable
  67     {
  68         Arrays.fill(out1, (byte)0);
  69         Arrays.fill(out2, (byte)0);
  70 
  71         def.setInput(in, 0, len);
  72         def.finish();
  73         int m = def.deflate(out1);
  74 
  75         Inflater inf = new Inflater(nowrap);
  76         inf.setInput(out1, 0, m);
  77         int n = inf.inflate(out2);
  78 
  79         if (n != len ||
  80             !Arrays.equals(Arrays.copyOf(in, len), Arrays.copyOf(out2, len)) ||
  81             inf.inflate(out2) != 0) {
  82             System.out.printf("m=%d, n=%d, len=%d, eq=%b%n",
  83                               m, n, len, Arrays.equals(in, out2));
  84             throw new RuntimeException("De/inflater failed:" + def);
  85         }





































































































  86     }
  87 
  88     private static Deflater newDeflater(int level, int strategy, boolean dowrap, byte[] tmp) {
  89         Deflater def = new Deflater(level, dowrap);
  90         if (strategy != Deflater.DEFAULT_STRATEGY) {
  91             def.setStrategy(strategy);
  92             // The first invocation after setLevel/Strategy()
  93             // with a different level/stragety returns 0, if
  94             // there is no need to flush out anything for the
  95             // previous setting/"data", this is tricky and
  96             // appears un-documented.
  97             def.deflate(tmp);
  98         }
  99         return def;
 100     }
 101 
 102     private static Deflater resetDeflater(Deflater def, int level, int strategy) {
 103         def.setLevel(level);
 104         def.setStrategy(strategy);
 105         def.reset();
 106         return def;
 107     }
 108 
 109     public static void main(String[] args) throws Throwable {
 110 
 111         byte[] dataIn = new byte[1024 * 512];
 112         new Random().nextBytes(dataIn);
 113         byte[] dataOut1 = new byte[dataIn.length + 1024];
 114         byte[] dataOut2 = new byte[dataIn.length];
 115 
 116         Deflater defNotWrap = new Deflater(Deflater.DEFAULT_COMPRESSION, false);
 117         Deflater defWrap = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
 118 
 119         for (int level = Deflater.DEFAULT_COMPRESSION;
 120                  level <= Deflater.BEST_COMPRESSION; level++) {
 121             for (int strategy = Deflater.DEFAULT_STRATEGY;
 122                      strategy <= Deflater.HUFFMAN_ONLY; strategy++) {
 123                 for (boolean dowrap : new boolean[] { false, true }) {
 124                     System.out.println("level:" + level +
 125                                      ", strategy: " + strategy +
 126                                      ", dowrap: " + dowrap);
 127                     for (int i = 0; i < 5; i++) {
 128                         int len = (i == 0)? dataIn.length
 129                                           : new Random().nextInt(dataIn.length);
 130                         // use a new deflater
 131                         Deflater def = newDeflater(level, strategy, dowrap, dataOut2);
 132                         check(def, dataIn, len, dataOut1, dataOut2, dowrap);

 133 
 134                         // reuse the deflater (with reset) and test on stream, which
 135                         // uses a "smaller" buffer (smaller than the overall data)
 136                         def = resetDeflater(dowrap ? defWrap : defNotWrap, level, strategy);
 137                         checkStream(def, dataIn, len, dataOut1, dataOut2, dowrap);
 138                     }
 139                 }


 140             }
 141         }
 142     }
 143 }
   1 /*
   2  * Copyright (c) 2011, 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 
  24 /**
  25  * @test
  26  * @bug 7110149 8184306 6341887
  27  * @summary Test basic deflater & inflater functionality
  28  * @key randomness
  29  */
  30 
  31 import java.io.*;
  32 import java.nio.*;
  33 import java.util.*;
  34 import java.util.zip.*;
  35 
  36 import static java.nio.charset.StandardCharsets.UTF_8;
  37 
  38 public class DeInflate {
  39 
  40     private static Random rnd = new Random();
  41 
  42 
  43     static void checkStream(Deflater def, byte[] in, int len,
  44                             byte[] out1, byte[] out2, boolean nowrap)
  45         throws Throwable
  46     {
  47         Arrays.fill(out1, (byte)0);
  48         Arrays.fill(out2, (byte)0);
  49 
  50         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  51         try (DeflaterOutputStream defos = new DeflaterOutputStream(baos, def)) {
  52             defos.write(in, 0, len);
  53         }
  54         out1 = baos.toByteArray();
  55         int m = out1.length;
  56 
  57         Inflater inf = new Inflater(nowrap);
  58         inf.setInput(out1, 0, m);
  59         int n = inf.inflate(out2);
  60 
  61         if (n != len ||
  62             !Arrays.equals(Arrays.copyOf(in, len), Arrays.copyOf(out2, len)) ||
  63             inf.inflate(out2) != 0) {
  64             System.out.printf("m=%d, n=%d, len=%d, eq=%b%n",
  65                               m, n, len, Arrays.equals(in, out2));
  66             throw new RuntimeException("De/inflater failed:" + def);
  67         }
  68     }
  69 
  70     static void checkByteBuffer(Deflater def, Inflater inf,
  71                                 ByteBuffer in, ByteBuffer out1, ByteBuffer out2,
  72                                 byte[] expected, int len, byte[] result,
  73                                 boolean out1ReadOnlyWhenInflate)
  74             throws Throwable {
  75         def.reset();
  76         inf.reset();
  77 
  78         def.setInput(in);        
  79         def.finish();
  80         int m = def.deflate(out1);
  81 
  82         out1.flip();
  83         if (out1ReadOnlyWhenInflate)
  84             out1 = out1.asReadOnlyBuffer();
  85         inf.setInput(out1);
  86         int n = inf.inflate(out2);
  87 
  88         out2.flip();
  89         out2.get(result, 0, n);
  90 
  91         if (n != len || out2.position() != len ||
  92             !Arrays.equals(Arrays.copyOf(expected, len), Arrays.copyOf(result, len)) ||
  93             inf.inflate(result) != 0) {
  94             throw new RuntimeException("De/inflater(buffer) failed:" + def);
  95         }
  96     }
  97 
  98     static void checkByteBufferReadonly(Deflater def, Inflater inf,
  99                                         ByteBuffer in, ByteBuffer out1, ByteBuffer out2)
 100             throws Throwable {
 101         def.reset();
 102         inf.reset();
 103         def.setInput(in);        
 104         def.finish();
 105         int m = -1;
 106         if (!out2.isReadOnly())
 107             out2 = out2.asReadOnlyBuffer();
 108         try {
 109             m = def.deflate(out2);
 110             throw new RuntimeException("deflater: ReadOnlyBufferException: failed");
 111         } catch (ReadOnlyBufferException robe) {}
 112         m = def.deflate(out1);
 113         out1.flip();
 114         inf.setInput(out1);
 115         try {
 116             inf.inflate(out2);
 117             throw new RuntimeException("inflater: ReadOnlyBufferException: failed");
 118         } catch (ReadOnlyBufferException robe) {}
 119     }
 120 
 121     static void check(Deflater def, byte[] in, int len,
 122                       byte[] out1, byte[] out2, boolean nowrap)
 123         throws Throwable
 124     {
 125         Arrays.fill(out1, (byte)0);
 126         Arrays.fill(out2, (byte)0);
 127 
 128         def.setInput(in, 0, len);
 129         def.finish();
 130         int m = def.deflate(out1);
 131 
 132         Inflater inf = new Inflater(nowrap);
 133         inf.setInput(out1, 0, m);
 134         int n = inf.inflate(out2);
 135 
 136         if (n != len ||
 137             !Arrays.equals(Arrays.copyOf(in, len), Arrays.copyOf(out2, len)) ||
 138             inf.inflate(out2) != 0) {
 139             System.out.printf("m=%d, n=%d, len=%d, eq=%b%n",
 140                               m, n, len, Arrays.equals(in, out2));
 141             throw new RuntimeException("De/inflater failed:" + def);
 142         }
 143 
 144         // readable
 145         Arrays.fill(out1, (byte)0);
 146         Arrays.fill(out2, (byte)0);
 147         ByteBuffer bbIn = ByteBuffer.wrap(in, 0, len);
 148         ByteBuffer bbOut1 = ByteBuffer.wrap(out1);
 149         ByteBuffer bbOut2 = ByteBuffer.wrap(out2);
 150         checkByteBuffer(def, inf, bbIn, bbOut1, bbOut2, in, len, out2, false);
 151         checkByteBufferReadonly(def, inf, bbIn, bbOut1, bbOut2);
 152 
 153         // readonly in
 154         Arrays.fill(out1, (byte)0);
 155         Arrays.fill(out2, (byte)0);
 156         bbIn = ByteBuffer.wrap(in, 0, len).asReadOnlyBuffer();
 157         bbOut1 = ByteBuffer.wrap(out1);
 158         bbOut2 = ByteBuffer.wrap(out2);
 159         checkByteBuffer(def, inf, bbIn, bbOut1, bbOut2, in, len, out2, false);
 160         checkByteBufferReadonly(def, inf, bbIn, bbOut1, bbOut2);
 161 
 162         // readonly out1 when inflate
 163         Arrays.fill(out1, (byte)0);
 164         Arrays.fill(out2, (byte)0);
 165         bbIn = ByteBuffer.wrap(in, 0, len);
 166         bbOut1 = ByteBuffer.wrap(out1);
 167         bbOut2 = ByteBuffer.wrap(out2);
 168         checkByteBuffer(def, inf, bbIn, bbOut1, bbOut2, in, len, out2, true);
 169         checkByteBufferReadonly(def, inf, bbIn, bbOut1, bbOut2);
 170 
 171         // direct
 172         bbIn = ByteBuffer.allocateDirect(in.length);
 173         bbIn.put(in, 0, n).flip();
 174         bbOut1 = ByteBuffer.allocateDirect(out1.length);
 175         bbOut2 = ByteBuffer.allocateDirect(out2.length);
 176         checkByteBuffer(def, inf, bbIn, bbOut1, bbOut2, in, len, out2, false);
 177         checkByteBufferReadonly(def, inf, bbIn, bbOut1, bbOut2);
 178     }
 179 
 180     static void checkDict(Deflater def, Inflater inf, byte[] src,
 181                           byte[] dstDef, byte[] dstInf,
 182                           ByteBuffer dictDef,  ByteBuffer dictInf) throws Throwable {
 183         def.reset();
 184         inf.reset();
 185 
 186         def.setDictionary(dictDef);
 187         def.setInput(src);
 188         def.finish();
 189         int n = def.deflate(dstDef);
 190 
 191         inf.setInput(dstDef, 0, n);
 192         n = inf.inflate(dstInf);
 193         if (n != 0 || !inf.needsDictionary()) {
 194             throw new RuntimeException("checkDict failed: need dict to continue");
 195         }
 196         inf.setDictionary(dictInf);
 197         n = inf.inflate(dstInf);
 198         // System.out.println("result: " + new String(dstInf, 0, n));
 199         if (n != src.length || !Arrays.equals(Arrays.copyOf(dstInf, n), src)) {
 200             throw new RuntimeException("checkDict failed: inflate result");
 201         }
 202     }
 203 
 204     static void checkDict(int level, int strategy) throws Throwable {
 205 
 206         Deflater def = newDeflater(level, strategy, false, new byte[0]);
 207         Inflater inf = new Inflater();
 208 
 209         byte[] src = "hello world, hello world, hello sherman".getBytes();
 210         byte[] dict = "hello".getBytes();
 211 
 212         byte[] dstDef = new byte[1024];
 213         byte[] dstInf = new byte[1024];
 214 
 215         def.setDictionary(dict);
 216         def.setInput(src);
 217         def.finish();
 218         int n = def.deflate(dstDef);
 219 
 220         inf.setInput(dstDef, 0, n);
 221         n = inf.inflate(dstInf);
 222         if (n != 0 || !inf.needsDictionary()) {
 223             throw new RuntimeException("checkDict failed: need dict to continue");
 224         }
 225         inf.setDictionary(dict);
 226         n = inf.inflate(dstInf);
 227         //System.out.println("result: " + new String(dstInf, 0, n));
 228         if (n != src.length || !Arrays.equals(Arrays.copyOf(dstInf, n), src)) {
 229             throw new RuntimeException("checkDict failed: inflate result");
 230         }
 231 
 232         ByteBuffer dictDef = ByteBuffer.wrap(dict);
 233         ByteBuffer dictInf = ByteBuffer.wrap(dict);
 234         checkDict(def, inf, src, dstDef, dstInf, dictDef, dictInf);
 235 
 236         dictDef = ByteBuffer.allocateDirect(dict.length);
 237         dictInf = ByteBuffer.allocateDirect(dict.length);
 238         dictDef.put(dict).flip();
 239         dictInf.put(dict).flip();
 240         checkDict(def, inf, src, dstDef, dstInf, dictDef, dictInf);
 241 
 242         def.end();
 243         inf.end();
 244     }
 245 
 246     private static Deflater newDeflater(int level, int strategy, boolean dowrap, byte[] tmp) {
 247         Deflater def = new Deflater(level, dowrap);
 248         if (strategy != Deflater.DEFAULT_STRATEGY) {
 249             def.setStrategy(strategy);
 250             // The first invocation after setLevel/Strategy()
 251             // with a different level/stragety returns 0, if
 252             // there is no need to flush out anything for the
 253             // previous setting/"data", this is tricky and
 254             // appears un-documented.
 255             def.deflate(tmp);
 256         }
 257         return def;
 258     }
 259 
 260     private static Deflater resetDeflater(Deflater def, int level, int strategy) {
 261         def.setLevel(level);
 262         def.setStrategy(strategy);
 263         def.reset();
 264         return def;
 265     }
 266 
 267     public static void main(String[] args) throws Throwable {
 268 
 269         byte[] dataIn = new byte[1024 * 512];
 270         rnd.nextBytes(dataIn);
 271         byte[] dataOut1 = new byte[dataIn.length + 1024];
 272         byte[] dataOut2 = new byte[dataIn.length];
 273 
 274         Deflater defNotWrap = new Deflater(Deflater.DEFAULT_COMPRESSION, false);
 275         Deflater defWrap = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
 276 
 277         for (int level = Deflater.DEFAULT_COMPRESSION;
 278                  level <= Deflater.BEST_COMPRESSION; level++) {
 279             for (int strategy = Deflater.DEFAULT_STRATEGY;
 280                      strategy <= Deflater.HUFFMAN_ONLY; strategy++) {
 281                 for (boolean dowrap : new boolean[] { false, true }) {
 282                     System.out.println("level:" + level +
 283                                      ", strategy: " + strategy +
 284                                      ", dowrap: " + dowrap);
 285                     for (int i = 0; i < 5; i++) {
 286                         int len = (i == 0)? dataIn.length
 287                                           : new Random().nextInt(dataIn.length);
 288                         // use a new deflater
 289                         Deflater def = newDeflater(level, strategy, dowrap, dataOut2);
 290                         check(def, dataIn, len, dataOut1, dataOut2, dowrap);
 291                         def.end();
 292 
 293                         // reuse the deflater (with reset) and test on stream, which
 294                         // uses a "smaller" buffer (smaller than the overall data)
 295                         def = resetDeflater(dowrap ? defWrap : defNotWrap, level, strategy);
 296                         checkStream(def, dataIn, len, dataOut1, dataOut2, dowrap);
 297                     }
 298                 }
 299                 // test setDictionary()
 300                 checkDict(level, strategy);
 301             }
 302         }
 303     }
 304 }