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