DurboInputStream.java 3.55 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.day.durbo.impl;

import com.day.durbo.DurboValue;
import com.day.durbo.io.ChunkedInflaterInputStream;
import com.day.durbo.io.RegionFileInputStream;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;

public class DurboInputStream {
    private InputStream in;

    public DurboInputStream(InputStream in) {
        this.in = in;
    }

    public void enableDecompression() throws IOException {
        if (this.in instanceof RegionFileInputStream) {
            RegionFileInputStream rin = (RegionFileInputStream)this.in;
            this.in = new RegionFileInputStream(rin.getFile(), rin.getAbsolutePosition(), rin.getRemaining(), true);
        } else {
            this.in = new ChunkedInflaterInputStream(this.in);
        }
    }

    public int readType() throws IOException {
        return this.in.read();
    }

    public int readInt() throws IOException {
        byte[] b = this.read(4);
        return ((b[0] & 255) << 24) + ((b[1] & 255) << 16) + ((b[2] & 255) << 8) + (b[3] & 255);
    }

    public long readSize() throws IOException {
        byte[] b = this.read(4);
        long len = (((long)b[0] & 255) << 24) + (((long)b[1] & 255) << 16) + (((long)b[2] & 255) << 8) + ((long)b[3] & 255);
        if (len == 0xFFFFFFFFL) {
            b = this.read(8);
            len = ((long)(b[0] & 255) << 56) + ((long)(b[1] & 255) << 48) + ((long)(b[2] & 255) << 40) + ((long)(b[3] & 255) << 32) + ((long)(b[4] & 255) << 24) + ((long)(b[5] & 255) << 16) + ((long)(b[6] & 255) << 8) + (long)(b[7] & 255);
        }
        return len;
    }

    public String readString() throws IOException {
        byte[] bytes = this.readBinary();
        return new String(bytes, "utf-8");
    }

    public byte[] readBinary() throws IOException {
        long size = this.readSize();
        if (size > Integer.MAX_VALUE) {
            throw new IllegalArgumentException("Unable to read binary value greater than 2^31 bytes.");
        }
        return this.read((int)size);
    }

    public byte[] read(int len) throws IOException {
        try {
            byte[] bytes = new byte[len];
            while (len > 0) {
                int read = this.in.read(bytes, bytes.length - len, len);
                if (read <= 0) {
                    throw new EOFException("" + len + " bytes expected, but read " + read);
                }
                len -= read;
            }
            return bytes;
        }
        catch (OutOfMemoryError e) {
            throw new IOException("Failed to allocate " + len + " bytes. Probably protocol error.");
        }
        catch (NegativeArraySizeException e) {
            throw new IOException("Failed to allocate " + len + " bytes. Probably protocol error.");
        }
    }

    public DurboValue readBinaryValue() throws IOException {
        DurboValue value;
        if (this.in instanceof RegionFileInputStream) {
            long size = this.readSize();
            if (size > 8192) {
                RegionFileInputStream subStream = ((RegionFileInputStream)this.in).substream(0, size);
                value = new DurboValue(2, subStream, size);
                long skipped = this.in.skip(size);
                if (skipped != size) {
                    throw new IOException("Needed to skip " + size + " bytes, but did skip " + skipped + " bytes.");
                }
            } else {
                value = new DurboValue(2, this.read((int)size));
            }
        } else {
            value = new DurboValue(2, this.readBinary());
        }
        return value;
    }
}