1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package com.allanbank.mongodb.bson.json;
23
24
25
26
27
28
29 class JavaCharStream
30 {
31
32 public static final boolean staticFlag = false;
33
34 static final int hexval(char c) throws java.io.IOException {
35 switch(c)
36 {
37 case '0' :
38 return 0;
39 case '1' :
40 return 1;
41 case '2' :
42 return 2;
43 case '3' :
44 return 3;
45 case '4' :
46 return 4;
47 case '5' :
48 return 5;
49 case '6' :
50 return 6;
51 case '7' :
52 return 7;
53 case '8' :
54 return 8;
55 case '9' :
56 return 9;
57
58 case 'a' :
59 case 'A' :
60 return 10;
61 case 'b' :
62 case 'B' :
63 return 11;
64 case 'c' :
65 case 'C' :
66 return 12;
67 case 'd' :
68 case 'D' :
69 return 13;
70 case 'e' :
71 case 'E' :
72 return 14;
73 case 'f' :
74 case 'F' :
75 return 15;
76 }
77
78 throw new java.io.IOException();
79 }
80
81
82 public int bufpos = -1;
83 int bufsize;
84 int available;
85 int tokenBegin;
86 protected int bufline[];
87 protected int bufcolumn[];
88
89 protected int column = 0;
90 protected int line = 1;
91
92 protected boolean prevCharIsCR = false;
93 protected boolean prevCharIsLF = false;
94
95 protected java.io.Reader inputStream;
96
97 protected char[] nextCharBuf;
98 protected char[] buffer;
99 protected int maxNextCharInd = 0;
100 protected int nextCharInd = -1;
101 protected int inBuf = 0;
102 protected int tabSize = 8;
103
104 protected void setTabSize(int i) { tabSize = i; }
105 protected int getTabSize(int i) { return tabSize; }
106
107 protected void ExpandBuff(boolean wrapAround)
108 {
109 char[] newbuffer = new char[bufsize + 2048];
110 int newbufline[] = new int[bufsize + 2048];
111 int newbufcolumn[] = new int[bufsize + 2048];
112
113 try
114 {
115 if (wrapAround)
116 {
117 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
118 System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
119 buffer = newbuffer;
120
121 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
122 System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
123 bufline = newbufline;
124
125 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
126 System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
127 bufcolumn = newbufcolumn;
128
129 bufpos += (bufsize - tokenBegin);
130 }
131 else
132 {
133 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
134 buffer = newbuffer;
135
136 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
137 bufline = newbufline;
138
139 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
140 bufcolumn = newbufcolumn;
141
142 bufpos -= tokenBegin;
143 }
144 }
145 catch (Throwable t)
146 {
147 throw new Error(t.getMessage());
148 }
149
150 available = (bufsize += 2048);
151 tokenBegin = 0;
152 }
153
154 protected void FillBuff() throws java.io.IOException
155 {
156 int i;
157 if (maxNextCharInd == 4096)
158 maxNextCharInd = nextCharInd = 0;
159
160 try {
161 if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
162 4096 - maxNextCharInd)) == -1)
163 {
164 inputStream.close();
165 throw new java.io.IOException();
166 }
167 else
168 maxNextCharInd += i;
169 return;
170 }
171 catch(java.io.IOException e) {
172 if (bufpos != 0)
173 {
174 --bufpos;
175 backup(0);
176 }
177 else
178 {
179 bufline[bufpos] = line;
180 bufcolumn[bufpos] = column;
181 }
182 throw e;
183 }
184 }
185
186 protected char ReadByte() throws java.io.IOException
187 {
188 if (++nextCharInd >= maxNextCharInd)
189 FillBuff();
190
191 return nextCharBuf[nextCharInd];
192 }
193
194
195 public char BeginToken() throws java.io.IOException
196 {
197 if (inBuf > 0)
198 {
199 --inBuf;
200
201 if (++bufpos == bufsize)
202 bufpos = 0;
203
204 tokenBegin = bufpos;
205 return buffer[bufpos];
206 }
207
208 tokenBegin = 0;
209 bufpos = -1;
210
211 return readChar();
212 }
213
214 protected void AdjustBuffSize()
215 {
216 if (available == bufsize)
217 {
218 if (tokenBegin > 2048)
219 {
220 bufpos = 0;
221 available = tokenBegin;
222 }
223 else
224 ExpandBuff(false);
225 }
226 else if (available > tokenBegin)
227 available = bufsize;
228 else if ((tokenBegin - available) < 2048)
229 ExpandBuff(true);
230 else
231 available = tokenBegin;
232 }
233
234 protected void UpdateLineColumn(char c)
235 {
236 column++;
237
238 if (prevCharIsLF)
239 {
240 prevCharIsLF = false;
241 line += (column = 1);
242 }
243 else if (prevCharIsCR)
244 {
245 prevCharIsCR = false;
246 if (c == '\n')
247 {
248 prevCharIsLF = true;
249 }
250 else
251 line += (column = 1);
252 }
253
254 switch (c)
255 {
256 case '\r' :
257 prevCharIsCR = true;
258 break;
259 case '\n' :
260 prevCharIsLF = true;
261 break;
262 case '\t' :
263 column--;
264 column += (tabSize - (column % tabSize));
265 break;
266 default :
267 break;
268 }
269
270 bufline[bufpos] = line;
271 bufcolumn[bufpos] = column;
272 }
273
274
275 public char readChar() throws java.io.IOException
276 {
277 if (inBuf > 0)
278 {
279 --inBuf;
280
281 if (++bufpos == bufsize)
282 bufpos = 0;
283
284 return buffer[bufpos];
285 }
286
287 char c;
288
289 if (++bufpos == available)
290 AdjustBuffSize();
291
292 if ((buffer[bufpos] = c = ReadByte()) == '\\')
293 {
294 UpdateLineColumn(c);
295
296 int backSlashCnt = 1;
297
298 for (;;)
299 {
300 if (++bufpos == available)
301 AdjustBuffSize();
302
303 try
304 {
305 if ((buffer[bufpos] = c = ReadByte()) != '\\')
306 {
307 UpdateLineColumn(c);
308
309 if ((c == 'u') && ((backSlashCnt & 1) == 1))
310 {
311 if (--bufpos < 0)
312 bufpos = bufsize - 1;
313
314 break;
315 }
316
317 backup(backSlashCnt);
318 return '\\';
319 }
320 }
321 catch(java.io.IOException e)
322 {
323
324 if (backSlashCnt > 1)
325 backup(backSlashCnt-1);
326
327 return '\\';
328 }
329
330 UpdateLineColumn(c);
331 backSlashCnt++;
332 }
333
334
335 try
336 {
337 while ((c = ReadByte()) == 'u')
338 ++column;
339
340 buffer[bufpos] = c = (char)(hexval(c) << 12 |
341 hexval(ReadByte()) << 8 |
342 hexval(ReadByte()) << 4 |
343 hexval(ReadByte()));
344
345 column += 4;
346 }
347 catch(java.io.IOException e)
348 {
349 throw new Error("Invalid escape character at line " + line +
350 " column " + column + ".");
351 }
352
353 if (backSlashCnt == 1)
354 return c;
355 else
356 {
357 backup(backSlashCnt - 1);
358 return '\\';
359 }
360 }
361 else
362 {
363 UpdateLineColumn(c);
364 return c;
365 }
366 }
367
368 @Deprecated
369
370
371
372
373 public int getColumn() {
374 return bufcolumn[bufpos];
375 }
376
377 @Deprecated
378
379
380
381
382 public int getLine() {
383 return bufline[bufpos];
384 }
385
386
387 public int getEndColumn() {
388 return bufcolumn[bufpos];
389 }
390
391
392 public int getEndLine() {
393 return bufline[bufpos];
394 }
395
396
397 public int getBeginColumn() {
398 return bufcolumn[tokenBegin];
399 }
400
401
402 public int getBeginLine() {
403 return bufline[tokenBegin];
404 }
405
406
407 public void backup(int amount) {
408
409 inBuf += amount;
410 if ((bufpos -= amount) < 0)
411 bufpos += bufsize;
412 }
413
414
415 public JavaCharStream(java.io.Reader dstream,
416 int startline, int startcolumn, int buffersize)
417 {
418 inputStream = dstream;
419 line = startline;
420 column = startcolumn - 1;
421
422 available = bufsize = buffersize;
423 buffer = new char[buffersize];
424 bufline = new int[buffersize];
425 bufcolumn = new int[buffersize];
426 nextCharBuf = new char[4096];
427 }
428
429
430 public JavaCharStream(java.io.Reader dstream,
431 int startline, int startcolumn)
432 {
433 this(dstream, startline, startcolumn, 4096);
434 }
435
436
437 public JavaCharStream(java.io.Reader dstream)
438 {
439 this(dstream, 1, 1, 4096);
440 }
441
442 public void ReInit(java.io.Reader dstream,
443 int startline, int startcolumn, int buffersize)
444 {
445 inputStream = dstream;
446 line = startline;
447 column = startcolumn - 1;
448
449 if (buffer == null || buffersize != buffer.length)
450 {
451 available = bufsize = buffersize;
452 buffer = new char[buffersize];
453 bufline = new int[buffersize];
454 bufcolumn = new int[buffersize];
455 nextCharBuf = new char[4096];
456 }
457 prevCharIsLF = prevCharIsCR = false;
458 tokenBegin = inBuf = maxNextCharInd = 0;
459 nextCharInd = bufpos = -1;
460 }
461
462
463 public void ReInit(java.io.Reader dstream,
464 int startline, int startcolumn)
465 {
466 ReInit(dstream, startline, startcolumn, 4096);
467 }
468
469
470 public void ReInit(java.io.Reader dstream)
471 {
472 ReInit(dstream, 1, 1, 4096);
473 }
474
475 public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
476 int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
477 {
478 this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
479 }
480
481
482 public JavaCharStream(java.io.InputStream dstream, int startline,
483 int startcolumn, int buffersize)
484 {
485 this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
486 }
487
488
489 public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
490 int startcolumn) throws java.io.UnsupportedEncodingException
491 {
492 this(dstream, encoding, startline, startcolumn, 4096);
493 }
494
495
496 public JavaCharStream(java.io.InputStream dstream, int startline,
497 int startcolumn)
498 {
499 this(dstream, startline, startcolumn, 4096);
500 }
501
502
503 public JavaCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
504 {
505 this(dstream, encoding, 1, 1, 4096);
506 }
507
508
509 public JavaCharStream(java.io.InputStream dstream)
510 {
511 this(dstream, 1, 1, 4096);
512 }
513
514
515 public void ReInit(java.io.InputStream dstream, String encoding, int startline,
516 int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
517 {
518 ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
519 }
520
521
522 public void ReInit(java.io.InputStream dstream, int startline,
523 int startcolumn, int buffersize)
524 {
525 ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
526 }
527
528 public void ReInit(java.io.InputStream dstream, String encoding, int startline,
529 int startcolumn) throws java.io.UnsupportedEncodingException
530 {
531 ReInit(dstream, encoding, startline, startcolumn, 4096);
532 }
533
534 public void ReInit(java.io.InputStream dstream, int startline,
535 int startcolumn)
536 {
537 ReInit(dstream, startline, startcolumn, 4096);
538 }
539
540 public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
541 {
542 ReInit(dstream, encoding, 1, 1, 4096);
543 }
544
545
546 public void ReInit(java.io.InputStream dstream)
547 {
548 ReInit(dstream, 1, 1, 4096);
549 }
550
551
552 public String GetImage()
553 {
554 if (bufpos >= tokenBegin)
555 return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
556 else
557 return new String(buffer, tokenBegin, bufsize - tokenBegin) +
558 new String(buffer, 0, bufpos + 1);
559 }
560
561
562 public char[] GetSuffix(int len)
563 {
564 char[] ret = new char[len];
565
566 if ((bufpos + 1) >= len)
567 System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
568 else
569 {
570 System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
571 len - bufpos - 1);
572 System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
573 }
574
575 return ret;
576 }
577
578
579 public void Done()
580 {
581 nextCharBuf = null;
582 buffer = null;
583 bufline = null;
584 bufcolumn = null;
585 }
586
587
588
589
590 public void adjustBeginLineColumn(int newLine, int newCol)
591 {
592 int start = tokenBegin;
593 int len;
594
595 if (bufpos >= tokenBegin)
596 {
597 len = bufpos - tokenBegin + inBuf + 1;
598 }
599 else
600 {
601 len = bufsize - tokenBegin + bufpos + 1 + inBuf;
602 }
603
604 int i = 0, j = 0, k = 0;
605 int nextColDiff = 0, columnDiff = 0;
606
607 while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
608 {
609 bufline[j] = newLine;
610 nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
611 bufcolumn[j] = newCol + columnDiff;
612 columnDiff = nextColDiff;
613 i++;
614 }
615
616 if (i < len)
617 {
618 bufline[j] = newLine++;
619 bufcolumn[j] = newCol + columnDiff;
620
621 while (i++ < len)
622 {
623 if (bufline[j = start % bufsize] != bufline[++start % bufsize])
624 bufline[j] = newLine++;
625 else
626 bufline[j] = newLine;
627 }
628 }
629
630 line = bufline[j];
631 column = bufcolumn[j];
632 }
633
634 }
635