1 18 package org.apache.batik.css.parser; 19 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.io.Reader ; 23 24 import org.apache.batik.util.io.NormalizingReader; 25 import org.apache.batik.util.io.StreamNormalizingReader; 26 import org.apache.batik.util.io.StringNormalizingReader; 27 28 35 public class Scanner { 36 37 40 protected NormalizingReader reader; 41 42 45 protected int current; 46 47 50 protected char[] buffer = new char[128]; 51 52 55 protected int position; 56 57 60 protected int type; 61 62 65 protected int start; 66 67 70 protected int end; 71 72 76 protected int blankCharacters; 77 78 82 public Scanner(Reader r) throws ParseException { 83 try { 84 reader = new StreamNormalizingReader(r); 85 current = nextChar(); 86 } catch (IOException e) { 87 throw new ParseException(e); 88 } 89 } 90 91 96 public Scanner(InputStream is, String enc) throws ParseException { 97 try { 98 reader = new StreamNormalizingReader(is, enc); 99 current = nextChar(); 100 } catch (IOException e) { 101 throw new ParseException(e); 102 } 103 } 104 105 109 public Scanner(String s) throws ParseException { 110 try { 111 reader = new StringNormalizingReader(s); 112 current = nextChar(); 113 } catch (IOException e) { 114 throw new ParseException(e); 115 } 116 } 117 118 121 public int getLine() { 122 return reader.getLine(); 123 } 124 125 128 public int getColumn() { 129 return reader.getColumn(); 130 } 131 132 135 public char[] getBuffer() { 136 return buffer; 137 } 138 139 142 public int getStart() { 143 return start; 144 } 145 146 149 public int getEnd() { 150 return end; 151 } 152 153 156 public void clearBuffer() { 157 if (position <= 0) { 158 position = 0; 159 } else { 160 buffer[0] = buffer[position-1]; 161 position = 1; 162 } 163 } 164 165 168 public int getType() { 169 return type; 170 } 171 172 175 public String getStringValue() { 176 return new String (buffer, start, end - start); 177 } 178 179 183 public void scanAtRule() throws ParseException { 184 try { 185 loop: for (;;) { 187 switch (current) { 188 case '{': 189 int brackets = 1; 190 for (;;) { 191 nextChar(); 192 switch (current) { 193 case '}': 194 if (--brackets > 0) { 195 break; 196 } 197 case -1: 198 break loop; 199 case '{': 200 brackets++; 201 } 202 } 203 case -1: 204 case ';': 205 break loop; 206 } 207 nextChar(); 208 } 209 end = position; 210 } catch (IOException e) { 211 throw new ParseException(e); 212 } 213 } 214 215 218 public int next() throws ParseException { 219 blankCharacters = 0; 220 start = position - 1; 221 nextToken(); 222 end = position - endGap(); 223 return type; 224 } 225 226 229 protected int endGap() { 230 int result = (current == -1) ? 0 : 1; 231 switch (type) { 232 case LexicalUnits.FUNCTION: 233 case LexicalUnits.STRING: 234 case LexicalUnits.S: 235 case LexicalUnits.PERCENTAGE: 236 result += 1; 237 break; 238 case LexicalUnits.COMMENT: 239 case LexicalUnits.HZ: 240 case LexicalUnits.EM: 241 case LexicalUnits.EX: 242 case LexicalUnits.PC: 243 case LexicalUnits.PT: 244 case LexicalUnits.PX: 245 case LexicalUnits.CM: 246 case LexicalUnits.MM: 247 case LexicalUnits.IN: 248 case LexicalUnits.MS: 249 result += 2; 250 break; 251 case LexicalUnits.KHZ: 252 case LexicalUnits.DEG: 253 case LexicalUnits.RAD: 254 result += 3; 255 break; 256 case LexicalUnits.GRAD: 257 result += 4; 258 } 259 return result + blankCharacters; 260 } 261 262 265 protected void nextToken() throws ParseException { 266 try { 267 switch (current) { 268 case -1: 269 type = LexicalUnits.EOF; 270 return; 271 case '{': 272 nextChar(); 273 type = LexicalUnits.LEFT_CURLY_BRACE; 274 return; 275 case '}': 276 nextChar(); 277 type = LexicalUnits.RIGHT_CURLY_BRACE; 278 return; 279 case '=': 280 nextChar(); 281 type = LexicalUnits.EQUAL; 282 return; 283 case '+': 284 nextChar(); 285 type = LexicalUnits.PLUS; 286 return; 287 case ',': 288 nextChar(); 289 type = LexicalUnits.COMMA; 290 return; 291 case ';': 292 nextChar(); 293 type = LexicalUnits.SEMI_COLON; 294 return; 295 case '>': 296 nextChar(); 297 type = LexicalUnits.PRECEDE; 298 return; 299 case '[': 300 nextChar(); 301 type = LexicalUnits.LEFT_BRACKET; 302 return; 303 case ']': 304 nextChar(); 305 type = LexicalUnits.RIGHT_BRACKET; 306 return; 307 case '*': 308 nextChar(); 309 type = LexicalUnits.ANY; 310 return; 311 case '(': 312 nextChar(); 313 type = LexicalUnits.LEFT_BRACE; 314 return; 315 case ')': 316 nextChar(); 317 type = LexicalUnits.RIGHT_BRACE; 318 return; 319 case ':': 320 nextChar(); 321 type = LexicalUnits.COLON; 322 return; 323 case ' ': 324 case '\t': 325 case '\r': 326 case '\n': 327 case '\f': 328 do { 329 nextChar(); 330 } while (ScannerUtilities.isCSSSpace((char)current)); 331 type = LexicalUnits.SPACE; 332 return; 333 case '/': 334 nextChar(); 335 if (current != '*') { 336 type = LexicalUnits.DIVIDE; 337 return; 338 } 339 nextChar(); 341 start = position - 1; 342 do { 343 while (current != -1 && current != '*') { 344 nextChar(); 345 } 346 do { 347 nextChar(); 348 } while (current != -1 && current == '*'); 349 } while (current != -1 && current != '/'); 350 if (current == -1) { 351 throw new ParseException("eof", 352 reader.getLine(), 353 reader.getColumn()); 354 } 355 nextChar(); 356 type = LexicalUnits.COMMENT; 357 return; 358 case '\'': type = string1(); 360 return; 361 case '"': type = string2(); 363 return; 364 case '<': 365 nextChar(); 366 if (current != '!') { 367 throw new ParseException("character", 368 reader.getLine(), 369 reader.getColumn()); 370 } 371 nextChar(); 372 if (current == '-') { 373 nextChar(); 374 if (current == '-') { 375 nextChar(); 376 type = LexicalUnits.CDO; 377 return; 378 } 379 } 380 throw new ParseException("character", 381 reader.getLine(), 382 reader.getColumn()); 383 case '-': 384 nextChar(); 385 if (current != '-') { 386 type = LexicalUnits.MINUS; 387 return; 388 } 389 nextChar(); 390 if (current == '>') { 391 nextChar(); 392 type = LexicalUnits.CDC; 393 return; 394 } 395 throw new ParseException("character", 396 reader.getLine(), 397 reader.getColumn()); 398 case '|': 399 nextChar(); 400 if (current == '=') { 401 nextChar(); 402 type = LexicalUnits.DASHMATCH; 403 return; 404 } 405 throw new ParseException("character", 406 reader.getLine(), 407 reader.getColumn()); 408 case '~': 409 nextChar(); 410 if (current == '=') { 411 nextChar(); 412 type = LexicalUnits.INCLUDES; 413 return; 414 } 415 throw new ParseException("character", 416 reader.getLine(), 417 reader.getColumn()); 418 case '#': 419 nextChar(); 420 if (ScannerUtilities.isCSSNameCharacter((char)current)) { 421 start = position - 1; 422 do { 423 nextChar(); 424 if (current == '\\') { 425 nextChar(); 426 escape(); 427 } 428 } while (current != -1 && 429 ScannerUtilities.isCSSNameCharacter 430 ((char)current)); 431 type = LexicalUnits.HASH; 432 return; 433 } 434 throw new ParseException("character", 435 reader.getLine(), 436 reader.getColumn()); 437 case '@': 438 nextChar(); 439 switch (current) { 440 case 'c': 441 case 'C': 442 start = position - 1; 443 if (isEqualIgnoreCase(nextChar(), 'h') && 444 isEqualIgnoreCase(nextChar(), 'a') && 445 isEqualIgnoreCase(nextChar(), 'r') && 446 isEqualIgnoreCase(nextChar(), 's') && 447 isEqualIgnoreCase(nextChar(), 'e') && 448 isEqualIgnoreCase(nextChar(), 't')) { 449 nextChar(); 450 type = LexicalUnits.CHARSET_SYMBOL; 451 return; 452 } 453 break; 454 case 'f': 455 case 'F': 456 start = position - 1; 457 if (isEqualIgnoreCase(nextChar(), 'o') && 458 isEqualIgnoreCase(nextChar(), 'n') && 459 isEqualIgnoreCase(nextChar(), 't') && 460 isEqualIgnoreCase(nextChar(), '-') && 461 isEqualIgnoreCase(nextChar(), 'f') && 462 isEqualIgnoreCase(nextChar(), 'a') && 463 isEqualIgnoreCase(nextChar(), 'c') && 464 isEqualIgnoreCase(nextChar(), 'e')) { 465 nextChar(); 466 type = LexicalUnits.FONT_FACE_SYMBOL; 467 return; 468 } 469 break; 470 case 'i': 471 case 'I': 472 start = position - 1; 473 if (isEqualIgnoreCase(nextChar(), 'm') && 474 isEqualIgnoreCase(nextChar(), 'p') && 475 isEqualIgnoreCase(nextChar(), 'o') && 476 isEqualIgnoreCase(nextChar(), 'r') && 477 isEqualIgnoreCase(nextChar(), 't')) { 478 nextChar(); 479 type = LexicalUnits.IMPORT_SYMBOL; 480 return; 481 } 482 break; 483 case 'm': 484 case 'M': 485 start = position - 1; 486 if (isEqualIgnoreCase(nextChar(), 'e') && 487 isEqualIgnoreCase(nextChar(), 'd') && 488 isEqualIgnoreCase(nextChar(), 'i') && 489 isEqualIgnoreCase(nextChar(), 'a')) { 490 nextChar(); 491 type = LexicalUnits.MEDIA_SYMBOL; 492 return; 493 } 494 break; 495 case 'p': 496 case 'P': 497 start = position - 1; 498 if (isEqualIgnoreCase(nextChar(), 'a') && 499 isEqualIgnoreCase(nextChar(), 'g') && 500 isEqualIgnoreCase(nextChar(), 'e')) { 501 nextChar(); 502 type = LexicalUnits.PAGE_SYMBOL; 503 return; 504 } 505 break; 506 default: 507 if (!ScannerUtilities.isCSSIdentifierStartCharacter 508 ((char)current)) { 509 throw new ParseException("identifier.character", 510 reader.getLine(), 511 reader.getColumn()); 512 } 513 start = position - 1; 514 } 515 do { 516 nextChar(); 517 if (current == '\\') { 518 nextChar(); 519 escape(); 520 } 521 } while (current != -1 && 522 ScannerUtilities.isCSSNameCharacter((char)current)); 523 type = LexicalUnits.AT_KEYWORD; 524 return; 525 case '!': 526 do { 527 nextChar(); 528 } while (current != -1 && 529 ScannerUtilities.isCSSSpace((char)current)); 530 if (isEqualIgnoreCase(current, 'i') && 531 isEqualIgnoreCase(nextChar(), 'm') && 532 isEqualIgnoreCase(nextChar(), 'p') && 533 isEqualIgnoreCase(nextChar(), 'o') && 534 isEqualIgnoreCase(nextChar(), 'r') && 535 isEqualIgnoreCase(nextChar(), 't') && 536 isEqualIgnoreCase(nextChar(), 'a') && 537 isEqualIgnoreCase(nextChar(), 'n') && 538 isEqualIgnoreCase(nextChar(), 't')) { 539 nextChar(); 540 type = LexicalUnits.IMPORTANT_SYMBOL; 541 return; 542 } 543 if (current == -1) { 544 throw new ParseException("eof", 545 reader.getLine(), 546 reader.getColumn()); 547 } else { 548 throw new ParseException("character", 549 reader.getLine(), 550 reader.getColumn()); 551 } 552 case '0': case '1': case '2': case '3': case '4': 553 case '5': case '6': case '7': case '8': case '9': 554 type = number(); 555 return; 556 case '.': 557 switch (nextChar()) { 558 case '0': case '1': case '2': case '3': case '4': 559 case '5': case '6': case '7': case '8': case '9': 560 type = dotNumber(); 561 return; 562 default: 563 type = LexicalUnits.DOT; 564 return; 565 } 566 case 'u': 567 case 'U': 568 nextChar(); 569 switch (current) { 570 case '+': 571 boolean range = false; 572 for (int i = 0; i < 6; i++) { 573 nextChar(); 574 switch (current) { 575 case '?': 576 range = true; 577 break; 578 default: 579 if (range && 580 !ScannerUtilities.isCSSHexadecimalCharacter 581 ((char)current)) { 582 throw new ParseException("character", 583 reader.getLine(), 584 reader.getColumn()); 585 } 586 } 587 } 588 nextChar(); 589 if (range) { 590 type = LexicalUnits.UNICODE_RANGE; 591 return; 592 } 593 if (current == '-') { 594 nextChar(); 595 if (!ScannerUtilities.isCSSHexadecimalCharacter 596 ((char)current)) { 597 throw new ParseException("character", 598 reader.getLine(), 599 reader.getColumn()); 600 } 601 nextChar(); 602 if (!ScannerUtilities.isCSSHexadecimalCharacter 603 ((char)current)) { 604 type = LexicalUnits.UNICODE_RANGE; 605 return; 606 } 607 nextChar(); 608 if (!ScannerUtilities.isCSSHexadecimalCharacter 609 ((char)current)) { 610 type = LexicalUnits.UNICODE_RANGE; 611 return; 612 } 613 nextChar(); 614 if (!ScannerUtilities.isCSSHexadecimalCharacter 615 ((char)current)) { 616 type = LexicalUnits.UNICODE_RANGE; 617 return; 618 } 619 nextChar(); 620 if (!ScannerUtilities.isCSSHexadecimalCharacter 621 ((char)current)) { 622 type = LexicalUnits.UNICODE_RANGE; 623 return; 624 } 625 nextChar(); 626 if (!ScannerUtilities.isCSSHexadecimalCharacter 627 ((char)current)) { 628 type = LexicalUnits.UNICODE_RANGE; 629 return; 630 } 631 nextChar(); 632 type = LexicalUnits.UNICODE_RANGE; 633 return; 634 } 635 case 'r': 636 case 'R': 637 nextChar(); 638 switch (current) { 639 case 'l': 640 case 'L': 641 nextChar(); 642 switch (current) { 643 case '(': 644 do { 645 nextChar(); 646 } while (current != -1 && 647 ScannerUtilities.isCSSSpace 648 ((char)current)); 649 switch (current) { 650 case '\'': 651 string1(); 652 blankCharacters += 2; 653 while (current != -1 && 654 ScannerUtilities.isCSSSpace 655 ((char)current)) { 656 blankCharacters++; 657 nextChar(); 658 } 659 if (current == -1) { 660 throw new ParseException 661 ("eof", 662 reader.getLine(), 663 reader.getColumn()); 664 } 665 if (current != ')') { 666 throw new ParseException 667 ("character", 668 reader.getLine(), 669 reader.getColumn()); 670 } 671 nextChar(); 672 type = LexicalUnits.URI; 673 return; 674 case '"': 675 string2(); 676 blankCharacters += 2; 677 while (current != -1 && 678 ScannerUtilities.isCSSSpace 679 ((char)current)) { 680 blankCharacters++; 681 nextChar(); 682 } 683 if (current == -1) { 684 throw new ParseException 685 ("eof", 686 reader.getLine(), 687 reader.getColumn()); 688 } 689 if (current != ')') { 690 throw new ParseException 691 ("character", 692 reader.getLine(), 693 reader.getColumn()); 694 } 695 nextChar(); 696 type = LexicalUnits.URI; 697 return; 698 case ')': 699 throw new ParseException("character", 700 reader.getLine(), 701 reader.getColumn()); 702 default: 703 if (!ScannerUtilities.isCSSURICharacter 704 ((char)current)) { 705 throw new ParseException 706 ("character", 707 reader.getLine(), 708 reader.getColumn()); 709 } 710 start = position - 1; 711 do { 712 nextChar(); 713 } while (current != -1 && 714 ScannerUtilities.isCSSURICharacter 715 ((char)current)); 716 blankCharacters++; 717 while (current != -1 && 718 ScannerUtilities.isCSSSpace 719 ((char)current)) { 720 blankCharacters++; 721 nextChar(); 722 } 723 if (current == -1) { 724 throw new ParseException 725 ("eof", 726 reader.getLine(), 727 reader.getColumn()); 728 } 729 if (current != ')') { 730 throw new ParseException 731 ("character", 732 reader.getLine(), 733 reader.getColumn()); 734 } 735 nextChar(); 736 type = LexicalUnits.URI; 737 return; 738 } 739 } 740 } 741 } 742 while (current != -1 && 743 ScannerUtilities.isCSSNameCharacter((char)current)) { 744 nextChar(); 745 } 746 if (current == '(') { 747 nextChar(); 748 type = LexicalUnits.FUNCTION; 749 return; 750 } 751 type = LexicalUnits.IDENTIFIER; 752 return; 753 default: 754 if (ScannerUtilities.isCSSIdentifierStartCharacter 755 ((char)current)) { 756 do { 758 nextChar(); 759 if (current == '\\') { 760 nextChar(); 761 escape(); 762 } 763 } while (current != -1 && 764 ScannerUtilities.isCSSNameCharacter 765 ((char)current)); 766 if (current == '(') { 767 nextChar(); 768 type = LexicalUnits.FUNCTION; 769 return; 770 } 771 type = LexicalUnits.IDENTIFIER; 772 return; 773 } 774 nextChar(); 775 throw new ParseException("identifier.character", 776 reader.getLine(), 777 reader.getColumn()); 778 } 779 } catch (IOException e) { 780 throw new ParseException(e); 781 } 782 } 783 784 787 protected int string1() throws IOException { 788 start = position; loop: for (;;) { 790 switch (nextChar()) { 791 case -1: 792 throw new ParseException("eof", 793 reader.getLine(), 794 reader.getColumn()); 795 case '\'': 796 break loop; 797 case '"': 798 break; 799 case '\\': 800 switch (nextChar()) { 801 case '\n': 802 case '\f': 803 break; 804 default: 805 escape(); 806 } 807 break; 808 default: 809 if (!ScannerUtilities.isCSSStringCharacter((char)current)) { 810 throw new ParseException("character", 811 reader.getLine(), 812 reader.getColumn()); 813 } 814 } 815 } 816 nextChar(); 817 return LexicalUnits.STRING; 818 } 819 820 823 protected int string2() throws IOException { 824 start = position; loop: for (;;) { 826 switch (nextChar()) { 827 case -1: 828 throw new ParseException("eof", 829 reader.getLine(), 830 reader.getColumn()); 831 case '\'': 832 break; 833 case '"': 834 break loop; 835 case '\\': 836 switch (nextChar()) { 837 case '\n': 838 case '\f': 839 break; 840 default: 841 escape(); 842 } 843 break; 844 default: 845 if (!ScannerUtilities.isCSSStringCharacter((char)current)) { 846 throw new ParseException("character", 847 reader.getLine(), 848 reader.getColumn()); 849 } 850 } 851 } 852 nextChar(); 853 return LexicalUnits.STRING; 854 } 855 856 859 protected int number() throws IOException { 860 loop: for (;;) { 861 switch (nextChar()) { 862 case '.': 863 switch (nextChar()) { 864 case '0': case '1': case '2': case '3': case '4': 865 case '5': case '6': case '7': case '8': case '9': 866 return dotNumber(); 867 } 868 throw new ParseException("character", 869 reader.getLine(), 870 reader.getColumn()); 871 default: 872 break loop; 873 case '0': case '1': case '2': case '3': case '4': 874 case '5': case '6': case '7': case '8': case '9': 875 } 876 } 877 return numberUnit(true); 878 } 879 880 883 protected int dotNumber() throws IOException { 884 loop: for (;;) { 885 switch (nextChar()) { 886 default: 887 break loop; 888 case '0': case '1': case '2': case '3': case '4': 889 case '5': case '6': case '7': case '8': case '9': 890 } 891 } 892 return numberUnit(false); 893 } 894 895 898 protected int numberUnit(boolean integer) throws IOException { 899 switch (current) { 900 case '%': 901 nextChar(); 902 return LexicalUnits.PERCENTAGE; 903 case 'c': 904 case 'C': 905 switch(nextChar()) { 906 case 'm': 907 case 'M': 908 nextChar(); 909 if (current != -1 && 910 ScannerUtilities.isCSSNameCharacter((char)current)) { 911 do { 912 nextChar(); 913 } while (current != -1 && 914 ScannerUtilities.isCSSNameCharacter 915 ((char)current)); 916 return LexicalUnits.DIMENSION; 917 } 918 return LexicalUnits.CM; 919 default: 920 while (current != -1 && 921 ScannerUtilities.isCSSNameCharacter((char)current)) { 922 nextChar(); 923 } 924 return LexicalUnits.DIMENSION; 925 } 926 case 'd': 927 case 'D': 928 switch(nextChar()) { 929 case 'e': 930 case 'E': 931 switch(nextChar()) { 932 case 'g': 933 case 'G': 934 nextChar(); 935 if (current != -1 && 936 ScannerUtilities.isCSSNameCharacter((char)current)) { 937 do { 938 nextChar(); 939 } while (current != -1 && 940 ScannerUtilities.isCSSNameCharacter 941 ((char)current)); 942 return LexicalUnits.DIMENSION; 943 } 944 return LexicalUnits.DEG; 945 } 946 default: 947 while (current != -1 && 948 ScannerUtilities.isCSSNameCharacter((char)current)) { 949 nextChar(); 950 } 951 return LexicalUnits.DIMENSION; 952 } 953 case 'e': 954 case 'E': 955 switch(nextChar()) { 956 case 'm': 957 case 'M': 958 nextChar(); 959 if (current != -1 && 960 ScannerUtilities.isCSSNameCharacter((char)current)) { 961 do { 962 nextChar(); 963 } while (current != -1 && 964 ScannerUtilities.isCSSNameCharacter 965 ((char)current)); 966 return LexicalUnits.DIMENSION; 967 } 968 return LexicalUnits.EM; 969 case 'x': 970 case 'X': 971 nextChar(); 972 if (current != -1 && 973 ScannerUtilities.isCSSNameCharacter((char)current)) { 974 do { 975 nextChar(); 976 } while (current != -1 && 977 ScannerUtilities.isCSSNameCharacter 978 ((char)current)); 979 return LexicalUnits.DIMENSION; 980 } 981 return LexicalUnits.EX; 982 default: 983 while (current != -1 && 984 ScannerUtilities.isCSSNameCharacter((char)current)) { 985 nextChar(); 986 } 987 return LexicalUnits.DIMENSION; 988 } 989 case 'g': 990 case 'G': 991 switch(nextChar()) { 992 case 'r': 993 case 'R': 994 switch(nextChar()) { 995 case 'a': 996 case 'A': 997 switch(nextChar()) { 998 case 'd': 999 case 'D': 1000 nextChar(); 1001 if (current != -1 && 1002 ScannerUtilities.isCSSNameCharacter 1003 ((char)current)) { 1004 do { 1005 nextChar(); 1006 } while (current != -1 && 1007 ScannerUtilities.isCSSNameCharacter 1008 ((char)current)); 1009 return LexicalUnits.DIMENSION; 1010 } 1011 return LexicalUnits.GRAD; 1012 } 1013 } 1014 default: 1015 while (current != -1 && 1016 ScannerUtilities.isCSSNameCharacter((char)current)) { 1017 nextChar(); 1018 } 1019 return LexicalUnits.DIMENSION; 1020 } 1021 case 'h': 1022 case 'H': 1023 nextChar(); 1024 switch(current) { 1025 case 'z': 1026 case 'Z': 1027 nextChar(); 1028 if (current != -1 && 1029 ScannerUtilities.isCSSNameCharacter((char)current)) { 1030 do { 1031 nextChar(); 1032 } while (current != -1 && 1033 ScannerUtilities.isCSSNameCharacter 1034 ((char)current)); 1035 return LexicalUnits.DIMENSION; 1036 } 1037 return LexicalUnits.HZ; 1038 default: 1039 while (current != -1 && 1040 ScannerUtilities.isCSSNameCharacter((char)current)) { 1041 nextChar(); 1042 } 1043 return LexicalUnits.DIMENSION; 1044 } 1045 case 'i': 1046 case 'I': 1047 switch(nextChar()) { 1048 case 'n': 1049 case 'N': 1050 nextChar(); 1051 if (current != -1 && 1052 ScannerUtilities.isCSSNameCharacter((char)current)) { 1053 do { 1054 nextChar(); 1055 } while (current != -1 && 1056 ScannerUtilities.isCSSNameCharacter 1057 ((char)current)); 1058 return LexicalUnits.DIMENSION; 1059 } 1060 return LexicalUnits.IN; 1061 default: 1062 while (current != -1 && 1063 ScannerUtilities.isCSSNameCharacter((char)current)) { 1064 nextChar(); 1065 } 1066 return LexicalUnits.DIMENSION; 1067 } 1068 case 'k': 1069 case 'K': 1070 switch(nextChar()) { 1071 case 'h': 1072 case 'H': 1073 switch(nextChar()) { 1074 case 'z': 1075 case 'Z': 1076 nextChar(); 1077 if (current != -1 && 1078 ScannerUtilities.isCSSNameCharacter((char)current)) { 1079 do { 1080 nextChar(); 1081 } while (current != -1 && 1082 ScannerUtilities.isCSSNameCharacter 1083 ((char)current)); 1084 return LexicalUnits.DIMENSION; 1085 } 1086 return LexicalUnits.KHZ; 1087 } 1088 default: 1089 while (current != -1 && 1090 ScannerUtilities.isCSSNameCharacter((char)current)) { 1091 nextChar(); 1092 } 1093 return LexicalUnits.DIMENSION; 1094 } 1095 case 'm': 1096 case 'M': 1097 switch(nextChar()) { 1098 case 'm': 1099 case 'M': 1100 nextChar(); 1101 if (current != -1 && 1102 ScannerUtilities.isCSSNameCharacter((char)current)) { 1103 do { 1104 nextChar(); 1105 } while (current != -1 && 1106 ScannerUtilities.isCSSNameCharacter 1107 ((char)current)); 1108 return LexicalUnits.DIMENSION; 1109 } 1110 return LexicalUnits.MM; 1111 case 's': 1112 case 'S': 1113 nextChar(); 1114 if (current != -1 && 1115 ScannerUtilities.isCSSNameCharacter((char)current)) { 1116 do { 1117 nextChar(); 1118 } while (current != -1 && 1119 ScannerUtilities.isCSSNameCharacter 1120 ((char)current)); 1121 return LexicalUnits.DIMENSION; 1122 } 1123 return LexicalUnits.MS; 1124 default: 1125 while (current != -1 && 1126 ScannerUtilities.isCSSNameCharacter((char)current)) { 1127 nextChar(); 1128 } 1129 return LexicalUnits.DIMENSION; 1130 } 1131 case 'p': 1132 case 'P': 1133 switch(nextChar()) { 1134 case 'c': 1135 case 'C': 1136 nextChar(); 1137 if (current != -1 && 1138 ScannerUtilities.isCSSNameCharacter((char)current)) { 1139 do { 1140 nextChar(); 1141 } while (current != -1 && 1142 ScannerUtilities.isCSSNameCharacter 1143 ((char)current)); 1144 return LexicalUnits.DIMENSION; 1145 } 1146 return LexicalUnits.PC; 1147 case 't': 1148 case 'T': 1149 nextChar(); 1150 if (current != -1 && 1151 ScannerUtilities.isCSSNameCharacter((char)current)) { 1152 do { 1153 nextChar(); 1154 } while (current != -1 && 1155 ScannerUtilities.isCSSNameCharacter 1156 ((char)current)); 1157 return LexicalUnits.DIMENSION; 1158 } 1159 return LexicalUnits.PT; 1160 case 'x': 1161 case 'X': 1162 nextChar(); 1163 if (current != -1 && 1164 ScannerUtilities.isCSSNameCharacter((char)current)) { 1165 do { 1166 nextChar(); 1167 } while (current != -1 && 1168 ScannerUtilities.isCSSNameCharacter 1169 ((char)current)); 1170 return LexicalUnits.DIMENSION; 1171 } 1172 return LexicalUnits.PX; 1173 default: 1174 while (current != -1 && 1175 ScannerUtilities.isCSSNameCharacter((char)current)) { 1176 nextChar(); 1177 } 1178 return LexicalUnits.DIMENSION; 1179 } 1180 case 'r': 1181 case 'R': 1182 switch(nextChar()) { 1183 case 'a': 1184 case 'A': 1185 switch(nextChar()) { 1186 case 'd': 1187 case 'D': 1188 nextChar(); 1189 if (current != -1 && 1190 ScannerUtilities.isCSSNameCharacter((char)current)) { 1191 do { 1192 nextChar(); 1193 } while (current != -1 && 1194 ScannerUtilities.isCSSNameCharacter 1195 ((char)current)); 1196 return LexicalUnits.DIMENSION; 1197 } 1198 return LexicalUnits.RAD; 1199 } 1200 default: 1201 while (current != -1 && 1202 ScannerUtilities.isCSSNameCharacter((char)current)) { 1203 nextChar(); 1204 } 1205 return LexicalUnits.DIMENSION; 1206 } 1207 case 's': 1208 case 'S': 1209 nextChar(); 1210 return LexicalUnits.S; 1211 default: 1212 if (current != -1 && 1213 ScannerUtilities.isCSSIdentifierStartCharacter 1214 ((char)current)) { 1215 do { 1216 nextChar(); 1217 } while (current != -1 && 1218 ScannerUtilities.isCSSNameCharacter((char)current)); 1219 return LexicalUnits.DIMENSION; 1220 } 1221 return (integer) ? LexicalUnits.INTEGER : LexicalUnits.REAL; 1222 } 1223 } 1224 1225 1228 protected void escape() throws IOException { 1229 if (ScannerUtilities.isCSSHexadecimalCharacter((char)current)) { 1230 nextChar(); 1231 if (!ScannerUtilities.isCSSHexadecimalCharacter((char)current)) { 1232 if (ScannerUtilities.isCSSSpace((char)current)) { 1233 nextChar(); 1234 } 1235 return; 1236 } 1237 nextChar(); 1238 if (!ScannerUtilities.isCSSHexadecimalCharacter((char)current)) { 1239 if (ScannerUtilities.isCSSSpace((char)current)) { 1240 nextChar(); 1241 } 1242 return; 1243 } 1244 nextChar(); 1245 if (!ScannerUtilities.isCSSHexadecimalCharacter((char)current)) { 1246 if (ScannerUtilities.isCSSSpace((char)current)) { 1247 nextChar(); 1248 } 1249 return; 1250 } 1251 nextChar(); 1252 if (!ScannerUtilities.isCSSHexadecimalCharacter((char)current)) { 1253 if (ScannerUtilities.isCSSSpace((char)current)) { 1254 nextChar(); 1255 } 1256 return; 1257 } 1258 nextChar(); 1259 if (!ScannerUtilities.isCSSHexadecimalCharacter((char)current)) { 1260 if (ScannerUtilities.isCSSSpace((char)current)) { 1261 nextChar(); 1262 } 1263 return; 1264 } 1265 } 1266 if ((current >= ' ' && current <= '~') || current >= 128) { 1267 nextChar(); 1268 return; 1269 } 1270 throw new ParseException("character", 1271 reader.getLine(), 1272 reader.getColumn()); 1273 } 1274 1275 1278 protected static boolean isEqualIgnoreCase(int i, char c) { 1279 return (i == -1) ? false : Character.toLowerCase((char)i) == c; 1280 } 1281 1282 1286 protected int nextChar() throws IOException { 1287 current = reader.read(); 1288 1289 if (current == -1) { 1290 return current; 1291 } 1292 1293 if (position == buffer.length) { 1294 char[] t = new char[position * 3 / 2]; 1295 for (int i = 0; i < position; i++) { 1296 t[i] = buffer[i]; 1297 } 1298 buffer = t; 1299 } 1300 1301 return buffer[position++] = (char)current; 1302 } 1303} 1304 | Popular Tags |