40 |
class CompressedInputStream extends DTPInputStream |
class CompressedInputStream extends DTPInputStream |
41 |
{ |
{ |
42 |
|
|
43 |
static final int EOF = 64; |
static final int EOF = 64; |
|
|
|
|
static final int RAW = 0x00; |
|
|
static final int COMPRESSED = 0x80; |
|
|
static final int FILLER = 0xc0; |
|
|
|
|
|
int descriptor; |
|
|
int max = -1; |
|
|
int count = -1; |
|
|
|
|
|
int state = RAW; // RAW | STATE | FILLER |
|
|
int rep; // the compressed byte |
|
|
int n = 0; // the number of compressed or raw bytes |
|
|
|
|
|
CompressedInputStream(DTP dtp, InputStream in) |
|
|
{ |
|
|
super(dtp, in); |
|
|
} |
|
|
|
|
|
public int read() |
|
|
throws IOException |
|
|
{ |
|
|
if (transferComplete) |
|
|
return -1; |
|
|
if (count==-1) |
|
|
readHeader(); |
|
|
if (max<1) |
|
|
{ |
|
|
close(); |
|
|
return -1; |
|
|
} |
|
|
if (n>0 && (state==COMPRESSED || state==FILLER)) |
|
|
{ |
|
|
n--; |
|
|
return rep; |
|
|
} |
|
|
int c = super.read(); |
|
|
if (c==-1) |
|
|
close(); |
|
|
count++; |
|
|
if (count>=max) |
|
|
{ |
|
|
count = -1; |
|
|
if (descriptor==EOF) |
|
|
close(); |
|
|
} |
|
|
if (c==-1) |
|
|
return c; |
|
|
while (n==0) // read code header |
|
|
{ |
|
|
state = (c & 0xc0); |
|
|
n = (c & 0x3f); |
|
|
c = super.read(); |
|
|
if (c==-1) |
|
|
return -1; |
|
|
} |
|
|
switch (state) |
|
|
{ |
|
|
case RAW: |
|
|
break; |
|
|
case COMPRESSED: |
|
|
case FILLER: |
|
|
rep = c; |
|
|
break; |
|
|
default: |
|
|
throw new ProtocolException("Illegal state: "+state); |
|
|
} |
|
|
n--; |
|
|
return c; |
|
|
} |
|
|
|
|
|
public int read(byte[] buf) |
|
|
throws IOException |
|
|
{ |
|
|
return read(buf, 0, buf.length); |
|
|
} |
|
|
|
|
|
public int read(byte[] buf, int off, int len) |
|
|
throws IOException |
|
|
{ |
|
|
if (transferComplete) |
|
|
return -1; |
|
|
if (count==-1) |
|
|
readHeader(); |
|
|
if (max<1) |
|
|
{ |
|
|
close(); |
|
|
return -1; |
|
|
} |
|
|
// TODO improve performance |
|
|
for (int i=off; i<len; i++) |
|
|
{ |
|
|
int c = read(); |
|
|
if (c==-1) |
|
|
{ |
|
|
close(); |
|
|
return i; |
|
|
} |
|
|
buf[i] = (byte)c; |
|
|
} |
|
|
return len; |
|
|
/* |
|
|
int l = super.read(buf, off, len); |
|
|
if (l==-1) |
|
|
close(); |
|
|
count += l; |
|
|
if (count>=max) |
|
|
{ |
|
|
count = -1; |
|
|
if (descriptor==EOF) |
|
|
close(); |
|
|
} |
|
|
return l; |
|
|
*/ |
|
|
} |
|
44 |
|
|
45 |
/** |
static final int RAW = 0x00; |
46 |
|
static final int COMPRESSED = 0x80; |
47 |
|
static final int FILLER = 0xc0; |
48 |
|
|
49 |
|
int descriptor; |
50 |
|
int max = -1; |
51 |
|
int count = -1; |
52 |
|
|
53 |
|
int state = RAW; // RAW | STATE | FILLER |
54 |
|
int rep; // the compressed byte |
55 |
|
int n = 0; // the number of compressed or raw bytes |
56 |
|
|
57 |
|
CompressedInputStream(DTP dtp, InputStream in) |
58 |
|
{ |
59 |
|
super(dtp, in); |
60 |
|
} |
61 |
|
|
62 |
|
public int read() throws IOException |
63 |
|
{ |
64 |
|
if (transferComplete) |
65 |
|
return -1; |
66 |
|
if (count == -1) |
67 |
|
readHeader(); |
68 |
|
if (max < 1) |
69 |
|
{ |
70 |
|
close(); |
71 |
|
return -1; |
72 |
|
} |
73 |
|
if (n > 0 && (state == COMPRESSED || state == FILLER)) |
74 |
|
{ |
75 |
|
n--; |
76 |
|
return rep; |
77 |
|
} |
78 |
|
int c = super.read(); |
79 |
|
if (c == -1) |
80 |
|
close(); |
81 |
|
count++; |
82 |
|
if (count >= max) |
83 |
|
{ |
84 |
|
count = -1; |
85 |
|
if (descriptor == EOF) |
86 |
|
close(); |
87 |
|
} |
88 |
|
if (c == -1) |
89 |
|
return c; |
90 |
|
while (n == 0) // read code header |
91 |
|
{ |
92 |
|
state = (c & 0xc0); |
93 |
|
n = (c & 0x3f); |
94 |
|
c = super.read(); |
95 |
|
if (c == -1) |
96 |
|
return -1; |
97 |
|
} |
98 |
|
switch (state) |
99 |
|
{ |
100 |
|
case RAW: |
101 |
|
break; |
102 |
|
case COMPRESSED: |
103 |
|
case FILLER: |
104 |
|
rep = c; |
105 |
|
break; |
106 |
|
default: |
107 |
|
throw new ProtocolException("Illegal state: " + state); |
108 |
|
} |
109 |
|
n--; |
110 |
|
return c; |
111 |
|
} |
112 |
|
|
113 |
|
public int read(byte[]buf) throws IOException |
114 |
|
{ |
115 |
|
return read(buf, 0, buf.length); |
116 |
|
} |
117 |
|
|
118 |
|
public int read(byte[]buf, int off, int len) throws IOException |
119 |
|
{ |
120 |
|
if (transferComplete) |
121 |
|
return -1; |
122 |
|
if (count == -1) |
123 |
|
readHeader(); |
124 |
|
if (max < 1) |
125 |
|
{ |
126 |
|
close(); |
127 |
|
return -1; |
128 |
|
} |
129 |
|
// TODO improve performance |
130 |
|
for (int i = off; i < len; i++) |
131 |
|
{ |
132 |
|
int c = read(); |
133 |
|
if (c == -1) |
134 |
|
{ |
135 |
|
close(); |
136 |
|
return i; |
137 |
|
} |
138 |
|
buf[i] = (byte) c; |
139 |
|
} |
140 |
|
return len; |
141 |
|
/* |
142 |
|
int l = super.read(buf, off, len); |
143 |
|
if (l==-1) |
144 |
|
close(); |
145 |
|
count += l; |
146 |
|
if (count>=max) |
147 |
|
{ |
148 |
|
count = -1; |
149 |
|
if (descriptor==EOF) |
150 |
|
close(); |
151 |
|
} |
152 |
|
return l; |
153 |
|
*/ |
154 |
|
} |
155 |
|
|
156 |
|
/** |
157 |
* Reads the block header. |
* Reads the block header. |
158 |
*/ |
*/ |
159 |
void readHeader() |
void readHeader() throws IOException |
160 |
throws IOException |
{ |
161 |
{ |
descriptor = super.read(); |
162 |
descriptor = super.read(); |
int max_hi = super.read(); |
163 |
int max_hi = super.read(); |
int max_lo = super.read(); |
164 |
int max_lo = super.read(); |
max = (max_hi << 8) | max_lo; |
165 |
max = (max_hi<<8) | max_lo; |
count = 0; |
166 |
count = 0; |
} |
|
} |
|
167 |
|
|
168 |
/** |
/** |
169 |
* Reads the code header. |
* Reads the code header. |
170 |
*/ |
*/ |
171 |
void readCodeHeader() |
void readCodeHeader() throws IOException |
172 |
throws IOException |
{ |
173 |
{ |
int code = super.read(); |
174 |
int code = super.read(); |
state = (code & 0xc0); |
175 |
state = (code & 0xc0); |
n = (code & 0x3f); |
176 |
n = (code & 0x3f); |
} |
|
} |
|
177 |
|
|
178 |
} |
} |