blob: 158b3e979b5db694fe2b11cc5332de7812ea973c [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package libcore.java.util.zip;
import java.io.ByteArrayOutputStream;
import java.util.zip.Adler32;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import junit.framework.TestCase;
public class InflaterTest extends TestCase {
public void testDefaultDictionary() throws Exception {
assertRoundTrip(null);
}
public void testPresetCustomDictionary() throws Exception {
assertRoundTrip("dictionary".getBytes("UTF-8"));
}
private static void assertRoundTrip(byte[] dictionary) throws Exception {
// Construct a nice long input byte sequence.
String expected = makeString();
byte[] expectedBytes = expected.getBytes("UTF-8");
// Compress the bytes, using the passed-in dictionary (or no dictionary).
byte[] deflatedBytes = deflate(expectedBytes, dictionary);
// Get ready to decompress deflatedBytes back to the original bytes ...
Inflater inflater = new Inflater();
// We'll only supply the input a little bit at a time, so that zlib has to ask for more.
final int CHUNK_SIZE = 16;
int offset = 0;
inflater.setInput(deflatedBytes, offset, CHUNK_SIZE);
offset += CHUNK_SIZE;
// If we used a dictionary to compress, check that we're asked for that same dictionary.
if (dictionary != null) {
// 1. there's no data available immediately...
assertEquals(0, inflater.inflate(new byte[8]));
// 2. ...because you need a dictionary.
assertTrue(inflater.needsDictionary());
// 3. ...and that dictionary has the same Adler32 as the dictionary we used.
assertEquals(adler32(dictionary), inflater.getAdler());
inflater.setDictionary(dictionary);
}
// Do the actual decompression, now the dictionary's set up appropriately...
// We use a tiny output buffer to ensure that we call inflate multiple times, and
// a tiny input buffer to ensure that zlib has to ask for more input.
ByteArrayOutputStream inflatedBytes = new ByteArrayOutputStream();
byte[] buf = new byte[8];
while (inflatedBytes.size() != expectedBytes.length) {
if (inflater.needsInput()) {
int nextChunkByteCount = Math.min(CHUNK_SIZE, deflatedBytes.length - offset);
inflater.setInput(deflatedBytes, offset, nextChunkByteCount);
offset += nextChunkByteCount;
} else {
int inflatedByteCount = inflater.inflate(buf);
if (inflatedByteCount > 0) {
inflatedBytes.write(buf, 0, inflatedByteCount);
}
}
}
inflater.end();
assertEquals(expected, new String(inflatedBytes.toByteArray(), "UTF-8"));
}
private static String makeString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1024; ++i) {
// This is arbitrary but convenient in that it gives our string
// an easily-recognizable beginning and end.
sb.append(i + 1024);
}
return sb.toString();
}
/**
* http://code.google.com/p/android/issues/detail?id=11755
*/
public void testEmptyFileAndEmptyBuffer() throws Exception {
byte[] emptyInput = deflate(new byte[0], null);
Inflater inflater = new Inflater();
inflater.setInput(emptyInput);
assertFalse(inflater.finished());
assertEquals(0, inflater.inflate(new byte[0], 0, 0));
assertTrue(inflater.finished());
}
private static byte[] deflate(byte[] input, byte[] dictionary) {
Deflater deflater = new Deflater();
if (dictionary != null) {
deflater.setDictionary(dictionary);
}
deflater.setInput(input);
deflater.finish();
ByteArrayOutputStream deflatedBytes = new ByteArrayOutputStream();
byte[] buf = new byte[8];
while (!deflater.finished()) {
int byteCount = deflater.deflate(buf);
deflatedBytes.write(buf, 0, byteCount);
}
deflater.end();
return deflatedBytes.toByteArray();
}
private static int adler32(byte[] bytes) {
Adler32 adler32 = new Adler32();
adler32.update(bytes);
return (int) adler32.getValue();
}
}