Package org.xmlBlaster.util.protocol

Source Code of org.xmlBlaster.util.protocol.ZBlockInputStream

package org.xmlBlaster.util.protocol;

import java.io.IOException;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;


/**
* @author Patrice Espié
* @author modifications by Balázs Póka
* Licensing: LGPL
*/
public class ZBlockInputStream extends java.io.FilterInputStream {

    private byte[] buffer;
    private byte[] compBuffer;
    private int readIndex;
    private int maxReadIndex;
    private Inflater inflater;

    public ZBlockInputStream(java.io.InputStream in) {
        super(in);
        buffer = new byte[ZBlockOutputStream.MAXBUFFERSIZE];
        compBuffer = new byte[ZBlockOutputStream.MAXBUFFERSIZE];
        readIndex = 0;
        maxReadIndex = 0;
        inflater = new Inflater();
    }

    public boolean markSupported() {
        return false;
    }

    public int available() throws IOException {
        if (maxReadIndex - readIndex == 0 && super.in.available()>0 && !readNextBuffer()) {
            return -1;
        } else {
            return maxReadIndex - readIndex;
        }
    }

    public int read() throws IOException {
        if (maxReadIndex == readIndex && !readNextBuffer()) {
            return -1;
        }

        byte b = buffer[readIndex++];

        if (b < 0) {
//            System.out.println("INPUT "+Integer.toHexString(b+256));
            return 256 + b;
        } else {
//            System.out.println("INPUT "+Integer.toHexString(b));
            return b;
        }
    }

    public int read(byte[] b) throws IOException {
        return read(b, 0, b.length);
    }

    public int read(byte[] b, int off, int len) throws IOException {
        if (maxReadIndex == readIndex && !readNextBuffer()) {
            return -1;
        }

        int read = 0;
        int i = 0;
        while (i < len && readIndex < maxReadIndex) {
            b[off + i] = buffer[readIndex++];
            i++;
            read++;
        }

        return read;
    }

    /**
     * This method is only called when the buffer is empty, otherwise bytes would be lost.
     * @return
     * @throws IOException
     */
    private boolean readNextBuffer() throws IOException {
        int compressionFlag = -1;
        compressionFlag = super.in.read();
        if (compressionFlag == -1) return false;

//        System.out.println("compflag "+compressionFlag);
        if (compressionFlag < 0 || compressionFlag > 1) {
            throw new IOException("Invalid stream input encountered.");
        }

        int newReadIndex = super.in.read() & 0xff;
        newReadIndex = newReadIndex << 8 | super.in.read() & 0xff;
        newReadIndex = newReadIndex << 8 | super.in.read() & 0xff;
        newReadIndex = newReadIndex << 8 | super.in.read() & 0xff;
       
        int compSize=0;
        if (compressionFlag == 1) {
            compSize = super.in.read() & 0xff;
            compSize = compSize << 8 | super.in.read() & 0xff;
            compSize = compSize << 8 | super.in.read() & 0xff;
            compSize = compSize << 8 | super.in.read() & 0xff;
        }
       
//        System.out.println("reading "+(compressionFlag==1 ? Integer.toString(compSize)+" compressed, " : "")
//                +newReadIndex+" deflated bytes");

        if (newReadIndex < ZBlockOutputStream.MAXBUFFERSIZE && compSize < ZBlockOutputStream.MAXBUFFERSIZE) {
            // seems to be ok...
            maxReadIndex=newReadIndex;
/*            if (buffer.length < maxReadIndex) {
                System.out.println("IN1 allocating "+(maxReadIndex + 40960));
                buffer = new byte[maxReadIndex + 40960];
            }*/

            if (compressionFlag == 1) {
/*                if (compBuffer.length < compSize) {
                    System.out.println("IN2 allocating "+(maxReadIndex + 40960));
                    compBuffer = new byte[compSize + 40960];
                }*/
               
                int read = 0;
                while (read < compSize) {
                    read += super.in.read(compBuffer, read, compSize - read);
                }
               
                inflater.reset();
                inflater.setInput(compBuffer, 0, compSize);
               
                try {
                    int output=inflater.inflate(buffer);
                    if (output!=newReadIndex) {
                        throw new IOException("Bad uncompressed size");
                    }
                } catch (DataFormatException ex) {
                    throw new IOException("Data format exception");
                }
            } else if (compressionFlag == 0) {
                int read = 0;
                while (read < maxReadIndex) {
                    read += super.in.read(buffer, read, maxReadIndex - read);
                }
            }
            readIndex = 0;
            return true;
        }
        else {
            throw new IOException("Invalid chunk length encountered.");
        }
    }

}
TOP

Related Classes of org.xmlBlaster.util.protocol.ZBlockInputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.