Deflate64CompressorInputStream.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.commons.compress.compressors.deflate64;
- import java.io.Closeable;
- import java.io.IOException;
- import java.io.InputStream;
- import org.apache.commons.compress.compressors.CompressorInputStream;
- import org.apache.commons.compress.utils.InputStreamStatistics;
- /**
- * Deflate64 decompressor.
- *
- * @since 1.16
- * @NotThreadSafe
- */
- public class Deflate64CompressorInputStream extends CompressorInputStream implements InputStreamStatistics {
- private InputStream originalStream;
- private HuffmanDecoder decoder;
- private long compressedBytesRead;
- private final byte[] oneByte = new byte[1];
- Deflate64CompressorInputStream(final HuffmanDecoder decoder) {
- this.decoder = decoder;
- }
- /**
- * Constructs a Deflate64CompressorInputStream.
- *
- * @param in the stream to read from
- */
- public Deflate64CompressorInputStream(final InputStream in) {
- this(new HuffmanDecoder(in));
- originalStream = in;
- }
- @Override
- public int available() throws IOException {
- return decoder != null ? decoder.available() : 0;
- }
- @Override
- public void close() throws IOException {
- try {
- closeDecoder();
- } finally {
- if (originalStream != null) {
- originalStream.close();
- originalStream = null;
- }
- }
- }
- private void closeDecoder() {
- final Closeable c = decoder;
- org.apache.commons.io.IOUtils.closeQuietly(c);
- decoder = null;
- }
- /**
- * @since 1.17
- */
- @Override
- public long getCompressedCount() {
- return compressedBytesRead;
- }
- /**
- * @throws java.io.EOFException if the underlying stream is exhausted before the end of deflated data was reached.
- */
- @Override
- public int read() throws IOException {
- while (true) {
- final int r = read(oneByte);
- switch (r) {
- case 1:
- return oneByte[0] & 0xFF;
- case -1:
- return -1;
- case 0:
- continue;
- default:
- throw new IllegalStateException("Invalid return value from read: " + r);
- }
- }
- }
- /**
- * @throws java.io.EOFException if the underlying stream is exhausted before the end of deflated data was reached.
- */
- @Override
- public int read(final byte[] b, final int off, final int len) throws IOException {
- if (len == 0) {
- return 0;
- }
- int read = -1;
- if (decoder != null) {
- try {
- read = decoder.decode(b, off, len);
- } catch (final RuntimeException ex) {
- throw new IOException("Invalid Deflate64 input", ex);
- }
- compressedBytesRead = decoder.getBytesRead();
- count(read);
- if (read == -1) {
- closeDecoder();
- }
- }
- return read;
- }
- }