1
2 package com.quiotix.html.parser;
3
4
5
6
7
8
9 public class SimpleCharStream
10 {
11
12 public static final boolean staticFlag = false;
13 int bufsize;
14 int available;
15 int tokenBegin;
16
17 public int bufpos = -1;
18 protected int bufline[];
19 protected int bufcolumn[];
20
21 protected int column = 0;
22 protected int line = 1;
23
24 protected boolean prevCharIsCR = false;
25 protected boolean prevCharIsLF = false;
26
27 protected java.io.Reader inputStream;
28
29 protected char[] buffer;
30 protected int maxNextCharInd = 0;
31 protected int inBuf = 0;
32 protected int tabSize = 8;
33
34 protected void setTabSize(int i) { tabSize = i; }
35 protected int getTabSize(int i) { return tabSize; }
36
37
38 protected void ExpandBuff(boolean wrapAround)
39 {
40 char[] newbuffer = new char[bufsize + 2048];
41 int newbufline[] = new int[bufsize + 2048];
42 int newbufcolumn[] = new int[bufsize + 2048];
43
44 try
45 {
46 if (wrapAround)
47 {
48 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
49 System.arraycopy(buffer, 0, newbuffer,
50 bufsize - tokenBegin, bufpos);
51 buffer = newbuffer;
52
53 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
54 System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
55 bufline = newbufline;
56
57 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
58 System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
59 bufcolumn = newbufcolumn;
60
61 maxNextCharInd = (bufpos += (bufsize - tokenBegin));
62 }
63 else
64 {
65 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
66 buffer = newbuffer;
67
68 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
69 bufline = newbufline;
70
71 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
72 bufcolumn = newbufcolumn;
73
74 maxNextCharInd = (bufpos -= tokenBegin);
75 }
76 }
77 catch (Throwable t)
78 {
79 throw new Error(t.getMessage());
80 }
81
82
83 bufsize += 2048;
84 available = bufsize;
85 tokenBegin = 0;
86 }
87
88 protected void FillBuff() throws java.io.IOException
89 {
90 if (maxNextCharInd == available)
91 {
92 if (available == bufsize)
93 {
94 if (tokenBegin > 2048)
95 {
96 bufpos = maxNextCharInd = 0;
97 available = tokenBegin;
98 }
99 else if (tokenBegin < 0)
100 bufpos = maxNextCharInd = 0;
101 else
102 ExpandBuff(false);
103 }
104 else if (available > tokenBegin)
105 available = bufsize;
106 else if ((tokenBegin - available) < 2048)
107 ExpandBuff(true);
108 else
109 available = tokenBegin;
110 }
111
112 int i;
113 try {
114 if ((i = inputStream.read(buffer, maxNextCharInd,
115 available - maxNextCharInd)) == -1)
116 {
117 inputStream.close();
118 throw new java.io.IOException();
119 }
120 else
121 maxNextCharInd += i;
122 return;
123 }
124 catch(java.io.IOException e) {
125 --bufpos;
126 backup(0);
127 if (tokenBegin == -1)
128 tokenBegin = bufpos;
129 throw e;
130 }
131 }
132
133
134 public char BeginToken() throws java.io.IOException
135 {
136 tokenBegin = -1;
137 char c = readChar();
138 tokenBegin = bufpos;
139
140 return c;
141 }
142
143 protected void UpdateLineColumn(char c)
144 {
145 column++;
146
147 if (prevCharIsLF)
148 {
149 prevCharIsLF = false;
150 line += (column = 1);
151 }
152 else if (prevCharIsCR)
153 {
154 prevCharIsCR = false;
155 if (c == '\n')
156 {
157 prevCharIsLF = true;
158 }
159 else
160 line += (column = 1);
161 }
162
163 switch (c)
164 {
165 case '\r' :
166 prevCharIsCR = true;
167 break;
168 case '\n' :
169 prevCharIsLF = true;
170 break;
171 case '\t' :
172 column--;
173 column += (tabSize - (column % tabSize));
174 break;
175 default :
176 break;
177 }
178
179 bufline[bufpos] = line;
180 bufcolumn[bufpos] = column;
181 }
182
183
184 public char readChar() throws java.io.IOException
185 {
186 if (inBuf > 0)
187 {
188 --inBuf;
189
190 if (++bufpos == bufsize)
191 bufpos = 0;
192
193 return buffer[bufpos];
194 }
195
196 if (++bufpos >= maxNextCharInd)
197 FillBuff();
198
199 char c = buffer[bufpos];
200
201 UpdateLineColumn(c);
202 return c;
203 }
204
205
206
207
208
209
210 public int getColumn() {
211 return bufcolumn[bufpos];
212 }
213
214
215
216
217
218
219 public int getLine() {
220 return bufline[bufpos];
221 }
222
223
224 public int getEndColumn() {
225 return bufcolumn[bufpos];
226 }
227
228
229 public int getEndLine() {
230 return bufline[bufpos];
231 }
232
233
234 public int getBeginColumn() {
235 return bufcolumn[tokenBegin];
236 }
237
238
239 public int getBeginLine() {
240 return bufline[tokenBegin];
241 }
242
243
244 public void backup(int amount) {
245
246 inBuf += amount;
247 if ((bufpos -= amount) < 0)
248 bufpos += bufsize;
249 }
250
251
252 public SimpleCharStream(java.io.Reader dstream, int startline,
253 int startcolumn, int buffersize)
254 {
255 inputStream = dstream;
256 line = startline;
257 column = startcolumn - 1;
258
259 available = bufsize = buffersize;
260 buffer = new char[buffersize];
261 bufline = new int[buffersize];
262 bufcolumn = new int[buffersize];
263 }
264
265
266 public SimpleCharStream(java.io.Reader dstream, int startline,
267 int startcolumn)
268 {
269 this(dstream, startline, startcolumn, 4096);
270 }
271
272
273 public SimpleCharStream(java.io.Reader dstream)
274 {
275 this(dstream, 1, 1, 4096);
276 }
277
278
279 public void ReInit(java.io.Reader dstream, int startline,
280 int startcolumn, int buffersize)
281 {
282 inputStream = dstream;
283 line = startline;
284 column = startcolumn - 1;
285
286 if (buffer == null || buffersize != buffer.length)
287 {
288 available = bufsize = buffersize;
289 buffer = new char[buffersize];
290 bufline = new int[buffersize];
291 bufcolumn = new int[buffersize];
292 }
293 prevCharIsLF = prevCharIsCR = false;
294 tokenBegin = inBuf = maxNextCharInd = 0;
295 bufpos = -1;
296 }
297
298
299 public void ReInit(java.io.Reader dstream, int startline,
300 int startcolumn)
301 {
302 ReInit(dstream, startline, startcolumn, 4096);
303 }
304
305
306 public void ReInit(java.io.Reader dstream)
307 {
308 ReInit(dstream, 1, 1, 4096);
309 }
310
311 public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
312 int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
313 {
314 this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
315 }
316
317
318 public SimpleCharStream(java.io.InputStream dstream, int startline,
319 int startcolumn, int buffersize)
320 {
321 this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
322 }
323
324
325 public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
326 int startcolumn) throws java.io.UnsupportedEncodingException
327 {
328 this(dstream, encoding, startline, startcolumn, 4096);
329 }
330
331
332 public SimpleCharStream(java.io.InputStream dstream, int startline,
333 int startcolumn)
334 {
335 this(dstream, startline, startcolumn, 4096);
336 }
337
338
339 public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
340 {
341 this(dstream, encoding, 1, 1, 4096);
342 }
343
344
345 public SimpleCharStream(java.io.InputStream dstream)
346 {
347 this(dstream, 1, 1, 4096);
348 }
349
350
351 public void ReInit(java.io.InputStream dstream, String encoding, int startline,
352 int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
353 {
354 ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
355 }
356
357
358 public void ReInit(java.io.InputStream dstream, int startline,
359 int startcolumn, int buffersize)
360 {
361 ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
362 }
363
364
365 public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
366 {
367 ReInit(dstream, encoding, 1, 1, 4096);
368 }
369
370
371 public void ReInit(java.io.InputStream dstream)
372 {
373 ReInit(dstream, 1, 1, 4096);
374 }
375
376 public void ReInit(java.io.InputStream dstream, String encoding, int startline,
377 int startcolumn) throws java.io.UnsupportedEncodingException
378 {
379 ReInit(dstream, encoding, startline, startcolumn, 4096);
380 }
381
382 public void ReInit(java.io.InputStream dstream, int startline,
383 int startcolumn)
384 {
385 ReInit(dstream, startline, startcolumn, 4096);
386 }
387
388 public String GetImage()
389 {
390 if (bufpos >= tokenBegin)
391 return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
392 else
393 return new String(buffer, tokenBegin, bufsize - tokenBegin) +
394 new String(buffer, 0, bufpos + 1);
395 }
396
397
398 public char[] GetSuffix(int len)
399 {
400 char[] ret = new char[len];
401
402 if ((bufpos + 1) >= len)
403 System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
404 else
405 {
406 System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
407 len - bufpos - 1);
408 System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
409 }
410
411 return ret;
412 }
413
414
415 public void Done()
416 {
417 buffer = null;
418 bufline = null;
419 bufcolumn = null;
420 }
421
422
423
424
425 public void adjustBeginLineColumn(int newLine, int newCol)
426 {
427 int start = tokenBegin;
428 int len;
429
430 if (bufpos >= tokenBegin)
431 {
432 len = bufpos - tokenBegin + inBuf + 1;
433 }
434 else
435 {
436 len = bufsize - tokenBegin + bufpos + 1 + inBuf;
437 }
438
439 int i = 0, j = 0, k = 0;
440 int nextColDiff = 0, columnDiff = 0;
441
442 while (i < len &&
443 bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
444 {
445 bufline[j] = newLine;
446 nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
447 bufcolumn[j] = newCol + columnDiff;
448 columnDiff = nextColDiff;
449 i++;
450 }
451
452 if (i < len)
453 {
454 bufline[j] = newLine++;
455 bufcolumn[j] = newCol + columnDiff;
456
457 while (i++ < len)
458 {
459 if (bufline[j = start % bufsize] != bufline[++start % bufsize])
460 bufline[j] = newLine++;
461 else
462 bufline[j] = newLine;
463 }
464 }
465
466 line = bufline[j];
467 column = bufcolumn[j];
468 }
469
470 }