1/*
2 * RangeDecoderFromBuffer
3 *
4 * Authors: Lasse Collin <lasse.collin@tukaani.org>
5 *          Igor Pavlov <http://7-zip.org/>
6 *
7 * This file has been put into the public domain.
8 * You can do whatever you want with this file.
9 */
10
11package org.tukaani.xz.rangecoder;
12
13import java.io.DataInputStream;
14import java.io.IOException;
15import org.tukaani.xz.CorruptedInputException;
16
17public final class RangeDecoderFromBuffer extends RangeDecoder {
18    private static final int INIT_SIZE = 5;
19
20    private final byte[] buf;
21    private int pos = 0;
22    private int end = 0;
23
24    public RangeDecoderFromBuffer(int inputSizeMax) {
25        buf = new byte[inputSizeMax - INIT_SIZE];
26    }
27
28    public void prepareInputBuffer(DataInputStream in, int len)
29            throws IOException {
30        if (len < INIT_SIZE)
31            throw new CorruptedInputException();
32
33        if (in.readUnsignedByte() != 0x00)
34            throw new CorruptedInputException();
35
36        code = in.readInt();
37        range = 0xFFFFFFFF;
38
39        pos = 0;
40        end = len - INIT_SIZE;
41        in.readFully(buf, 0, end);
42    }
43
44    public boolean isInBufferOK() {
45        return pos <= end;
46    }
47
48    public boolean isFinished() {
49        return pos == end && code == 0;
50    }
51
52    public void normalize() throws IOException {
53        if ((range & TOP_MASK) == 0) {
54            try {
55                // If the input is corrupt, this might throw
56                // ArrayIndexOutOfBoundsException.
57                code = (code << SHIFT_BITS) | (buf[pos++] & 0xFF);
58                range <<= SHIFT_BITS;
59            } catch (ArrayIndexOutOfBoundsException e) {
60                throw new CorruptedInputException();
61            }
62        }
63    }
64}
65