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
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FilterOutputStream;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream;
23b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughesimport java.util.Arrays;
24ff8234c90ecab9f1db368924bf92a5b16460f9b5Elliott Hughesimport libcore.io.Streams;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class provides an implementation of {@code FilterOutputStream} that
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * compresses data using the <i>DEFLATE</i> algorithm. Basically it wraps the
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Deflater} class and takes care of the buffering.
3057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson *
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Deflater
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class DeflaterOutputStream extends FilterOutputStream {
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static final int BUF_SIZE = 512;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The buffer for the data to be written to.
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected byte[] buf;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The deflater used.
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected Deflater def;
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    boolean done = false;
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
48cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    private final boolean syncFlush;
49cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This constructor lets you pass the {@code Deflater} specifying the
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * compression algorithm.
53f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson     *
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param os
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            is the {@code OutputStream} where to write the compressed data
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            to.
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param def
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            is the specific {@code Deflater} that is used to compress
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            data.
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public DeflaterOutputStream(OutputStream os, Deflater def) {
62cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        this(os, def, BUF_SIZE, false);
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This is the most basic constructor. You only need to pass the {@code
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * OutputStream} to which the compressed data shall be written to. The
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * default settings for the {@code Deflater} and internal buffer are used.
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * In particular the {@code Deflater} produces a ZLIB header in the output
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * stream.
71f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson     *
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param os
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            is the OutputStream where to write the compressed data to.
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public DeflaterOutputStream(OutputStream os) {
76cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        this(os, new Deflater(), BUF_SIZE, false);
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This constructor lets you specify both the compression algorithm as well
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * as the internal buffer size to be used.
82f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson     *
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param os
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            is the {@code OutputStream} where to write the compressed data
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            to.
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param def
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            is the specific {@code Deflater} that will be used to compress
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            data.
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bsize
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            is the size to be used for the internal buffer.
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public DeflaterOutputStream(OutputStream os, Deflater def, int bsize) {
93cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        this(os, def, bsize, false);
94cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    }
95cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson
96cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    /**
97cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @hide
98cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @since 1.7
99cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     */
100cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    public DeflaterOutputStream(OutputStream os, boolean syncFlush) {
101cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        this(os, new Deflater(), BUF_SIZE, syncFlush);
102cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    }
103cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson
104cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    /**
105cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @hide
106cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @since 1.7
107cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     */
108cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    public DeflaterOutputStream(OutputStream os, Deflater def, boolean syncFlush) {
109cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        this(os, def, BUF_SIZE, syncFlush);
110cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    }
111cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson
112cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    /**
113cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @hide
114cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * @since 1.7
115cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     */
116cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    public DeflaterOutputStream(OutputStream os, Deflater def, int bsize, boolean syncFlush) {
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super(os);
11886acc043d3334651ee26c65467d78d6cefedd397Kenny Root        if (os == null) {
11986acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("os == null");
12086acc043d3334651ee26c65467d78d6cefedd397Kenny Root        } else if (def == null) {
12186acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("def == null");
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (bsize <= 0) {
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.def = def;
127cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        this.syncFlush = syncFlush;
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        buf = new byte[bsize];
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compress the data in the input buffer and write it to the underlying
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * stream.
134f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson     *
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an error occurs during deflation.
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void deflate() throws IOException {
13971509f2a9fca846292c5cde06d8fd3e60912cc4bBrian Carlstrom        int byteCount;
14071509f2a9fca846292c5cde06d8fd3e60912cc4bBrian Carlstrom        while ((byteCount = def.deflate(buf)) != 0) {
1412d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes            out.write(buf, 0, byteCount);
14271509f2a9fca846292c5cde06d8fd3e60912cc4bBrian Carlstrom        }
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Writes any unwritten compressed data to the underlying stream, the closes
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * all underlying streams. This stream can no longer be used after close()
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * has been called.
149f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson     *
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an error occurs while closing the data compression
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             process.
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void close() throws IOException {
1562d9c5fa8ce0182cd8c14736241b709fd50cab6f8Elliott Hughes        // everything closed here should also be closed in ZipOutputStream.close()
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!def.finished()) {
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            finish();
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        def.end();
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        out.close();
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Writes any unwritten data to the underlying stream. Does not close the
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * stream.
167f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson     *
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an error occurs.
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void finish() throws IOException {
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (done) {
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        def.finish();
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (!def.finished()) {
17771509f2a9fca846292c5cde06d8fd3e60912cc4bBrian Carlstrom            int byteCount = def.deflate(buf);
17871509f2a9fca846292c5cde06d8fd3e60912cc4bBrian Carlstrom            out.write(buf, 0, byteCount);
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        done = true;
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
183ff8234c90ecab9f1db368924bf92a5b16460f9b5Elliott Hughes    @Override public void write(int i) throws IOException {
184ff8234c90ecab9f1db368924bf92a5b16460f9b5Elliott Hughes        Streams.writeSingleByte(this, i);
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
188b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes     * Compresses {@code byteCount} bytes of data from {@code buf} starting at
189b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes     * {@code offset} and writes it to the underlying stream.
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an error occurs during writing.
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
193ff8234c90ecab9f1db368924bf92a5b16460f9b5Elliott Hughes    @Override public void write(byte[] buffer, int offset, int byteCount) throws IOException {
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (done) {
195b1433b3bd4dfc05426e5d9c3100b5fbaa198d8a0Elliott Hughes            throw new IOException("attempt to write after finish");
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
197b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes        Arrays.checkOffsetAndCount(buffer.length, offset, byteCount);
198b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes        if (!def.needsInput()) {
199b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes            throw new IOException();
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
201b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes        def.setInput(buffer, offset, byteCount);
202b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes        deflate();
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
204cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson
205cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    /**
206cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * Flushes the underlying stream. This flushes only the bytes that can be
207cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * compressed at the highest level.
208cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     *
209cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * <p>For deflater output streams constructed with Java 7's
210cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * {@code syncFlush} parameter set to true (not yet available on Android),
211cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * this first flushes all outstanding data so that it may be immediately
212cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     * read by its recipient. Doing so may degrade compression.
213cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson     */
214cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    @Override public void flush() throws IOException {
215cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        if (syncFlush) {
21671509f2a9fca846292c5cde06d8fd3e60912cc4bBrian Carlstrom            int byteCount;
21771509f2a9fca846292c5cde06d8fd3e60912cc4bBrian Carlstrom            while ((byteCount = def.deflate(buf, 0, buf.length, Deflater.SYNC_FLUSH)) != 0) {
21871509f2a9fca846292c5cde06d8fd3e60912cc4bBrian Carlstrom                out.write(buf, 0, byteCount);
21971509f2a9fca846292c5cde06d8fd3e60912cc4bBrian Carlstrom            }
220cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        }
221cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson        out.flush();
222cf900b4862df0e261b3cce2195ff0654124ad7dbJesse Wilson    }
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
224