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