1 /* 2 * Copyright (c) 2011, 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 6571338 27 * @summary Inflater should not require a buffer to the inflate() methods 28 * larger than 1 byte. 29 */ 30 31 import java.io.*; 32 import java.nio.*; 33 import java.util.*; 34 import java.util.zip.*; 35 36 public class InflaterBufferSize { 37 private static final int DATA_LEN = 1024 *64; 38 private static byte[] data; 39 40 // If true, print extra info. 41 private static final boolean debug = System.getProperty("debug") != null; 42 43 private static void debug(String s) { 44 if (debug) System.out.println(s); 45 } 46 47 private static void createData() { 48 ByteBuffer bb = ByteBuffer.allocate(8); 49 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 50 for (int i = 0; i < DATA_LEN; i++) { 51 bb.putDouble(0, Math.random()); 52 baos.write(bb.array(), 0, 8); 53 } 54 data = baos.toByteArray(); 55 } 56 57 private static byte[] grow(byte[] a, int capacity) { 58 while (a.length < capacity) { 59 byte[] a2 = new byte[a.length * 2]; 60 System.arraycopy(a, 0, a2, 0, a.length); 61 a = a2; 62 } 63 return a; 64 } 65 66 private static byte[] trim(byte[] a, int length) { 67 byte[] res = new byte[length]; 68 System.arraycopy(a, 0, res, 0, length); 69 return res; 70 } 71 72 private static byte[] deflate(byte[] in, int level) throws Throwable { 73 final Deflater flater = new Deflater(level); 74 flater.setInput(in); 75 flater.finish(); 76 final byte[] smallBuffer = new byte[32]; 77 byte[] flated = new byte[32]; 78 int count = 0; 79 int n; 80 while ((n = flater.deflate(smallBuffer)) > 0) { 81 flated = grow(flated, count + n); 82 System.arraycopy(smallBuffer, 0, flated, count, n); 83 count += n; 84 } 85 return trim(flated, count); 86 } 87 88 private static byte[] inflate(byte[] in) throws Throwable { 89 final Inflater flater = new Inflater(); 90 flater.setInput(in); 91 // This is the buffer of interest. It should be possible to use any 92 // non-zero size. 93 final byte[] smallBuffer = new byte[1]; 94 byte[] flated = new byte[32]; 95 int count = 0; 96 int n; 97 while ((n = flater.inflate(smallBuffer)) > 0) { 98 flated = grow(flated, count + n); 99 System.arraycopy(smallBuffer, 0, flated, count, n); 100 count += n; 101 } 102 return trim(flated, count); 103 } 104 105 public static void realMain(String[] args) throws Throwable { 106 byte deflated[], inflated[]; 107 108 int level = -1; 109 if (args.length > 0) { 110 level = Integer.parseInt(args[0]); 111 } 112 debug("Using level " + level); 113 114 if (args.length > 1) { 115 FileInputStream fis = new FileInputStream(args[1]); 116 int len = fis.available(); 117 data = new byte[len]; 118 check(fis.read(data, 0, len) == len, "Did not read complete file"); 119 debug("Original data from " + args[1]); 120 fis.close(); 121 } else { 122 createData(); 123 debug("Original data from random byte array"); 124 } 125 debug("Original data length: " + data.length + " bytes"); 126 127 debug(""); 128 deflated = deflate(data, level); 129 debug("Deflated data length: " + deflated.length + " bytes"); 130 131 inflated = inflate(deflated); 132 debug("Inflated data length: "+ inflated.length + " bytes" ); 133 134 if (!check(Arrays.equals(data, inflated), 135 "Inflated and deflated arrays do not match")) { 136 OutputStream os = new BufferedOutputStream(new FileOutputStream("deflated.zip")); 137 try { 138 os.write(deflated); 139 } finally { 140 os.close(); 141 } 142 } 143 } 144 145 //--------------------- Infrastructure --------------------------- 146 static volatile int passed = 0, failed = 0; 147 static void pass() {passed++;} 148 static void pass(String msg) {System.out.println(msg); passed++;} 149 static void fail() {failed++; Thread.dumpStack();} 150 static void fail(String msg) {System.out.println(msg); fail();} 151 static void unexpected(Throwable t) {failed++; t.printStackTrace();} 152 static void unexpected(Throwable t, String msg) { 153 System.out.println(msg); failed++; t.printStackTrace();} 154 static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;} 155 static boolean check(boolean cond, String msg) {if (cond) pass(); else fail(msg); return cond;} 156 static void equal(Object x, Object y) { 157 if (x == null ? y == null : x.equals(y)) pass(); 158 else fail(x + " not equal to " + y);} 159 public static void main(String[] args) throws Throwable { 160 try {realMain(args);} catch (Throwable t) {unexpected(t);} 161 System.out.println("\nPassed = " + passed + " failed = " + failed); 162 if (failed > 0) throw new AssertionError("Some tests failed");} 163 }