• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
11 package org.tukaani.xz.rangecoder;
12 
13 import java.io.DataInputStream;
14 import java.io.IOException;
15 import org.tukaani.xz.ArrayCache;
16 import org.tukaani.xz.CorruptedInputException;
17 
18 public final class RangeDecoderFromBuffer extends RangeDecoder {
19     private static final int INIT_SIZE = 5;
20 
21     private final byte[] buf;
22     private int pos;
23 
RangeDecoderFromBuffer(int inputSizeMax, ArrayCache arrayCache)24     public RangeDecoderFromBuffer(int inputSizeMax, ArrayCache arrayCache) {
25         // We will use the *end* of the array so if the cache gives us
26         // a bigger-than-requested array, we still want to use buf.length.
27         buf = arrayCache.getByteArray(inputSizeMax - INIT_SIZE, false);
28         pos = buf.length;
29     }
30 
putArraysToCache(ArrayCache arrayCache)31     public void putArraysToCache(ArrayCache arrayCache) {
32         arrayCache.putArray(buf);
33     }
34 
prepareInputBuffer(DataInputStream in, int len)35     public void prepareInputBuffer(DataInputStream in, int len)
36             throws IOException {
37         if (len < INIT_SIZE)
38             throw new CorruptedInputException();
39 
40         if (in.readUnsignedByte() != 0x00)
41             throw new CorruptedInputException();
42 
43         code = in.readInt();
44         range = 0xFFFFFFFF;
45 
46         // Read the data to the end of the buffer. If the data is corrupt
47         // and the decoder, reading from buf, tries to read past the end of
48         // the data, ArrayIndexOutOfBoundsException will be thrown and
49         // the problem is detected immediately.
50         len -= INIT_SIZE;
51         pos = buf.length - len;
52         in.readFully(buf, pos, len);
53     }
54 
isFinished()55     public boolean isFinished() {
56         return pos == buf.length && code == 0;
57     }
58 
normalize()59     public void normalize() throws IOException {
60         if ((range & TOP_MASK) == 0) {
61             try {
62                 // If the input is corrupt, this might throw
63                 // ArrayIndexOutOfBoundsException.
64                 code = (code << SHIFT_BITS) | (buf[pos++] & 0xFF);
65                 range <<= SHIFT_BITS;
66             } catch (ArrayIndexOutOfBoundsException e) {
67                 throw new CorruptedInputException();
68             }
69         }
70     }
71 }
72