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 android.core;
18
19import junit.framework.TestCase;
20
21import java.io.ByteArrayInputStream;
22import java.io.ByteArrayOutputStream;
23import java.io.IOException;
24import java.util.zip.ZipEntry;
25import java.util.zip.ZipInputStream;
26import java.util.zip.ZipOutputStream;
27import android.test.suitebuilder.annotation.LargeTest;
28
29/**
30 * Basic tests for ZipStream
31 */
32public class ZipStreamTest extends TestCase {
33
34    @LargeTest
35    public void testZipStream() throws Exception {
36        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
37        createCompressedZip(bytesOut);
38
39        byte[] zipData = bytesOut.toByteArray();
40
41        /*
42        FileOutputStream outFile = new FileOutputStream("/tmp/foo.zip");
43        outFile.write(zipData, 0, zipData.length);
44        outFile.close();
45        */
46
47        /*
48        FileInputStream inFile = new FileInputStream("/tmp/foo.zip");
49        int inputLength = inFile.available();
50        zipData = new byte[inputLength];
51        if (inFile.read(zipData) != inputLength)
52            throw new RuntimeException();
53        inFile.close();
54        */
55
56        ByteArrayInputStream bytesIn = new ByteArrayInputStream(zipData);
57        scanZip(bytesIn);
58
59        bytesOut = new ByteArrayOutputStream();
60        createUncompressedZip(bytesOut);
61
62        zipData = bytesOut.toByteArray();
63
64        bytesIn = new ByteArrayInputStream(zipData);
65        scanZip(bytesIn);
66    }
67
68    /*
69     * stepStep == 0 --> >99% compression
70     * stepStep == 1 --> ~30% compression
71     * stepStep == 2 --> no compression
72     */
73    private static byte[] makeSampleFile(int stepStep) throws IOException {
74        byte[] sample = new byte[128 * 1024];
75        byte val, step;
76        int i, j, offset;
77
78        val = 0;
79        step = 1;
80        offset = 0;
81        for (i = 0; i < (128 * 1024) / 256; i++) {
82            for (j = 0; j < 256; j++) {
83                sample[offset++] = val;
84                val += step;
85            }
86
87            step += stepStep;
88        }
89
90        return sample;
91    }
92
93    private static void createCompressedZip(ByteArrayOutputStream bytesOut) throws IOException {
94        ZipOutputStream out = new ZipOutputStream(bytesOut);
95        try {
96            int i;
97
98            for (i = 0; i < 3; i++) {
99                byte[] input = makeSampleFile(i);
100                ZipEntry newEntry = new ZipEntry("file-" + i);
101
102                if (i != 1)
103                    newEntry.setComment("this is file " + i);
104                out.putNextEntry(newEntry);
105                out.write(input, 0, input.length);
106                out.closeEntry();
107            }
108
109            out.setComment("This is a lovely compressed archive!");
110        } finally {
111            out.close();
112        }
113    }
114
115    private static void createUncompressedZip(ByteArrayOutputStream bytesOut) throws IOException {
116        ZipOutputStream out = new ZipOutputStream(bytesOut);
117        try {
118            long[] crcs = {0x205fbff3, 0x906fae57L, 0x2c235131};
119            int i;
120
121            for (i = 0; i < 3; i++) {
122                byte[] input = makeSampleFile(i);
123                ZipEntry newEntry = new ZipEntry("file-" + i);
124
125                if (i != 1)
126                    newEntry.setComment("this is file " + i);
127                newEntry.setMethod(ZipEntry.STORED);
128                newEntry.setSize(128 * 1024);
129                newEntry.setCrc(crcs[i]);
130                out.putNextEntry(newEntry);
131                out.write(input, 0, input.length);
132                out.closeEntry();
133            }
134
135            out.setComment("This is a lovely, but uncompressed, archive!");
136        } finally {
137            out.close();
138        }
139    }
140
141    private static void scanZip(ByteArrayInputStream bytesIn) throws IOException {
142        ZipInputStream in = new ZipInputStream(bytesIn);
143        try {
144            int i;
145
146            for (i = 0; i < 3; i++) {
147                ZipEntry entry = in.getNextEntry();
148                ByteArrayOutputStream contents = new ByteArrayOutputStream();
149                byte[] buf = new byte[4096];
150                int len, totalLen = 0;
151
152                while ((len = in.read(buf)) > 0) {
153                    contents.write(buf, 0, len);
154                    totalLen += len;
155                }
156
157                assertEquals(128 * 1024, totalLen);
158
159//                System.out.println("ZipStreamTest: name='" + entry.getName()
160//                        + "', zero=" + contents.toByteArray()[0]
161//                        + ", tfs=" + contents.toByteArray()[257]
162//                        + ", crc=" + Long.toHexString(entry.getCrc()));
163            }
164
165            assertNull("should only be three entries", in.getNextEntry());
166        } finally {
167            in.close();
168        }
169    }
170}
171
172