OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / libcore / luni / src / main / java / java / util / zip / InflaterOutputStream.java
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package java.util.zip;
19
20 import java.io.FilterOutputStream;
21 import java.io.IOException;
22 import java.io.OutputStream;
23
24 /**
25  * An {@code OutputStream} filter to decompress data. Callers write
26  * compressed data in the "deflate" format, and uncompressed data is
27  * written to the underlying stream.
28  * @since 1.6
29  */
30 public class InflaterOutputStream extends FilterOutputStream {
31     private static final int DEFAULT_BUFFER_SIZE = 1024;
32
33     protected final Inflater inf;
34     protected final byte[] buf;
35
36     private boolean closed = false;
37
38     /**
39      * Constructs an {@code InflaterOutputStream} with a new {@code Inflater} and an
40      * implementation-defined default internal buffer size. {@code out} is a destination
41      * for uncompressed data, and compressed data will be written to this stream.
42      *
43      * @param out the destination {@code OutputStream}
44      */
45     public InflaterOutputStream(OutputStream out) {
46         this(out, new Inflater());
47     }
48
49     /**
50      * Constructs an {@code InflaterOutputStream} with the given {@code Inflater} and an
51      * implementation-defined default internal buffer size. {@code out} is a destination
52      * for uncompressed data, and compressed data will be written to this stream.
53      *
54      * @param out the destination {@code OutputStream}
55      * @param inf the {@code Inflater} to be used for decompression
56      */
57     public InflaterOutputStream(OutputStream out, Inflater inf) {
58         this(out, inf, DEFAULT_BUFFER_SIZE);
59     }
60
61     /**
62      * Constructs an {@code InflaterOutputStream} with the given {@code Inflater} and
63      * given internal buffer size. {@code out} is a destination
64      * for uncompressed data, and compressed data will be written to this stream.
65      *
66      * @param out the destination {@code OutputStream}
67      * @param inf the {@code Inflater} to be used for decompression
68      * @param bufferSize the length in bytes of the internal buffer
69      */
70     public InflaterOutputStream(OutputStream out, Inflater inf, int bufferSize) {
71         super(out);
72         if (out == null || inf == null) {
73             throw new NullPointerException();
74         }
75         if (bufferSize <= 0) {
76             throw new IllegalArgumentException();
77         }
78         this.inf = inf;
79         this.buf = new byte[bufferSize];
80     }
81
82     /**
83      * Writes remaining data into the output stream and closes the underlying
84      * output stream.
85      */
86     @Override
87     public void close() throws IOException {
88         if (!closed) {
89             finish();
90             inf.end();
91             out.close();
92             closed = true;
93         }
94     }
95
96     @Override
97     public void flush() throws IOException {
98         finish();
99         out.flush();
100     }
101
102     /**
103      * Finishes writing current uncompressed data into the InflaterOutputStream
104      * without closing it.
105      *
106      * @throws IOException if an I/O error occurs, or the stream has been closed
107      */
108     public void finish() throws IOException {
109         checkClosed();
110         write();
111     }
112
113     /**
114      * Writes a byte to the decompressing output stream. {@code b} should be a byte of
115      * compressed input. The corresponding uncompressed data will be written to the underlying
116      * stream.
117      *
118      * @param b the byte
119      * @throws IOException if an I/O error occurs, or the stream has been closed
120      * @throws ZipException if a zip exception occurs.
121      */
122     @Override
123     public void write(int b) throws IOException, ZipException {
124         write(new byte[] { (byte) b }, 0, 1);
125     }
126
127     /**
128      * Writes bytes to the decompressing output stream. {@code b} should be an array of
129      * compressed input. The corresponding uncompressed data will be written to the underlying
130      * stream.
131      *
132      * @param b the byte array
133      * @param off the start offset in the byte array
134      * @param len the number of the bytes to take from the byte array
135      * @throws IOException if an I/O error occurs, or the stream has been closed
136      * @throws ZipException if a zip exception occurs.
137      * @throws NullPointerException if {@code b == null}.
138      * @throws IndexOutOfBoundsException if {@code off < 0 || len < 0 || off + len > b.length}
139      */
140     @Override
141     public void write(byte[] b, int off, int len) throws IOException, ZipException {
142         checkClosed();
143         if (b == null) {
144             throw new NullPointerException();
145         }
146         if (off < 0 || len < 0 || len > b.length - off) {
147             throw new IndexOutOfBoundsException();
148         }
149
150         inf.setInput(b, off, len);
151         write();
152     }
153
154     private void write() throws IOException, ZipException {
155         try {
156             int inflated;
157             while ((inflated = inf.inflate(buf)) > 0) {
158                 out.write(buf, 0, inflated);
159             }
160         } catch (DataFormatException e) {
161             throw new ZipException();
162         }
163     }
164
165     private void checkClosed() throws IOException {
166         if (closed) {
167             throw new IOException();
168         }
169     }
170 }