1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package org.apache.harmony.tests.java.util.zip;
19
20import java.io.ByteArrayInputStream;
21import java.io.IOException;
22import java.io.InputStream;
23import java.util.Arrays;
24import java.util.zip.DataFormatException;
25import java.util.zip.Deflater;
26import java.util.zip.DeflaterInputStream;
27
28import junit.framework.TestCase;
29import libcore.io.Streams;
30
31public class DeflaterInputStreamTest extends TestCase {
32
33    private static final String TEST_STR = "Hi,this is a test";
34
35    private static final byte[] TEST_STRING_DEFLATED_BYTES = {
36            120, -100, -13, -56, -44, 41, -55, -56, 44, 86,
37            0, -94, 68, -123, -110, -44, -30, 18, 0, 52,
38            34, 5, -13 };
39
40    private InputStream is;
41
42    @Override
43    protected void setUp() throws Exception {
44        super.setUp();
45        is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8"));
46    }
47
48    @Override
49    protected void tearDown() throws Exception {
50        is.close();
51        super.tearDown();
52    }
53
54    /**
55     * DeflaterInputStream#available()
56     */
57    public void testAvailable() throws IOException {
58        byte[] buf = new byte[1024];
59        DeflaterInputStream dis = new DeflaterInputStream(is);
60        assertEquals(1, dis.available());
61        assertEquals(120, dis.read());
62        assertEquals(1, dis.available());
63        assertEquals(22, dis.read(buf, 0, 1024));
64        assertEquals(0, dis.available());
65        assertEquals(-1, dis.read());
66        assertEquals(0, dis.available());
67        dis.close();
68        try {
69            dis.available();
70            fail("should throw IOException");
71        } catch (IOException e) {
72            // expected
73        }
74    }
75
76    /**
77     * DeflaterInputStream#close()
78     */
79    public void testClose() throws IOException {
80        byte[] buf = new byte[1024];
81        DeflaterInputStream dis = new DeflaterInputStream(is);
82        assertEquals(1, dis.available());
83        dis.close();
84        try {
85            dis.available();
86            fail("should throw IOException");
87        } catch (IOException e) {
88            // expected
89        }
90        try {
91            dis.read(buf, 0, 1024);
92            fail("should throw IOException");
93        } catch (IOException e) {
94            // expected
95        }
96        // can close after close
97        dis.close();
98    }
99
100    /**
101     * DeflaterInputStream#mark()
102     */
103    public void testMark() throws IOException {
104        // mark do nothing
105        DeflaterInputStream dis = new DeflaterInputStream(is);
106        dis.mark(-1);
107        dis.mark(0);
108        dis.mark(1);
109        dis.close();
110        dis.mark(1);
111    }
112
113    /**
114     * DeflaterInputStream#markSupported()
115     */
116    public void testMarkSupported() throws IOException {
117        DeflaterInputStream dis = new DeflaterInputStream(is);
118        assertFalse(dis.markSupported());
119        dis.close();
120        assertFalse(dis.markSupported());
121    }
122
123    /**
124     * DeflaterInputStream#read()
125     */
126    public void testRead() throws IOException {
127        DeflaterInputStream dis = new DeflaterInputStream(is);
128        assertEquals(1, dis.available());
129        assertEquals(120, dis.read());
130        assertEquals(1, dis.available());
131        assertEquals(156, dis.read());
132        assertEquals(1, dis.available());
133        assertEquals(243, dis.read());
134        assertEquals(1, dis.available());
135        dis.close();
136        try {
137            dis.read();
138            fail("should throw IOException");
139        } catch (IOException e) {
140            // expected
141        }
142    }
143
144    public void testRead_golden() throws Exception {
145        DeflaterInputStream dis = new DeflaterInputStream(is);
146        byte[] contents = Streams.readFully(dis);
147        assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, contents));
148
149        byte[] result = new byte[32];
150        dis = new DeflaterInputStream(new ByteArrayInputStream(TEST_STR.getBytes("UTF-8")));
151        int count = 0;
152        int bytesRead = 0;
153        while ((bytesRead = dis.read(result, count, 4)) != -1) {
154            count += bytesRead;
155        }
156        assertEquals(23, count);
157        byte[] splicedResult = new byte[23];
158        System.arraycopy(result, 0, splicedResult, 0, 23);
159        assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, splicedResult));
160    }
161
162    public void testRead_leavesBufUnmodified() throws Exception {
163        DeflaterInputStreamWithPublicBuffer dis = new DeflaterInputStreamWithPublicBuffer(is);
164        byte[] contents = Streams.readFully(dis);
165        assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, contents));
166
167        // protected field buf is a part of the public API of this class.
168        // we guarantee that it's only used as an input buffer, and not for
169        // anything else.
170        byte[] buf = dis.getBuffer();
171        byte[] expected = TEST_STR.getBytes("UTF-8");
172
173        byte[] splicedBuf = new byte[expected.length];
174        System.arraycopy(buf, 0, splicedBuf, 0, splicedBuf.length);
175        assertTrue(Arrays.equals(expected, splicedBuf));
176    }
177
178    /**
179     * DeflaterInputStream#read(byte[], int, int)
180     */
181    public void testReadByteArrayIntInt() throws IOException {
182        byte[] buf1 = new byte[256];
183        byte[] buf2 = new byte[256];
184        DeflaterInputStream dis = new DeflaterInputStream(is);
185        assertEquals(23, dis.read(buf1, 0, 256));
186        dis = new DeflaterInputStream(is);
187        assertEquals(8, dis.read(buf2, 0, 256));
188        is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8"));
189        dis = new DeflaterInputStream(is);
190        assertEquals(1, dis.available());
191        assertEquals(120, dis.read());
192        assertEquals(1, dis.available());
193        assertEquals(22, dis.read(buf2, 0, 256));
194        assertEquals(0, dis.available());
195        assertEquals(-1, dis.read());
196        assertEquals(0, dis.available());
197        try {
198            dis.read(buf1, 0, 512);
199            fail("should throw IndexOutOfBoundsException");
200        } catch (IndexOutOfBoundsException e) {
201            // expected
202        }
203        try {
204            dis.read(null, 0, 0);
205            fail("should throw NullPointerException");
206        } catch (NullPointerException e) {
207            // expected
208        }
209        try {
210            dis.read(null, -1, 0);
211            fail("should throw NullPointerException");
212        } catch (NullPointerException e) {
213            // expected
214        }
215        try {
216            dis.read(null, -1, -1);
217            fail("should throw NullPointerException");
218        } catch (NullPointerException e) {
219            // expected
220        }
221        try {
222            dis.read(buf1, -1, -1);
223            fail("should throw IndexOutOfBoundsException");
224        } catch (IndexOutOfBoundsException e) {
225            // expected
226        }
227        try {
228            dis.read(buf1, 0, -1);
229            fail("should throw IndexOutOfBoundsException");
230        } catch (IndexOutOfBoundsException e) {
231            // expected
232        }
233        dis.close();
234        try {
235            dis.read(buf1, 0, 512);
236            fail("should throw IOException");
237        } catch (IOException e) {
238            // expected
239        }
240        try {
241            dis.read(buf1, 0, 1);
242            fail("should throw IOException");
243        } catch (IOException e) {
244            // expected
245        }
246        try {
247            dis.read(null, 0, 0);
248            fail("should throw IOException");
249        } catch (IOException e) {
250            // expected
251        }
252        try {
253            dis.read(null, -1, 0);
254            fail("should throw IOException");
255        } catch (IOException e) {
256            // expected
257        }
258        try {
259            dis.read(null, -1, -1);
260            fail("should throw IOException");
261        } catch (IOException e) {
262            // expected
263        }
264        try {
265            dis.read(buf1, -1, -1);
266            fail("should throw IOException");
267        } catch (IOException e) {
268            // expected
269        }
270        try {
271            dis.read(buf1, 0, -1);
272            fail("should throw IOException");
273        } catch (IOException e) {
274            // expected
275        }
276    }
277
278    /**
279     * DeflaterInputStream#reset()
280     */
281    public void testReset() throws IOException {
282        DeflaterInputStream dis = new DeflaterInputStream(is);
283        try {
284            dis.reset();
285            fail("should throw IOException");
286        } catch (IOException e) {
287            // expected
288        }
289        dis.close();
290        try {
291            dis.reset();
292            fail("should throw IOException");
293        } catch (IOException e) {
294            // expected
295        }
296    }
297
298    /**
299     * DeflaterInputStream#skip()
300     */
301    public void testSkip() throws IOException {
302        byte[] buf = new byte[1024];
303        DeflaterInputStream dis = new DeflaterInputStream(is);
304        assertEquals(1, dis.available());
305        dis.skip(1);
306        assertEquals(1, dis.available());
307        assertEquals(22, dis.read(buf, 0, 1024));
308        assertEquals(0, dis.available());
309        assertEquals(0, dis.available());
310        is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8"));
311        dis = new DeflaterInputStream(is);
312        assertEquals(1, dis.available());
313        dis.skip(56);
314        assertEquals(0, dis.available());
315        assertEquals(-1, dis.read(buf, 0, 1024));
316
317        assertEquals(0, dis.available());
318        // can still skip
319        dis.skip(1);
320        dis.close();
321        try {
322            dis.skip(1);
323            fail("should throw IOException");
324        } catch (IOException e) {
325            // expected
326        }
327
328        is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8"));
329        dis = new DeflaterInputStream(is);
330        assertEquals(23, dis.skip(Long.MAX_VALUE));
331        assertEquals(0, dis.available());
332    }
333
334    /**
335     * DeflaterInputStream#DeflaterInputStream(InputStream)
336     */
337    public void testDeflaterInputStreamInputStream() {
338        // ok
339        new DeflaterInputStream(is);
340        // fail
341        try {
342            new DeflaterInputStream(null);
343            fail("should throw NullPointerException");
344        } catch (NullPointerException e) {
345            // expected
346        }
347    }
348
349    /**
350     * DataFormatException#DataFormatException()
351     */
352    public void testDataFormatException() {
353        new DataFormatException();
354    }
355
356    /**
357     * DeflaterInputStream#DeflaterInputStream(InputStream, Deflater)
358     */
359    public void testDeflaterInputStreamInputStreamDeflater() {
360        // ok
361        new DeflaterInputStream(is, new Deflater());
362        // fail
363        try {
364            new DeflaterInputStream(is, null);
365            fail("should throw NullPointerException");
366        } catch (NullPointerException e) {
367            // expected
368        }
369        try {
370            new DeflaterInputStream(null, new Deflater());
371            fail("should throw NullPointerException");
372        } catch (NullPointerException e) {
373            // expected
374        }
375    }
376
377    /**
378     * DeflaterInputStream#DeflaterInputStream(InputStream, Deflater, int)
379     */
380    public void testDeflaterInputStreamInputStreamDeflaterInt() {
381        // ok
382        new DeflaterInputStream(is, new Deflater(), 1024);
383        // fail
384        try {
385            new DeflaterInputStream(is, null, 1024);
386            fail("should throw NullPointerException");
387        } catch (NullPointerException e) {
388            // expected
389        }
390        try {
391            new DeflaterInputStream(null, new Deflater(), 1024);
392            fail("should throw NullPointerException");
393        } catch (NullPointerException e) {
394            // expected
395        }
396        try {
397            new DeflaterInputStream(is, new Deflater(), -1);
398            fail("should throw IllegalArgumentException");
399        } catch (IllegalArgumentException e) {
400            // expected
401        }
402        try {
403            new DeflaterInputStream(null, new Deflater(), -1);
404            fail("should throw NullPointerException");
405        } catch (NullPointerException e) {
406            // expected
407        }
408        try {
409            new DeflaterInputStream(is, null, -1);
410            fail("should throw NullPointerException");
411        } catch (NullPointerException e) {
412            // expected
413        }
414    }
415
416    public static final class DeflaterInputStreamWithPublicBuffer extends DeflaterInputStream {
417
418        public DeflaterInputStreamWithPublicBuffer(InputStream in) {
419            super(in);
420        }
421
422        public byte[] getBuffer() {
423            return buf;
424        }
425    }
426}
427