001 /*
002 Copyright (c) 1996-2011, Damon Hart-Davis
003 All rights reserved.
004
005 Redistribution and use in source and binary forms, with or without
006 modification, are permitted provided that the following conditions are
007 met:
008
009 * Redistributions of source code must retain the above copyright
010 notice, this list of conditions and the following disclaimer.
011
012 * Redistributions in binary form must reproduce the above copyright
013 notice, this list of conditions and the following disclaimer in the
014 documentation and/or other materials provided with the
015 distribution.
016
017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
019 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
020 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
021 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028 */
029 package org.hd.d.pg2k.svrCore;
030
031 import java.io.ByteArrayInputStream;
032 import java.io.IOException;
033 import java.io.InputStream;
034 import java.io.SequenceInputStream;
035 import java.util.zip.Inflater;
036 import java.util.zip.InflaterInputStream;
037
038 /**Like GZIPInputStream but no GZIP or ZLIB header or checksum.
039 * This is meant to give maximum compression and assumes error
040 * checking/recovery is done elsewhere.
041 */
042 public final class DefInputStream extends InflaterInputStream
043 {
044 /**Indicates end of input stream. */
045 private boolean eos;
046
047 /**Is the stream already closed? */
048 private boolean closed = false;
049
050 /**Check to make sure that this stream has not been closed.
051 */
052 private synchronized void ensureOpen()
053 throws IOException
054 { if(closed) { throw new IOException("already closed"); } }
055
056 /**Creates a new input stream with the specified buffer size.
057 * In cases where we know that the input stream has one or more
058 * trailing bytes that we don't care about
059 * then the hasDummyTrailingData arg can be true
060 * to save us having to wrap the input stream.
061 *
062 * @param in the input stream
063 * @param hasDummyTrailingByte if true then the input stream has
064 * one or more bytes of trailing data that ZLIB can eat harmlessly
065 * @exception IOException if an I/O error has occurred
066 */
067 public DefInputStream(final InputStream in,
068 final boolean hasDummyTrailingByte)
069 throws IOException
070 {
071 super(hasDummyTrailingByte ? in : new SequenceInputStream(in, new ByteArrayInputStream(new byte[1])),
072 new Inflater(true),
073 512); // Standard deflater buffer size is fine...
074 }
075
076 /**Creates a new input stream with a default buffer size.
077 * @param in the input stream
078 * @exception IOException if an I/O error has occurred
079 */
080 public DefInputStream(final InputStream in)
081 throws IOException
082 { this(in, false); }
083
084 /**Reads uncompressed data into an array of bytes.
085 * Blocks until enough input is available for decompression.
086 *
087 * @return the actual number of bytes read, or -1 if the end of the
088 * compressed input stream is reached
089 * @exception IOException if an I/O error has occurred or the compressed
090 * input data is corrupt
091 */
092 @Override
093 public synchronized int read(final byte[] buf, final int off, int len)
094 throws IOException
095 {
096 ensureOpen();
097 if(eos) { return(-1); }
098 len = super.read(buf, off, len);
099 if(len == -1) { eos = true; }
100 return(len);
101 }
102
103 /**Closes the input stream and releases non-Java resources.
104 * @exception IOException if an I/O error has occurred
105 */
106 @Override
107 public synchronized void close()
108 throws IOException
109 {
110 inf.end();
111 in.close();
112 eos = true;
113 closed = true;
114 }
115 }