source: josm/trunk/src/org/tukaani/xz/lz/LZDecoder.java@ 15979

Last change on this file since 15979 was 13350, checked in by stoecker, 8 years ago

see #15816 - add XZ support

File size: 3.1 KB
Line 
1/*
2 * LZDecoder
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.lz;
12
13import java.io.DataInputStream;
14import java.io.IOException;
15import org.tukaani.xz.ArrayCache;
16import org.tukaani.xz.CorruptedInputException;
17
18public final class LZDecoder {
19 private final byte[] buf;
20 private final int bufSize; // To avoid buf.length with an array-cached buf.
21 private int start = 0;
22 private int pos = 0;
23 private int full = 0;
24 private int limit = 0;
25 private int pendingLen = 0;
26 private int pendingDist = 0;
27
28 public LZDecoder(int dictSize, byte[] presetDict, ArrayCache arrayCache) {
29 bufSize = dictSize;
30 buf = arrayCache.getByteArray(bufSize, false);
31
32 if (presetDict != null) {
33 pos = Math.min(presetDict.length, dictSize);
34 full = pos;
35 start = pos;
36 System.arraycopy(presetDict, presetDict.length - pos, buf, 0, pos);
37 }
38 }
39
40 public void putArraysToCache(ArrayCache arrayCache) {
41 arrayCache.putArray(buf);
42 }
43
44 public void reset() {
45 start = 0;
46 pos = 0;
47 full = 0;
48 limit = 0;
49 buf[bufSize - 1] = 0x00;
50 }
51
52 public void setLimit(int outMax) {
53 if (bufSize - pos <= outMax)
54 limit = bufSize;
55 else
56 limit = pos + outMax;
57 }
58
59 public boolean hasSpace() {
60 return pos < limit;
61 }
62
63 public boolean hasPending() {
64 return pendingLen > 0;
65 }
66
67 public int getPos() {
68 return pos;
69 }
70
71 public int getByte(int dist) {
72 int offset = pos - dist - 1;
73 if (dist >= pos)
74 offset += bufSize;
75
76 return buf[offset] & 0xFF;
77 }
78
79 public void putByte(byte b) {
80 buf[pos++] = b;
81
82 if (full < pos)
83 full = pos;
84 }
85
86 public void repeat(int dist, int len) throws IOException {
87 if (dist < 0 || dist >= full)
88 throw new CorruptedInputException();
89
90 int left = Math.min(limit - pos, len);
91 pendingLen = len - left;
92 pendingDist = dist;
93
94 int back = pos - dist - 1;
95 if (dist >= pos)
96 back += bufSize;
97
98 do {
99 buf[pos++] = buf[back++];
100 if (back == bufSize)
101 back = 0;
102 } while (--left > 0);
103
104 if (full < pos)
105 full = pos;
106 }
107
108 public void repeatPending() throws IOException {
109 if (pendingLen > 0)
110 repeat(pendingDist, pendingLen);
111 }
112
113 public void copyUncompressed(DataInputStream inData, int len)
114 throws IOException {
115 int copySize = Math.min(bufSize - pos, len);
116 inData.readFully(buf, pos, copySize);
117 pos += copySize;
118
119 if (full < pos)
120 full = pos;
121 }
122
123 public int flush(byte[] out, int outOff) {
124 int copySize = pos - start;
125 if (pos == bufSize)
126 pos = 0;
127
128 System.arraycopy(buf, start, out, outOff, copySize);
129 start = pos;
130
131 return copySize;
132 }
133}
Note: See TracBrowser for help on using the repository browser.