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