1
14
15 package com.liferay.portal.kernel.io.unsync;
16
17 import com.liferay.portal.kernel.util.CharPool;
18 import com.liferay.portal.kernel.util.StringBundler;
19
20 import java.io.IOException;
21 import java.io.Reader;
22
23
32 public class UnsyncBufferedReader extends Reader {
33
34 public UnsyncBufferedReader(Reader reader) {
35 this(reader, _DEFAULT_BUFFER_SIZE);
36 }
37
38 public UnsyncBufferedReader(Reader reader, int size) {
39 this.reader = reader;
40 buffer = new char[size];
41 }
42
43 public void close() throws IOException {
44 if (reader != null) {
45 reader.close();
46
47 reader = null;
48 }
49
50 buffer = null;
51 }
52
53 public void mark(int markLimit) throws IOException {
54 if (reader == null) {
55 throw new IOException("Reader is null");
56 }
57
58 this.markLimit = markLimit;
59 markIndex = index;
60 }
61
62 public boolean markSupported() {
63 return true;
64 }
65
66 public int read() throws IOException {
67 if (reader == null) {
68 throw new IOException("Reader is null");
69 }
70
71 if (index >= firstInvalidIndex) {
72 readUnderlyingReader();
73
74 if (index >= firstInvalidIndex) {
75 return -1;
76 }
77 }
78
79 return buffer[index++];
80 }
81
82 public int read(char[] charArray) throws IOException {
83 return read(charArray, 0, charArray.length);
84 }
85
86 public int read(char[] charArray, int offset, int length)
87 throws IOException {
88
89 if (reader == null) {
90 throw new IOException("Reader is null");
91 }
92
93 if (length <= 0) {
94 return 0;
95 }
96
97 int read = 0;
98
99 while (true) {
100 int available = firstInvalidIndex - index;
101
102 if ((available + read) >= length) {
103
104
106 int leftSize = length - read;
107
108 System.arraycopy(buffer, index, charArray, read, leftSize);
109
110 index += leftSize;
111
112 return length;
113 }
114
115 if (available <= 0) {
116
117
119 readUnderlyingReader();
120
121 available = firstInvalidIndex - index;
122
123 if (available <= 0) {
124
125
127 if (read == 0) {
128 return -1;
129 }
130 else {
131 return read;
132 }
133 }
134 }
135 else {
136
137
139 System.arraycopy(buffer, index, charArray, read, available);
140
141 index += available;
142 read += available;
143 }
144 }
145 }
146
147 public String readLine() throws IOException {
148 if (reader == null) {
149 throw new IOException("Reader is null");
150 }
151
152 StringBundler sb = null;
153
154 while (true) {
155 if (index >= firstInvalidIndex) {
156 readUnderlyingReader();
157 }
158
159 if (index >= firstInvalidIndex) {
160 if ((sb != null) && (sb.index() > 0)) {
161 return sb.toString();
162 }
163 else {
164 return null;
165 }
166 }
167
168 boolean hasLineBreak = false;
169 char lineEndChar = 0;
170
171 int x = index;
172 int y = index;
173
174 while (y < firstInvalidIndex) {
175 lineEndChar = buffer[y];
176
177 if ((lineEndChar == CharPool.NEW_LINE) ||
178 (lineEndChar == CharPool.RETURN)) {
179
180 hasLineBreak = true;
181
182 break;
183 }
184
185 y++;
186 }
187
188 String line = new String(buffer, x, y - x);
189
190 index = y;
191
192 if (hasLineBreak) {
193 index++;
194
195 if (lineEndChar == CharPool.RETURN) {
196 if ((index < buffer.length) &&
197 (buffer[index] == CharPool.NEW_LINE)) {
198
199 index++;
200 }
201 }
202
203 if (sb == null) {
204 return line;
205 }
206 else {
207 sb.append(line);
208
209 return sb.toString();
210 }
211 }
212
213 if (sb == null) {
214 sb = new StringBundler();
215 }
216
217 sb.append(line);
218 }
219 }
220
221 public boolean ready() throws IOException {
222 if (reader == null) {
223 throw new IOException("Reader is null");
224 }
225
226 return (index < firstInvalidIndex) || reader.ready();
227 }
228
229 public void reset() throws IOException {
230 if (reader == null) {
231 throw new IOException("Reader is null");
232 }
233
234 if (markIndex < 0) {
235 throw new IOException("Resetting to invalid mark");
236 }
237
238 index = markIndex;
239 }
240
241 public long skip(long skip) throws IOException {
242 if (reader == null) {
243 throw new IOException("Reader is null");
244 }
245
246 if (skip <= 0) {
247 return 0;
248 }
249
250 long available = firstInvalidIndex - index;
251
252 if (available > 0) {
253
254
256 if (available < skip) {
257 skip = available;
258 }
259 }
260 else {
261
262
264 if (markIndex < 0) {
265
266
268 skip = reader.skip(skip);
269 }
270 else {
271
272
274 readUnderlyingReader();
275
276 available = firstInvalidIndex - index;
277
278 if (available > 0) {
279
280
282 if (available < skip) {
283 skip = available;
284 }
285 }
286 }
287 }
288
289 index += skip;
290
291 return skip;
292 }
293
294 protected void readUnderlyingReader() throws IOException {
295 if (markIndex < 0) {
296
297
299 index = firstInvalidIndex = 0;
300
301 int number = reader.read(buffer);
302
303 if (number > 0) {
304 firstInvalidIndex = number;
305 }
306
307 return;
308 }
309
310
312 if (index >= buffer.length) {
313
314
316 if ((firstInvalidIndex - markIndex) > markLimit) {
317
318
320 markIndex = -1;
321 index = 0;
322 }
323 else if (markIndex > _MAX_MARK_WASTE_SIZE) {
324
325
328 int realDataSize = index - markIndex;
329
330 System.arraycopy(
331 buffer, markIndex, buffer, 0, realDataSize);
332
333 markIndex = 0;
334 index = realDataSize;
335 }
336 else {
337
338
341 int newBufferSize = index << 1;
342
343 if ((newBufferSize - _MAX_MARK_WASTE_SIZE) > markLimit) {
344
345
347 newBufferSize = markLimit + _MAX_MARK_WASTE_SIZE;
348 }
349
350 char[] newBuffer = new char[newBufferSize];
351
352 System.arraycopy(buffer, 0, newBuffer, 0, index);
353
354 buffer = newBuffer;
355 }
356 }
357
358
360 firstInvalidIndex = index;
361
362 int number = reader.read(buffer, index, buffer.length - index);
363
364 if (number > 0) {
365 firstInvalidIndex += number;
366 }
367 }
368
369 protected char[] buffer;
370 protected int firstInvalidIndex;
371 protected int index;
372 protected int markIndex = -1;
373 protected int markLimit;
374 protected Reader reader;
375
376 private static int _DEFAULT_BUFFER_SIZE = 8192;
377
378 private static int _MAX_MARK_WASTE_SIZE = 4096;
379
380 }