private Object ParseNextToken( PushbackStream pis )
{
Object retval = null;
int nextByte = pis.ReadByte();
//skip whitespace
while ( nextByte == 0x09 || nextByte == 0x20 || nextByte == 0x0D || nextByte == 0x0A )
{
nextByte = pis.ReadByte();
}
switch ( nextByte )
{
case '%':
{
//header operations, for now return the entire line
//may need to smarter in the future
StringBuilder buffer = new StringBuilder();
buffer.Append( (char)nextByte );
ReadUntilEndOfLine( pis, buffer );
retval = buffer.ToString();
break;
}
case '(':
{
StringBuilder buffer = new StringBuilder();
int stringByte = pis.ReadByte();
while ( stringByte != -1 && stringByte != ')' )
{
buffer.Append( (char)stringByte );
stringByte = pis.ReadByte();
}
retval = buffer.ToString();
break;
}
case '>':
{
int secondCloseBrace = pis.ReadByte();
if ( secondCloseBrace == '>' )
{
retval = MARK_END_OF_DICTIONARY;
}
else
{
throw new IOException(MessageLocalization.GetComposedMessage("error.expected.the.end.of.a.dictionary"));
}
break;
}
case ']':
{
retval = MARK_END_OF_ARRAY;
break;
}
case '[':
{
IList<Object> list = new List<Object>();
Object nextToken = ParseNextToken( pis );
while (!MARK_END_OF_ARRAY.Equals(nextToken) )
{
list.Add( nextToken );
nextToken = ParseNextToken( pis );
}
retval = list;
break;
}
case '<':
{
int theNextByte = pis.ReadByte();
if ( theNextByte == '<' )
{
IDictionary<String, Object> result = new Dictionary<String, Object>();
//we are reading a dictionary
Object key = ParseNextToken( pis );
while ( key is LiteralName && !MARK_END_OF_DICTIONARY.Equals(key) )
{
Object value = ParseNextToken( pis );
result[((LiteralName)key).name] = value;
key = ParseNextToken( pis );
}
retval = result;
}
else
{
//won't read more than 512 bytes
int multiplyer = 16;
int bufferIndex = -1;
while ( theNextByte != -1 && theNextByte != '>' )
{
int intValue = 0;
if ( theNextByte >= '0' && theNextByte <= '9' )
{
intValue = theNextByte - '0';
}
else if ( theNextByte >= 'A' && theNextByte <= 'F' )
{
intValue = 10 + theNextByte - 'A';
}
else if ( theNextByte >= 'a' && theNextByte <= 'f' )
{
intValue = 10 + theNextByte - 'a';
}
else
{
throw new IOException(MessageLocalization.GetComposedMessage("error.expected.hex.character.and.not.char.thenextbyte.1", theNextByte));
}
intValue *= multiplyer;
if ( multiplyer == 16 )
{
bufferIndex++;
tokenParserByteBuffer[bufferIndex] = 0;
multiplyer = 1;
}
else
{
multiplyer = 16;
}
tokenParserByteBuffer[bufferIndex]+= (byte)intValue;
theNextByte = pis.ReadByte();
}
byte[] finalResult = new byte[bufferIndex+1];
System.Array.Copy(tokenParserByteBuffer,0,finalResult, 0, bufferIndex+1);
retval = finalResult;
}
break;
}
case '/':
{
StringBuilder buffer = new StringBuilder();
int stringByte = pis.ReadByte();
while ( !IsWhitespaceOrEOF( stringByte ) )
{
buffer.Append( (char)stringByte );
stringByte = pis.ReadByte();
}
retval = new LiteralName( buffer.ToString() );
break;
}
case -1:
{
//EOF return null;
break;
}
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
StringBuilder buffer = new StringBuilder();
buffer.Append( (char)nextByte );
nextByte = pis.ReadByte();
while ( !IsWhitespaceOrEOF( nextByte ) &&
(Char.IsDigit( (char)nextByte )||
nextByte == '.' ) )
{
buffer.Append( (char)nextByte );
nextByte = pis.ReadByte();
}
pis.Unread( nextByte );
String value = buffer.ToString();
if ( value.IndexOf( '.' ) >=0 )
{
retval = double.Parse(value, CultureInfo.InvariantCulture);
}
else
{
retval = int.Parse(value, CultureInfo.InvariantCulture);
}
break;
}
default:
{
StringBuilder buffer = new StringBuilder();
buffer.Append( (char)nextByte );
nextByte = pis.ReadByte();
while ( !IsWhitespaceOrEOF( nextByte ) )
{
buffer.Append( (char)nextByte );
nextByte = pis.ReadByte();
}
retval = new Operator( buffer.ToString() );
break;
}
}
return retval;
}