Home | History | Annotate | Download | only in core
      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 
     17 package android.core;
     18 
     19 import junit.framework.TestCase;
     20 
     21 import java.io.UnsupportedEncodingException;
     22 import java.util.zip.DataFormatException;
     23 import java.util.zip.Deflater;
     24 import java.util.zip.Inflater;
     25 import android.test.suitebuilder.annotation.LargeTest;
     26 
     27 public 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