All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xbib.io.compress.xz.lz.LZDecoder Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version

package org.xbib.io.compress.xz.lz;

import org.xbib.io.compress.xz.CorruptedInputException;

import java.io.DataInputStream;
import java.io.IOException;

public final class LZDecoder {
    private final byte[] buf;
    private int start = 0;
    private int pos = 0;
    private int full = 0;
    private int limit = 0;
    private int pendingLen = 0;
    private int pendingDist = 0;

    public LZDecoder(int dictSize, byte[] presetDict) {
        buf = new byte[dictSize];

        if (presetDict != null) {
            pos = Math.min(presetDict.length, dictSize);
            full = pos;
            start = pos;
            System.arraycopy(presetDict, presetDict.length - pos, buf, 0, pos);
        }
    }

    public void reset() {
        start = 0;
        pos = 0;
        full = 0;
        limit = 0;
        buf[buf.length - 1] = 0x00;
    }

    public void setLimit(int outMax) {
        if (buf.length - pos <= outMax) {
            limit = buf.length;
        } else {
            limit = pos + outMax;
        }
    }

    public boolean hasSpace() {
        return pos < limit;
    }

    public boolean hasPending() {
        return pendingLen > 0;
    }

    public int getPos() {
        return pos;
    }

    public int getByte(int dist) {
        int offset = pos - dist - 1;
        if (dist >= pos) {
            offset += buf.length;
        }

        return buf[offset] & 0xFF;
    }

    public void putByte(byte b) {
        buf[pos++] = b;

        if (full < pos) {
            full = pos;
        }
    }

    public void repeat(int dist, int len) throws IOException {
        if (dist < 0 || dist >= full) {
            throw new CorruptedInputException();
        }

        int left = Math.min(limit - pos, len);
        pendingLen = len - left;
        pendingDist = dist;

        int back = pos - dist - 1;
        if (dist >= pos) {
            back += buf.length;
        }

        do {
            buf[pos++] = buf[back++];
            if (back == buf.length) {
                back = 0;
            }
        } while (--left > 0);

        if (full < pos) {
            full = pos;
        }
    }

    public void repeatPending() throws IOException {
        if (pendingLen > 0) {
            repeat(pendingDist, pendingLen);
        }
    }

    public void copyUncompressed(DataInputStream inData, int len)
            throws IOException {
        int copySize = Math.min(buf.length - pos, len);
        inData.readFully(buf, pos, copySize);
        pos += copySize;

        if (full < pos) {
            full = pos;
        }
    }

    public int flush(byte[] out, int outOff) {
        int copySize = pos - start;
        if (pos == buf.length) {
            pos = 0;
        }

        System.arraycopy(buf, start, out, outOff, copySize);
        start = pos;

        return copySize;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy