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.UnsupportedEncodingException; 22import java.util.zip.DataFormatException; 23import java.util.zip.Deflater; 24import java.util.zip.Inflater; 25import android.test.suitebuilder.annotation.LargeTest; 26 27public class DeflateTest extends TestCase { 28 29 @LargeTest 30 public void testDeflate() throws Exception { 31 simpleTest(); 32 33 bigTest(0, 1738149618); 34 bigTest(1, 934350518); 35 bigTest(2, -532869390); 36 } 37 38 /* 39 * Simple inflate/deflate test, taken from the reference docs for the 40 * Inflater/Deflater classes. 41 */ 42 private void simpleTest() 43 throws UnsupportedEncodingException, DataFormatException { 44 // Encode a String into bytes 45 String inputString = "blahblahblah??"; 46 byte[] input = inputString.getBytes("UTF-8"); 47 48 // Compress the bytes 49 byte[] output = new byte[100]; 50 Deflater compresser = new Deflater(); 51 compresser.setInput(input); 52 compresser.finish(); 53 int compressedDataLength = compresser.deflate(output); 54 55 // Decompress the bytes 56 Inflater decompresser = new Inflater(); 57 decompresser.setInput(output, 0, compressedDataLength); 58 byte[] result = new byte[100]; 59 int resultLength = decompresser.inflate(result); 60 61 // Decode the bytes into a String 62 String outputString = new String(result, 0, resultLength, "UTF-8"); 63 64 assertEquals(inputString, outputString); 65 assertEquals(compresser.getAdler(), decompresser.getAdler()); 66 67 decompresser.end(); 68 } 69 70 /* 71 * "step" determines how compressible the data is. 72 * 73 * Note we must set "nowrap" to false, or the Adler-32 doesn't get 74 * computed. 75 */ 76 private void bigTest(int step, int expectedAdler) 77 throws UnsupportedEncodingException, DataFormatException { 78 byte[] input = new byte[128 * 1024]; 79 byte[] comp = new byte[128 * 1024 + 512]; 80 byte[] output = new byte[128 * 1024 + 512]; 81 Inflater inflater = new Inflater(false); 82 Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, false); 83 84 createSample(input, step); 85 86 compress(deflater, input, comp); 87 expand(inflater, comp, (int) deflater.getBytesWritten(), output); 88 89 assertEquals(inflater.getBytesWritten(), input.length); 90 assertEquals(deflater.getAdler(), inflater.getAdler()); 91 assertEquals(deflater.getAdler(), expectedAdler); 92 } 93 94 /* 95 * Create a large data sample. 96 * stepStep = 0 --> >99% compression 97 * stepStep = 1 --> ~30% compression 98 * stepStep = 2 --> no compression 99 */ 100 private void createSample(byte[] sample, int stepStep) { 101 byte val, step; 102 int i, j, offset; 103 104 assertTrue(sample.length >= 128 * 1024); 105 106 val = 0; 107 step = 1; 108 offset = 0; 109 for (i = 0; i < (128 * 1024) / 256; i++) { 110 for (j = 0; j < 256; j++) { 111 sample[offset++] = val; 112 val += step; 113 } 114 115 step += stepStep; 116 } 117 } 118 119 private static final int LOCAL_BUF_SIZE = 256; 120 121 /* 122 * Compress all data in "in" to "out". We use a small window on input 123 * and output to exercise that part of the code. 124 * 125 * It's the caller's responsibility to ensure that "out" has enough 126 * space. 127 */ 128 private void compress(Deflater deflater, byte[] inBuf, byte[] outBuf) { 129 int inCount = inBuf.length; // use all 130 int inPosn; 131 int outPosn; 132 133 inPosn = outPosn = 0; 134 135 //System.out.println("### starting compress"); 136 137 while (!deflater.finished()) { 138 int want = -1, got; 139 140 // only read if the input buffer is empty 141 if (deflater.needsInput() && inCount != 0) { 142 want = (inCount < LOCAL_BUF_SIZE) ? inCount : LOCAL_BUF_SIZE; 143 144 deflater.setInput(inBuf, inPosn, want); 145 146 inCount -= want; 147 inPosn += want; 148 if (inCount == 0) { 149 deflater.finish(); 150 } 151 } 152 153 // deflate to current position in output buffer 154 int compCount; 155 156 compCount = deflater.deflate(outBuf, outPosn, LOCAL_BUF_SIZE); 157 outPosn += compCount; 158 159 //System.out.println("Compressed " + want + ", output " + compCount); 160 } 161 } 162 163 /* 164 * Expand data from "inBuf" to "outBuf". Uses a small window to better 165 * exercise the code. 166 */ 167 private void expand(Inflater inflater, byte[] inBuf, int inCount, 168 byte[] outBuf) throws DataFormatException { 169 int inPosn; 170 int outPosn; 171 172 inPosn = outPosn = 0; 173 174 //System.out.println("### starting expand, inCount is " + inCount); 175 176 while (!inflater.finished()) { 177 int want = -1, got; 178 179 // only read if the input buffer is empty 180 if (inflater.needsInput() && inCount != 0) { 181 want = (inCount < LOCAL_BUF_SIZE) ? inCount : LOCAL_BUF_SIZE; 182 183 inflater.setInput(inBuf, inPosn, want); 184 185 inCount -= want; 186 inPosn += want; 187 } 188 189 // inflate to current position in output buffer 190 int compCount; 191 192 compCount = inflater.inflate(outBuf, outPosn, LOCAL_BUF_SIZE); 193 outPosn += compCount; 194 195 //System.out.println("Expanded " + want + ", output " + compCount); 196 } 197 } 198} 199 200