1
14
15 package com.liferay.portal.kernel.io.unsync;
16
17 import java.io.IOException;
18 import java.io.InputStream;
19
20
29 public class UnsyncBufferedInputStream extends UnsyncFilterInputStream {
30
31 public UnsyncBufferedInputStream(InputStream inputStream) {
32 this(inputStream, _DEFAULT_BUFFER_SIZE);
33 }
34
35 public UnsyncBufferedInputStream(InputStream inputStream, int size) {
36 super(inputStream);
37
38 buffer = new byte[size];
39 }
40
41 public int available() throws IOException {
42 if (inputStream == null) {
43 throw new IOException("Input stream is null");
44 }
45
46 return inputStream.available() + (firstInvalidIndex - index);
47 }
48
49 public void close() throws IOException {
50 if (inputStream != null) {
51 inputStream.close();
52
53 inputStream = null;
54 }
55
56 buffer = null;
57 }
58
59 public void mark(int readLimit) {
60 markLimit = readLimit;
61 markIndex = index;
62 }
63
64 public boolean markSupported() {
65 return true;
66 }
67
68 public int read() throws IOException {
69 if (inputStream == null) {
70 throw new IOException("Input stream is null");
71 }
72
73 if (index >= firstInvalidIndex) {
74 readUnderlyingInputStream();
75
76 if (index >= firstInvalidIndex) {
77 return -1;
78 }
79 }
80
81 return buffer[index++] & 0xff;
82 }
83
84 public int read(byte[] byteArray) throws IOException {
85 return read(byteArray, 0, byteArray.length);
86 }
87
88 public int read(byte[] byteArray, int offset, int length)
89 throws IOException {
90
91 if (inputStream == null) {
92 throw new IOException("Input stream is null");
93 }
94
95 if (length <= 0) {
96 return 0;
97 }
98
99 int read = 0;
100
101 while (true) {
102 int available = firstInvalidIndex - index;
103
104 if ((available + read) >= length) {
105
106
108 int leftSize = length - read;
109
110 System.arraycopy(
111 buffer, index, byteArray, offset + read, leftSize);
112
113 index += leftSize;
114
115 return length;
116 }
117
118 if (available <= 0) {
119
120
122 readUnderlyingInputStream();
123
124 available = firstInvalidIndex - index;
125
126 if (available <= 0) {
127
128
130 if (read == 0) {
131 return -1;
132 }
133 else {
134 return read;
135 }
136 }
137 }
138 else {
139
140
142 System.arraycopy(
143 buffer, index, byteArray, offset + read, available);
144
145 index += available;
146 read += available;
147 }
148 }
149 }
150 public void reset() throws IOException {
151 if (inputStream == null) {
152 throw new IOException("Input stream is null");
153 }
154
155 if (markIndex < 0) {
156 throw new IOException("Resetting to invalid mark");
157 }
158
159 index = markIndex;
160 }
161
162 public long skip(long skip) throws IOException {
163 if (inputStream == null) {
164 throw new IOException("Input stream is null");
165 }
166
167 if (skip <= 0) {
168 return 0;
169 }
170 long available = firstInvalidIndex - index;
171
172 if (available > 0) {
173
174
176 if (available < skip) {
177 skip = available;
178 }
179 }
180 else {
181
182
184 if (markIndex < 0) {
185
186
188 skip = inputStream.skip(skip);
189 }
190 else {
191
192
194 readUnderlyingInputStream();
195
196 available = firstInvalidIndex - index;
197
198 if (available > 0) {
199
200
202 if (available < skip) {
203 skip = available;
204 }
205 }
206 }
207 }
208
209 index += skip;
210
211 return skip;
212 }
213
214 protected void readUnderlyingInputStream() throws IOException {
215 if (markIndex < 0) {
216
217
219 index = firstInvalidIndex = 0;
220
221 int number = inputStream.read(buffer);
222
223 if (number > 0) {
224 firstInvalidIndex = number;
225 }
226
227 return;
228 }
229
230
232 if (index >= buffer.length) {
233
234
236 if ((firstInvalidIndex - markIndex) > markLimit) {
237
238
240 markIndex = -1;
241 index = 0;
242 }
243 else if (markIndex > _MAX_MARK_WASTE_SIZE) {
244
245
248 int realDataSize = index - markIndex;
249
250 System.arraycopy(
251 buffer, markIndex, buffer, 0, realDataSize);
252
253 markIndex = 0;
254 index = realDataSize;
255 }
256 else {
257
258
261 int newBufferSize = index << 1;
262
263 if ((newBufferSize - _MAX_MARK_WASTE_SIZE) > markLimit) {
264
265
267 newBufferSize = markLimit + _MAX_MARK_WASTE_SIZE;
268 }
269
270 byte[] newBuffer = new byte[newBufferSize];
271
272 System.arraycopy(buffer, 0, newBuffer, 0, index);
273
274 buffer = newBuffer;
275 }
276 }
277
278
280 firstInvalidIndex = index;
281
282 int number = inputStream.read(buffer, index, buffer.length - index);
283
284 if (number > 0) {
285 firstInvalidIndex += number;
286 }
287 }
288
289 protected byte[] buffer;
290 protected int firstInvalidIndex;
291 protected int index;
292 protected int markIndex = -1;
293 protected int markLimit;
294
295 private static int _DEFAULT_BUFFER_SIZE = 8192;
296
297 private static int _MAX_MARK_WASTE_SIZE = 4096;
298
299 }