|
CssLexer |
|
/*
** Luxor - XML User Interface Language (XUL) Toolkit
** Copyright (c) 2001, 2002 by Gerald Bauer
**
** This program is free software.
**
** You may redistribute it and/or modify it under the terms of the GNU
** General Public License as published by the Free Software Foundation.
** Version 2 of the license should be included with this distribution in
** the file LICENSE, as well as License.html. If the license is not
** included with this distribution, you may find a copy at the FSF web
** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
**
** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
** REDISTRIBUTION OF THIS SOFTWARE.
**
*/
package luxor.css;
import java.io.IOException;
import java.io.Reader;
/**
* CSS scanner - an object which decodes CSS lexical units.
*/
public class CssLexer
{
/**
* The characters to skip to create the string which represents the current
* token.
*/
protected int _blankCharacters;
/**
* The recording buffer.
*/
protected char[] _buffer = new char[128];
/**
* The current column.
*/
protected int _column;
/**
* The current char.
*/
protected int _current;
/**
* The end offset of the last lexical unit.
*/
protected int _end;
/**
* The current line.
*/
protected int _line = 1;
/**
* The current position in the buffer.
*/
protected int _position;
/**
* The reading buffer.
*/
protected char[] _readBuffer;
/**
* The current read buffer count.
*/
protected int _readCount;
/**
* The current position in the read buffer.
*/
protected int _readPosition;
protected Reader _reader;
/**
* The start offset of the last lexical unit.
*/
protected int _start;
/**
* The type of the current lexical unit.
*/
protected int _type;
/**
* Creates a new Scanner object.
*
*@param r The reader to scan.
*@exception CssParseException Description of the Exception
*/
public CssLexer( Reader r ) throws CssParseException
{
try
{
_reader = r;
_readBuffer = new char[4096];
_current = nextChar();
}
catch( IOException e )
{
throw new CssParseException( e );
}
}
/**
* Creates a new Scanner object.
*
*@param r The reader to scan.
*@param s Description of the Parameter
*@exception CssParseException Description of the Exception
*/
public CssLexer( String s ) throws CssParseException
{
try
{
_reader = null;
_readBuffer = s.toCharArray();
_readPosition = 0;
_readCount = _readBuffer.length;
collapseCRNL( 0 );
if( _readCount == 0 )
_current = -1;
else
_current = nextChar();
}
catch( IOException e )
{
throw new CssParseException( e );
}
}
/**
* Returns the buffer used to store the chars.
*/
public char[] getBuffer()
{
return _buffer;
}
/**
* Returns the current column.
*/
public int getColumn()
{
return _column;
}
/**
* Returns the end offset of the last lexical unit.
*/
public int getEnd()
{
return _end;
}
/**
* Returns the current line.
*/
public int getLine()
{
return _line;
}
/**
* Returns the start offset of the last lexical unit.
*/
public int getStart()
{
return _start;
}
/**
* Returns the string representation of the current lexical unit.
*/
public String getStringValue()
{
return new String( _buffer, _start, _end - _start );
}
/**
* The current lexical unit type like defined in Css.Token
*/
public int getType()
{
return _type;
}
/**
* Compares the given int with the given character, ignoring case.
*/
protected static boolean isEqualIgnoreCase( int i, char c )
{
return ( i == -1 ) ? false : Character.toLowerCase( ( char ) i ) == c;
}
/**
* Clears the buffer.
*/
public void clearBuffer()
{
if( _position <= 0 )
_position = 0;
else
{
_buffer[0] = _buffer[_position - 1];
_position = 1;
}
}
/**
* Returns the next token.
*/
public int next() throws CssParseException
{
_blankCharacters = 0;
_start = _position - 1;
nextToken();
_end = _position - endGap();
return _type;
}
/**
* Scans the decimal part of a number.
*/
protected int dotNumber() throws IOException
{
loop :
for( ; ; )
{
switch ( nextChar() )
{
default:
break loop;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
}
}
return numberUnit( false );
}
/**
* Returns the end gap of the current lexical unit.
*/
protected int endGap()
{
int result = ( _current == -1 ) ? 0 : 1;
switch ( _type )
{
case Css.Token.FUNCTION:
case Css.Token.STRING:
case Css.Token.S:
case Css.Token.PERCENTAGE:
result += 1;
break;
case Css.Token.COMMENT:
case Css.Token.HZ:
case Css.Token.EM:
case Css.Token.EX:
case Css.Token.PC:
case Css.Token.PT:
case Css.Token.PX:
case Css.Token.CM:
case Css.Token.MM:
case Css.Token.IN:
case Css.Token.MS:
result += 2;
break;
case Css.Token.KHZ:
case Css.Token.DEG:
case Css.Token.RAD:
result += 3;
break;
case Css.Token.GRAD:
result += 4;
}
return result + _blankCharacters;
}
/**
* Scans an escape sequence, if one.
*/
protected void escape() throws IOException
{
if( CssCharUtils.isHexadecimal( ( char ) _current ) )
{
nextChar();
if( !CssCharUtils.isHexadecimal( ( char ) _current ) )
{
if( CssCharUtils.isSpace( ( char ) _current ) )
nextChar();
return;
}
nextChar();
if( !CssCharUtils.isHexadecimal( ( char ) _current ) )
{
if( CssCharUtils.isSpace( ( char ) _current ) )
nextChar();
return;
}
nextChar();
if( !CssCharUtils.isHexadecimal( ( char ) _current ) )
{
if( CssCharUtils.isSpace( ( char ) _current ) )
nextChar();
return;
}
nextChar();
if( !CssCharUtils.isHexadecimal( ( char ) _current ) )
{
if( CssCharUtils.isSpace( ( char ) _current ) )
nextChar();
return;
}
nextChar();
if( !CssCharUtils.isHexadecimal( ( char ) _current ) )
{
if( CssCharUtils.isSpace( ( char ) _current ) )
nextChar();
return;
}
}
if( ( _current >= ' ' && _current <= '~' ) || _current >= 128 )
{
nextChar();
return;
}
throw new CssParseException( "character", _line, _column );
}
/**
* Sets the value of the current char to the next character or -1 if the end
* of stream has been reached.
*/
protected int nextChar() throws IOException
{
if( _readPosition == _readCount && !fillReadBuffer() )
return _current = -1;
if( _current != 10 )
_column++;
else
{
_line++;
_column = 1;
}
_current = _readBuffer[_readPosition++];
if( _position == _buffer.length )
{
char[] t = new char[_position * 3 / 2];
System.arraycopy( _buffer, 0, t, 0, _position );
_buffer = t;
}
return _buffer[_position++] = ( char ) _current;
}
/**
* Returns the next token.
*/
protected void nextToken() throws CssParseException
{
try
{
switch ( _current )
{
case -1:
_type = Css.Token.EOF;
return;
case '{':
nextChar();
_type = Css.Token.LEFT_CURLY_BRACE;
return;
case '}':
nextChar();
_type = Css.Token.RIGHT_CURLY_BRACE;
return;
case '=':
nextChar();
_type = Css.Token.EQUAL;
return;
case '+':
nextChar();
_type = Css.Token.PLUS;
return;
case ',':
nextChar();
_type = Css.Token.COMMA;
return;
case ';':
nextChar();
_type = Css.Token.SEMI_COLON;
return;
case '>':
nextChar();
_type = Css.Token.PRECEDE;
return;
case '[':
nextChar();
_type = Css.Token.LEFT_BRACKET;
return;
case ']':
nextChar();
_type = Css.Token.RIGHT_BRACKET;
return;
case '*':
nextChar();
_type = Css.Token.ANY;
return;
case '(':
nextChar();
_type = Css.Token.LEFT_BRACE;
return;
case ')':
nextChar();
_type = Css.Token.RIGHT_BRACE;
return;
case ':':
nextChar();
_type = Css.Token.COLON;
return;
case ' ':
case '\t':
case '\r':
case '\n':
case '\f':
do
{
nextChar();
}while ( CssCharUtils.isSpace( ( char ) _current ) );
_type = Css.Token.SPACE;
return;
case '/':
nextChar();
if( _current != '*' )
{
_type = Css.Token.DIVIDE;
return;
}
// Comment
nextChar();
_start = _position - 1;
do
{
while( _current != -1 && _current != '*' )
{
nextChar();
}
do
{
nextChar();
}while ( _current != -1 && _current == '*' );
}while ( _current != -1 && _current != '/' );
if( _current == -1 )
throw new CssParseException( "eof", _line, _column );
nextChar();
_type = Css.Token.COMMENT;
return;
case '\'':
// String1
_type = string1();
return;
case '"':
// String2
_type = string2();
return;
case '<':
nextChar();
if( _current != '!' )
throw new CssParseException( "character", _line, _column );
nextChar();
if( _current == '-' )
{
nextChar();
if( _current == '-' )
{
nextChar();
_type = Css.Token.CDO;
return;
}
}
throw new CssParseException( "character", _line, _column );
case '-':
nextChar();
if( _current != '-' )
{
_type = Css.Token.MINUS;
return;
}
nextChar();
if( _current == '>' )
{
nextChar();
_type = Css.Token.CDC;
return;
}
throw new CssParseException( "character", _line, _column );
case '|':
nextChar();
if( _current == '=' )
{
nextChar();
_type = Css.Token.DASHMATCH;
return;
}
throw new CssParseException( "character", _line, _column );
case '~':
nextChar();
if( _current == '=' )
{
nextChar();
_type = Css.Token.INCLUDES;
return;
}
throw new CssParseException( "character", _line, _column );
case '#':
nextChar();
if( CssCharUtils.isName( ( char ) _current ) )
{
_start = _position - 1;
do
{
nextChar();
if( _current == '\\' )
{
nextChar();
escape();
}
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
_type = Css.Token.HASH;
return;
}
throw new CssParseException( "character", _line, _column );
case '!':
do
{
nextChar();
}while ( _current != -1 && CssCharUtils.isSpace( ( char ) _current ) );
if( isEqualIgnoreCase( _current, 'i' ) &&
isEqualIgnoreCase( nextChar(), 'm' ) &&
isEqualIgnoreCase( nextChar(), 'p' ) &&
isEqualIgnoreCase( nextChar(), 'o' ) &&
isEqualIgnoreCase( nextChar(), 'r' ) &&
isEqualIgnoreCase( nextChar(), 't' ) &&
isEqualIgnoreCase( nextChar(), 'a' ) &&
isEqualIgnoreCase( nextChar(), 'n' ) &&
isEqualIgnoreCase( nextChar(), 't' ) )
{
nextChar();
_type = Css.Token.IMPORTANT_SYMBOL;
return;
}
if( _current == -1 )
throw new CssParseException( "eof", _line, _column );
else
throw new CssParseException( "character", _line, _column );
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
_type = number();
return;
case '.':
switch ( nextChar() )
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
_type = dotNumber();
return;
default:
_type = Css.Token.DOT;
return;
}
case 'u':
case 'U':
nextChar();
switch ( _current )
{
case 'r':
case 'R':
nextChar();
switch ( _current )
{
case 'l':
case 'L':
nextChar();
switch ( _current )
{
case '(':
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isSpace( ( char ) _current ) );
switch ( _current )
{
case '\'':
string1();
_blankCharacters += 2;
while( _current != -1 &&
CssCharUtils.isSpace( ( char ) _current ) )
{
_blankCharacters++;
nextChar();
}
if( _current == -1 )
{
throw new CssParseException( "eof", _line, _column );
}
if( _current != ')' )
{
throw new CssParseException( "character", _line, _column );
}
nextChar();
_type = Css.Token.URI;
return;
case '"':
string2();
_blankCharacters += 2;
while( _current != -1 &&
CssCharUtils.isSpace( ( char ) _current ) )
{
_blankCharacters++;
nextChar();
}
if( _current == -1 )
throw new CssParseException( "eof", _line, _column );
if( _current != ')' )
throw new CssParseException( "character", _line, _column );
nextChar();
_type = Css.Token.URI;
return;
case ')':
throw new CssParseException( "character", _line, _column );
default:
if( !CssCharUtils.isUri( ( char ) _current ) )
throw new CssParseException( "character", _line, _column );
_start = _position - 1;
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isUri( ( char ) _current ) );
_blankCharacters++;
while( _current != -1 &&
CssCharUtils.isSpace( ( char ) _current ) )
{
_blankCharacters++;
nextChar();
}
if( _current == -1 )
throw new CssParseException( "eof", _line, _column );
if( _current != ')' )
throw new CssParseException( "character", _line, _column );
nextChar();
_type = Css.Token.URI;
return;
}
}
}
}
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
if( _current == '(' )
{
nextChar();
_type = Css.Token.FUNCTION;
return;
}
_type = Css.Token.IDENTIFIER;
return;
default:
if( CssCharUtils.isIdentifierStart( ( char ) _current ) )
{
// Identifier
do
{
nextChar();
if( _current == '\\' )
{
nextChar();
escape();
}
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
if( _current == '(' )
{
nextChar();
_type = Css.Token.FUNCTION;
return;
}
_type = Css.Token.IDENTIFIER;
return;
}
nextChar();
throw new CssParseException( "character", _line, _column );
}
}
catch( IOException e )
{
throw new CssParseException( e );
}
}
/**
* Scans a number.
*/
protected int number() throws IOException
{
loop :
for( ; ; )
{
switch ( nextChar() )
{
case '.':
switch ( nextChar() )
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return dotNumber();
}
throw new CssParseException( "character", _line, _column );
default:
break loop;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
}
}
return numberUnit( true );
}
/**
* Scans the unit of a number.
*/
protected int numberUnit( boolean integer ) throws IOException
{
switch ( _current )
{
case '%':
nextChar();
return Css.Token.PERCENTAGE;
case 'c':
case 'C':
switch ( nextChar() )
{
case 'm':
case 'M':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.CM;
default:
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
return Css.Token.DIMENSION;
}
case 'd':
case 'D':
switch ( nextChar() )
{
case 'e':
case 'E':
switch ( nextChar() )
{
case 'g':
case 'G':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.DEG;
}
default:
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
return Css.Token.DIMENSION;
}
case 'e':
case 'E':
switch ( nextChar() )
{
case 'm':
case 'M':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.EM;
case 'x':
case 'X':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.EX;
default:
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
return Css.Token.DIMENSION;
}
case 'g':
case 'G':
switch ( nextChar() )
{
case 'r':
case 'R':
switch ( nextChar() )
{
case 'a':
case 'A':
switch ( nextChar() )
{
case 'd':
case 'D':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.GRAD;
}
}
default:
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
return Css.Token.DIMENSION;
}
case 'h':
case 'H':
nextChar();
switch ( _current )
{
case 'z':
case 'Z':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.HZ;
default:
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
return Css.Token.DIMENSION;
}
case 'i':
case 'I':
switch ( nextChar() )
{
case 'n':
case 'N':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.IN;
default:
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
return Css.Token.DIMENSION;
}
case 'k':
case 'K':
switch ( nextChar() )
{
case 'h':
case 'H':
switch ( nextChar() )
{
case 'z':
case 'Z':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.KHZ;
}
default:
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
return Css.Token.DIMENSION;
}
case 'm':
case 'M':
switch ( nextChar() )
{
case 'm':
case 'M':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.MM;
case 's':
case 'S':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.MS;
default:
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
return Css.Token.DIMENSION;
}
case 'p':
case 'P':
switch ( nextChar() )
{
case 'c':
case 'C':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.PC;
case 't':
case 'T':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.PT;
case 'x':
case 'X':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.PX;
default:
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
return Css.Token.DIMENSION;
}
case 'r':
case 'R':
switch ( nextChar() )
{
case 'a':
case 'A':
switch ( nextChar() )
{
case 'd':
case 'D':
nextChar();
if( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return Css.Token.RAD;
}
default:
while( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) )
{
nextChar();
}
return Css.Token.DIMENSION;
}
case 's':
case 'S':
nextChar();
return Css.Token.S;
default:
if( _current != -1 &&
CssCharUtils.isIdentifierStart( ( char ) _current ) )
{
do
{
nextChar();
}while ( _current != -1 &&
CssCharUtils.isName( ( char ) _current ) );
return Css.Token.DIMENSION;
}
return ( integer ) ? Css.Token.INTEGER : Css.Token.REAL;
}
}
/**
* Scans a single quoted string.
*/
protected int string1() throws IOException
{
nextChar();
_start = _position - 1;
loop :
for( ; ; )
{
switch ( nextChar() )
{
case -1:
throw new CssParseException( "eof", _line, _column );
case '\'':
break loop;
case '"':
break;
case '\\':
switch ( nextChar() )
{
case '\n':
case '\f':
break;
default:
escape();
}
break;
default:
if( !CssCharUtils.isString( ( char ) _current ) )
throw new CssParseException( "character", _line, _column );
}
}
nextChar();
return Css.Token.STRING;
}
/**
* Scans a double quoted string.
*/
protected int string2() throws IOException
{
nextChar();
_start = _position - 1;
loop :
for( ; ; )
{
switch ( nextChar() )
{
case -1:
throw new CssParseException( "eof", _line, _column );
case '\'':
break;
case '"':
break loop;
case '\\':
switch ( nextChar() )
{
case '\n':
case '\f':
break;
default:
escape();
}
break;
default:
if( !CssCharUtils.isString( ( char ) _current ) )
throw new CssParseException( "character", _line, _column );
}
}
nextChar();
return Css.Token.STRING;
}
private void collapseCRNL( int src )
{
// Now collapse cr/nl...
while( src < _readCount )
{
if( _readBuffer[src] != 13 )
src++;
else
{
_readBuffer[src] = 10;
src++;
if( src >= _readCount )
break;
if( _readBuffer[src] == 10 )
{
// We now need to collapse some of the chars to
// eliminate cr/nl pairs. This is where we do it...
int dst = src;
// start writing where this 10 is
src++;
// skip reading this 10.
while( src < _readCount )
{
if( _readBuffer[src] == 13 )
{
_readBuffer[dst++] = 10;
src++;
if( src >= _readCount )
break;
if( _readBuffer[src] == 10 )
src++;
continue;
}
_readBuffer[dst++] = _readBuffer[src++];
}
_readCount = dst;
break;
}
}
}
}
private boolean fillReadBuffer() throws IOException
{
if( _readCount != 0 )
{
if( _readPosition == _readCount )
{
_readBuffer[0] = _readBuffer[_readCount - 1];
_readCount = 1;
_readPosition = 1;
}
else
{
// we keep the last char in our readBuffer.
System.arraycopy( _readBuffer, _readPosition - 1, _readBuffer, 0,
_readCount - _readPosition + 1 );
_readCount = ( _readCount - _readPosition ) + 1;
_readPosition = 1;
}
}
// No reader so can't extend...
if( _reader == null )
return ( _readCount != _readPosition );
// remember where the fill starts...
int src = _readCount - 1;
if( src < 0 )
src = 0;
// Refill the readBuffer...
int read = _reader.read( _readBuffer, _readCount,
_readBuffer.length - _readCount );
if( read == -1 )
return _readCount != _readPosition;
_readCount += read;
// add in chars read.
collapseCRNL( src );
// Now collapse cr/nl...
return _readCount != _readPosition;
}
}
|
CssLexer |
|