11e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan/* 21e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * RangeDecoderFromBuffer 31e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * 41e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * Authors: Lasse Collin <lasse.collin@tukaani.org> 51e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * Igor Pavlov <http://7-zip.org/> 61e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * 71e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * This file has been put into the public domain. 81e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * You can do whatever you want with this file. 91e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan */ 101e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 111e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnanpackage org.tukaani.xz.rangecoder; 121e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 131e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnanimport java.io.DataInputStream; 141e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnanimport java.io.IOException; 151e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnanimport org.tukaani.xz.CorruptedInputException; 161e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 171e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnanpublic final class RangeDecoderFromBuffer extends RangeDecoder { 181e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan private static final int INIT_SIZE = 5; 191e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 201e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan private final byte[] buf; 211e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan private int pos = 0; 221e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan private int end = 0; 231e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 241e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan public RangeDecoderFromBuffer(int inputSizeMax) { 251e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan buf = new byte[inputSizeMax - INIT_SIZE]; 261e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan } 271e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 281e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan public void prepareInputBuffer(DataInputStream in, int len) 291e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan throws IOException { 301e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan if (len < INIT_SIZE) 311e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan throw new CorruptedInputException(); 321e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 331e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan if (in.readUnsignedByte() != 0x00) 341e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan throw new CorruptedInputException(); 351e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 361e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan code = in.readInt(); 371e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan range = 0xFFFFFFFF; 381e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 391e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan pos = 0; 401e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan end = len - INIT_SIZE; 411e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan in.readFully(buf, 0, end); 421e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan } 431e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 441e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan public boolean isInBufferOK() { 451e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan return pos <= end; 461e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan } 471e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 481e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan public boolean isFinished() { 491e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan return pos == end && code == 0; 501e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan } 511e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan 521e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan public void normalize() throws IOException { 531e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan if ((range & TOP_MASK) == 0) { 541e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan try { 551e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan // If the input is corrupt, this might throw 561e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan // ArrayIndexOutOfBoundsException. 571e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan code = (code << SHIFT_BITS) | (buf[pos++] & 0xFF); 581e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan range <<= SHIFT_BITS; 591e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan } catch (ArrayIndexOutOfBoundsException e) { 601e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan throw new CorruptedInputException(); 611e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan } 621e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan } 631e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan } 641e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan} 65