001 package railo.transformer.util; 002 003 import java.io.IOException; 004 import java.io.InputStream; 005 import java.util.ArrayList; 006 007 import railo.commons.io.IOUtil; 008 import railo.commons.io.SystemUtil; 009 import railo.commons.lang.ClassUtil; 010 import railo.runtime.SourceFile; 011 012 /** 013 * this class is a Parser String optimized for the transfomer (CFML Parser) 014 */ 015 public final class CFMLString { 016 017 /** 018 * Mindestens einen Space 019 */ 020 public static final short AT_LEAST_ONE_SPACE=0; 021 022 /** 023 * Mindestens ein Space 024 */ 025 public static final short ZERO_OR_MORE_SPACE=1; 026 027 /** 028 * Field <code>pos</code> 029 */ 030 protected int pos=0; 031 /** 032 * Field <code>text</code> 033 */ 034 protected char[] text; 035 /** 036 * Field <code>lcText</code> 037 */ 038 protected char[] lcText; 039 /** 040 * Field <code>lines</code> 041 */ 042 protected Integer[] lines;// TODO to int[] 043 /** 044 * Field <code>file</code> 045 */ 046 protected SourceFile sf; 047 048 private String charset; 049 050 private boolean writeLog; 051 052 private String source; 053 054 private static final String NL=System.getProperty("line.separator"); 055 056 057 058 public CFMLString(SourceFile sf,String charset,boolean writeLog) throws IOException { 059 this.writeLog=writeLog; 060 this.charset=charset; 061 this.sf=sf; 062 this.source=sf.getPhyscalFile().getAbsolutePath(); 063 String content; 064 InputStream is=null; 065 try { 066 is = IOUtil.toBufferedInputStream(sf.getPhyscalFile().getInputStream()); 067 if(ClassUtil.isBytecode(is))throw new AlreadyClassException(sf.getPhyscalFile()); 068 content=IOUtil.toString(is,charset); 069 070 } 071 finally { 072 IOUtil.closeEL(is); 073 } 074 init(content.toString().toCharArray()); 075 } 076 077 /** 078 * Constructor of the class 079 * in this case source file is just for information 080 * @param text 081 * @param charset 082 * @param writeLog 083 * @param sf 084 */ 085 public CFMLString(String text,String charset,boolean writeLog,SourceFile sf) { 086 init(text.toCharArray()); 087 this.charset=charset; 088 this.writeLog=writeLog; 089 this.sf=sf; 090 } 091 092 /** 093 * Constructor of the class 094 * @param text 095 * @param charset 096 */ 097 public CFMLString(String text,String charset) { 098 init(text.toCharArray()); 099 this.charset=charset; 100 this.writeLog=false; 101 } 102 103 /** 104 * initialize the CFMLString, used by all constructors 105 * @param text 106 */ 107 protected void init(char[] text) { 108 this.text=text; 109 lcText=new char[text.length]; 110 111 ArrayList<Integer> arr=new ArrayList<Integer>(); 112 113 for(int i=0;i<text.length;i++) { 114 pos=i; 115 if(text[i]=='\n') { 116 arr.add(new Integer(i)); 117 lcText[i]=' '; 118 } 119 else if(text[i]=='\r') { 120 if(isNextRaw('\n')){ 121 lcText[i++]=' '; 122 } 123 arr.add(new Integer(i)); 124 lcText[i]=' '; 125 } 126 else if(text[i]=='\t') lcText[i]=' '; 127 else lcText[i]=Character.toLowerCase(text[i]); 128 } 129 pos=0; 130 arr.add(new Integer(text.length)); 131 lines=(Integer[])arr.toArray(new Integer[arr.size()]); 132 } 133 134 /** 135 * returns if the internal pointer is not on the last positions 136 */ 137 public boolean hasNext() { 138 return pos+1<lcText.length; 139 } 140 141 /** 142 * moves the internal pointer to the next position, no check if the next position is still valid 143 */ 144 public void next(){ 145 pos++; 146 } 147 /** 148 * moves the internal pointer to the previous position, no check if the next position is still valid 149 */ 150 public void previous(){ 151 pos--; 152 } 153 154 /** 155 * returns the character of the current position of the internal pointer 156 */ 157 public char getCurrent() { 158 return text[pos]; 159 } 160 161 /** 162 * returns the lower case representation of the character of the current position 163 */ 164 public char getCurrentLower() { 165 return lcText[pos]; 166 } 167 168 /** 169 * returns the character at the given position 170 */ 171 public char charAt(int pos) { 172 return text[pos]; 173 } 174 175 /** 176 * returns the character at the given position as lower case representation 177 */ 178 public char charAtLower(int pos) { 179 return lcText[pos]; 180 } 181 182 /** 183 * is the character at the next position the same as the character provided by the input parameter 184 */ 185 public boolean isNext(char c) { 186 if(!hasNext()) return false; 187 return lcText[pos+1]==c; 188 } 189 190 private boolean isNextRaw(char c) { 191 if(!hasNext()) return false; 192 return text[pos+1]==c; 193 } 194 195 196 /** 197 * is the character at the current position (internal pointer) in the range of the given input characters? 198 * @param left lower value. 199 * @param right upper value. 200 */ 201 public boolean isCurrentBetween(char left, char right) { 202 if(!isValidIndex()) return false; 203 return lcText[pos]>=left && lcText[pos]<=right; 204 } 205 206 207 /** 208 * returns if the character at the current position (internal pointer) is a valid variable character 209 */ 210 public boolean isCurrentVariableCharacter() { 211 if(!isValidIndex()) return false; 212 return isCurrentLetter() || isCurrentNumber() || isCurrent('$') || isCurrent('_'); 213 } 214 215 /** 216 * returns if the current character is a letter (a-z,A-Z) 217 * @return is a letter 218 */ 219 public boolean isCurrentLetter() { 220 if(!isValidIndex()) return false; 221 return lcText[pos]>='a' && lcText[pos]<='z'; 222 } 223 224 /** 225 * returns if the current character is a number (0-9) 226 * @return is a letter 227 */ 228 public boolean isCurrentNumber() { 229 if(!isValidIndex()) return false; 230 return lcText[pos]>='0' && lcText[pos]<='9'; 231 } 232 233 234 /** 235 * retuns if the current character (internal pointer) is a valid special sign (_, $, Pound Symbol, Euro Symbol) 236 */ 237 public boolean isCurrentSpecial() { 238 if(!isValidIndex()) return false; 239 return lcText[pos]=='_' || lcText[pos]=='$' || lcText[pos]==SystemUtil.CHAR_EURO || lcText[pos]==SystemUtil.CHAR_POUND; 240 } 241 242 /** 243 * is the current character (internal pointer) the same as the given 244 */ 245 public boolean isCurrent(char c) { 246 if(!isValidIndex()) return false; 247 return lcText[pos]==c; 248 } 249 250 /** 251 * forward the internal pointer plus one if the next character is the same as the given input 252 */ 253 public boolean forwardIfCurrent(char c) { 254 if(isCurrent(c)) { 255 pos++; 256 return true; 257 } 258 return false; 259 } 260 261 /** 262 * returns if the current character (internal pointer) and the following are the same as the given input 263 */ 264 public boolean isCurrent(String str) { 265 if(pos+str.length()>lcText.length) return false; 266 for(int i=str.length()-1;i>=0;i--) { 267 if(str.charAt(i)!=lcText[pos+i]) return false; 268 } 269 return true; 270 /*char[] c=str.toCharArray(); 271 // @ todo not shure for length 272 if(pos+c.length>text.length) return false; 273 for(int i=c.length-1;i>=0;i--) { 274 if(c[i]!=lcText[pos+i]) return false; 275 } 276 return true;*/ 277 } 278 279 /** 280 * forwards if the current character (internal pointer) and the following are the same as the given input 281 */ 282 public boolean forwardIfCurrent(String str) { 283 boolean is=isCurrent(str); 284 if(is)pos+=str.length(); 285 return is; 286 } 287 288 /** 289 * @param str string to check against current position 290 * @param startWithSpace if true there must be whitespace at the current position 291 * @return does the criteria match? 292 */ 293 public boolean forwardIfCurrent(String str, boolean startWithSpace) { 294 if(!startWithSpace) return forwardIfCurrent(str); 295 296 int start=pos; 297 if(!removeSpace())return false; 298 299 if(!forwardIfCurrent(str)){ 300 pos=start; 301 return false; 302 } 303 return true; 304 } 305 306 /** 307 * @param str string to check against current position 308 * @param startWithSpace if true there must be whitespace at the current position 309 * @param followedByNoVariableCharacter the character following the string must be a none variable character (!a-z,A-Z,0-9,_$) (not eaten) 310 * @return does the criteria match? 311 */ 312 public boolean forwardIfCurrent(String str, boolean startWithSpace, boolean followedByNoVariableCharacter) { 313 314 int start=pos; 315 if(startWithSpace && !removeSpace())return false; 316 317 if(!forwardIfCurrent(str)){ 318 pos=start; 319 return false; 320 } 321 if(followedByNoVariableCharacter && isCurrentVariableCharacter()) { 322 pos=start; 323 return false; 324 } 325 return true; 326 } 327 328 329 330 331 332 /** 333 * forwards if the current character (internal pointer) and the following are the same as the given input, followed by a none word character 334 */ 335 public boolean forwardIfCurrentAndNoWordAfter(String str) { 336 int c=pos; 337 if(forwardIfCurrent(str)) { 338 if(!isCurrentBetween('a','z') && !isCurrent('_'))return true; 339 } 340 pos=c; 341 return false; 342 } 343 344 /** 345 * forwards if the current character (internal pointer) and the following are the same as the given input, followed by a none word character or a number 346 */ 347 public boolean forwardIfCurrentAndNoVarExt(String str) { 348 int c=pos; 349 if(forwardIfCurrent(str)) { 350 if(!isCurrentBetween('a','z') &&!isCurrentBetween('0','9') && !isCurrent('_'))return true; 351 } 352 pos=c; 353 return false; 354 } 355 356 /** 357 * Gibt zur�ck ob first den folgenden Zeichen entspricht, gefolgt von Leerzeichen und second. 358 * @param first Erste Zeichen zum Vergleich (Vor den Leerzeichen). 359 * @param second Zweite Zeichen zum Vergleich (Nach den Leerzeichen). 360 * @return Gibt zur�ck ob die eingegebenen Werte dem Inhalt beim aktuellen Stand des Zeigers entsprechen. 361 */ 362 public boolean isCurrent(String first,char second) { 363 int start=pos; 364 if(!forwardIfCurrent(first)) return false; 365 removeSpace(); 366 boolean rtn=isCurrent(second); 367 pos=start; 368 return rtn; 369 } 370 371 /** 372 * Gibt zur�ck ob first den folgenden Zeichen entspricht, gefolgt von Leerzeichen und second. 373 * @param first Erstes Zeichen zum Vergleich (Vor den Leerzeichen). 374 * @param second Zweites Zeichen zum Vergleich (Nach den Leerzeichen). 375 * @return Gibt zur�ck ob die eingegebenen Werte dem Inhalt beim aktuellen Stand des Zeigers entsprechen. 376 */ 377 public boolean isCurrent(char first,char second) { 378 int start=pos; 379 if(!forwardIfCurrent(first)) return false; 380 removeSpace(); 381 boolean rtn=isCurrent(second); 382 pos=start; 383 return rtn; 384 } 385 386 /** 387 * Gibt zur�ck ob first den folgenden Zeichen entspricht, 388 * gefolgt von Leerzeichen und second, 389 * wenn ja wird der Zeiger um die L�nge der �bereinstimmung nach vorne gestellt. 390 * @param first Erste Zeichen zum Vergleich (Vor den Leerzeichen). 391 * @param second Zweite Zeichen zum Vergleich (Nach den Leerzeichen). 392 * @return Gibt zur�ck ob der Zeiger vorw�rts geschoben wurde oder nicht. 393 */ 394 public boolean forwardIfCurrent(String first,char second) { 395 int start=pos; 396 if(!forwardIfCurrent(first)) return false; 397 removeSpace(); 398 boolean rtn=forwardIfCurrent(second); 399 if(!rtn)pos=start; 400 return rtn; 401 } 402 403 /** 404 * Gibt zur�ck ob ein Wert folgt und vor und hinterher Leerzeichen folgen. 405 * @param before Definition der Leerzeichen vorher. 406 * @param val Gefolgter Wert der erartet wird. 407 * @param after Definition der Leerzeichen nach dem Wert. 408 * @return Gibt zur�ck ob der Zeiger vorw�rts geschoben wurde oder nicht. 409 */ 410 public boolean forwardIfCurrent(short before, String val,short after) { 411 int start=pos; 412 // space before 413 if(before==AT_LEAST_ONE_SPACE) { 414 if(!removeSpace()) return false; 415 } 416 else removeSpace(); 417 418 // value 419 if(!forwardIfCurrent(val)) { 420 setPos(start); 421 return false; 422 } 423 424 // space after 425 if(after==AT_LEAST_ONE_SPACE) { 426 if(!removeSpace()) { 427 setPos(start); 428 return false; 429 } 430 } 431 else removeSpace(); 432 return true; 433 } 434 435 /** 436 * Gibt zur�ck ob first den folgenden Zeichen entspricht, 437 * gefolgt von Leerzeichen und second, 438 * wenn ja wird der Zeiger um die L�nge der �bereinstimmung nach vorne gestellt. 439 * @param first Erste Zeichen zum Vergleich (Vor den Leerzeichen). 440 * @param second Zweite Zeichen zum Vergleich (Nach den Leerzeichen). 441 * @return Gibt zur�ck ob der Zeiger vorw�rts geschoben wurde oder nicht. 442 */ 443 public boolean forwardIfCurrent(char first,char second) { 444 int start=pos; 445 if(!forwardIfCurrent(first)) return false; 446 removeSpace(); 447 boolean rtn=forwardIfCurrent(second); 448 if(!rtn)pos=start; 449 return rtn; 450 } 451 452 /** 453 * Gibt zur�ck ob first den folgenden Zeichen entspricht, gefolgt von Leerzeichen und second. 454 * @param first Erste Zeichen zum Vergleich (Vor den Leerzeichen). 455 * @param second Zweite Zeichen zum Vergleich (Nach den Leerzeichen). 456 * @return Gibt zur�ck ob die eingegebenen Werte dem Inhalt beim aktuellen Stand des Zeigers entsprechen. 457 */ 458 public boolean isCurrent(String first,String second) { 459 int start=pos; 460 if(!forwardIfCurrent(first)) return false; 461 removeSpace(); 462 boolean rtn=isCurrent(second); 463 pos=start; 464 return rtn; 465 } 466 467 /** 468 * Gibt zur�ck ob first den folgenden Zeichen entspricht, 469 * gefolgt von Leerzeichen und second, 470 * wenn ja wird der Zeiger um die L�nge der �bereinstimmung nach vorne gestellt. 471 * @param first Erste Zeichen zum Vergleich (Vor den Leerzeichen). 472 * @param second Zweite Zeichen zum Vergleich (Nach den Leerzeichen). 473 * @return Gibt zur�ck ob der Zeiger vorw�rts geschoben wurde oder nicht. 474 */ 475 public boolean forwardIfCurrent(String first,String second) { 476 int start=pos; 477 if(!forwardIfCurrent(first)) return false; 478 if(!removeSpace()){ 479 pos=start; 480 return false; 481 } 482 boolean rtn=forwardIfCurrent(second); 483 if(!rtn)pos=start; 484 return rtn; 485 } 486 487 public boolean forwardIfCurrent(String first,String second,String third) { 488 int start=pos; 489 if(!forwardIfCurrent(first)) return false; 490 491 if(!removeSpace()){ 492 pos=start; 493 return false; 494 } 495 496 if(!forwardIfCurrent(second)){ 497 pos=start; 498 return false; 499 } 500 501 if(!removeSpace()){ 502 pos=start; 503 return false; 504 } 505 506 boolean rtn=forwardIfCurrent(third); 507 if(!rtn)pos=start; 508 return rtn; 509 } 510 511 public boolean forwardIfCurrent(String first,String second,String third, boolean startWithSpace) { 512 if(!startWithSpace) return forwardIfCurrent(first, second, third); 513 int start=pos; 514 515 if(!removeSpace())return false; 516 517 if(!forwardIfCurrent(first,second,third)){ 518 pos=start; 519 return false; 520 } 521 return true; 522 } 523 524 public boolean forwardIfCurrent(String first,String second,String third, boolean startWithSpace, boolean followedByNoVariableCharacter) { 525 int start=pos; 526 527 if(startWithSpace && !removeSpace())return false; 528 529 if(!forwardIfCurrent(first,second,third)){ 530 pos=start; 531 return false; 532 } 533 if(followedByNoVariableCharacter && isCurrentVariableCharacter()) { 534 pos=start; 535 return false; 536 } 537 return true; 538 } 539 540 541 public boolean forwardIfCurrent(String first,String second, boolean startWithSpace, boolean followedByNoVariableCharacter) { 542 int start=pos; 543 544 if(startWithSpace && !removeSpace())return false; 545 546 if(!forwardIfCurrent(first,second)){ 547 pos=start; 548 return false; 549 } 550 if(followedByNoVariableCharacter && isCurrentVariableCharacter()) { 551 pos=start; 552 return false; 553 } 554 return true; 555 } 556 557 558 559 public boolean forwardIfCurrent(String first,String second,String third, String forth) { 560 int start=pos; 561 if(!forwardIfCurrent(first)) return false; 562 563 if(!removeSpace()){ 564 pos=start; 565 return false; 566 } 567 568 if(!forwardIfCurrent(second)){ 569 pos=start; 570 return false; 571 } 572 573 if(!removeSpace()){ 574 pos=start; 575 return false; 576 } 577 578 579 if(!forwardIfCurrent(third)){ 580 pos=start; 581 return false; 582 } 583 584 if(!removeSpace()){ 585 pos=start; 586 return false; 587 } 588 589 boolean rtn=forwardIfCurrent(forth); 590 if(!rtn)pos=start; 591 return rtn; 592 593 } 594 595 596 /** 597 * Gibt zur�ck ob sich vor dem aktuellen Zeichen Leerzeichen befinden. 598 * @return Gibt zur�ck ob sich vor dem aktuellen Zeichen Leerzeichen befinden. 599 */ 600 public boolean hasSpaceBefore() { 601 return pos > 0 && lcText[pos - 1] == ' '; 602 } 603 604 public boolean hasNLBefore() { 605 int index=0; 606 while(pos-(++index) >= 0){ 607 if(text[pos - index] == '\n')return true; 608 if(text[pos - index] == '\r')return true; 609 if(lcText[pos - index] != ' ') return false; 610 } 611 return false; 612 } 613 614 /** 615 * Stellt den Zeiger nach vorne, wenn er sich innerhalb von Leerzeichen befindet, 616 * bis die Leerzeichen fertig sind. 617 * @return Gibt zur�ck ob der Zeiger innerhalb von Leerzeichen war oder nicht. 618 */ 619 public boolean removeSpace() { 620 int start=pos; 621 while(pos<lcText.length && lcText[pos]==' ') { 622 pos++; 623 } 624 return (start<pos); 625 } 626 public String removeAndGetSpace() { 627 int start=pos; 628 while(pos<lcText.length && lcText[pos]==' ') { 629 pos++; 630 } 631 return substring(start,pos-start); 632 } 633 634 /** 635 * Stellt den internen Zeiger an den Anfang der n�chsten Zeile, 636 * gibt zur�ck ob eine weitere Zeile existiert oder ob es bereits die letzte Zeile war. 637 * @return Existiert eine weitere Zeile. 638 */ 639 public boolean nextLine() { 640 while(isValidIndex() && text[pos]!='\n' && text[pos]!='\r') { 641 next(); 642 } 643 if(!isValidIndex()) return false; 644 645 if(text[pos]=='\n') { 646 next(); 647 return isValidIndex(); 648 } 649 if(text[pos]=='\r') { 650 next(); 651 if(isValidIndex() && text[pos]=='\n') { 652 next(); 653 } 654 return isValidIndex(); 655 } 656 return false; 657 } 658 659 /** 660 * Gibt eine Untermenge des CFMLString als Zeichenkette zur�ck, 661 * ausgehend von start bis zum Ende des CFMLString. 662 * @param start Von wo aus die Untermege ausgegeben werden soll. 663 * @return Untermenge als Zeichenkette 664 */ 665 public String substring(int start) { 666 return substring(start,lcText.length-start); 667 } 668 669 /** 670 * Gibt eine Untermenge des CFMLString als Zeichenkette zur�ck, 671 * ausgehend von start mit einer maximalen L�nge count. 672 * @param start Von wo aus die Untermenge ausgegeben werden soll. 673 * @param count Wie lange die zur�ckgegebene Zeichenkette maximal sein darf. 674 * @return Untermenge als Zeichenkette. 675 */ 676 public String substring(int start, int count) { 677 return String.valueOf(text,start,count); 678 } 679 680 /** 681 * Gibt eine Untermenge des CFMLString als Zeichenkette in Kleinbuchstaben zur�ck, 682 * ausgehend von start bis zum Ende des CFMLString. 683 * @param start Von wo aus die Untermenge ausgegeben werden soll. 684 * @return Untermenge als Zeichenkette in Kleinbuchstaben. 685 */ 686 public String substringLower(int start) { 687 return substringLower(start,lcText.length-start); 688 } 689 690 /** 691 * Gibt eine Untermenge des CFMLString als Zeichenkette in Kleinbuchstaben zur�ck, 692 * ausgehend von start mit einer maximalen L�nge count. 693 * @param start Von wo aus die Untermenge ausgegeben werden soll. 694 * @param count Wie lange die zur�ckgegebene Zeichenkette maximal sein darf. 695 * @return Untermenge als Zeichenkette in Kleinbuchstaben. 696 */ 697 public String substringLower(int start, int count) { 698 return String.valueOf(lcText,start,count); 699 } 700 701 /** 702 * Gibt eine Untermenge des CFMLString als CFMLString zur�ck, 703 * ausgehend von start bis zum Ende des CFMLString. 704 * @param start Von wo aus die Untermenge ausgegeben werden soll. 705 * @return Untermenge als CFMLString 706 */ 707 public CFMLString subCFMLString(int start) { 708 return subCFMLString(start,text.length-start); 709 } 710 711 /** 712 * Gibt eine Untermenge des CFMLString als CFMLString zur�ck, 713 * ausgehend von start mit einer maximalen L�nge count. 714 * @param start Von wo aus die Untermenge ausgegeben werden soll. 715 * @param count Wie lange die zur�ckgegebene Zeichenkette maximal sein darf. 716 * @return Untermenge als CFMLString 717 */ 718 public CFMLString subCFMLString(int start, int count) { 719 return new CFMLString(String.valueOf(text,start,count),charset,writeLog,sf); 720 721 } 722 723 /** Gibt den CFMLString als String zur�ck. 724 * @see java.lang.Object#toString() 725 */ 726 public String toString() { 727 return new String(this.text); 728 } 729 730 /** 731 * Gibt die aktuelle Position des Zeigers innerhalb des CFMLString zur�ck. 732 * @return Position des Zeigers 733 */ 734 public int getPos() { 735 return pos; 736 } 737 738 /** 739 * Setzt die Position des Zeigers innerhalb des CFMLString, ein ung�ltiger index wird ignoriert. 740 * @param pos Position an die der Zeiger gestellt werde soll. 741 */ 742 public void setPos(int pos) { 743 this.pos= pos; 744 } 745 746 /** 747 * Gibt die aktuelle Zeile zur�ck in der der Zeiger des CFMLString steht. 748 * @return Zeilennummer 749 */ 750 public int getLine() { 751 return getLine(pos); 752 } 753 754 /** 755 * Gibt zur�ck in welcher Zeile die angegebene Position ist. 756 * @param pos Position von welcher die Zeile erfragt wird 757 * @return Zeilennummer 758 */ 759 public int getLine(int pos) { 760 for(int i=0;i<lines.length;i++) { 761 if(pos<=lines[i].intValue()) 762 return i+1; 763 } 764 return lines.length; 765 } 766 767 /** 768 * Gibt die Stelle in der aktuelle Zeile zur�ck, in welcher der Zeiger steht. 769 * @return Position innerhalb der Zeile. 770 */ 771 public int getColumn() { 772 return getColumn(pos); 773 } 774 775 /** 776 * Gibt die Stelle in der Zeile auf die pos zeigt zur�ck. 777 * @param pos Position von welcher die Zeile erfragt wird 778 * @return Position innerhalb der Zeile. 779 */ 780 public int getColumn(int pos) { 781 int line=getLine(pos)-1; 782 if(line==0) return pos+1; 783 return pos-lines[line-1].intValue(); 784 } 785 786 /** 787 * Gibt die Zeile auf welcher der Zeiger steht als String zur�ck. 788 * @return Zeile als Zeichenkette 789 */ 790 public String getLineAsString() { 791 return getLineAsString(getLine(pos)); 792 } 793 /** 794 * Gibt die angegebene Zeile als String zur�ck. 795 * @param line Zeile die zur�ck gegeben werden soll 796 * @return Zeile als Zeichenkette 797 */ 798 public String getLineAsString(int line) { 799 int index=line-1; 800 if(lines.length<=index) return null; 801 int max=lines[index].intValue(); 802 int min=0; 803 if(index!=0) 804 min=lines[index-1].intValue()+1; 805 806 if(min<max && max-1<lcText.length) 807 return this.substring(min, max-min); 808 return ""; 809 } 810 811 /** 812 * Gibt zur�ck ob der Zeiger auf dem letzten Zeichen steht. 813 * @return Gibt zur�ck ob der Zeiger auf dem letzten Zeichen steht. 814 */ 815 public boolean isLast() { 816 return pos==lcText.length-1; 817 } 818 819 /** 820 * Gibt zur�ck ob der Zeiger nach dem letzten Zeichen steht. 821 * @return Gibt zur�ck ob der Zeiger nach dem letzten Zeichen steht. 822 */ 823 public boolean isAfterLast() { 824 return pos>=lcText.length; 825 } 826 /** 827 * Gibt zur�ck ob der Zeiger einen korrekten Index hat. 828 * @return Gibt zur�ck ob der Zeiger einen korrekten Index hat. 829 */ 830 public boolean isValidIndex() { 831 return pos<lcText.length && pos>-1; 832 } 833 834 /** 835 * Gibt zur�ck, ausgehend von der aktuellen Position, 836 * wann das n�chste Zeichen folgt das gleich ist wie die Eingabe, 837 * falls keines folgt wird �1 zur�ck gegeben. 838 * Gross- und Kleinschreibung der Zeichen werden igoriert. 839 * @param c gesuchtes Zeichen 840 * @return Zeichen das gesucht werden soll. 841 */ 842 public int indexOfNext(char c) { 843 for(int i=pos;i<lcText.length;i++) { 844 if(lcText[i]==c) return i; 845 } 846 return -1; 847 } 848 849 /** 850 * Gibt das letzte Wort das sich vor dem aktuellen Zeigerstand befindet zur�ck, 851 * falls keines existiert wird null zur�ck gegeben. 852 * @return Word vor dem aktuellen Zeigerstand. 853 */ 854 public String lastWord() { 855 int size = 1; 856 while (pos - size > 0 && lcText[pos - size] == ' ') { 857 size++; 858 } 859 while (pos - size > 0 860 && lcText[pos - size] != ' ' 861 && lcText[pos - size] != ';') { 862 size++; 863 } 864 return this.substring((pos - size + 1), (pos - 1)); 865 } 866 867 /** 868 * Gibt die L�nge des CFMLString zur�ck. 869 * @return L�nge des CFMLString. 870 */ 871 public int length() { 872 return lcText.length; 873 } 874 875 /** 876 * Gibt die Quelle aus dem der CFML Code stammt als File Objekt zur�ck, 877 * falls dies nicht aud einem File stammt wird null zur�ck gegeben. 878 * @return source Quelle des CFML Code. 879 */ 880 public SourceFile getSourceFile() { 881 return sf; 882 } 883 884 /** 885 * Pr�ft ob das �bergebene Objekt diesem Objekt entspricht. 886 * @param o Object zum vergleichen. 887 * @return Ist das �bergebene Objekt das selbe wie dieses. 888 */ 889 public boolean equals(Object o) { 890 if(!(o instanceof CFMLString))return false; 891 return o.toString().equals(this.toString()); 892 } 893 894 public String getCharset() { 895 return charset; 896 } 897 898 899 public boolean getWriteLog() { 900 return writeLog; 901 } 902 903 904 public String getText() { 905 return new String(text); 906 } 907 908 909 910 /** 911 * @return the source 912 */ 913 public String getSource() { 914 return source; 915 } 916 }