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(buffer, index, byteArray, read, leftSize);
111
112 index += leftSize;
113
114 return length;
115 }
116
117 if (available <= 0) {
118
119
121 readUnderlyingInputStream();
122
123 available = firstInvalidIndex - index;
124
125 if (available <= 0) {
126
127
129 if (read == 0) {
130 return -1;
131 }
132 else {
133 return read;
134 }
135 }
136 }
137 else {
138
139
141 System.arraycopy(
142 buffer, index, byteArray, read, available);
143
144 index += available;
145 read += available;
146 }
147 }
148 }
149 public void reset() throws IOException {
150 if (inputStream == null) {
151 throw new IOException("Input stream is null");
152 }
153
154 if (markIndex < 0) {
155 throw new IOException("Resetting to invalid mark");
156 }
157
158 index = markIndex;
159 }
160
161 public long skip(long skip) throws IOException {
162 if (inputStream == null) {
163 throw new IOException("Input stream is null");
164 }
165
166 if (skip <= 0) {
167 return 0;
168 }
169 long available = firstInvalidIndex - index;
170
171 if (available > 0) {
172
173
175 if (available < skip) {
176 skip = available;
177 }
178 }
179 else {
180
181
183 if (markIndex < 0) {
184
185
187 skip = inputStream.skip(skip);
188 }
189 else {
190
191
193 readUnderlyingInputStream();
194
195 available = firstInvalidIndex - index;
196
197 if (available > 0) {
198
199
201 if (available < skip) {
202 skip = available;
203 }
204 }
205 }
206 }
207
208 index += skip;
209
210 return skip;
211 }
212
213 protected void readUnderlyingInputStream() throws IOException {
214 if (markIndex < 0) {
215
216
218 index = firstInvalidIndex = 0;
219
220 int number = inputStream.read(buffer);
221
222 if (number > 0) {
223 firstInvalidIndex = number;
224 }
225
226 return;
227 }
228
229
231 if (index >= buffer.length) {
232
233
235 if ((firstInvalidIndex - markIndex) > markLimit) {
236
237
239 markIndex = -1;
240 index = 0;
241 }
242 else if (markIndex > _MAX_MARK_WASTE_SIZE) {
243
244
247 int realDataSize = index - markIndex;
248
249 System.arraycopy(
250 buffer, markIndex, buffer, 0, realDataSize);
251
252 markIndex = 0;
253 index = realDataSize;
254 }
255 else {
256
257
260 int newBufferSize = index << 1;
261
262 if ((newBufferSize - _MAX_MARK_WASTE_SIZE) > markLimit) {
263
264
266 newBufferSize = markLimit + _MAX_MARK_WASTE_SIZE;
267 }
268
269 byte[] newBuffer = new byte[newBufferSize];
270
271 System.arraycopy(buffer, 0, newBuffer, 0, index);
272
273 buffer = newBuffer;
274 }
275 }
276
277
279 firstInvalidIndex = index;
280
281 int number = inputStream.read(buffer, index, buffer.length - index);
282
283 if (number > 0) {
284 firstInvalidIndex += number;
285 }
286 }
287
288 protected byte[] buffer;
289 protected int firstInvalidIndex;
290 protected int index;
291 protected int markIndex = -1;
292 protected int markLimit;
293
294 private static int _DEFAULT_BUFFER_SIZE = 8192;
295
296 private static int _MAX_MARK_WASTE_SIZE = 4096;
297
298 }