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

com.fitbur.tukaani.xz.lz.LZDecoder Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
/*
 * LZDecoder
 *
 * Authors: Lasse Collin 
 *          Igor Pavlov 
 *
 * This file has been put into the public domain.
 * You can do whatever you want with this file.
 */

package com.fitbur.tukaani.xz.lz;

import java.io.DataInputStream;
import java.io.IOException;
import com.fitbur.tukaani.xz.CorruptedInputException;

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