e.g. Calendar Search Help
You must enter a value before pressing Search
batik

Class: org.apache.batik.css.parser.Scanner   ©

 OK to copy?
0001 /*
0002 
0003  ============================================================================
0004                    The Apache Software License, Version 1.1
0005  ============================================================================
0006 
0007  Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
0008 
0009  Redistribution and use in source and binary forms, with or without modifica-
0010  tion, are permitted provided that the following conditions are met:
0011 
0012  1. Redistributions of  source code must  retain the above copyright  notice,
0013     this list of conditions and the following disclaimer.
0014 
0015  2. Redistributions in binary form must reproduce the above copyright notice,
0016     this list of conditions and the following disclaimer in the documentation
0017     and/or other materials provided with the distribution.
0018 
0019  3. The end-user documentation included with the redistribution, if any, must
0020     include  the following  acknowledgment:  "This product includes  software
0021     developed  by the  Apache Software Foundation  (http://www.apache.org/)."
0022     Alternately, this  acknowledgment may  appear in the software itself,  if
0023     and wherever such third-party acknowledgments normally appear.
0024 
0025  4. The names "Batik" and  "Apache Software Foundation" must  not  be
0026     used to  endorse or promote  products derived from  this software without
0027     prior written permission. For written permission, please contact
0028     apache@apache.org.
0029 
0030  5. Products  derived from this software may not  be called "Apache", nor may
0031     "Apache" appear  in their name,  without prior written permission  of the
0032     Apache Software Foundation.
0033 
0034  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
0035  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
0036  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
0037  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
0038  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
0039  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
0040  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
0041  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
0042  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
0043  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0044 
0045  This software  consists of voluntary contributions made  by many individuals
0046  on  behalf of the Apache Software  Foundation. For more  information on the
0047  Apache Software Foundation, please see <http://www.apache.org/>.
0048 
0049 */
0050 
0051 package org.apache.batik.css.parser;
0052 
0053 import java.io.IOException;
0054 import java.io.InputStream;
0055 import java.io.Reader;
0056 
0057 import org.apache.batik.util.io.NormalizingReader;
0058 import org.apache.batik.util.io.StreamNormalizingReader;
0059 import org.apache.batik.util.io.StringNormalizingReader;
0060 
0061 /**
0062  * This class represents a CSS scanner - an object which decodes CSS lexical
0063  * units.
0064  *
0065  * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
0066  * @version $Id: Scanner.java,v 1.14 2004/02/16 16:33:54 hillion Exp $
0067  */
0068 public class Scanner {
0069 
0070     /**
0071      * The reader.
0072      */
0073     protected NormalizingReader reader;
0074 
0075     /**
0076      * The current char.
0077      */
0078     protected int current;
0079 
0080     /**
0081      * The recording buffer.
0082      */
0083     protected char[] buffer = new char[128];
0084 
0085     /**
0086      * The current position in the buffer.
0087      */
0088     protected int position;
0089 
0090     /**
0091      * The type of the current lexical unit.
0092      */
0093     protected int type;
0094 
0095     /**
0096      * The start offset of the last lexical unit.
0097      */
0098     protected int start;
0099 
0100     /**
0101      * The end offset of the last lexical unit.
0102      */
0103     protected int end;
0104 
0105     /**
0106      * The characters to skip to create the string which represents the
0107      * current token.
0108      */
0109     protected int blankCharacters;
0110 
0111     /**
0112      * Creates a new Scanner object.
0113      * @param r The reader to scan.
0114      */
0115     public Scanner(Reader r) throws ParseException {
0116         try {
0117             reader = new StreamNormalizingReader(r);
Rate0118             current = nextChar();
0119         } catch (IOException e) {
0120             throw new ParseException(e);
0121         }
0122     }
0123 
0124     /**
0125      * Creates a new Scanner object.
0126      * @param is The input stream to scan.
0127      * @param enc The encoding to use to decode the input stream, or null.
0128      */
0129     public Scanner(InputStream is, String enc) throws ParseException {
0130         try {
0131             reader = new StreamNormalizingReader(is, enc);
Rate0132             current = nextChar();
0133         } catch (IOException e) {
0134             throw new ParseException(e);
0135         }
0136     }
0137 
0138     /**
0139      * Creates a new Scanner object.
0140      * @param r The reader to scan.
0141      */
0142     public Scanner(String s) throws ParseException {
0143         try {
0144             reader = new StringNormalizingReader(s);
Rate0145             current = nextChar(); 
0146         } catch (IOException e) {
0147             throw new ParseException(e);
0148         }
0149     }
0150 
0151     /**
0152      * Returns the current line.
0153      */
0154     public int getLine() {
0155         return reader.getLine();
0156     }
0157 
0158     /**
0159      * Returns the current column.
0160      */
0161     public int getColumn() {
0162         return reader.getColumn();
0163     }
0164 
0165     /**
0166      * Returns the buffer used to store the chars.
0167      */
0168     public char[] getBuffer() {
0169         return buffer;
0170     }
0171 
0172     /**
0173      * Returns the start offset of the last lexical unit.
0174      */
0175     public int getStart() {
0176         return start;
0177     }
0178 
0179     /**
0180      * Returns the end offset of the last lexical unit.
0181      */
0182     public int getEnd() {
0183         return end;
0184     }
0185 
0186     /**
0187      * Clears the buffer.
0188      */
0189     public void clearBuffer() {
0190         if (position <= 0) {
0191             position = 0;
0192         } else {
0193             buffer[0] = buffer[position-1];
0194             position = 1;
0195         }
0196     }
0197 
0198     /**
0199      * The current lexical unit type like defined in LexicalUnits.
0200      */
0201     public int getType() {
0202         return type;
0203     }
0204 
0205     /**
0206      * Returns the string representation of the current lexical unit.
0207      */
0208     public String getStringValue() {
0209         return new String(buffer, start, end - start);
0210     }
0211 
0212     /**
0213      * Scans a @rule value. This method assumes that the current
0214      * lexical unit is a at keyword.
0215      */
0216     public void scanAtRule() throws ParseException {
0217         try {
0218             // waiting for EOF, ';' or '{'
0219             loop: for (;;) {
0220                 switch (current) {
0221                 case '{':
0222                     int brackets = 1;
0223                     for (;;) {
Rate0224                         nextChar();
0225                         switch (current) {
0226                         case '}':
0227                             if (--brackets > 0) {
0228                                 break;
0229                             }
0230                         case -1:
0231                             break loop;
0232                         case '{':
0233                             brackets++;
0234                         }
0235                     }
0236                 case -1:
0237                 case ';':
0238                     break loop;
0239                 }
Rate0240                 nextChar();
0241             }
0242             end = position;
0243         } catch (IOException e) {
0244             throw new ParseException(e);
0245         }
0246     }
0247     
0248     /**
0249      * Returns the next token.
0250      */
0251     public int next() throws ParseException {
0252         blankCharacters = 0;
0253         start = position - 1;
0254         nextToken();
0255         end = position - endGap();
0256         return type;
0257     }
0258 
0259     /**
0260      * Returns the end gap of the current lexical unit.
0261      */
0262     protected int endGap() {
0263         int result = (current == -1) ? 0 : 1;
0264         switch (type) {
0265         case LexicalUnits.FUNCTION:
0266         case LexicalUnits.STRING:
0267         case LexicalUnits.S:
0268         case LexicalUnits.PERCENTAGE:
0269             result += 1;
0270             break;
0271         case LexicalUnits.COMMENT:
0272         case LexicalUnits.HZ:
0273         case LexicalUnits.EM:
0274         case LexicalUnits.EX:
0275         case LexicalUnits.PC:
0276         case LexicalUnits.PT:
0277         case LexicalUnits.PX:
0278         case LexicalUnits.CM:
0279         case LexicalUnits.MM:
0280         case LexicalUnits.IN:
0281         case LexicalUnits.MS:
0282             result += 2;
0283             break;
0284         case LexicalUnits.KHZ:
0285         case LexicalUnits.DEG:
0286         case LexicalUnits.RAD:
0287             result += 3;
0288             break;
0289         case LexicalUnits.GRAD:
0290             result += 4;
0291         }
0292         return result + blankCharacters;
0293     }
0294 
0295     /**
0296      * Returns the next token.
0297      */
0298     protected void nextToken() throws ParseException {
0299         try {
0300             switch (current) {
0301             case -1:
0302                 type = LexicalUnits.EOF;
0303                 return;
0304             case '{':
Rate0305                 nextChar();
0306                 type = LexicalUnits.LEFT_CURLY_BRACE;
0307                 return;
0308             case '}':
Rate0309                 nextChar();
0310                 type = LexicalUnits.RIGHT_CURLY_BRACE;
0311                 return;
0312             case '=':
Rate0313                 nextChar();
0314                 type = LexicalUnits.EQUAL;
0315                 return;
0316             case '+':
Rate0317                 nextChar();
0318                 type = LexicalUnits.PLUS;
0319                 return;
0320             case ',':
Rate0321                 nextChar();
0322                 type = LexicalUnits.COMMA;
0323                 return;
0324             case ';':
Rate0325                 nextChar();
0326                 type = LexicalUnits.SEMI_COLON;
0327                 return;
0328             case '>':
Rate0329                 nextChar();
0330                 type = LexicalUnits.PRECEDE;
0331                 return;
0332             case '[':
Rate0333                 nextChar();
0334                 type = LexicalUnits.LEFT_BRACKET;
0335                 return;
0336             case ']':
Rate0337                 nextChar();
0338                 type = LexicalUnits.RIGHT_BRACKET;
0339                 return;
0340             case '*':
Rate0341                 nextChar();
0342                 type = LexicalUnits.ANY;
0343                 return;
0344             case '(':
Rate0345                 nextChar();
0346                 type = LexicalUnits.LEFT_BRACE;
0347                 return;
0348             case ')':
Rate0349                 nextChar();
0350                 type = LexicalUnits.RIGHT_BRACE;
0351                 return;
0352             case ':':
Rate0353                 nextChar();
0354                 type = LexicalUnits.COLON;
0355                 return;
0356             case ' ':
0357             case '\t':
0358             case '\r':
0359             case '\n':
0360             case '\f':
0361                 do {
Rate0362                     nextChar();
0363                 } while (ScannerUtilities.isCSSSpace((char)current));
0364                 type = LexicalUnits.SPACE;
0365                 return;
0366             case '/':
Rate0367                 nextChar();
0368                 if (current != '*') {
0369                     type = LexicalUnits.DIVIDE;
0370                     return;
0371                 }
0372                 // Comment
Rate0373                 nextChar();
0374                 start = position - 1;
0375                 do {
0376                     while (current != -1 && current != '*') {
Rate0377                         nextChar();
0378                     }
0379                     do {
Rate0380                         nextChar();
0381                     } while (current != -1 && current == '*');
0382                 } while (current != -1 && current != '/');
0383                 if (current == -1) {
0384                     throw new ParseException("eof",
0385                                              reader.getLine(),
0386                                              reader.getColumn());
0387                 }
Rate0388                 nextChar();
0389                 type = LexicalUnits.COMMENT; 
0390                 return;
0391             case '\'': // String1
0392                 type = string1();
0393                 return;
0394             case '"': // String2
0395                 type = string2();
0396                 return;
0397             case '<':
Rate0398                 nextChar();
0399                 if (current != '!') {
0400                     throw new ParseException("character",
0401                                              reader.getLine(),
0402                                              reader.getColumn());
0403                 }
Rate0404                 nextChar();
0405                 if (current == '-') {
Rate0406                     nextChar();
0407                     if (current == '-') {
Rate0408                         nextChar();
0409                         type = LexicalUnits.CDO;
0410                         return;
0411                     }
0412                 }
0413                 throw new ParseException("character",
0414                                          reader.getLine(),
0415                                          reader.getColumn());
0416             case '-':
Rate0417                 nextChar();
0418                 if (current != '-') {
0419                     type = LexicalUnits.MINUS;
0420                     return;
0421                 }
Rate0422                 nextChar();
0423                 if (current == '>') {
Rate0424                     nextChar();
0425                     type = LexicalUnits.CDC;
0426                     return;
0427                 }
0428                 throw new ParseException("character",
0429                                          reader.getLine(),
0430                                          reader.getColumn());
0431             case '|':
Rate0432                 nextChar();
0433                 if (current == '=') {
Rate0434                     nextChar();
0435                     type = LexicalUnits.DASHMATCH;
0436                     return;
0437                 }
0438                 throw new ParseException("character",
0439                                          reader.getLine(),
0440                                          reader.getColumn());
0441             case '~':
Rate0442                 nextChar();
0443                 if (current == '=') {
Rate0444                     nextChar();
0445                     type = LexicalUnits.INCLUDES;
0446                     return;
0447                 }
0448                 throw new ParseException("character",
0449                                          reader.getLine(),
0450                                          reader.getColumn());
0451             case '#':
Rate0452                 nextChar();
0453                 if (ScannerUtilities.isCSSNameCharacter((char)current)) {
0454                     start = position - 1;
0455                     do {
Rate0456                         nextChar();
0457                         if (current == '\\') {
Rate0458                             nextChar();
0459                             escape();
0460                         }
0461                     } while (current != -1 &&
0462                              ScannerUtilities.isCSSNameCharacter
0463                                  ((char)current));
0464                     type = LexicalUnits.HASH;
0465                     return;
0466                 }
0467                 throw new ParseException("character",
0468                                          reader.getLine(),
0469                                          reader.getColumn());
0470             case '@':
Rate0471                 nextChar();
0472                 switch (current) {
0473                 case 'c':
0474                 case 'C':
0475                     start = position - 1;
Rate0476                     if (isEqualIgnoreCase(nextChar(), 'h') &&
0477                         isEqualIgnoreCase(nextChar(), 'a') &&
0478                         isEqualIgnoreCase(nextChar(), 'r') &&
0479                         isEqualIgnoreCase(nextChar(), 's') &&
0480                         isEqualIgnoreCase(nextChar(), 'e') &&
0481                         isEqualIgnoreCase(nextChar(), 't')) {
Rate0482                         nextChar();
0483                         type = LexicalUnits.CHARSET_SYMBOL;
0484                         return;
0485                     }
0486                     break;
0487                 case 'f':
0488                 case 'F':
0489                     start = position - 1;
Rate0490                     if (isEqualIgnoreCase(nextChar(), 'o') &&
0491                         isEqualIgnoreCase(nextChar(), 'n') &&
0492                         isEqualIgnoreCase(nextChar(), 't') &&
0493                         isEqualIgnoreCase(nextChar(), '-') &&
0494                         isEqualIgnoreCase(nextChar(), 'f') &&
0495                         isEqualIgnoreCase(nextChar(), 'a') &&
0496                         isEqualIgnoreCase(nextChar(), 'c') &&
0497                         isEqualIgnoreCase(nextChar(), 'e')) {
Rate0498                         nextChar();
0499                         type = LexicalUnits.FONT_FACE_SYMBOL;
0500                         return;
0501                     }
0502                     break;
0503                 case 'i':
0504                 case 'I':
0505                     start = position - 1;
Rate0506                     if (isEqualIgnoreCase(nextChar(), 'm') &&
0507                         isEqualIgnoreCase(nextChar(), 'p') &&
0508                         isEqualIgnoreCase(nextChar(), 'o') &&
0509                         isEqualIgnoreCase(nextChar(), 'r') &&
0510                         isEqualIgnoreCase(nextChar(), 't')) {
Rate0511                         nextChar();
0512                         type = LexicalUnits.IMPORT_SYMBOL;
0513                         return;
0514                     }
0515                     break;
0516                 case 'm':
0517                 case 'M':
0518                     start = position - 1;
Rate0519                     if (isEqualIgnoreCase(nextChar(), 'e') &&
0520                         isEqualIgnoreCase(nextChar(), 'd') &&
0521                         isEqualIgnoreCase(nextChar(), 'i') &&
0522                         isEqualIgnoreCase(nextChar(), 'a')) {
Rate0523                         nextChar();
0524                         type = LexicalUnits.MEDIA_SYMBOL;
0525                         return;
0526                     }
0527                     break;
0528                 case 'p':
0529                 case 'P':
0530                     start = position - 1;
Rate0531                     if (isEqualIgnoreCase(nextChar(), 'a') &&
0532                         isEqualIgnoreCase(nextChar(), 'g') &&
0533                         isEqualIgnoreCase(nextChar(), 'e')) {
Rate0534                         nextChar();
0535                         type = LexicalUnits.PAGE_SYMBOL;
0536                         return;
0537                     }
0538                     break;
0539                 default:
0540                     if (!ScannerUtilities.isCSSIdentifierStartCharacter
0541                         ((char)current)) {
0542                         throw new ParseException("identifier.character",
0543                                                  reader.getLine(),
0544                                                  reader.getColumn());
0545                     }
0546                     start = position - 1;
0547                 }
0548                 do {
Rate0549                     nextChar();
0550                     if (current == '\\') {
Rate0551                         nextChar();
0552                         escape();
0553                     }
0554                 } while (current != -1 &&
0555                          ScannerUtilities.isCSSNameCharacter((char)current));
0556                 type = LexicalUnits.AT_KEYWORD;
0557                 return;
0558             case '!':
0559                 do {
Rate0560                     nextChar();
0561                 } while (current != -1 &&
0562                          ScannerUtilities.isCSSSpace((char)current));
Rate0563                 if (isEqualIgnoreCase(current, 'i') &&
0564                     isEqualIgnoreCase(nextChar(), 'm') &&
0565                     isEqualIgnoreCase(nextChar(), 'p') &&
0566                     isEqualIgnoreCase(nextChar(), 'o') &&
0567                     isEqualIgnoreCase(nextChar(), 'r') &&
0568                     isEqualIgnoreCase(nextChar(), 't') &&
0569                     isEqualIgnoreCase(nextChar(), 'a') &&
0570                     isEqualIgnoreCase(nextChar(), 'n') &&
0571                     isEqualIgnoreCase(nextChar(), 't')) {
Rate0572                     nextChar();
0573                     type = LexicalUnits.IMPORTANT_SYMBOL;
0574                     return;
0575                 }
0576                 if (current == -1) {
0577                     throw new ParseException("eof",
0578                                              reader.getLine(),
0579                                              reader.getColumn());
0580                 } else {
0581                     throw new ParseException("character",
0582                                              reader.getLine(),
0583                                              reader.getColumn());
0584                 }
0585             case '0': case '1': case '2': case '3': case '4':
0586             case '5': case '6': case '7': case '8': case '9':
0587                 type = number();
0588                 return;
0589             case '.':
Rate0590                 switch (nextChar()) {
0591                 case '0': case '1': case '2': case '3': case '4':
0592                 case '5': case '6': case '7': case '8': case '9':
0593                     type = dotNumber();
0594                     return;
0595                 default:
0596                     type = LexicalUnits.DOT;
0597                     return;
0598                 }
0599             case 'u':
0600             case 'U':
Rate0601                 nextChar();
0602                 switch (current) {
0603                 case '+':
0604                     boolean range = false;
0605                     for (int i = 0; i < 6; i++) {
Rate0606                         nextChar();
0607                         switch (current) {
0608                         case '?':
0609                             range = true;
0610                             break;
0611                         default:
0612                             if (range &&
0613                             !ScannerUtilities.isCSSHexadecimalCharacter
0614                                 ((char)current)) {
0615                                 throw new ParseException("character",
0616                                                          reader.getLine(),
0617                                                          reader.getColumn());
0618                             }
0619                         }
0620                     }
Rate0621                     nextChar();
0622                     if (range) {
0623                         type = LexicalUnits.UNICODE_RANGE;
0624                         return;
0625                     }
0626                     if (current == '-') {
Rate0627                         nextChar();
0628                         if (!ScannerUtilities.isCSSHexadecimalCharacter
0629                             ((char)current)) {
0630                             throw new ParseException("character",
0631                                                      reader.getLine(),
0632                                                      reader.getColumn());
0633                         }
Rate0634                         nextChar();
0635                         if (!ScannerUtilities.isCSSHexadecimalCharacter
0636                             ((char)current)) {
0637                             type = LexicalUnits.UNICODE_RANGE;
0638                             return;
0639                         }
Rate0640                         nextChar();
0641                         if (!ScannerUtilities.isCSSHexadecimalCharacter
0642                             ((char)current)) {
0643                             type = LexicalUnits.UNICODE_RANGE;
0644                             return;
0645                         }
Rate0646                         nextChar();
0647                         if (!ScannerUtilities.isCSSHexadecimalCharacter
0648                             ((char)current)) {
0649                             type = LexicalUnits.UNICODE_RANGE;
0650                             return;
0651                         }
Rate0652                         nextChar();
0653                         if (!ScannerUtilities.isCSSHexadecimalCharacter
0654                             ((char)current)) {
0655                             type = LexicalUnits.UNICODE_RANGE;
0656                             return;
0657                         }
Rate0658                         nextChar();
0659                         if (!ScannerUtilities.isCSSHexadecimalCharacter
0660                             ((char)current)) {
0661                             type = LexicalUnits.UNICODE_RANGE;
0662                             return;
0663                         }
Rate0664                         nextChar();
0665                         type = LexicalUnits.UNICODE_RANGE;
0666                         return;
0667                     }
0668                 case 'r':
0669                 case 'R':
Rate0670                     nextChar();
0671                     switch (current) {
0672                     case 'l':
0673                     case 'L':
Rate0674                         nextChar();
0675                         switch (current) {
0676                         case '(':
0677                             do {
Rate0678                                 nextChar();
0679                             } while (current != -1 &&
0680                                      ScannerUtilities.isCSSSpace
0681                                      ((char)current));
0682                             switch (current) {
0683                             case '\'':
0684                                 string1();
0685                                 blankCharacters += 2;
0686                                 while (current != -1 &&
0687                                        ScannerUtilities.isCSSSpace
0688                                        ((char)current)) {
0689                                     blankCharacters++;
Rate0690                                     nextChar();
0691                                 }
0692                                 if (current == -1) {
0693                                     throw new ParseException
0694                                         ("eof",
0695                                          reader.getLine(),
0696                                          reader.getColumn());
0697                                 }
0698                                 if (current != ')') {
0699                                     throw new ParseException
0700                                         ("character",
0701                                          reader.getLine(),
0702                                          reader.getColumn());
0703                                 }
Rate0704                                 nextChar();
0705                                 type = LexicalUnits.URI;
0706                                 return;
0707                             case '"':
0708                                 string2();
0709                                 blankCharacters += 2;
0710                                 while (current != -1 &&
0711                                        ScannerUtilities.isCSSSpace
0712                                        ((char)current)) {
0713                                     blankCharacters++;
Rate0714                                     nextChar();
0715                                 }
0716                                 if (current == -1) {
0717                                     throw new ParseException
0718                                         ("eof",
0719                                          reader.getLine(),
0720                                          reader.getColumn());
0721                                 }
0722                                 if (current != ')') {
0723                                     throw new ParseException
0724                                         ("character",
0725                                          reader.getLine(),
0726                                          reader.getColumn());
0727                                 }
Rate0728                                 nextChar();
0729                                 type = LexicalUnits.URI;
0730                                 return;
0731                             case ')':
0732                                 throw new ParseException("character",
0733                                                          reader.getLine(),
0734                                                          reader.getColumn());
0735                             default:
0736                                 if (!ScannerUtilities.isCSSURICharacter
0737                                     ((char)current)) {
0738                                     throw new ParseException
0739                                         ("character",
0740                                          reader.getLine(),
0741                                          reader.getColumn());
0742                                 }
0743                                 start = position - 1;
0744                                 do {
Rate0745                                     nextChar();
0746                                 } while (current != -1 &&
0747                                       ScannerUtilities.isCSSURICharacter
0748                                          ((char)current));
0749                                 blankCharacters++;
0750                                 while (current != -1 &&
0751                                        ScannerUtilities.isCSSSpace
0752                                        ((char)current)) {
0753                                     blankCharacters++;
Rate0754                                     nextChar();
0755                                 }
0756                                 if (current == -1) {
0757                                     throw new ParseException
0758                                         ("eof",
0759                                          reader.getLine(),
0760                                          reader.getColumn());
0761                                 }
0762                                 if (current != ')') {
0763                                     throw new ParseException
0764                                         ("character",
0765                                          reader.getLine(),
0766                                          reader.getColumn());
0767                                 }
Rate0768                                 nextChar();
0769                                 type = LexicalUnits.URI;
0770                                 return;
0771                             }
0772                         }
0773                     }
0774                 }
0775                 while (current != -1 &&
0776                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate0777                     nextChar();
0778                 }
0779                 if (current == '(') {
Rate0780                     nextChar();
0781                     type = LexicalUnits.FUNCTION;
0782                     return;
0783                 }
0784                 type = LexicalUnits.IDENTIFIER;
0785                 return;
0786             default:
0787                 if (ScannerUtilities.isCSSIdentifierStartCharacter
0788                     ((char)current)) {
0789                     // Identifier
0790                     do {
Rate0791                         nextChar();
0792                         if (current == '\\') {
Rate0793                             nextChar();
0794                             escape();
0795                         }
0796                     } while (current != -1 && 
0797                              ScannerUtilities.isCSSNameCharacter
0798                              ((char)current));
0799                     if (current == '(') {
Rate0800                         nextChar();
0801                         type = LexicalUnits.FUNCTION;
0802                         return;
0803                     }
0804                     type = LexicalUnits.IDENTIFIER;
0805                     return;
0806                 }
Rate0807                 nextChar();
0808                 throw new ParseException("identifier.character",
0809                                          reader.getLine(),
0810                                          reader.getColumn());
0811             }
0812         } catch (IOException e) {
0813             throw new ParseException(e);
0814         }
0815     }
0816 
0817     /**
0818      * Scans a single quoted string.
0819      */
0820     protected int string1() throws IOException {
Rate0821         nextChar();
0822         start = position - 1;
0823         loop: for (;;) {
Rate0824             switch (nextChar()) {
0825             case -1:
0826                 throw new ParseException("eof",
0827                                          reader.getLine(),
0828                                          reader.getColumn());
0829             case '\'':
0830                 break loop;
0831             case '"':
0832                 break;
0833             case '\\':
Rate0834                 switch (nextChar()) {
0835                 case '\n':
0836                 case '\f':
0837                     break;
0838                 default:
0839                     escape();
0840                 }
0841                 break;
0842             default:
0843                 if (!ScannerUtilities.isCSSStringCharacter((char)current)) {
0844                     throw new ParseException("character",
0845                                              reader.getLine(),
0846                                              reader.getColumn());
0847                 }
0848             }
0849         }
Rate0850         nextChar();
0851         return LexicalUnits.STRING;
0852     }
0853 
0854     /**
0855      * Scans a double quoted string.
0856      */
0857     protected int string2() throws IOException {
Rate0858         nextChar();
0859         start = position - 1;
0860         loop: for (;;) {
Rate0861             switch (nextChar()) {
0862             case -1:
0863                 throw new ParseException("eof",
0864                                          reader.getLine(),
0865                                          reader.getColumn());
0866             case '\'':
0867                 break;
0868             case '"':
0869                 break loop;
0870             case '\\':
Rate0871                 switch (nextChar()) {
0872                 case '\n':
0873                 case '\f':
0874                     break;
0875                 default:
0876                     escape();
0877                 }
0878                 break;
0879             default:
0880                 if (!ScannerUtilities.isCSSStringCharacter((char)current)) {
0881                     throw new ParseException("character",
0882                                              reader.getLine(),
0883                                              reader.getColumn());
0884                 }
0885             }
0886         }
Rate0887         nextChar();
0888         return LexicalUnits.STRING;
0889     }
0890 
0891     /**
0892      * Scans a number.
0893      */
0894     protected int number() throws IOException {
0895         loop: for (;;) {
Rate0896             switch (nextChar()) {
0897             case '.':
Rate0898                 switch (nextChar()) {
0899                 case '0': case '1': case '2': case '3': case '4':
0900                 case '5': case '6': case '7': case '8': case '9':
0901                     return dotNumber();
0902                 }
0903                 throw new ParseException("character",
0904                                          reader.getLine(),
0905                                          reader.getColumn());
0906             default:
0907                 break loop;
0908             case '0': case '1': case '2': case '3': case '4':
0909             case '5': case '6': case '7': case '8': case '9':
0910             }
0911         }
0912         return numberUnit(true);
0913     }        
0914 
0915     /**
0916      * Scans the decimal part of a number.
0917      */
0918     protected int dotNumber() throws IOException {
0919         loop: for (;;) {
Rate0920             switch (nextChar()) {
0921             default:
0922                 break loop;
0923             case '0': case '1': case '2': case '3': case '4':
0924             case '5': case '6': case '7': case '8': case '9':
0925             }
0926         }
0927         return numberUnit(false);
0928     }
0929 
0930     /**
0931      * Scans the unit of a number.
0932      */
0933     protected int numberUnit(boolean integer) throws IOException {
0934         switch (current) {
0935         case '%':
Rate0936             nextChar();
0937             return LexicalUnits.PERCENTAGE;
0938         case 'c':
0939         case 'C':
Rate0940             switch(nextChar()) {
0941             case 'm':
0942             case 'M':
Rate0943                 nextChar();
0944                 if (current != -1 &&
0945                     ScannerUtilities.isCSSNameCharacter((char)current)) {
0946                     do {
Rate0947                         nextChar();
0948                     } while (current != -1 &&
0949                              ScannerUtilities.isCSSNameCharacter
0950                              ((char)current));
0951                     return LexicalUnits.DIMENSION;
0952                 }
0953                 return LexicalUnits.CM;
0954             default:
0955                 while (current != -1 &&
0956                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate0957                     nextChar();
0958                 }
0959                 return LexicalUnits.DIMENSION;
0960             }
0961         case 'd':
0962         case 'D':
Rate0963             switch(nextChar()) {
0964             case 'e':
0965             case 'E':
Rate0966                 switch(nextChar()) {
0967                 case 'g':
0968                 case 'G':
Rate0969                     nextChar();
0970                     if (current != -1 &&
0971                         ScannerUtilities.isCSSNameCharacter((char)current)) {
0972                         do {
Rate0973                             nextChar();
0974                         } while (current != -1 &&
0975                                  ScannerUtilities.isCSSNameCharacter
0976                                  ((char)current));
0977                         return LexicalUnits.DIMENSION;
0978                     }
0979                     return LexicalUnits.DEG;
0980                 }
0981             default:
0982                 while (current != -1 &&
0983                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate0984                     nextChar();
0985                 }
0986                 return LexicalUnits.DIMENSION;
0987             }
0988         case 'e':
0989         case 'E':
Rate0990             switch(nextChar()) {
0991             case 'm':
0992             case 'M':
Rate0993                 nextChar();
0994                 if (current != -1 &&
0995                     ScannerUtilities.isCSSNameCharacter((char)current)) {
0996                     do {
Rate0997                         nextChar();
0998                     } while (current != -1 &&
0999                              ScannerUtilities.isCSSNameCharacter
1000                              ((char)current));
1001                     return LexicalUnits.DIMENSION;
1002                 }
1003                 return LexicalUnits.EM;
1004             case 'x':
1005             case 'X':
Rate1006                 nextChar();
1007                 if (current != -1 &&
1008                     ScannerUtilities.isCSSNameCharacter((char)current)) {
1009                     do {
Rate1010                         nextChar();
1011                     } while (current != -1 &&
1012                              ScannerUtilities.isCSSNameCharacter
1013                              ((char)current));
1014                     return LexicalUnits.DIMENSION;
1015                 }
1016                 return LexicalUnits.EX;
1017             default:
1018                 while (current != -1 &&
1019                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate1020                     nextChar();
1021                 }
1022                 return LexicalUnits.DIMENSION;
1023             }
1024         case 'g':
1025         case 'G':
Rate1026             switch(nextChar()) {
1027             case 'r':
1028             case 'R':
Rate1029                 switch(nextChar()) {
1030                 case 'a':
1031                 case 'A':
Rate1032                     switch(nextChar()) {
1033                     case 'd':
1034                     case 'D':
Rate1035                         nextChar();
1036                         if (current != -1 &&
1037                             ScannerUtilities.isCSSNameCharacter
1038                             ((char)current)) {
1039                             do {
Rate1040                                 nextChar();
1041                             } while (current != -1 &&
1042                                      ScannerUtilities.isCSSNameCharacter
1043                                      ((char)current));
1044                             return LexicalUnits.DIMENSION;
1045                         }
1046                         return LexicalUnits.GRAD;
1047                     }
1048                 }
1049             default:
1050                 while (current != -1 &&
1051                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate1052                     nextChar();
1053                 }
1054                 return LexicalUnits.DIMENSION;
1055             }
1056         case 'h':
1057         case 'H':
Rate1058             nextChar();
1059             switch(current) {
1060             case 'z':
1061             case 'Z':
Rate1062                 nextChar();
1063                 if (current != -1 &&
1064                     ScannerUtilities.isCSSNameCharacter((char)current)) {
1065                     do {
Rate1066                         nextChar();
1067                     } while (current != -1 &&
1068                              ScannerUtilities.isCSSNameCharacter
1069                              ((char)current));
1070                     return LexicalUnits.DIMENSION;
1071                 }
1072                 return LexicalUnits.HZ;
1073             default:
1074                 while (current != -1 &&
1075                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate1076                     nextChar();
1077                 }
1078                 return LexicalUnits.DIMENSION;
1079             }
1080         case 'i':
1081         case 'I':
Rate1082             switch(nextChar()) {
1083             case 'n':
1084             case 'N':
Rate1085                 nextChar();
1086                 if (current != -1 &&
1087                     ScannerUtilities.isCSSNameCharacter((char)current)) {
1088                     do {
Rate1089                         nextChar();
1090                     } while (current != -1 &&
1091                              ScannerUtilities.isCSSNameCharacter
1092                              ((char)current));
1093                     return LexicalUnits.DIMENSION;
1094                 }
1095                 return LexicalUnits.IN;
1096             default:
1097                 while (current != -1 &&
1098                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate1099                     nextChar();
1100                 }
1101                 return LexicalUnits.DIMENSION;
1102             }
1103         case 'k':
1104         case 'K':
Rate1105             switch(nextChar()) {
1106             case 'h':
1107             case 'H':
Rate1108                 switch(nextChar()) {
1109                 case 'z':
1110                 case 'Z':
Rate1111                     nextChar();
1112                     if (current != -1 &&
1113                         ScannerUtilities.isCSSNameCharacter((char)current)) {
1114                         do {
Rate1115                             nextChar();
1116                         } while (current != -1 &&
1117                                  ScannerUtilities.isCSSNameCharacter
1118                                  ((char)current));
1119                         return LexicalUnits.DIMENSION;
1120                     }
1121                     return LexicalUnits.KHZ;
1122                 }
1123             default:
1124                 while (current != -1 &&
1125                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate1126                     nextChar();
1127                 }
1128                 return LexicalUnits.DIMENSION;
1129             }
1130         case 'm':
1131         case 'M':
Rate1132             switch(nextChar()) {
1133             case 'm':
1134             case 'M':
Rate1135                 nextChar();
1136                 if (current != -1 &&
1137                     ScannerUtilities.isCSSNameCharacter((char)current)) {
1138                     do {
Rate1139                         nextChar();
1140                     } while (current != -1 &&
1141                              ScannerUtilities.isCSSNameCharacter
1142                              ((char)current));
1143                     return LexicalUnits.DIMENSION;
1144                 }
1145                 return LexicalUnits.MM;
1146             case 's':
1147             case 'S':
Rate1148                 nextChar();
1149                 if (current != -1 &&
1150                     ScannerUtilities.isCSSNameCharacter((char)current)) {
1151                     do {
Rate1152                         nextChar();
1153                     } while (current != -1 &&
1154                              ScannerUtilities.isCSSNameCharacter
1155                              ((char)current));
1156                     return LexicalUnits.DIMENSION;
1157                 }
1158                 return LexicalUnits.MS;
1159             default:
1160                 while (current != -1 &&
1161                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate1162                     nextChar();
1163                 }
1164                 return LexicalUnits.DIMENSION;
1165             }
1166         case 'p':
1167         case 'P':
Rate1168             switch(nextChar()) {
1169             case 'c':
1170             case 'C':
Rate1171                 nextChar();
1172                 if (current != -1 &&
1173                     ScannerUtilities.isCSSNameCharacter((char)current)) {
1174                     do {
Rate1175                         nextChar();
1176                     } while (current != -1 &&
1177                              ScannerUtilities.isCSSNameCharacter
1178                              ((char)current));
1179                     return LexicalUnits.DIMENSION;
1180                 }
1181                 return LexicalUnits.PC;
1182             case 't':
1183             case 'T':
Rate1184                 nextChar();
1185                 if (current != -1 &&
1186                     ScannerUtilities.isCSSNameCharacter((char)current)) {
1187                     do {
Rate1188                         nextChar();
1189                     } while (current != -1 &&
1190                              ScannerUtilities.isCSSNameCharacter
1191                              ((char)current));
1192                     return LexicalUnits.DIMENSION;
1193                 }
1194                 return LexicalUnits.PT;
1195             case 'x':
1196             case 'X':
Rate1197                 nextChar();
1198                 if (current != -1 &&
1199                     ScannerUtilities.isCSSNameCharacter((char)current)) {
1200                     do {
Rate1201                         nextChar();
1202                     } while (current != -1 &&
1203                              ScannerUtilities.isCSSNameCharacter
1204                              ((char)current));
1205                     return LexicalUnits.DIMENSION;
1206                 }
1207                 return LexicalUnits.PX;
1208             default:
1209                 while (current != -1 &&
1210                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate1211                     nextChar();
1212                 }
1213                 return LexicalUnits.DIMENSION;
1214             }            
1215         case 'r':
1216         case 'R':
Rate1217             switch(nextChar()) {
1218             case 'a':
1219             case 'A':
Rate1220                 switch(nextChar()) {
1221                 case 'd':
1222                 case 'D':
Rate1223                     nextChar();
1224                     if (current != -1 &&
1225                         ScannerUtilities.isCSSNameCharacter((char)current)) {
1226                         do {
Rate1227                             nextChar();
1228                         } while (current != -1 &&
1229                                  ScannerUtilities.isCSSNameCharacter
1230                                  ((char)current));
1231                         return LexicalUnits.DIMENSION;
1232                     }
1233                     return LexicalUnits.RAD;
1234                 }
1235             default:
1236                 while (current != -1 &&
1237                        ScannerUtilities.isCSSNameCharacter((char)current)) {
Rate1238                     nextChar();
1239                 }
1240                 return LexicalUnits.DIMENSION;
1241             }
1242         case 's':
1243         case 'S':
Rate1244             nextChar();
1245             return LexicalUnits.S;
1246         default:
1247             if (current != -1 &&
1248                 ScannerUtilities.isCSSIdentifierStartCharacter
1249                 ((char)current)) {
1250                 do {
Rate1251                     nextChar();
1252                 } while (current != -1 &&
1253                          ScannerUtilities.isCSSNameCharacter((char)current));
1254                 return LexicalUnits.DIMENSION;
1255             }
1256             return (integer) ? LexicalUnits.INTEGER : LexicalUnits.REAL;
1257         }
1258     }
1259 
1260     /**
1261      * Scans an escape sequence, if one.
1262      */
1263     protected void escape() throws IOException {
1264         if (ScannerUtilities.isCSSHexadecimalCharacter((char)current)) {
Rate1265             nextChar();
1266             if (!ScannerUtilities.isCSSHexadecimalCharacter((char)current)) {
1267                 if (ScannerUtilities.isCSSSpace((char)current)) {
Rate1268                     nextChar();
1269                 }
1270                 return;
1271             }
Rate1272             nextChar();
1273             if (!ScannerUtilities.isCSSHexadecimalCharacter((char)current)) {
1274                 if (ScannerUtilities.isCSSSpace((char)current)) {
Rate1275                     nextChar();
1276                 }
1277                 return;
1278             }
Rate1279             nextChar();
1280             if (!ScannerUtilities.isCSSHexadecimalCharacter((char)current)) {
1281                 if (ScannerUtilities.isCSSSpace((char)current)) {
Rate1282                     nextChar();
1283                 }
1284                 return;
1285             }
Rate1286             nextChar();
1287             if (!ScannerUtilities.isCSSHexadecimalCharacter((char)current)) {
1288                 if (ScannerUtilities.isCSSSpace((char)current)) {
Rate1289                     nextChar();
1290                 }
1291                 return;
1292             }
Rate1293             nextChar();
1294             if (!ScannerUtilities.isCSSHexadecimalCharacter((char)current)) {
1295                 if (ScannerUtilities.isCSSSpace((char)current)) {
Rate1296                     nextChar();
1297                 }
1298                 return;
1299             }
1300         }
1301         if ((current >= ' ' && current <= '~') || current >= 128) {
Rate1302             nextChar();
1303             return;
1304         }
1305         throw new ParseException("character",
1306                                  reader.getLine(),
1307                                  reader.getColumn());
1308     }
1309 
1310     /**
1311      * Compares the given int with the given character, ignoring case.
1312      */
1313     protected static boolean isEqualIgnoreCase(int i, char c) {
1314         return (i == -1) ? false : Character.toLowerCase((char)i) == c;
1315     }
1316 
1317     /**
1318      * Sets the value of the current char to the next character or -1 if the
1319      * end of stream has been reached.
1320      */
1321     protected int nextChar() throws IOException {
1322         current = reader.read();
1323 
1324         if (current == -1) {
1325             return current;
1326         }
1327 
1328         if (position == buffer.length) {
1329             char[] t = new char[position * 3 / 2];
1330             for (int i = 0; i < position; i++) {
1331                 t[i] = buffer[i];
1332             }
1333             buffer = t;
1334         }
1335 
1336         return buffer[position++] = (char)current;
1337     }
1338 }

            
All Examples in File:
Example
Line
Rating (found
useful by...)
118 0% of 0
132 0% of 0
145 0% of 0
224 0% of 0
240 0% of 0
305 0% of 0
309 0% of 0
313 0% of 0
317 0% of 0
321 0% of 0
325 0% of 0
329 0% of 0
333 0% of 0
337 0% of 0
341 0% of 0
345 0% of 0
349 0% of 0
353 0% of 0
362 0% of 0
367 0% of 0
373 0% of 0
377 0% of 0
380 0% of 0
388 0% of 0
398 0% of 0
404 0% of 0
406 0% of 0
408 0% of 0
417 0% of 0
422 0% of 0
424 0% of 0
432 0% of 0
434 0% of 0
442 0% of 0
444 0% of 0
452 0% of 0
456 0% of 0
458 0% of 0
471 0% of 0
476 0% of 0
482 0% of 0
490 0% of 0
498 0% of 0
506 0% of 0
511 0% of 0
519 0% of 0
523 0% of 0
531 0% of 0
534 0% of 0
549 0% of 0
551 0% of 0
560 0% of 0
563 0% of 0
572 0% of 0
590 0% of 0
601 0% of 0
606 0% of 0
621 0% of 0
627 0% of 0
634 0% of 0
640 0% of 0
646 0% of 0
652 0% of 0
658 0% of 0
664 0% of 0
670 0% of 0
674 0% of 0
678 0% of 0
690 0% of 0
704 0% of 0
714 0% of 0
728 0% of 0
745 0% of 0
754 0% of 0
768 0% of 0
777 0% of 0
780 0% of 0
791 0% of 0
793 0% of 0
800 0% of 0
807 0% of 0
821 0% of 0
824 0% of 0
834 0% of 0
850 0% of 0
858 0% of 0
861 0% of 0
871 0% of 0
887 0% of 0
896 0% of 0
898 0% of 0
920 0% of 0
936 0% of 0
940 0% of 0
943 0% of 0
947 0% of 0
957 0% of 0
963 0% of 0
966 0% of 1
969 0% of 0
973 0% of 0
984 0% of 0
990 0% of 0
993 0% of 0
997 0% of 0
1006 0% of 0
1010 0% of 0
1020 0% of 0
1026 0% of 0
1029 0% of 0
1032 0% of 0
1035 0% of 0
1040 0% of 0
1052 0% of 0
1058 0% of 0
1062 0% of 0
1066 0% of 0
1076 0% of 0
1082 0% of 0
1085 0% of 0
1089 0% of 0
1099 0% of 0
1105 0% of 0
1108 0% of 0
1111 0% of 0
1115 0% of 0
1126 0% of 0
1132 0% of 0
1135 0% of 0
1139 0% of 0
1148 0% of 0
1152 0% of 0
1162 0% of 0
1168 0% of 0
1171 0% of 0
1175 0% of 0
1184 0% of 0
1188 0% of 0
1197 0% of 0
1201 0% of 0
1211 0% of 0
1217 0% of 0
1220 0% of 0
1223 0% of 0
1227 0% of 0
1238 0% of 0
1244 0% of 0
1251 0% of 0
1265 0% of 0
1268 0% of 0
1272 0% of 0
1275 0% of 0
1279 0% of 0
1282 0% of 0
1286 0% of 0
1289 0% of 0
1293 0% of 0
1296 0% of 0
1302 0% of 0