Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

239
LINES

< > BotCompany Repo | #1031088 // GZIPInputStream_relaxed - GZIPInputStream accepting incomplete files

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar

Download Jar. Transpiled version (526L) is out of date.

1  
sclass GZIPInputStream_relaxed extends InflaterInputStream_relaxed {
2  
    /**
3  
     * CRC-32 for uncompressed data.
4  
     */
5  
    protected CRC32 crc = new CRC32();
6  
7  
    /**
8  
     * Indicates end of input stream.
9  
     */
10  
    protected boolean eos;
11  
12  
    /**
13  
     * Creates a new input stream with the specified buffer size.
14  
     * @param in the input stream
15  
     * @param size the input buffer size
16  
     *
17  
     * @throws    ZipException if a GZIP format error has occurred or the
18  
     *                         compression method used is unsupported
19  
     * @throws    IOException if an I/O error has occurred
20  
     * @throws    IllegalArgumentException if {@code size <= 0}
21  
     */
22  
    public GZIPInputStream_relaxed(InputStream in, int size) throws IOException {
23  
        super(in, new Inflater(true), size);
24  
        usesDefaultInflater = true;
25  
        readHeader(in);
26  
    }
27  
28  
    /**
29  
     * Creates a new input stream with a default buffer size.
30  
     * @param in the input stream
31  
     *
32  
     * @throws    ZipException if a GZIP format error has occurred or the
33  
     *                         compression method used is unsupported
34  
     * @throws    IOException if an I/O error has occurred
35  
     */
36  
    public GZIPInputStream_relaxed(InputStream in) throws IOException {
37  
        this(in, 512);
38  
    }
39  
40  
    /**
41  
     * Reads uncompressed data into an array of bytes. If {@code len} is not
42  
     * zero, the method will block until some input can be decompressed; otherwise,
43  
     * no bytes are read and {@code 0} is returned.
44  
     * @param buf the buffer into which the data is read
45  
     * @param off the start offset in the destination array {@code b}
46  
     * @param len the maximum number of bytes read
47  
     * @return  the actual number of bytes read, or -1 if the end of the
48  
     *          compressed input stream is reached
49  
     *
50  
     * @throws     NullPointerException If {@code buf} is {@code null}.
51  
     * @throws     IndexOutOfBoundsException If {@code off} is negative,
52  
     * {@code len} is negative, or {@code len} is greater than
53  
     * {@code buf.length - off}
54  
     * @throws    ZipException if the compressed input data is corrupt.
55  
     * @throws    IOException if an I/O error has occurred.
56  
     *
57  
     */
58  
    public int read(byte[] buf, int off, int len) throws IOException {
59  
        ensureOpen();
60  
        if (eos) {
61  
            return -1;
62  
        }
63  
        int n = super.read(buf, off, len);
64  
        if (n == -1) {
65  
            if (readTrailer())
66  
                eos = true;
67  
            else
68  
                return this.read(buf, off, len);
69  
        } else {
70  
            crc.update(buf, off, n);
71  
        }
72  
        return n;
73  
    }
74  
75  
    /**
76  
     * Closes this input stream and releases any system resources associated
77  
     * with the stream.
78  
     * @throws    IOException if an I/O error has occurred
79  
     */
80  
    public void close() throws IOException {
81  
        if (!closed) {
82  
            super.close();
83  
            eos = true;
84  
            closed = true;
85  
        }
86  
    }
87  
88  
    /**
89  
     * GZIP header magic number.
90  
     */
91  
    public static final int GZIP_MAGIC = 0x8b1f;
92  
93  
    /*
94  
     * File header flags.
95  
     */
96  
    private static final int FTEXT      = 1;    // Extra text
97  
    private static final int FHCRC      = 2;    // Header CRC
98  
    private static final int FEXTRA     = 4;    // Extra field
99  
    private static final int FNAME      = 8;    // File name
100  
    private static final int FCOMMENT   = 16;   // File comment
101  
102  
    /*
103  
     * Reads GZIP member header and returns the total byte number
104  
     * of this member header.
105  
     */
106  
    private int readHeader(InputStream this_in) throws IOException {
107  
        CheckedInputStream in = new CheckedInputStream(this_in, crc);
108  
        crc.reset();
109  
        // Check header magic
110  
        if (readUShort(in) != GZIP_MAGIC) {
111  
            throw new ZipException("Not in GZIP format");
112  
        }
113  
        // Check compression method
114  
        if (readUByte(in) != 8) {
115  
            throw new ZipException("Unsupported compression method");
116  
        }
117  
        // Read flags
118  
        int flg = readUByte(in);
119  
        // Skip MTIME, XFL, and OS fields
120  
        skipBytes(in, 6);
121  
        int n = 2 + 2 + 6;
122  
        // Skip optional extra field
123  
        if ((flg & FEXTRA) == FEXTRA) {
124  
            int m = readUShort(in);
125  
            skipBytes(in, m);
126  
            n += m + 2;
127  
        }
128  
        // Skip optional file name
129  
        if ((flg & FNAME) == FNAME) {
130  
            do {
131  
                n++;
132  
            } while (readUByte(in) != 0);
133  
        }
134  
        // Skip optional file comment
135  
        if ((flg & FCOMMENT) == FCOMMENT) {
136  
            do {
137  
                n++;
138  
            } while (readUByte(in) != 0);
139  
        }
140  
        // Check optional header CRC
141  
        if ((flg & FHCRC) == FHCRC) {
142  
            int v = (int)crc.getValue() & 0xffff;
143  
            if (readUShort(in) != v) {
144  
                throw new ZipException("Corrupt GZIP header");
145  
            }
146  
            n += 2;
147  
        }
148  
        crc.reset();
149  
        return n;
150  
    }
151  
152  
    /*
153  
     * Reads GZIP member trailer and returns true if the eos
154  
     * reached, false if there are more (concatenated gzip
155  
     * data set)
156  
     */
157  
    private boolean readTrailer() throws IOException {
158  
        InputStream in = this.in;
159  
        int n = inf.getRemaining();
160  
        if (n > 0) {
161  
            in = new SequenceInputStream(
162  
                        new ByteArrayInputStream(buf, len - n, n),
163  
                        new FilterInputStream(in) {
164  
                            public void close() throws IOException {}
165  
                        });
166  
        }
167  
        // Uses left-to-right evaluation order
168  
        if ((readUInt(in) != crc.getValue()) ||
169  
            // rfc1952; ISIZE is the input size modulo 2^32
170  
            (readUInt(in) != (inf.getBytesWritten() & 0xffffffffL)))
171  
            throw new ZipException("Corrupt GZIP trailer");
172  
173  
        // If there are more bytes available in "in" or
174  
        // the leftover in the "inf" is > 26 bytes:
175  
        // this.trailer(8) + next.header.min(10) + next.trailer(8)
176  
        // try concatenated case
177  
        if (this.in.available() > 0 || n > 26) {
178  
            int m = 8;                  // this.trailer
179  
            try {
180  
                m += readHeader(in);    // next.header
181  
            } catch (IOException ze) {
182  
                return true;  // ignore any malformed, do nothing
183  
            }
184  
            inf.reset();
185  
            if (n > m)
186  
                inf.setInput(buf, len - n + m, n - m);
187  
            return false;
188  
        }
189  
        return true;
190  
    }
191  
192  
    /*
193  
     * Reads unsigned integer in Intel byte order.
194  
     */
195  
    private long readUInt(InputStream in) throws IOException {
196  
        long s = readUShort(in);
197  
        return ((long)readUShort(in) << 16) | s;
198  
    }
199  
200  
    /*
201  
     * Reads unsigned short in Intel byte order.
202  
     */
203  
    private int readUShort(InputStream in) throws IOException {
204  
        int b = readUByte(in);
205  
        return (readUByte(in) << 8) | b;
206  
    }
207  
208  
    /*
209  
     * Reads unsigned byte.
210  
     */
211  
    private int readUByte(InputStream in) throws IOException {
212  
        int b = in.read();
213  
        if (b == -1) {
214  
            throw new EOFException();
215  
        }
216  
        if (b < -1 || b > 255) {
217  
            // Report on this.in, not argument in; see read{Header, Trailer}.
218  
            throw new IOException(this.in.getClass().getName()
219  
                + ".read() returned value out of range -1..255: " + b);
220  
        }
221  
        return b;
222  
    }
223  
224  
    private byte[] tmpbuf = new byte[128];
225  
226  
    /*
227  
     * Skips bytes of input data blocking until all bytes are skipped.
228  
     * Does not assume that the input stream is capable of seeking.
229  
     */
230  
    private void skipBytes(InputStream in, int n) throws IOException {
231  
        while (n > 0) {
232  
            int len = in.read(tmpbuf, 0, n < tmpbuf.length ? n : tmpbuf.length);
233  
            if (len == -1) {
234  
                throw new EOFException();
235  
            }
236  
            n -= len;
237  
        }
238  
    }
239  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1031088
Snippet name: GZIPInputStream_relaxed - GZIPInputStream accepting incomplete files
Eternal ID of this version: #1031088/5
Text MD5: 8d00ccdd55f68c8be2d9733844a2441f
Author: stefan
Category: javax / io
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-05-01 00:20:33
Source code size: 8141 bytes / 239 lines
Pitched / IR pitched: No / No
Views / Downloads: 150 / 634
Version history: 4 change(s)
Referenced in: [show references]