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
17package libcore.java.util.zip;
18
19import junit.framework.TestCase;
20
21import java.io.UnsupportedEncodingException;
22import java.util.zip.DataFormatException;
23import java.util.zip.Deflater;
24import java.util.zip.Inflater;
25
26public class OldAndroidDeflateTest extends TestCase {
27
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     */
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     */
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     */
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     */
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     */
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