1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package libcore.java.util.zip;
18 
19 import junit.framework.TestCase;
20 
21 import java.io.UnsupportedEncodingException;
22 import java.util.zip.DataFormatException;
23 import java.util.zip.Deflater;
24 import java.util.zip.Inflater;
25 
26 public class OldAndroidDeflateTest extends TestCase {
27 
testDeflate()28     public void testDeflate() throws Exception {
29         simpleTest();
30 
31         bigTest(0, 1738149618);
32         bigTest(1, 934350518);
33         bigTest(2, -532869390);
34     }
35 
36     /*
37      * Simple inflate/deflate test, taken from the reference docs for the
38      * Inflater/Deflater classes.
39      */
simpleTest()40     private void simpleTest()
41             throws UnsupportedEncodingException, DataFormatException {
42         // Encode a String into bytes
43         String inputString = "blahblahblah??";
44         byte[] input = inputString.getBytes("UTF-8");
45 
46         // Compress the bytes
47         byte[] output = new byte[100];
48         Deflater compresser = new Deflater();
49         compresser.setInput(input);
50         compresser.finish();
51         int compressedDataLength = compresser.deflate(output);
52 
53         // Decompress the bytes
54         Inflater decompresser = new Inflater();
55         decompresser.setInput(output, 0, compressedDataLength);
56         byte[] result = new byte[100];
57         int resultLength = decompresser.inflate(result);
58 
59         // Decode the bytes into a String
60         String outputString = new String(result, 0, resultLength, "UTF-8");
61 
62         assertEquals(inputString, outputString);
63         assertEquals(compresser.getAdler(), decompresser.getAdler());
64 
65         decompresser.end();
66     }
67 
68     /*
69      * "step" determines how compressible the data is.
70      *
71      * Note we must set "nowrap" to false, or the Adler-32 doesn't get
72      * computed.
73      */
bigTest(int step, int expectedAdler)74     private void bigTest(int step, int expectedAdler)
75             throws UnsupportedEncodingException, DataFormatException {
76         byte[] input = new byte[128 * 1024];
77         byte[] comp = new byte[128 * 1024 + 512];
78         byte[] output = new byte[128 * 1024 + 512];
79         Inflater inflater = new Inflater(false);
80         Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, false);
81 
82         createSample(input, step);
83 
84         compress(deflater, input, comp);
85         expand(inflater, comp, (int) deflater.getBytesWritten(), output);
86 
87         assertEquals(inflater.getBytesWritten(), input.length);
88         assertEquals(deflater.getAdler(), inflater.getAdler());
89         assertEquals(deflater.getAdler(), expectedAdler);
90     }
91 
92     /*
93      * Create a large data sample.
94      * stepStep = 0 --> >99% compression
95      * stepStep = 1 --> ~30% compression
96      * stepStep = 2 --> no compression
97      */
createSample(byte[] sample, int stepStep)98     private void createSample(byte[] sample, int stepStep) {
99         byte val, step;
100         int i, j, offset;
101 
102         assertTrue(sample.length >= 128 * 1024);
103 
104         val = 0;
105         step = 1;
106         offset = 0;
107         for (i = 0; i < (128 * 1024) / 256; i++) {
108             for (j = 0; j < 256; j++) {
109                 sample[offset++] = val;
110                 val += step;
111             }
112 
113             step += stepStep;
114         }
115     }
116 
117     private static final int LOCAL_BUF_SIZE = 256;
118 
119     /*
120      * Compress all data in "in" to "out".  We use a small window on input
121      * and output to exercise that part of the code.
122      *
123      * It's the caller's responsibility to ensure that "out" has enough
124      * space.
125      */
compress(Deflater deflater, byte[] inBuf, byte[] outBuf)126     private void compress(Deflater deflater, byte[] inBuf, byte[] outBuf) {
127         int inCount = inBuf.length;        // use all
128         int inPosn;
129         int outPosn;
130 
131         inPosn = outPosn = 0;
132 
133         //System.out.println("### starting compress");
134 
135         while (!deflater.finished()) {
136             int want = -1, got;
137 
138             // only read if the input buffer is empty
139             if (deflater.needsInput() && inCount != 0) {
140                 want = (inCount < LOCAL_BUF_SIZE) ? inCount : LOCAL_BUF_SIZE;
141 
142                 deflater.setInput(inBuf, inPosn, want);
143 
144                 inCount -= want;
145                 inPosn += want;
146                 if (inCount == 0) {
147                     deflater.finish();
148                 }
149             }
150 
151             // deflate to current position in output buffer
152             int compCount;
153 
154             compCount = deflater.deflate(outBuf, outPosn, LOCAL_BUF_SIZE);
155             outPosn += compCount;
156 
157             //System.out.println("Compressed " + want + ", output " + compCount);
158         }
159     }
160 
161     /*
162      * Expand data from "inBuf" to "outBuf".  Uses a small window to better
163      * exercise the code.
164      */
expand(Inflater inflater, byte[] inBuf, int inCount, byte[] outBuf)165     private void expand(Inflater inflater, byte[] inBuf, int inCount,
166             byte[] outBuf) throws DataFormatException {
167         int inPosn;
168         int outPosn;
169 
170         inPosn = outPosn = 0;
171 
172         //System.out.println("### starting expand, inCount is " + inCount);
173 
174         while (!inflater.finished()) {
175             int want = -1, got;
176 
177             // only read if the input buffer is empty
178             if (inflater.needsInput() && inCount != 0) {
179                 want = (inCount < LOCAL_BUF_SIZE) ? inCount : LOCAL_BUF_SIZE;
180 
181                 inflater.setInput(inBuf, inPosn, want);
182 
183                 inCount -= want;
184                 inPosn += want;
185             }
186 
187             // inflate to current position in output buffer
188             int compCount;
189 
190             compCount = inflater.inflate(outBuf, outPosn, LOCAL_BUF_SIZE);
191             outPosn += compCount;
192 
193             //System.out.println("Expanded " + want + ", output " + compCount);
194         }
195     }
196 }
197 
198