1f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License.  You may obtain a copy of the License at
8f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.zip;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstromimport dalvik.system.CloseGuard;
212d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughesimport java.util.Arrays;
226186821cb13f4ac7ff50950c813394367e021eaeJesse Wilsonimport libcore.util.EmptyArray;
2357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class compresses data using the <i>DEFLATE</i> algorithm (see <a
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * href="http://www.gzip.org/algorithm.txt">specification</a>).
2757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson *
282d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes * <p>It is usually more convenient to use {@link DeflaterOutputStream}.
292d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *
302d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes * <p>To compress an in-memory {@code byte[]} to another in-memory {@code byte[]} manually:
312d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes * <pre>
322d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *     byte[] originalBytes = ...
332d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *
342d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *     Deflater deflater = new Deflater();
352d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *     deflater.setInput(originalBytes);
362d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *     deflater.finish();
372d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *
382d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *     ByteArrayOutputStream baos = new ByteArrayOutputStream();
392d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *     byte[] buf = new byte[8192];
402d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *     while (!deflater.finished()) {
412d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *         int byteCount = deflater.deflate(buf);
422d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *         baos.write(buf, 0, byteCount);
432d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *     }
442d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *     deflater.end();
452d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *
462d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes *     byte[] compressedBytes = baos.toByteArray();
472d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes * </pre>
482d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes * <p>In situations where you don't have all the input in one array (or have so much
492d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes * input that you want to feed it to the deflater in chunks), it's possible to call
508601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom * {@link #setInput setInput} repeatedly, but you're much better off using
518601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom * {@link DeflaterOutputStream} to handle all this for you. {@link DeflaterOutputStream} also helps
528601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom * minimize memory requirements&nbsp;&mdash; the sample code above is very expensive.
53d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma *
54d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma * <a name="compression_level"><h3>Compression levels</h3></a>
55d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma * <p>A compression level must be {@link #DEFAULT_COMPRESSION} to compromise between speed and
56d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma * compression (currently equivalent to level 6), or between 0 ({@link #NO_COMPRESSION}, where
57d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma * the input is simply copied) and 9 ({@link #BEST_COMPRESSION}). Level 1 ({@link #BEST_SPEED})
58d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma * performs some compression, but with minimal speed overhead.
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class Deflater {
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
63d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * This <a href="#compression_level">compression level</a> gives the best compression,
64d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * but takes the most time.
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int BEST_COMPRESSION = 9;
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
69d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * This <a href="#compression_level">compression level</a> gives minimal compression,
70d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * but takes the least time (of any level that actually performs compression;
71d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * see {@link #NO_COMPRESSION}).
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int BEST_SPEED = 1;
7457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
76d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * This <a href="#compression_level">compression level</a> does no compression.
77d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * It is even faster than {@link #BEST_SPEED}.
78d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     */
79d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma    public static final int NO_COMPRESSION = 0;
80d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma
81d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma    /**
82d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * The default <a href="#compression_level">compression level</a>.
83d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * This is a trade-off between speed and compression, currently equivalent to level 6.
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int DEFAULT_COMPRESSION = -1;
8657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
882d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * The default compression strategy.
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int DEFAULT_STRATEGY = 0;
9157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
932d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * The default compression method.
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int DEFLATED = 8;
9657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
982d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * A compression strategy.
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int FILTERED = 1;
10157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1032d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * A compression strategy.
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int HUFFMAN_ONLY = 2;
10657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
108cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * Use buffering for best compression.
109cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @since 1.7
110cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     */
111cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    public static final int NO_FLUSH = 0;
112cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson
113cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    /**
114cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * Flush buffers so recipients can immediately decode the data sent thus
115cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * far. This mode may degrade compression.
116cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @since 1.7
117cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     */
118cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    public static final int SYNC_FLUSH = 2;
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
120cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    /**
121cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * Flush buffers so recipients can immediately decode the data sent thus
122cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * far. The compression state is also reset to permit random access and
123cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * recovery for clients who have discarded or damaged their own copy. This
124cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * mode may degrade compression.
125cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @since 1.7
126cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     */
127cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    public static final int FULL_FLUSH = 3;
128cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson
129cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    /**
1302d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * Flush buffers and mark the end of the data stream.
131cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     */
132cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    private static final int FINISH = 4;
13357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
134fa9647657b7c3ebb13d6e5e7dace3cf23f7189fdElliott Hughes    /**
13557192e68f53e80ac1effae04f23d91f4cf162eeaElliott Hughes     * The ugly name flushParm is for RI compatibility, should code need to access this
136fa9647657b7c3ebb13d6e5e7dace3cf23f7189fdElliott Hughes     * field via reflection if it's not able to use public API to choose what
137fa9647657b7c3ebb13d6e5e7dace3cf23f7189fdElliott Hughes     * kind of flushing it gets.
138fa9647657b7c3ebb13d6e5e7dace3cf23f7189fdElliott Hughes     */
139fa9647657b7c3ebb13d6e5e7dace3cf23f7189fdElliott Hughes    private int flushParm = NO_FLUSH;
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean finished;
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int compressLevel = DEFAULT_COMPRESSION;
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int strategy = DEFAULT_STRATEGY;
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private long streamHandle = -1;
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] inputBuffer;
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int inRead;
15257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int inLength;
15457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
15512f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom    private final CloseGuard guard = CloseGuard.get();
156f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
158d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * Constructs a new {@code Deflater} instance using the
159d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * default <a href="#compression_level">compression level</a>.
160d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * The compression strategy can be specified with {@link #setStrategy}. A
1612d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * header is added to the output by default; use {@link
1622d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * #Deflater(int, boolean)} if you need to omit the header.
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Deflater() {
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(DEFAULT_COMPRESSION, false);
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
16757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
169d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * Constructs a new {@code Deflater} instance with the
170d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * given <a href="#compression_level">compression level</a>.
171d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * The compression strategy can be specified with {@link #setStrategy}.
1722d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * A header is added to the output by default; use
1732d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * {@link #Deflater(int, boolean)} if you need to omit the header.
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Deflater(int level) {
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(level, false);
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
180d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * Constructs a new {@code Deflater} instance with the
181d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * given <a href="#compression_level">compression level</a>.
182d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * If {@code noHeader} is true, no ZLIB header is added to the
183f05aeedc00c8e7ab7650067ce1dc301547a3914bElliott Hughes     * output. In a zip file, every entry (compressed file) comes with such a
1842d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * header. The strategy can be specified using {@link #setStrategy}.
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Deflater(int level, boolean noHeader) {
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (level < DEFAULT_COMPRESSION || level > BEST_COMPRESSION) {
188cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes            throw new IllegalArgumentException("Bad level: " + level);
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        compressLevel = level;
191a7822286b7f39e9f733b78e275bacee527829166Jesse Wilson        streamHandle = createStream(compressLevel, strategy, noHeader);
19212f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom        guard.open("end");
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1968601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom     * Deflates the data (previously passed to {@link #setInput setInput}) into the
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * supplied buffer.
198f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson     *
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return number of bytes of compressed data written to {@code buf}.
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int deflate(byte[] buf) {
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return deflate(buf, 0, buf.length);
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2068601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom     * Deflates data (previously passed to {@link #setInput setInput}) into a specific
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * region within the supplied buffer.
208f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson     *
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of bytes of compressed data written to {@code buf}.
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2112d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    public synchronized int deflate(byte[] buf, int offset, int byteCount) {
212fa9647657b7c3ebb13d6e5e7dace3cf23f7189fdElliott Hughes        return deflateImpl(buf, offset, byteCount, flushParm);
213cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    }
214cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson
215cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    /**
2168601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom     * Deflates data (previously passed to {@link #setInput setInput}) into a specific
217cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * region within the supplied buffer, optionally flushing the input buffer.
218cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     *
2192d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * @param flush one of {@link #NO_FLUSH}, {@link #SYNC_FLUSH} or {@link #FULL_FLUSH}.
220cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @return the number of compressed bytes written to {@code buf}. If this
2212d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     *      equals {@code byteCount}, the number of bytes of input to be flushed
222cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     *      may have exceeded the output buffer's capacity. In this case,
223cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     *      finishing a flush will require the output buffer to be drained
224cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     *      and additional calls to {@link #deflate} to be made.
2258ffa0b68c9fd3f722bee2bcd94b1d38151a0791dElliott Hughes     * @throws IllegalArgumentException if {@code flush} is invalid.
226cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @since 1.7
227cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     */
2282d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    public synchronized int deflate(byte[] buf, int offset, int byteCount, int flush) {
229cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) {
2302d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes            throw new IllegalArgumentException("Bad flush value: " + flush);
231cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        }
2322d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        return deflateImpl(buf, offset, byteCount, flush);
233cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    }
234cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson
2352d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    private synchronized int deflateImpl(byte[] buf, int offset, int byteCount, int flush) {
236aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        checkOpen();
2372d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        Arrays.checkOffsetAndCount(buf.length, offset, byteCount);
238cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        if (inputBuffer == null) {
239693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes            setInput(EmptyArray.BYTE);
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2412d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        return deflateImpl(buf, offset, byteCount, streamHandle, flush);
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
244fa9647657b7c3ebb13d6e5e7dace3cf23f7189fdElliott Hughes    private native int deflateImpl(byte[] buf, int offset, int byteCount, long handle, int flushParm);
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Frees all resources held onto by this deflating algorithm. Any unused
2482d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * input or output is discarded. This method should be called explicitly in
2492d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * order to free native resources as soon as possible. After {@code end()} is
2502d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * called, other methods will typically throw {@code IllegalStateException}.
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void end() {
253f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        guard.close();
254e131f2c4bba92efd68568dadd0f46ff74fdb3588Jesse Wilson        endImpl();
255e131f2c4bba92efd68568dadd0f46ff74fdb3588Jesse Wilson    }
256e131f2c4bba92efd68568dadd0f46ff74fdb3588Jesse Wilson
257e131f2c4bba92efd68568dadd0f46ff74fdb3588Jesse Wilson    private void endImpl() {
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (streamHandle != -1) {
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            endImpl(streamHandle);
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            inputBuffer = null;
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            streamHandle = -1;
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2652d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    private native void endImpl(long handle);
2662d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes
267e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom    @Override protected void finalize() {
268e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom        try {
26912f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom            if (guard != null) {
27012f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom                guard.warnIfOpen();
27112f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom            }
272e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom            synchronized (this) {
273e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom                end(); // to allow overriding classes to clean up
274e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom                endImpl(); // in case those classes don't call super.end()
275e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom            }
276e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom        } finally {
277e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom            try {
278e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom                super.finalize();
279e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom            } catch (Throwable t) {
280e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom                throw new AssertionError(t);
281e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom            }
282e131f2c4bba92efd68568dadd0f46ff74fdb3588Jesse Wilson        }
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Indicates to the {@code Deflater} that all uncompressed input has been provided
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to it.
288f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson     *
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #finished
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void finish() {
292fa9647657b7c3ebb13d6e5e7dace3cf23f7189fdElliott Hughes        flushParm = FINISH;
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2968601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom     * Returns true if {@link #finish finish} has been called and all
2978601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom     * data provided by {@link #setInput setInput} has been
2988601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom     * successfully compressed and consumed by {@link #deflate deflate}.
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized boolean finished() {
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return finished;
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3054e872ddaa8763051bcabe5ab804e677a39fa94ddBrian Carlstrom     * Returns the {@link Adler32} checksum of the uncompressed data read so far.
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getAdler() {
308aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        checkOpen();
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getAdlerImpl(streamHandle);
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3122d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    private native int getAdlerImpl(long handle);
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3152d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * Returns the total number of bytes of input read by this {@code Deflater}. This
3162d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * method is limited to 32 bits; use {@link #getBytesRead} instead.
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getTotalIn() {
319aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        checkOpen();
32057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        return (int) getTotalInImpl(streamHandle);
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3232d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    private native long getTotalInImpl(long handle);
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3262d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * Returns the total number of bytes written to the output buffer by this {@code
3272d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * Deflater}. The method is limited to 32 bits; use {@link #getBytesWritten} instead.
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getTotalOut() {
330aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        checkOpen();
33157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        return (int) getTotalOutImpl(streamHandle);
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3342d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    private native long getTotalOutImpl(long handle);
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3378601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom     * Returns true if {@link #setInput setInput} must be called before deflation can continue.
3382d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * If all uncompressed data has been provided to the {@code Deflater},
3392d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * {@link #finish} must be called to ensure the compressed data is output.
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized boolean needsInput() {
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (inputBuffer == null) {
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return inRead == inLength;
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Resets the {@code Deflater} to accept new input without affecting any
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * previously made settings for the compression strategy or level. This
3512d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * operation <i>must</i> be called after {@link #finished} returns
3522d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * true if the {@code Deflater} is to be reused.
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void reset() {
355aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        checkOpen();
356fa9647657b7c3ebb13d6e5e7dace3cf23f7189fdElliott Hughes        flushParm = NO_FLUSH;
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        finished = false;
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        resetImpl(streamHandle);
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        inputBuffer = null;
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3622d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    private native void resetImpl(long handle);
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the dictionary to be used for compression by this {@code Deflater}.
3662d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * This method can only be called if this {@code Deflater} supports the writing
3672d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * of ZLIB headers. This is the default, but can be overridden
3682d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * using {@link #Deflater(int, boolean)}.
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3702d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    public void setDictionary(byte[] dictionary) {
3712d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        setDictionary(dictionary, 0, dictionary.length);
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the dictionary to be used for compression by this {@code Deflater}.
3762d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * This method can only be called if this {@code Deflater} supports the writing
3772d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * of ZLIB headers. This is the default, but can be overridden
3782d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * using {@link #Deflater(int, boolean)}.
3792d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     */
3802d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    public synchronized void setDictionary(byte[] buf, int offset, int byteCount) {
381aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        checkOpen();
3822d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        Arrays.checkOffsetAndCount(buf.length, offset, byteCount);
3832d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        setDictionaryImpl(buf, offset, byteCount, streamHandle);
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3862d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    private native void setDictionaryImpl(byte[] buf, int offset, int byteCount, long handle);
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the input buffer the {@code Deflater} will use to extract uncompressed bytes
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * for later compression.
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setInput(byte[] buf) {
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setInput(buf, 0, buf.length);
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the input buffer the {@code Deflater} will use to extract uncompressed bytes
3982d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * for later compression.
3992d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     */
4002d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    public synchronized void setInput(byte[] buf, int offset, int byteCount) {
401aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        checkOpen();
4022d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        Arrays.checkOffsetAndCount(buf.length, offset, byteCount);
4032d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        inLength = byteCount;
4042d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        inRead = 0;
4052d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        if (inputBuffer == null) {
4062d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes            setLevelsImpl(compressLevel, strategy, streamHandle);
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
4082d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        inputBuffer = buf;
4092d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        setInputImpl(buf, offset, byteCount, streamHandle);
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
4122d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    private native void setLevelsImpl(int level, int strategy, long handle);
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
4142d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes    private native void setInputImpl(byte[] buf, int offset, int byteCount, long handle);
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
417d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * Sets the given <a href="#compression_level">compression level</a>
418d38edfcfac60602940080a521800c0f5227d47d7Jorrit Jongma     * to be used when compressing data. This value must be set
4198601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom     * prior to calling {@link #setInput setInput}.
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @exception IllegalArgumentException
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                If the compression level is invalid.
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setLevel(int level) {
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (level < DEFAULT_COMPRESSION || level > BEST_COMPRESSION) {
4252d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes            throw new IllegalArgumentException("Bad level: " + level);
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (inputBuffer != null) {
4282d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes            throw new IllegalStateException("setLevel cannot be called after setInput");
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        compressLevel = level;
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the compression strategy to be used. The strategy must be one of
4352d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * FILTERED, HUFFMAN_ONLY or DEFAULT_STRATEGY. This value must be set prior
4368601d6b5872167f20f3ab845160ae7f9e0fad94bBrian Carlstrom     * to calling {@link #setInput setInput}.
437f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson     *
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @exception IllegalArgumentException
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                If the strategy specified is not one of FILTERED,
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                HUFFMAN_ONLY or DEFAULT_STRATEGY.
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setStrategy(int strategy) {
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (strategy < DEFAULT_STRATEGY || strategy > HUFFMAN_ONLY) {
4442d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes            throw new IllegalArgumentException("Bad strategy: " + strategy);
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (inputBuffer != null) {
4472d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes            throw new IllegalStateException("setStrategy cannot be called after setInput");
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.strategy = strategy;
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
45157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4532d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * Returns the total number of bytes read by the {@code Deflater}. This
4542d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * method is the same as {@link #getTotalIn} except that it returns a
4552d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * {@code long} value instead of an integer.
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized long getBytesRead() {
458aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        checkOpen();
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getTotalInImpl(streamHandle);
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4632d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * Returns a the total number of bytes written by this {@code Deflater}. This
4642d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * method is the same as {@code getTotalOut} except it returns a
4652d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes     * {@code long} value instead of an integer.
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized long getBytesWritten() {
468aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        checkOpen();
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getTotalOutImpl(streamHandle);
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private native long createStream(int level, int strategy1, boolean noHeader1);
473aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes
474aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes    private void checkOpen() {
475aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        if (streamHandle == -1) {
476aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes            throw new IllegalStateException("attempt to use Deflater after calling end");
477aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes        }
478aee3e4d2e0a2830fc2ef8e96a13796d012becab2Elliott Hughes    }
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
480