Lines 191-196
Link Here
|
191 |
} |
191 |
} |
192 |
return ch; |
192 |
return ch; |
193 |
} |
193 |
} |
|
|
194 |
|
195 |
/** |
196 |
* A better performance solution for calling {@link #mark()} & {@link #nextChar()} |
197 |
* Assume that the parameter mark should be used internal. |
198 |
* |
199 |
* @param mark |
200 |
* @return |
201 |
* @throws JasperException |
202 |
*/ |
203 |
int nextChar(Mark mark) throws JasperException { |
204 |
if (!hasMoreInput()) |
205 |
return -1; |
206 |
|
207 |
int ch = current.stream[current.cursor]; |
208 |
|
209 |
mark.init(current, singleFile); |
210 |
|
211 |
current.cursor++; |
212 |
|
213 |
if (ch == '\n') { |
214 |
current.line++; |
215 |
current.col = 0; |
216 |
} else { |
217 |
current.col++; |
218 |
} |
219 |
return ch; |
220 |
} |
221 |
|
222 |
/** |
223 |
* Search the given character, If it was found, then mark the current cursor and the cursor point to next character |
224 |
* |
225 |
* @param mark |
226 |
* @return |
227 |
* @throws JasperException |
228 |
*/ |
229 |
Boolean indexOf(char c, Mark mark) throws JasperException { |
230 |
if (!hasMoreInput()) |
231 |
return null; |
232 |
|
233 |
int end = current.stream.length; |
234 |
int ch; |
235 |
int line = current.line; |
236 |
int col = current.col; |
237 |
int i = current.cursor; |
238 |
for(; i < end; i ++) { |
239 |
ch = current.stream[i]; |
240 |
|
241 |
if (ch == c) { |
242 |
mark.update(i, line, col); |
243 |
} |
244 |
if (ch == '\n') { |
245 |
line++; |
246 |
col = 0; |
247 |
} else { |
248 |
col++; |
249 |
} |
250 |
if (ch == c) { |
251 |
current.update(i+1, line, col); |
252 |
return Boolean.TRUE; |
253 |
} |
254 |
} |
255 |
current.update(i, line, col); |
256 |
return Boolean.FALSE; |
257 |
} |
194 |
|
258 |
|
195 |
/** |
259 |
/** |
196 |
* Back up the current cursor by one char, assumes current.cursor > 0, |
260 |
* Back up the current cursor by one char, assumes current.cursor > 0, |
Lines 205-214
Link Here
|
205 |
Mark oldstart = mark(); |
269 |
Mark oldstart = mark(); |
206 |
reset(start); |
270 |
reset(start); |
207 |
CharArrayWriter caw = new CharArrayWriter(); |
271 |
CharArrayWriter caw = new CharArrayWriter(); |
208 |
while (!stop.equals(mark())) |
272 |
while (!markEquals(stop)) |
209 |
caw.write(nextChar()); |
273 |
caw.write(nextChar()); |
210 |
caw.close(); |
274 |
caw.close(); |
211 |
reset(oldstart); |
275 |
setCurrent(oldstart); |
212 |
return caw.toString(); |
276 |
return caw.toString(); |
213 |
} |
277 |
} |
214 |
|
278 |
|
Lines 221-230
Link Here
|
221 |
Mark mark() { |
285 |
Mark mark() { |
222 |
return new Mark(current); |
286 |
return new Mark(current); |
223 |
} |
287 |
} |
|
|
288 |
|
289 |
/** |
290 |
* This method can avoid to call {@link #mark()} when doing comparison. |
291 |
* It is used in {@link #getText(Mark, Mark)} |
292 |
* |
293 |
* @param another |
294 |
* @return |
295 |
*/ |
296 |
boolean markEquals(Mark another) { |
297 |
return another.equals(current); |
298 |
} |
224 |
|
299 |
|
225 |
void reset(Mark mark) { |
300 |
void reset(Mark mark) { |
226 |
current = new Mark(mark); |
301 |
current = new Mark(mark); |
227 |
} |
302 |
} |
|
|
303 |
|
304 |
/** |
305 |
* Similar with {@link #reset(Mark)}, however, no new Mark will be created. |
306 |
* So the parameter mark must NOT be used in other place. |
307 |
* |
308 |
* @param mark |
309 |
*/ |
310 |
void setCurrent(Mark mark) { |
311 |
current = mark; |
312 |
} |
228 |
|
313 |
|
229 |
/** |
314 |
/** |
230 |
* search the stream for a match to a string |
315 |
* search the stream for a match to a string |
Lines 234-250
Link Here
|
234 |
* false</strong> otherwise, position in stream unchanged. |
319 |
* false</strong> otherwise, position in stream unchanged. |
235 |
*/ |
320 |
*/ |
236 |
boolean matches(String string) throws JasperException { |
321 |
boolean matches(String string) throws JasperException { |
237 |
Mark mark = mark(); |
322 |
int len = string.length(); |
238 |
int ch = 0; |
323 |
int cursor = current.cursor; |
239 |
int i = 0; |
324 |
int streamSize = current.stream.length; |
240 |
do { |
325 |
if (cursor + len < streamSize) {//Try to scan in memory |
241 |
ch = nextChar(); |
326 |
int line = current.line; |
242 |
if (((char) ch) != string.charAt(i++)) { |
327 |
int col = current.col; |
243 |
reset(mark); |
328 |
int ch; |
244 |
return false; |
329 |
int i = 0; |
245 |
} |
330 |
for(; i < len; i ++) { |
246 |
} while (i < string.length()); |
331 |
ch = current.stream[i+cursor]; |
247 |
return true; |
332 |
if (string.charAt(i) != ch) { |
|
|
333 |
return false; |
334 |
} |
335 |
if (ch == '\n') { |
336 |
line ++; |
337 |
col = 0; |
338 |
} else { |
339 |
col++; |
340 |
} |
341 |
} |
342 |
current.update(i+cursor, line, col); |
343 |
return true; |
344 |
} |
345 |
else { |
346 |
Mark mark = mark(); |
347 |
int ch = 0; |
348 |
int i = 0; |
349 |
do { |
350 |
ch = nextChar(); |
351 |
if (((char) ch) != string.charAt(i++)) { |
352 |
setCurrent(mark); |
353 |
return false; |
354 |
} |
355 |
} while (i < len); |
356 |
return true; |
357 |
} |
248 |
} |
358 |
} |
249 |
|
359 |
|
250 |
boolean matchesETag(String tagName) throws JasperException { |
360 |
boolean matchesETag(String tagName) throws JasperException { |
Lines 256-262
Link Here
|
256 |
if (nextChar() == '>') |
366 |
if (nextChar() == '>') |
257 |
return true; |
367 |
return true; |
258 |
|
368 |
|
259 |
reset(mark); |
369 |
setCurrent(mark); |
260 |
return false; |
370 |
return false; |
261 |
} |
371 |
} |
262 |
|
372 |
|
Lines 271-277
Link Here
|
271 |
if (nextChar() == '>') |
381 |
if (nextChar() == '>') |
272 |
return true; |
382 |
return true; |
273 |
|
383 |
|
274 |
reset(mark); |
384 |
setCurrent(mark); |
275 |
return false; |
385 |
return false; |
276 |
} |
386 |
} |
277 |
|
387 |
|
Lines 290-296
Link Here
|
290 |
skipSpaces(); |
400 |
skipSpaces(); |
291 |
boolean result = matches( s ); |
401 |
boolean result = matches( s ); |
292 |
if( !result ) { |
402 |
if( !result ) { |
293 |
reset( mark ); |
403 |
setCurrent( mark ); |
294 |
} |
404 |
} |
295 |
|
405 |
|
296 |
return result; |
406 |
return result; |
Lines 315-339
Link Here
|
315 |
* otherwise. |
425 |
* otherwise. |
316 |
*/ |
426 |
*/ |
317 |
Mark skipUntil(String limit) throws JasperException { |
427 |
Mark skipUntil(String limit) throws JasperException { |
318 |
Mark ret = null; |
428 |
Mark ret = mark(); |
319 |
int limlen = limit.length(); |
429 |
int limlen = limit.length(); |
320 |
int ch; |
|
|
321 |
|
430 |
|
|
|
431 |
char firstChar = limit.charAt(0); |
432 |
Boolean result = null; |
433 |
Mark restart = null; |
322 |
skip: |
434 |
skip: |
323 |
for (ret = mark(), ch = nextChar() ; ch != -1 ; |
435 |
while((result = indexOf(firstChar, ret)) != null) { |
324 |
ret = mark(), ch = nextChar()) { |
436 |
if (result.booleanValue()) { |
325 |
if (ch == limit.charAt(0)) { |
437 |
if (restart != null) { |
326 |
Mark restart = mark(); |
438 |
restart.init(current, singleFile); |
327 |
for (int i = 1 ; i < limlen ; i++) { |
439 |
} |
328 |
if (peekChar() == limit.charAt(i)) |
440 |
else { |
329 |
nextChar(); |
441 |
restart = mark(); |
330 |
else { |
442 |
} |
331 |
reset(restart); |
443 |
for (int i = 1 ; i < limlen ; i++) { |
332 |
continue skip; |
444 |
if (peekChar() == limit.charAt(i)) |
333 |
} |
445 |
nextChar(); |
334 |
} |
446 |
else { |
335 |
return ret; |
447 |
setCurrent(restart); |
336 |
} |
448 |
continue skip; |
|
|
449 |
} |
450 |
} |
451 |
return ret; |
452 |
} |
337 |
} |
453 |
} |
338 |
return null; |
454 |
return null; |
339 |
} |
455 |
} |
Lines 349-366
Link Here
|
349 |
* otherwise. |
465 |
* otherwise. |
350 |
*/ |
466 |
*/ |
351 |
Mark skipUntilIgnoreEsc(String limit) throws JasperException { |
467 |
Mark skipUntilIgnoreEsc(String limit) throws JasperException { |
352 |
Mark ret = null; |
468 |
Mark ret = mark(); |
353 |
int limlen = limit.length(); |
469 |
int limlen = limit.length(); |
354 |
int ch; |
470 |
int ch; |
355 |
int prev = 'x'; // Doesn't matter |
471 |
int prev = 'x'; // Doesn't matter |
356 |
|
472 |
|
|
|
473 |
char firstChar = limit.charAt(0); |
357 |
skip: |
474 |
skip: |
358 |
for (ret = mark(), ch = nextChar() ; ch != -1 ; |
475 |
for (ch = nextChar(ret) ; ch != -1 ; prev = ch, ch = nextChar(ret)) { |
359 |
ret = mark(), prev = ch, ch = nextChar()) { |
|
|
360 |
if (ch == '\\' && prev == '\\') { |
476 |
if (ch == '\\' && prev == '\\') { |
361 |
ch = 0; // Double \ is not an escape char anymore |
477 |
ch = 0; // Double \ is not an escape char anymore |
362 |
} |
478 |
} |
363 |
else if (ch == limit.charAt(0) && prev != '\\') { |
479 |
else if (ch == firstChar && prev != '\\') { |
364 |
for (int i = 1 ; i < limlen ; i++) { |
480 |
for (int i = 1 ; i < limlen ; i++) { |
365 |
if (peekChar() == limit.charAt(i)) |
481 |
if (peekChar() == limit.charAt(i)) |
366 |
nextChar(); |
482 |
nextChar(); |
Lines 477-486
Link Here
|
477 |
Mark mark = mark(); |
593 |
Mark mark = mark(); |
478 |
if (((ch = nextChar()) == '>') |
594 |
if (((ch = nextChar()) == '>') |
479 |
|| ((ch == '-') && (nextChar() == '>'))) { |
595 |
|| ((ch == '-') && (nextChar() == '>'))) { |
480 |
reset(mark); |
596 |
setCurrent(mark); |
481 |
return true; |
597 |
return true; |
482 |
} else { |
598 |
} else { |
483 |
reset(mark); |
599 |
setCurrent(mark); |
484 |
return false; |
600 |
return false; |
485 |
} |
601 |
} |
486 |
} |
602 |
} |