001
014
015 package com.liferay.portal.kernel.io.unsync;
016
017 import java.io.IOException;
018 import java.io.InputStream;
019
020
027 public class UnsyncBufferedInputStream extends UnsyncFilterInputStream {
028
029 public UnsyncBufferedInputStream(InputStream inputStream) {
030 this(inputStream, _DEFAULT_BUFFER_SIZE);
031 }
032
033 public UnsyncBufferedInputStream(InputStream inputStream, int size) {
034 super(inputStream);
035
036 buffer = new byte[size];
037 }
038
039 public int available() throws IOException {
040 if (inputStream == null) {
041 throw new IOException("Input stream is null");
042 }
043
044 return inputStream.available() + (firstInvalidIndex - index);
045 }
046
047 public void close() throws IOException {
048 if (inputStream != null) {
049 inputStream.close();
050
051 inputStream = null;
052 }
053
054 buffer = null;
055 }
056
057 public void mark(int readLimit) {
058 markLimit = readLimit;
059 markIndex = index;
060 }
061
062 public boolean markSupported() {
063 return true;
064 }
065
066 public int read() throws IOException {
067 if (inputStream == null) {
068 throw new IOException("Input stream is null");
069 }
070
071 if (index >= firstInvalidIndex) {
072 readUnderlyingInputStream();
073
074 if (index >= firstInvalidIndex) {
075 return -1;
076 }
077 }
078
079 return buffer[index++] & 0xff;
080 }
081
082 public int read(byte[] byteArray) throws IOException {
083 return read(byteArray, 0, byteArray.length);
084 }
085
086 public int read(byte[] byteArray, int offset, int length)
087 throws IOException {
088
089 if (inputStream == null) {
090 throw new IOException("Input stream is null");
091 }
092
093 if (length <= 0) {
094 return 0;
095 }
096
097 int read = 0;
098
099 while (true) {
100 int available = firstInvalidIndex - index;
101
102 if ((available + read) >= length) {
103
104
105
106 int leftSize = length - read;
107
108 System.arraycopy(
109 buffer, index, byteArray, offset + read, leftSize);
110
111 index += leftSize;
112
113 return length;
114 }
115
116 if (available <= 0) {
117
118
119
120 readUnderlyingInputStream();
121
122 available = firstInvalidIndex - index;
123
124 if (available <= 0) {
125
126
127
128 if (read == 0) {
129 return -1;
130 }
131 else {
132 return read;
133 }
134 }
135 }
136 else {
137
138
139
140 System.arraycopy(
141 buffer, index, byteArray, offset + read, available);
142
143 index += available;
144 read += available;
145 }
146 }
147 }
148 public void reset() throws IOException {
149 if (inputStream == null) {
150 throw new IOException("Input stream is null");
151 }
152
153 if (markIndex < 0) {
154 throw new IOException("Resetting to invalid mark");
155 }
156
157 index = markIndex;
158 }
159
160 public long skip(long skip) throws IOException {
161 if (inputStream == null) {
162 throw new IOException("Input stream is null");
163 }
164
165 if (skip <= 0) {
166 return 0;
167 }
168 long available = firstInvalidIndex - index;
169
170 if (available > 0) {
171
172
173
174 if (available < skip) {
175 skip = available;
176 }
177 }
178 else {
179
180
181
182 if (markIndex < 0) {
183
184
185
186 skip = inputStream.skip(skip);
187 }
188 else {
189
190
191
192 readUnderlyingInputStream();
193
194 available = firstInvalidIndex - index;
195
196 if (available > 0) {
197
198
199
200 if (available < skip) {
201 skip = available;
202 }
203 }
204 }
205 }
206
207 index += skip;
208
209 return skip;
210 }
211
212 protected void readUnderlyingInputStream() throws IOException {
213 if (markIndex < 0) {
214
215
216
217 index = firstInvalidIndex = 0;
218
219 int number = inputStream.read(buffer);
220
221 if (number > 0) {
222 firstInvalidIndex = number;
223 }
224
225 return;
226 }
227
228
229
230 if (index >= buffer.length) {
231
232
233
234 if ((firstInvalidIndex - markIndex) > markLimit) {
235
236
237
238 markIndex = -1;
239 index = 0;
240 }
241 else if (markIndex > _MAX_MARK_WASTE_SIZE) {
242
243
244
245
246 int realDataSize = index - markIndex;
247
248 System.arraycopy(
249 buffer, markIndex, buffer, 0, realDataSize);
250
251 markIndex = 0;
252 index = realDataSize;
253 }
254 else {
255
256
257
258
259 int newBufferSize = index << 1;
260
261 if ((newBufferSize - _MAX_MARK_WASTE_SIZE) > markLimit) {
262
263
264
265 newBufferSize = markLimit + _MAX_MARK_WASTE_SIZE;
266 }
267
268 byte[] newBuffer = new byte[newBufferSize];
269
270 System.arraycopy(buffer, 0, newBuffer, 0, index);
271
272 buffer = newBuffer;
273 }
274 }
275
276
277
278 firstInvalidIndex = index;
279
280 int number = inputStream.read(buffer, index, buffer.length - index);
281
282 if (number > 0) {
283 firstInvalidIndex += number;
284 }
285 }
286
287 protected byte[] buffer;
288 protected int firstInvalidIndex;
289 protected int index;
290 protected int markIndex = -1;
291 protected int markLimit;
292
293 private static int _DEFAULT_BUFFER_SIZE = 8192;
294
295 private static int _MAX_MARK_WASTE_SIZE = 4096;
296
297 }