2009-09-30 23:50:03 +00:00
//
// In order to convert some functionality to Visual C#, the Java Language Conversion Assistant
// creates "support classes" that duplicate the original functionality.
//
// Support classes replicate the functionality of the original code, but in some cases they are
// substantially different architecturally. Although every effort is made to preserve the
// original architecture of the application in the converted project, the user should be aware that
// the primary goal of these support classes is to replicate functionality, and that at times
// the architecture of the resulting solution may differ somewhat.
//
using System ;
/// <summary>
/// This interface should be implemented by any class whose instances are intended
/// to be executed by a thread.
/// </summary>
public interface IThreadRunnable
{
/// <summary>
/// This method has to be implemented in order that starting of the thread causes the object's
/// run method to be called in that separately executing thread.
/// </summary>
void Run ( ) ;
}
/// <summary>
/// Contains conversion support elements such as classes, interfaces and static methods.
/// </summary>
internal class SupportClass
{
/// <summary>
/// Converts an array of sbytes to an array of bytes
/// </summary>
/// <param name="sbyteArray">The array of sbytes to be converted</param>
/// <returns>The new array of bytes</returns>
public static byte [ ] ToByteArray ( sbyte [ ] sbyteArray )
{
byte [ ] byteArray = null ;
if ( sbyteArray ! = null )
{
byteArray = new byte [ sbyteArray . Length ] ;
for ( int index = 0 ; index < sbyteArray . Length ; index + + )
byteArray [ index ] = ( byte ) sbyteArray [ index ] ;
}
return byteArray ;
}
/// <summary>
/// Converts a string to an array of bytes
/// </summary>
/// <param name="sourceString">The string to be converted</param>
/// <returns>The new array of bytes</returns>
public static byte [ ] ToByteArray ( System . String sourceString )
{
return System . Text . UTF8Encoding . UTF8 . GetBytes ( sourceString ) ;
}
/// <summary>
/// Converts a array of object-type instances to a byte-type array.
/// </summary>
/// <param name="tempObjectArray">Array to convert.</param>
/// <returns>An array of byte type elements.</returns>
public static byte [ ] ToByteArray ( System . Object [ ] tempObjectArray )
{
byte [ ] byteArray = null ;
if ( tempObjectArray ! = null )
{
byteArray = new byte [ tempObjectArray . Length ] ;
for ( int index = 0 ; index < tempObjectArray . Length ; index + + )
byteArray [ index ] = ( byte ) tempObjectArray [ index ] ;
}
return byteArray ;
}
/*******************************/
/// <summary>
/// Writes the exception stack trace to the received stream
/// </summary>
/// <param name="throwable">Exception to obtain information from</param>
/// <param name="stream">Output sream used to write to</param>
public static void WriteStackTrace ( System . Exception throwable , System . IO . TextWriter stream )
{
stream . Write ( throwable . StackTrace ) ;
stream . Flush ( ) ;
}
/*******************************/
/// <summary>
/// Receives a byte array and returns it transformed in an sbyte array
/// </summary>
/// <param name="byteArray">Byte array to process</param>
/// <returns>The transformed array</returns>
public static sbyte [ ] ToSByteArray ( byte [ ] byteArray )
{
sbyte [ ] sbyteArray = null ;
if ( byteArray ! = null )
{
sbyteArray = new sbyte [ byteArray . Length ] ;
for ( int index = 0 ; index < byteArray . Length ; index + + )
sbyteArray [ index ] = ( sbyte ) byteArray [ index ] ;
}
return sbyteArray ;
}
/*******************************/
/// <summary>
/// Converts an array of sbytes to an array of chars
/// </summary>
/// <param name="sByteArray">The array of sbytes to convert</param>
/// <returns>The new array of chars</returns>
public static char [ ] ToCharArray ( sbyte [ ] sByteArray )
{
return System . Text . UTF8Encoding . UTF8 . GetChars ( ToByteArray ( sByteArray ) ) ;
}
/// <summary>
/// Converts an array of bytes to an array of chars
/// </summary>
/// <param name="byteArray">The array of bytes to convert</param>
/// <returns>The new array of chars</returns>
public static char [ ] ToCharArray ( byte [ ] byteArray )
{
return System . Text . UTF8Encoding . UTF8 . GetChars ( byteArray ) ;
}
/*******************************/
/// <summary>
/// This method returns the literal value received
/// </summary>
/// <param name="literal">The literal to return</param>
/// <returns>The received value</returns>
public static long Identity ( long literal )
{
return literal ;
}
/// <summary>
/// This method returns the literal value received
/// </summary>
/// <param name="literal">The literal to return</param>
/// <returns>The received value</returns>
public static ulong Identity ( ulong literal )
{
return literal ;
}
/// <summary>
/// This method returns the literal value received
/// </summary>
/// <param name="literal">The literal to return</param>
/// <returns>The received value</returns>
public static float Identity ( float literal )
{
return literal ;
}
/// <summary>
/// This method returns the literal value received
/// </summary>
/// <param name="literal">The literal to return</param>
/// <returns>The received value</returns>
public static double Identity ( double literal )
{
return literal ;
}
/*******************************/
/// <summary>
/// Provides support functions to create read-write random acces files and write functions
/// </summary>
public class RandomAccessFileSupport
{
/// <summary>
/// Creates a new random acces stream with read-write or read rights
/// </summary>
/// <param name="fileName">A relative or absolute path for the file to open</param>
/// <param name="mode">Mode to open the file in</param>
/// <returns>The new System.IO.FileStream</returns>
public static System . IO . FileStream CreateRandomAccessFile ( System . String fileName , System . String mode )
{
System . IO . FileStream newFile = null ;
if ( mode . CompareTo ( "rw" ) = = 0 )
// newFile = new System.IO.FileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite);
//else if (mode.CompareTo("rw+") == 0)
newFile = new System . IO . FileStream ( fileName , System . IO . FileMode . OpenOrCreate , System . IO . FileAccess . ReadWrite ) ;
else if ( mode . CompareTo ( "r" ) = = 0 )
newFile = new System . IO . FileStream ( fileName , System . IO . FileMode . Open , System . IO . FileAccess . Read ) ;
else
throw new System . ArgumentException ( ) ;
return newFile ;
}
/// <summary>
/// Creates a new random acces stream with read-write or read rights
/// </summary>
/// <param name="fileName">File infomation for the file to open</param>
/// <param name="mode">Mode to open the file in</param>
/// <returns>The new System.IO.FileStream</returns>
public static System . IO . FileStream CreateRandomAccessFile ( System . IO . FileInfo fileName , System . String mode )
{
return CreateRandomAccessFile ( fileName . FullName , mode ) ;
}
/// <summary>
/// Writes the data to the specified file stream
/// </summary>
/// <param name="data">Data to write</param>
/// <param name="fileStream">File to write to</param>
public static void WriteBytes ( System . String data , System . IO . FileStream fileStream )
{
int index = 0 ;
int length = data . Length ;
while ( index < length )
fileStream . WriteByte ( ( byte ) data [ index + + ] ) ;
}
/// <summary>
/// Writes the received string to the file stream
/// </summary>
/// <param name="data">String of information to write</param>
/// <param name="fileStream">File to write to</param>
public static void WriteChars ( System . String data , System . IO . FileStream fileStream )
{
WriteBytes ( data , fileStream ) ;
}
/// <summary>
/// Writes the received data to the file stream
/// </summary>
/// <param name="sByteArray">Data to write</param>
/// <param name="fileStream">File to write to</param>
public static void WriteRandomFile ( sbyte [ ] sByteArray , System . IO . FileStream fileStream )
{
byte [ ] byteArray = ToByteArray ( sByteArray ) ;
fileStream . Write ( byteArray , 0 , byteArray . Length ) ;
}
}
/*******************************/
/// <summary>
/// Performs an unsigned bitwise right shift with the specified number
/// </summary>
/// <param name="number">Number to operate on</param>
/// <param name="bits">Ammount of bits to shift</param>
/// <returns>The resulting number from the shift operation</returns>
public static int URShift ( int number , int bits )
{
if ( number > = 0 )
return number > > bits ;
else
return ( number > > bits ) + ( 2 < < ~ bits ) ;
}
/// <summary>
/// Performs an unsigned bitwise right shift with the specified number
/// </summary>
/// <param name="number">Number to operate on</param>
/// <param name="bits">Ammount of bits to shift</param>
/// <returns>The resulting number from the shift operation</returns>
public static int URShift ( int number , long bits )
{
return URShift ( number , ( int ) bits ) ;
}
/// <summary>
/// Performs an unsigned bitwise right shift with the specified number
/// </summary>
/// <param name="number">Number to operate on</param>
/// <param name="bits">Ammount of bits to shift</param>
/// <returns>The resulting number from the shift operation</returns>
public static long URShift ( long number , int bits )
{
if ( number > = 0 )
return number > > bits ;
else
return ( number > > bits ) + ( 2L < < ~ bits ) ;
}
/// <summary>
/// Performs an unsigned bitwise right shift with the specified number
/// </summary>
/// <param name="number">Number to operate on</param>
/// <param name="bits">Ammount of bits to shift</param>
/// <returns>The resulting number from the shift operation</returns>
public static long URShift ( long number , long bits )
{
return URShift ( number , ( int ) bits ) ;
}
/*******************************/
/// <summary>Reads a number of characters from the current source Stream and writes the data to the target array at the specified index.</summary>
/// <param name="sourceStream">The source Stream to read from.</param>
/// <param name="target">Contains the array of characteres read from the source Stream.</param>
/// <param name="start">The starting index of the target array.</param>
/// <param name="count">The maximum number of characters to read from the source Stream.</param>
/// <returns>The number of characters read. The number will be less than or equal to count depending on the data available in the source Stream. Returns -1 if the end of the stream is reached.</returns>
public static System . Int32 ReadInput ( System . IO . Stream sourceStream , sbyte [ ] target , int start , int count )
{
// Returns 0 bytes if not enough space in target
if ( target . Length = = 0 )
return 0 ;
byte [ ] receiver = new byte [ target . Length ] ;
int bytesRead = sourceStream . Read ( receiver , start , count ) ;
// Returns -1 if EOF
if ( bytesRead = = 0 )
return - 1 ;
for ( int i = start ; i < start + bytesRead ; i + + )
target [ i ] = ( sbyte ) receiver [ i ] ;
return bytesRead ;
}
/// <summary>Reads a number of characters from the current source TextReader and writes the data to the target array at the specified index.</summary>
/// <param name="sourceTextReader">The source TextReader to read from</param>
/// <param name="target">Contains the array of characteres read from the source TextReader.</param>
/// <param name="start">The starting index of the target array.</param>
/// <param name="count">The maximum number of characters to read from the source TextReader.</param>
/// <returns>The number of characters read. The number will be less than or equal to count depending on the data available in the source TextReader. Returns -1 if the end of the stream is reached.</returns>
public static System . Int32 ReadInput ( System . IO . TextReader sourceTextReader , sbyte [ ] target , int start , int count )
{
// Returns 0 bytes if not enough space in target
if ( target . Length = = 0 ) return 0 ;
char [ ] charArray = new char [ target . Length ] ;
int bytesRead = sourceTextReader . Read ( charArray , start , count ) ;
// Returns -1 if EOF
if ( bytesRead = = 0 ) return - 1 ;
for ( int index = start ; index < start + bytesRead ; index + + )
target [ index ] = ( sbyte ) charArray [ index ] ;
return bytesRead ;
}
/*******************************/
/// <summary>
/// The class performs token processing in strings
/// </summary>
public class Tokenizer : System . Collections . IEnumerator
{
/// Position over the string
private long currentPos = 0 ;
/// Include demiliters in the results.
private bool includeDelims = false ;
/// Char representation of the String to tokenize.
private char [ ] chars = null ;
//The tokenizer uses the default delimiter set: the space character, the tab character, the newline character, and the carriage-return character and the form-feed character
private string delimiters = " \t\n\r\f" ;
/// <summary>
/// Initializes a new class instance with a specified string to process
/// </summary>
/// <param name="source">String to tokenize</param>
public Tokenizer ( System . String source )
{
this . chars = source . ToCharArray ( ) ;
}
/// <summary>
/// Initializes a new class instance with a specified string to process
/// and the specified token delimiters to use
/// </summary>
/// <param name="source">String to tokenize</param>
/// <param name="delimiters">String containing the delimiters</param>
public Tokenizer ( System . String source , System . String delimiters ) : this ( source )
{
this . delimiters = delimiters ;
}
/// <summary>
/// Initializes a new class instance with a specified string to process, the specified token
/// delimiters to use, and whether the delimiters must be included in the results.
/// </summary>
/// <param name="source">String to tokenize</param>
/// <param name="delimiters">String containing the delimiters</param>
/// <param name="includeDelims">Determines if delimiters are included in the results.</param>
public Tokenizer ( System . String source , System . String delimiters , bool includeDelims ) : this ( source , delimiters )
{
this . includeDelims = includeDelims ;
}
/// <summary>
/// Returns the next token from the token list
/// </summary>
/// <returns>The string value of the token</returns>
public System . String NextToken ( )
{
return NextToken ( this . delimiters ) ;
}
/// <summary>
/// Returns the next token from the source string, using the provided
/// token delimiters
/// </summary>
/// <param name="delimiters">String containing the delimiters to use</param>
/// <returns>The string value of the token</returns>
public System . String NextToken ( System . String delimiters )
{
//According to documentation, the usage of the received delimiters should be temporary (only for this call).
//However, it seems it is not true, so the following line is necessary.
this . delimiters = delimiters ;
//at the end
if ( this . currentPos = = this . chars . Length )
throw new System . ArgumentOutOfRangeException ( ) ;
//if over a delimiter and delimiters must be returned
else if ( ( System . Array . IndexOf ( delimiters . ToCharArray ( ) , chars [ this . currentPos ] ) ! = - 1 )
& & this . includeDelims )
return "" + this . chars [ this . currentPos + + ] ;
//need to get the token wo delimiters.
else
return nextToken ( delimiters . ToCharArray ( ) ) ;
}
//Returns the nextToken wo delimiters
private System . String nextToken ( char [ ] delimiters )
{
string token = "" ;
long pos = this . currentPos ;
//skip possible delimiters
while ( System . Array . IndexOf ( delimiters , this . chars [ currentPos ] ) ! = - 1 )
//The last one is a delimiter (i.e there is no more tokens)
if ( + + this . currentPos = = this . chars . Length )
{
this . currentPos = pos ;
throw new System . ArgumentOutOfRangeException ( ) ;
}
//getting the token
while ( System . Array . IndexOf ( delimiters , this . chars [ this . currentPos ] ) = = - 1 )
{
token + = this . chars [ this . currentPos ] ;
//the last one is not a delimiter
if ( + + this . currentPos = = this . chars . Length )
break ;
}
return token ;
}
/// <summary>
/// Determines if there are more tokens to return from the source string
/// </summary>
/// <returns>True or false, depending if there are more tokens</returns>
public bool HasMoreTokens ( )
{
//keeping the current pos
long pos = this . currentPos ;
try
{
this . NextToken ( ) ;
}
catch ( System . ArgumentOutOfRangeException )
{
return false ;
}
finally
{
this . currentPos = pos ;
}
return true ;
}
/// <summary>
/// Remaining tokens count
/// </summary>
public int Count
{
get
{
//keeping the current pos
long pos = this . currentPos ;
int i = 0 ;
try
{
while ( true )
{
this . NextToken ( ) ;
i + + ;
}
}
catch ( System . ArgumentOutOfRangeException )
{
this . currentPos = pos ;
return i ;
}
}
}
/// <summary>
/// Performs the same action as NextToken.
/// </summary>
public System . Object Current
{
get
{
return ( Object ) this . NextToken ( ) ;
}
}
/// <summary>
// Performs the same action as HasMoreTokens.
/// </summary>
/// <returns>True or false, depending if there are more tokens</returns>
public bool MoveNext ( )
{
return this . HasMoreTokens ( ) ;
}
/// <summary>
/// Does nothing.
/// </summary>
public void Reset ( )
{
;
}
}
/*******************************/
/// <summary>
/// This class provides auxiliar functionality to read and unread characters from a string into a buffer.
/// </summary>
private class BackStringReader : System . IO . StringReader
{
private char [ ] buffer ;
private int position = 1 ;
/// <summary>
/// Constructor. Calls the base constructor.
/// </summary>
/// <param name="stringReader">The buffer from which chars will be read.</param>
/// <param name="size">The size of the Back buffer.</param>
public BackStringReader ( String s ) : base ( s )
{
this . buffer = new char [ position ] ;
}
/// <summary>
/// Reads a character.
/// </summary>
/// <returns>The character read.</returns>
public override int Read ( )
{
if ( this . position > = 0 & & this . position < this . buffer . Length )
return ( int ) this . buffer [ this . position + + ] ;
return base . Read ( ) ;
}
/// <summary>
/// Reads an amount of characters from the buffer and copies the values to the array passed.
/// </summary>
/// <param name="array">Array where the characters will be stored.</param>
/// <param name="index">The beginning index to read.</param>
/// <param name="count">The number of characters to read.</param>
/// <returns>The number of characters read.</returns>
public override int Read ( char [ ] array , int index , int count )
{
int readLimit = this . buffer . Length - this . position ;
if ( count < = 0 )
return 0 ;
if ( readLimit > 0 )
{
if ( count < readLimit )
readLimit = count ;
2010-08-06 03:11:08 +00:00
System . Array . Copy ( this . buffer , this . position , array , index , readLimit ) ;
2009-09-30 23:50:03 +00:00
count - = readLimit ;
index + = readLimit ;
this . position + = readLimit ;
}
if ( count > 0 )
{
count = base . Read ( array , index , count ) ;
if ( count = = - 1 )
{
if ( readLimit = = 0 )
return - 1 ;
return readLimit ;
}
return readLimit + count ;
}
return readLimit ;
}
/// <summary>
/// Unreads a character.
/// </summary>
/// <param name="unReadChar">The character to be unread.</param>
public void UnRead ( int unReadChar )
{
this . position - - ;
this . buffer [ this . position ] = ( char ) unReadChar ;
}
/// <summary>
/// Unreads an amount of characters by moving these to the buffer.
/// </summary>
/// <param name="array">The character array to be unread.</param>
/// <param name="index">The beginning index to unread.</param>
/// <param name="count">The number of characters to unread.</param>
public void UnRead ( char [ ] array , int index , int count )
{
this . Move ( array , index , count ) ;
}
/// <summary>
/// Unreads an amount of characters by moving these to the buffer.
/// </summary>
/// <param name="array">The character array to be unread.</param>
public void UnRead ( char [ ] array )
{
this . Move ( array , 0 , array . Length - 1 ) ;
}
/// <summary>
/// Moves the array of characters to the buffer.
/// </summary>
/// <param name="array">Array of characters to move.</param>
/// <param name="index">Offset of the beginning.</param>
/// <param name="count">Amount of characters to move.</param>
private void Move ( char [ ] array , int index , int count )
{
for ( int arrayPosition = index + count ; arrayPosition > = index ; arrayPosition - - )
this . UnRead ( array [ arrayPosition ] ) ;
}
}
/*******************************/
/// <summary>
/// The StreamTokenizerSupport class takes an input stream and parses it into "tokens".
/// The stream tokenizer can recognize identifiers, numbers, quoted strings, and various comment styles.
/// </summary>
public class StreamTokenizerSupport
{
/// <summary>
/// Internal constants and fields
/// </summary>
private const System . String TOKEN = "Token[" ;
private const System . String NOTHING = "NOTHING" ;
private const System . String NUMBER = "number=" ;
private const System . String EOF = "EOF" ;
private const System . String EOL = "EOL" ;
private const System . String QUOTED = "quoted string=" ;
private const System . String LINE = "], Line " ;
private const System . String DASH = "-." ;
private const System . String DOT = "." ;
private const int TT_NOTHING = - 4 ;
private const sbyte ORDINARYCHAR = 0x00 ;
private const sbyte WORDCHAR = 0x01 ;
private const sbyte WHITESPACECHAR = 0x02 ;
private const sbyte COMMENTCHAR = 0x04 ;
private const sbyte QUOTECHAR = 0x08 ;
private const sbyte NUMBERCHAR = 0x10 ;
private const int STATE_NEUTRAL = 0 ;
private const int STATE_WORD = 1 ;
private const int STATE_NUMBER1 = 2 ;
private const int STATE_NUMBER2 = 3 ;
private const int STATE_NUMBER3 = 4 ;
private const int STATE_NUMBER4 = 5 ;
private const int STATE_STRING = 6 ;
private const int STATE_LINECOMMENT = 7 ;
private const int STATE_DONE_ON_EOL = 8 ;
private const int STATE_PROCEED_ON_EOL = 9 ;
private const int STATE_POSSIBLEC_COMMENT = 10 ;
private const int STATE_POSSIBLEC_COMMENT_END = 11 ;
private const int STATE_C_COMMENT = 12 ;
private const int STATE_STRING_ESCAPE_SEQ = 13 ;
private const int STATE_STRING_ESCAPE_SEQ_OCTAL = 14 ;
private const int STATE_DONE = 100 ;
private sbyte [ ] attribute = new sbyte [ 256 ] ;
private bool eolIsSignificant = false ;
private bool slashStarComments = false ;
private bool slashSlashComments = false ;
private bool lowerCaseMode = false ;
private bool pushedback = false ;
private int lineno = 1 ;
private BackReader inReader ;
private BackStringReader inStringReader ;
private BackInputStream inStream ;
private System . Text . StringBuilder buf ;
/// <summary>
/// Indicates that the end of the stream has been read.
/// </summary>
public const int TT_EOF = - 1 ;
/// <summary>
/// Indicates that the end of the line has been read.
/// </summary>
public const int TT_EOL = '\n' ;
/// <summary>
/// Indicates that a number token has been read.
/// </summary>
public const int TT_NUMBER = - 2 ;
/// <summary>
/// Indicates that a word token has been read.
/// </summary>
public const int TT_WORD = - 3 ;
/// <summary>
/// If the current token is a number, this field contains the value of that number.
/// </summary>
public double nval ;
/// <summary>
/// If the current token is a word token, this field contains a string giving the characters of the word
/// token.
/// </summary>
public System . String sval ;
/// <summary>
/// After a call to the nextToken method, this field contains the type of the token just read.
/// </summary>
public int ttype ;
/// <summary>
/// Internal methods
/// </summary>
private int read ( )
{
if ( this . inReader ! = null )
return this . inReader . Read ( ) ;
else if ( this . inStream ! = null )
return this . inStream . Read ( ) ;
else
return this . inStringReader . Read ( ) ;
}
private void unread ( int ch )
{
if ( this . inReader ! = null )
this . inReader . UnRead ( ch ) ;
else if ( this . inStream ! = null )
this . inStream . UnRead ( ch ) ;
else
this . inStringReader . UnRead ( ch ) ;
}
private void init ( )
{
this . buf = new System . Text . StringBuilder ( ) ;
this . ttype = StreamTokenizerSupport . TT_NOTHING ;
this . WordChars ( 'A' , 'Z' ) ;
this . WordChars ( 'a' , 'z' ) ;
this . WordChars ( 160 , 255 ) ;
this . WhitespaceChars ( 0x00 , 0x20 ) ;
this . CommentChar ( '/' ) ;
this . QuoteChar ( '\'' ) ;
this . QuoteChar ( '\"' ) ;
this . ParseNumbers ( ) ;
}
private void setAttributes ( int low , int hi , sbyte attrib )
{
int l = System . Math . Max ( 0 , low ) ;
int h = System . Math . Min ( 255 , hi ) ;
for ( int i = l ; i < = h ; i + + )
this . attribute [ i ] = attrib ;
}
private bool isWordChar ( int data )
{
char ch = ( char ) data ;
return ( data ! = - 1 & & ( ch > 255 | | this . attribute [ ch ] = = StreamTokenizerSupport . WORDCHAR | | this . attribute [ ch ] = = StreamTokenizerSupport . NUMBERCHAR ) ) ;
}
/// <summary>
/// Creates a StreamToknizerSupport that parses the given string.
/// </summary>
/// <param name="reader">The System.IO.StringReader that contains the String to be parsed.</param>
public StreamTokenizerSupport ( System . IO . StringReader reader )
{
string s = "" ;
for ( int i = reader . Read ( ) ; i ! = - 1 ; i = reader . Read ( ) )
{
s + = ( char ) i ;
}
reader . Close ( ) ;
this . inStringReader = new BackStringReader ( s ) ;
this . init ( ) ;
}
/// <summary>
/// Creates a StreamTokenizerSupport that parses the given stream.
/// </summary>
/// <param name="reader">Reader to be parsed.</param>
public StreamTokenizerSupport ( System . IO . StreamReader reader )
{
this . inReader = new BackReader ( new System . IO . StreamReader ( reader . BaseStream , reader . CurrentEncoding ) . BaseStream , 2 , reader . CurrentEncoding ) ;
this . init ( ) ;
}
/// <summary>
/// Creates a StreamTokenizerSupport that parses the given stream.
/// </summary>
/// <param name="stream">Stream to be parsed.</param>
public StreamTokenizerSupport ( System . IO . Stream stream )
{
this . inStream = new BackInputStream ( new System . IO . BufferedStream ( stream ) , 2 ) ;
this . init ( ) ;
}
/// <summary>
/// Specified that the character argument starts a single-line comment.
/// </summary>
/// <param name="ch">The character.</param>
public virtual void CommentChar ( int ch )
{
if ( ch > = 0 & & ch < = 255 )
this . attribute [ ch ] = StreamTokenizerSupport . COMMENTCHAR ;
}
/// <summary>
/// Determines whether or not ends of line are treated as tokens.
/// </summary>
/// <param name="flag">True indicates that end-of-line characters are separate tokens; False indicates
/// that end-of-line characters are white space.</param>
public virtual void EOLIsSignificant ( bool flag )
{
this . eolIsSignificant = flag ;
}
/// <summary>
/// Return the current line number.
/// </summary>
/// <returns>Current line number</returns>
public virtual int Lineno ( )
{
return this . lineno ;
}
/// <summary>
/// Determines whether or not word token are automatically lowercased.
/// </summary>
/// <param name="flag">True indicates that all word tokens should be lowercased.</param>
public virtual void LowerCaseMode ( bool flag )
{
this . lowerCaseMode = flag ;
}
/// <summary>
/// Parses the next token from the input stream of this tokenizer.
/// </summary>
/// <returns>The value of the ttype field.</returns>
public virtual int NextToken ( )
{
char prevChar = ( char ) ( 0 ) ;
char ch = ( char ) ( 0 ) ;
char qChar = ( char ) ( 0 ) ;
int octalNumber = 0 ;
int state ;
if ( this . pushedback )
{
this . pushedback = false ;
return this . ttype ;
}
this . ttype = StreamTokenizerSupport . TT_NOTHING ;
state = StreamTokenizerSupport . STATE_NEUTRAL ;
this . nval = 0.0 ;
this . sval = null ;
this . buf . Length = 0 ;
do
{
int data = this . read ( ) ;
prevChar = ch ;
ch = ( char ) data ;
switch ( state )
{
case StreamTokenizerSupport . STATE_NEUTRAL :
{
if ( data = = - 1 )
{
this . ttype = TT_EOF ;
state = StreamTokenizerSupport . STATE_DONE ;
}
else if ( ch > 255 )
{
this . buf . Append ( ch ) ;
this . ttype = StreamTokenizerSupport . TT_WORD ;
state = StreamTokenizerSupport . STATE_WORD ;
}
else if ( this . attribute [ ch ] = = StreamTokenizerSupport . COMMENTCHAR )
{
state = StreamTokenizerSupport . STATE_LINECOMMENT ;
}
else if ( this . attribute [ ch ] = = StreamTokenizerSupport . WORDCHAR )
{
this . buf . Append ( ch ) ;
this . ttype = StreamTokenizerSupport . TT_WORD ;
state = StreamTokenizerSupport . STATE_WORD ;
}
else if ( this . attribute [ ch ] = = StreamTokenizerSupport . NUMBERCHAR )
{
this . ttype = StreamTokenizerSupport . TT_NUMBER ;
this . buf . Append ( ch ) ;
if ( ch = = '-' )
state = StreamTokenizerSupport . STATE_NUMBER1 ;
else if ( ch = = '.' )
state = StreamTokenizerSupport . STATE_NUMBER3 ;
else
state = StreamTokenizerSupport . STATE_NUMBER2 ;
}
else if ( this . attribute [ ch ] = = StreamTokenizerSupport . QUOTECHAR )
{
qChar = ch ;
this . ttype = ch ;
state = StreamTokenizerSupport . STATE_STRING ;
}
else if ( ( this . slashSlashComments | | this . slashStarComments ) & & ch = = '/' )
state = StreamTokenizerSupport . STATE_POSSIBLEC_COMMENT ;
else if ( this . attribute [ ch ] = = StreamTokenizerSupport . ORDINARYCHAR )
{
this . ttype = ch ;
state = StreamTokenizerSupport . STATE_DONE ;
}
else if ( ch = = '\n' | | ch = = '\r' )
{
this . lineno + + ;
if ( this . eolIsSignificant )
{
this . ttype = StreamTokenizerSupport . TT_EOL ;
if ( ch = = '\n' )
state = StreamTokenizerSupport . STATE_DONE ;
else if ( ch = = '\r' )
state = StreamTokenizerSupport . STATE_DONE_ON_EOL ;
}
else if ( ch = = '\r' )
state = StreamTokenizerSupport . STATE_PROCEED_ON_EOL ;
}
break ;
}
case StreamTokenizerSupport . STATE_WORD :
{
if ( this . isWordChar ( data ) )
this . buf . Append ( ch ) ;
else
{
if ( data ! = - 1 )
this . unread ( ch ) ;
this . sval = this . buf . ToString ( ) ;
state = StreamTokenizerSupport . STATE_DONE ;
}
break ;
}
case StreamTokenizerSupport . STATE_NUMBER1 :
{
if ( data = = - 1 | | this . attribute [ ch ] ! = StreamTokenizerSupport . NUMBERCHAR | | ch = = '-' )
{
if ( this . attribute [ ch ] = = StreamTokenizerSupport . COMMENTCHAR & & System . Char . IsNumber ( ch ) )
{
this . buf . Append ( ch ) ;
state = StreamTokenizerSupport . STATE_NUMBER2 ;
}
else
{
if ( data ! = - 1 )
this . unread ( ch ) ;
this . ttype = '-' ;
state = StreamTokenizerSupport . STATE_DONE ;
}
}
else
{
this . buf . Append ( ch ) ;
if ( ch = = '.' )
state = StreamTokenizerSupport . STATE_NUMBER3 ;
else
state = StreamTokenizerSupport . STATE_NUMBER2 ;
}
break ;
}
case StreamTokenizerSupport . STATE_NUMBER2 :
{
if ( data = = - 1 | | this . attribute [ ch ] ! = StreamTokenizerSupport . NUMBERCHAR | | ch = = '-' )
{
if ( System . Char . IsNumber ( ch ) & & this . attribute [ ch ] = = StreamTokenizerSupport . WORDCHAR )
{
this . buf . Append ( ch ) ;
}
else if ( ch = = '.' & & this . attribute [ ch ] = = StreamTokenizerSupport . WHITESPACECHAR )
{
this . buf . Append ( ch ) ;
}
else if ( ( data ! = - 1 ) & & ( this . attribute [ ch ] = = StreamTokenizerSupport . COMMENTCHAR & & System . Char . IsNumber ( ch ) ) )
{
this . buf . Append ( ch ) ;
}
else
{
if ( data ! = - 1 )
this . unread ( ch ) ;
try
{
this . nval = System . Double . Parse ( this . buf . ToString ( ) ) ;
}
catch ( System . FormatException ) { }
state = StreamTokenizerSupport . STATE_DONE ;
}
}
else
{
this . buf . Append ( ch ) ;
if ( ch = = '.' )
state = StreamTokenizerSupport . STATE_NUMBER3 ;
}
break ;
}
case StreamTokenizerSupport . STATE_NUMBER3 :
{
if ( data = = - 1 | | this . attribute [ ch ] ! = StreamTokenizerSupport . NUMBERCHAR | | ch = = '-' | | ch = = '.' )
{
if ( this . attribute [ ch ] = = StreamTokenizerSupport . COMMENTCHAR & & System . Char . IsNumber ( ch ) )
{
this . buf . Append ( ch ) ;
}
else
{
if ( data ! = - 1 )
this . unread ( ch ) ;
System . String str = this . buf . ToString ( ) ;
if ( str . Equals ( StreamTokenizerSupport . DASH ) )
{
this . unread ( '.' ) ;
this . ttype = '-' ;
}
else if ( str . Equals ( StreamTokenizerSupport . DOT ) & & ! ( StreamTokenizerSupport . WORDCHAR ! = this . attribute [ prevChar ] ) )
this . ttype = '.' ;
else
{
try
{
this . nval = System . Double . Parse ( str ) ;
}
catch ( System . FormatException ) { }
}
state = StreamTokenizerSupport . STATE_DONE ;
}
}
else
{
this . buf . Append ( ch ) ;
state = StreamTokenizerSupport . STATE_NUMBER4 ;
}
break ;
}
case StreamTokenizerSupport . STATE_NUMBER4 :
{
if ( data = = - 1 | | this . attribute [ ch ] ! = StreamTokenizerSupport . NUMBERCHAR | | ch = = '-' | | ch = = '.' )
{
if ( data ! = - 1 )
this . unread ( ch ) ;
try
{
this . nval = System . Double . Parse ( this . buf . ToString ( ) ) ;
}
catch ( System . FormatException ) { }
state = StreamTokenizerSupport . STATE_DONE ;
}
else
this . buf . Append ( ch ) ;
break ;
}
case StreamTokenizerSupport . STATE_LINECOMMENT :
{
if ( data = = - 1 )
{
this . ttype = StreamTokenizerSupport . TT_EOF ;
state = StreamTokenizerSupport . STATE_DONE ;
}
else if ( ch = = '\n' | | ch = = '\r' )
{
this . unread ( ch ) ;
state = StreamTokenizerSupport . STATE_NEUTRAL ;
}
break ;
}
case StreamTokenizerSupport . STATE_DONE_ON_EOL :
{
if ( ch ! = '\n' & & data ! = - 1 )
this . unread ( ch ) ;
state = StreamTokenizerSupport . STATE_DONE ;
break ;
}
case StreamTokenizerSupport . STATE_PROCEED_ON_EOL :
{
if ( ch ! = '\n' & & data ! = - 1 )
this . unread ( ch ) ;
state = StreamTokenizerSupport . STATE_NEUTRAL ;
break ;
}
case StreamTokenizerSupport . STATE_STRING :
{
if ( data = = - 1 | | ch = = qChar | | ch = = '\r' | | ch = = '\n' )
{
this . sval = this . buf . ToString ( ) ;
if ( ch = = '\r' | | ch = = '\n' )
this . unread ( ch ) ;
state = StreamTokenizerSupport . STATE_DONE ;
}
else if ( ch = = '\\' )
state = StreamTokenizerSupport . STATE_STRING_ESCAPE_SEQ ;
else
this . buf . Append ( ch ) ;
break ;
}
case StreamTokenizerSupport . STATE_STRING_ESCAPE_SEQ :
{
if ( data = = - 1 )
{
this . sval = this . buf . ToString ( ) ;
state = StreamTokenizerSupport . STATE_DONE ;
break ;
}
state = StreamTokenizerSupport . STATE_STRING ;
if ( ch = = 'a' )
this . buf . Append ( 0x7 ) ;
else if ( ch = = 'b' )
this . buf . Append ( '\b' ) ;
else if ( ch = = 'f' )
this . buf . Append ( 0xC ) ;
else if ( ch = = 'n' )
this . buf . Append ( '\n' ) ;
else if ( ch = = 'r' )
this . buf . Append ( '\r' ) ;
else if ( ch = = 't' )
this . buf . Append ( '\t' ) ;
else if ( ch = = 'v' )
this . buf . Append ( 0xB ) ;
else if ( ch > = '0' & & ch < = '7' )
{
octalNumber = ch - '0' ;
state = StreamTokenizerSupport . STATE_STRING_ESCAPE_SEQ_OCTAL ;
}
else
this . buf . Append ( ch ) ;
break ;
}
case StreamTokenizerSupport . STATE_STRING_ESCAPE_SEQ_OCTAL :
{
if ( data = = - 1 | | ch < '0' | | ch > '7' )
{
this . buf . Append ( ( char ) octalNumber ) ;
if ( data = = - 1 )
{
this . sval = buf . ToString ( ) ;
state = StreamTokenizerSupport . STATE_DONE ;
}
else
{
this . unread ( ch ) ;
state = StreamTokenizerSupport . STATE_STRING ;
}
}
else
{
int temp = octalNumber * 8 + ( ch - '0' ) ;
if ( temp < 256 )
octalNumber = temp ;
else
{
buf . Append ( ( char ) octalNumber ) ;
buf . Append ( ch ) ;
state = StreamTokenizerSupport . STATE_STRING ;
}
}
break ;
}
case StreamTokenizerSupport . STATE_POSSIBLEC_COMMENT :
{
if ( ch = = '*' )
state = StreamTokenizerSupport . STATE_C_COMMENT ;
else if ( ch = = '/' )
state = StreamTokenizerSupport . STATE_LINECOMMENT ;
else
{
if ( data ! = - 1 )
this . unread ( ch ) ;
this . ttype = '/' ;
state = StreamTokenizerSupport . STATE_DONE ;
}
break ;
}
case StreamTokenizerSupport . STATE_C_COMMENT :
{
if ( ch = = '*' )
state = StreamTokenizerSupport . STATE_POSSIBLEC_COMMENT_END ;
if ( ch = = '\n' )
this . lineno + + ;
else if ( data = = - 1 )
{
this . ttype = StreamTokenizerSupport . TT_EOF ;
state = StreamTokenizerSupport . STATE_DONE ;
}
break ;
}
case StreamTokenizerSupport . STATE_POSSIBLEC_COMMENT_END :
{
if ( data = = - 1 )
{
this . ttype = StreamTokenizerSupport . TT_EOF ;
state = StreamTokenizerSupport . STATE_DONE ;
}
else if ( ch = = '/' )
state = StreamTokenizerSupport . STATE_NEUTRAL ;
else if ( ch ! = '*' )
state = StreamTokenizerSupport . STATE_C_COMMENT ;
break ;
}
}
}
while ( state ! = StreamTokenizerSupport . STATE_DONE ) ;
if ( this . ttype = = StreamTokenizerSupport . TT_WORD & & this . lowerCaseMode )
this . sval = this . sval . ToLower ( ) ;
return this . ttype ;
}
/// <summary>
/// Specifies that the character argument is "ordinary" in this tokenizer.
/// </summary>
/// <param name="ch">The character.</param>
public virtual void OrdinaryChar ( int ch )
{
if ( ch > = 0 & & ch < = 255 )
this . attribute [ ch ] = StreamTokenizerSupport . ORDINARYCHAR ;
}
/// <summary>
/// Specifies that all characters c in the range low less-equal c less-equal high are "ordinary" in this
/// tokenizer.
/// </summary>
/// <param name="low">Low end of the range.</param>
/// <param name="hi">High end of the range.</param>
public virtual void OrdinaryChars ( int low , int hi )
{
this . setAttributes ( low , hi , StreamTokenizerSupport . ORDINARYCHAR ) ;
}
/// <summary>
/// Specifies that numbers should be parsed by this tokenizer.
/// </summary>
public virtual void ParseNumbers ( )
{
for ( int i = '0' ; i < = '9' ; i + + )
this . attribute [ i ] = StreamTokenizerSupport . NUMBERCHAR ;
this . attribute [ '.' ] = StreamTokenizerSupport . NUMBERCHAR ;
this . attribute [ '-' ] = StreamTokenizerSupport . NUMBERCHAR ;
}
/// <summary>
/// Causes the next call to the nextToken method of this tokenizer to return the current value in the
/// ttype field, and not to modify the value in the nval or sval field.
/// </summary>
public virtual void PushBack ( )
{
if ( this . ttype ! = StreamTokenizerSupport . TT_NOTHING )
this . pushedback = true ;
}
/// <summary>
/// Specifies that matching pairs of this character delimit string constants in this tokenizer.
/// </summary>
/// <param name="ch">The character.</param>
public virtual void QuoteChar ( int ch )
{
if ( ch > = 0 & & ch < = 255 )
this . attribute [ ch ] = QUOTECHAR ;
}
/// <summary>
/// Resets this tokenizer's syntax table so that all characters are "ordinary." See the ordinaryChar
/// method for more information on a character being ordinary.
/// </summary>
public virtual void ResetSyntax ( )
{
this . OrdinaryChars ( 0x00 , 0xff ) ;
}
/// <summary>
/// Determines whether or not the tokenizer recognizes C++-style comments.
/// </summary>
/// <param name="flag">True indicates to recognize and ignore C++-style comments.</param>
public virtual void SlashSlashComments ( bool flag )
{
this . slashSlashComments = flag ;
}
/// <summary>
/// Determines whether or not the tokenizer recognizes C-style comments.
/// </summary>
/// <param name="flag">True indicates to recognize and ignore C-style comments.</param>
public virtual void SlashStarComments ( bool flag )
{
this . slashStarComments = flag ;
}
/// <summary>
/// Returns the string representation of the current stream token.
/// </summary>
/// <returns>A String representation of the current stream token.</returns>
public override System . String ToString ( )
{
System . Text . StringBuilder buffer = new System . Text . StringBuilder ( StreamTokenizerSupport . TOKEN ) ;
switch ( this . ttype )
{
case StreamTokenizerSupport . TT_NOTHING :
{
buffer . Append ( StreamTokenizerSupport . NOTHING ) ;
break ;
}
case StreamTokenizerSupport . TT_WORD :
{
buffer . Append ( this . sval ) ;
break ;
}
case StreamTokenizerSupport . TT_NUMBER :
{
buffer . Append ( StreamTokenizerSupport . NUMBER ) ;
buffer . Append ( this . nval ) ;
break ;
}
case StreamTokenizerSupport . TT_EOF :
{
buffer . Append ( StreamTokenizerSupport . EOF ) ;
break ;
}
case StreamTokenizerSupport . TT_EOL :
{
buffer . Append ( StreamTokenizerSupport . EOL ) ;
break ;
}
}
if ( this . ttype > 0 )
{
if ( this . attribute [ this . ttype ] = = StreamTokenizerSupport . QUOTECHAR )
{
buffer . Append ( StreamTokenizerSupport . QUOTED ) ;
buffer . Append ( this . sval ) ;
}
else
{
buffer . Append ( '\'' ) ;
buffer . Append ( ( char ) this . ttype ) ;
buffer . Append ( '\'' ) ;
}
}
buffer . Append ( StreamTokenizerSupport . LINE ) ;
buffer . Append ( this . lineno ) ;
return buffer . ToString ( ) ;
}
/// <summary>
/// Specifies that all characters c in the range low less-equal c less-equal high are white space
/// characters.
/// </summary>
/// <param name="low">The low end of the range.</param>
/// <param name="hi">The high end of the range.</param>
public virtual void WhitespaceChars ( int low , int hi )
{
this . setAttributes ( low , hi , StreamTokenizerSupport . WHITESPACECHAR ) ;
}
/// <summary>
/// Specifies that all characters c in the range low less-equal c less-equal high are word constituents.
/// </summary>
/// <param name="low">The low end of the range.</param>
/// <param name="hi">The high end of the range.</param>
public virtual void WordChars ( int low , int hi )
{
this . setAttributes ( low , hi , StreamTokenizerSupport . WORDCHAR ) ;
}
}
/*******************************/
/// <summary>
/// This class provides functionality to reads and unread characters into a buffer.
/// </summary>
public class BackReader : System . IO . StreamReader
{
private char [ ] buffer ;
private int position = 1 ;
//private int markedPosition;
/// <summary>
/// Constructor. Calls the base constructor.
/// </summary>
/// <param name="streamReader">The buffer from which chars will be read.</param>
/// <param name="size">The size of the Back buffer.</param>
public BackReader ( System . IO . Stream streamReader , int size , System . Text . Encoding encoding ) : base ( streamReader , encoding )
{
this . buffer = new char [ size ] ;
this . position = size ;
}
/// <summary>
/// Constructor. Calls the base constructor.
/// </summary>
/// <param name="streamReader">The buffer from which chars will be read.</param>
public BackReader ( System . IO . Stream streamReader , System . Text . Encoding encoding ) : base ( streamReader , encoding )
{
this . buffer = new char [ this . position ] ;
}
/// <summary>
/// Checks if this stream support mark and reset methods.
/// </summary>
/// <remarks>
/// This method isn't supported.
/// </remarks>
/// <returns>Always false.</returns>
public bool MarkSupported ( )
{
return false ;
}
/// <summary>
/// Marks the element at the corresponding position.
/// </summary>
/// <remarks>
/// This method isn't supported.
/// </remarks>
public void Mark ( int position )
{
throw new System . IO . IOException ( "Mark operations are not allowed" ) ;
}
/// <summary>
/// Resets the current stream.
/// </summary>
/// <remarks>
/// This method isn't supported.
/// </remarks>
public void Reset ( )
{
throw new System . IO . IOException ( "Mark operations are not allowed" ) ;
}
/// <summary>
/// Reads a character.
/// </summary>
/// <returns>The character read.</returns>
public override int Read ( )
{
if ( this . position > = 0 & & this . position < this . buffer . Length )
return ( int ) this . buffer [ this . position + + ] ;
return base . Read ( ) ;
}
/// <summary>
/// Reads an amount of characters from the buffer and copies the values to the array passed.
/// </summary>
/// <param name="array">Array where the characters will be stored.</param>
/// <param name="index">The beginning index to read.</param>
/// <param name="count">The number of characters to read.</param>
/// <returns>The number of characters read.</returns>
public override int Read ( char [ ] array , int index , int count )
{
int readLimit = this . buffer . Length - this . position ;
if ( count < = 0 )
return 0 ;
if ( readLimit > 0 )
{
if ( count < readLimit )
readLimit = count ;
2010-08-06 03:11:08 +00:00
System . Array . Copy ( this . buffer , this . position , array , index , readLimit ) ;
2009-09-30 23:50:03 +00:00
count - = readLimit ;
index + = readLimit ;
this . position + = readLimit ;
}
if ( count > 0 )
{
count = base . Read ( array , index , count ) ;
if ( count = = - 1 )
{
if ( readLimit = = 0 )
return - 1 ;
return readLimit ;
}
return readLimit + count ;
}
return readLimit ;
}
/// <summary>
/// Checks if this buffer is ready to be read.
/// </summary>
/// <returns>True if the position is less than the length, otherwise false.</returns>
public bool IsReady ( )
{
return ( this . position > = this . buffer . Length | | this . BaseStream . Position > = this . BaseStream . Length ) ;
}
/// <summary>
/// Unreads a character.
/// </summary>
/// <param name="unReadChar">The character to be unread.</param>
public void UnRead ( int unReadChar )
{
this . position - - ;
this . buffer [ this . position ] = ( char ) unReadChar ;
}
/// <summary>
/// Unreads an amount of characters by moving these to the buffer.
/// </summary>
/// <param name="array">The character array to be unread.</param>
/// <param name="index">The beginning index to unread.</param>
/// <param name="count">The number of characters to unread.</param>
public void UnRead ( char [ ] array , int index , int count )
{
this . Move ( array , index , count ) ;
}
/// <summary>
/// Unreads an amount of characters by moving these to the buffer.
/// </summary>
/// <param name="array">The character array to be unread.</param>
public void UnRead ( char [ ] array )
{
this . Move ( array , 0 , array . Length - 1 ) ;
}
/// <summary>
/// Moves the array of characters to the buffer.
/// </summary>
/// <param name="array">Array of characters to move.</param>
/// <param name="index">Offset of the beginning.</param>
/// <param name="count">Amount of characters to move.</param>
private void Move ( char [ ] array , int index , int count )
{
for ( int arrayPosition = index + count ; arrayPosition > = index ; arrayPosition - - )
this . UnRead ( array [ arrayPosition ] ) ;
}
}
/*******************************/
/// <summary>
/// Provides functionality to read and unread from a Stream.
/// </summary>
public class BackInputStream : System . IO . BinaryReader
{
private byte [ ] buffer ;
private int position = 1 ;
/// <summary>
/// Creates a BackInputStream with the specified stream and size for the buffer.
/// </summary>
/// <param name="streamReader">The stream to use.</param>
/// <param name="size">The specific size of the buffer.</param>
public BackInputStream ( System . IO . Stream streamReader , System . Int32 size ) : base ( streamReader )
{
this . buffer = new byte [ size ] ;
this . position = size ;
}
/// <summary>
/// Creates a BackInputStream with the specified stream.
/// </summary>
/// <param name="streamReader">The stream to use.</param>
public BackInputStream ( System . IO . Stream streamReader ) : base ( streamReader )
{
this . buffer = new byte [ this . position ] ;
}
/// <summary>
/// Checks if this stream support mark and reset methods.
/// </summary>
/// <returns>Always false, these methods aren't supported.</returns>
public bool MarkSupported ( )
{
return false ;
}
/// <summary>
/// Reads the next bytes in the stream.
/// </summary>
/// <returns>The next byte readed</returns>
public override int Read ( )
{
if ( position > = 0 & & position < buffer . Length )
return ( int ) this . buffer [ position + + ] ;
return base . Read ( ) ;
}
/// <summary>
/// Reads the amount of bytes specified from the stream.
/// </summary>
/// <param name="array">The buffer to read data into.</param>
/// <param name="index">The beginning point to read.</param>
/// <param name="count">The number of characters to read.</param>
/// <returns>The number of characters read into buffer.</returns>
public virtual int Read ( sbyte [ ] array , int index , int count )
{
int byteCount = 0 ;
int readLimit = count + index ;
byte [ ] aux = ToByteArray ( array ) ;
for ( byteCount = 0 ; position < buffer . Length & & index < readLimit ; byteCount + + )
aux [ index + + ] = buffer [ position + + ] ;
if ( index < readLimit )
byteCount + = base . Read ( aux , index , readLimit - index ) ;
for ( int i = 0 ; i < aux . Length ; i + + )
array [ i ] = ( sbyte ) aux [ i ] ;
return byteCount ;
}
/// <summary>
/// Unreads a byte from the stream.
/// </summary>
/// <param name="element">The value to be unread.</param>
public void UnRead ( int element )
{
this . position - - ;
if ( position > = 0 )
this . buffer [ this . position ] = ( byte ) element ;
}
/// <summary>
/// Unreads an amount of bytes from the stream.
/// </summary>
/// <param name="array">The byte array to be unread.</param>
/// <param name="index">The beginning index to unread.</param>
/// <param name="count">The number of bytes to be unread.</param>
public void UnRead ( byte [ ] array , int index , int count )
{
this . Move ( array , index , count ) ;
}
/// <summary>
/// Unreads an array of bytes from the stream.
/// </summary>
/// <param name="array">The byte array to be unread.</param>
public void UnRead ( byte [ ] array )
{
this . Move ( array , 0 , array . Length - 1 ) ;
}
/// <summary>
/// Skips the specified number of bytes from the underlying stream.
/// </summary>
/// <param name="numberOfBytes">The number of bytes to be skipped.</param>
/// <returns>The number of bytes actually skipped</returns>
public long Skip ( long numberOfBytes )
{
return this . BaseStream . Seek ( numberOfBytes , System . IO . SeekOrigin . Current ) - this . BaseStream . Position ;
}
/// <summary>
/// Moves data from the array to the buffer field.
/// </summary>
/// <param name="array">The array of bytes to be unread.</param>
/// <param name="index">The beginning index to unread.</param>
/// <param name="count">The amount of bytes to be unread.</param>
private void Move ( byte [ ] array , int index , int count )
{
for ( int arrayPosition = index + count ; arrayPosition > = index ; arrayPosition - - )
this . UnRead ( array [ arrayPosition ] ) ;
}
}
/*******************************/
/// <summary>
/// Support class used to handle threads
/// </summary>
public class ThreadClass : IThreadRunnable
{
/// <summary>
/// The instance of System.Threading.Thread
/// </summary>
private System . Threading . Thread threadField ;
/// <summary>
/// Initializes a new instance of the ThreadClass class
/// </summary>
public ThreadClass ( )
{
threadField = new System . Threading . Thread ( new System . Threading . ThreadStart ( Run ) ) ;
}
/// <summary>
/// Initializes a new instance of the Thread class.
/// </summary>
/// <param name="Name">The name of the thread</param>
public ThreadClass ( System . String Name )
{
threadField = new System . Threading . Thread ( new System . Threading . ThreadStart ( Run ) ) ;
this . Name = Name ;
}
/// <summary>
/// Initializes a new instance of the Thread class.
/// </summary>
/// <param name="Start">A ThreadStart delegate that references the methods to be invoked when this thread begins executing</param>
public ThreadClass ( System . Threading . ThreadStart Start )
{
threadField = new System . Threading . Thread ( Start ) ;
}
/// <summary>
/// Initializes a new instance of the Thread class.
/// </summary>
/// <param name="Start">A ThreadStart delegate that references the methods to be invoked when this thread begins executing</param>
/// <param name="Name">The name of the thread</param>
public ThreadClass ( System . Threading . ThreadStart Start , System . String Name )
{
threadField = new System . Threading . Thread ( Start ) ;
this . Name = Name ;
}
/// <summary>
/// This method has no functionality unless the method is overridden
/// </summary>
public virtual void Run ( )
{
}
/// <summary>
/// Causes the operating system to change the state of the current thread instance to ThreadState.Running
/// </summary>
public virtual void Start ( )
{
threadField . Start ( ) ;
}
/// <summary>
/// Interrupts a thread that is in the WaitSleepJoin thread state
/// </summary>
public virtual void Interrupt ( )
{
threadField . Interrupt ( ) ;
}
/// <summary>
/// Gets the current thread instance
/// </summary>
public System . Threading . Thread Instance
{
get
{
return threadField ;
}
set
{
threadField = value ;
}
}
/// <summary>
/// Gets or sets the name of the thread
/// </summary>
public System . String Name
{
get
{
return threadField . Name ;
}
set
{
if ( threadField . Name = = null )
threadField . Name = value ;
}
}
/// <summary>
/// Gets or sets a value indicating the scheduling priority of a thread
/// </summary>
public System . Threading . ThreadPriority Priority
{
get
{
return threadField . Priority ;
}
set
{
threadField . Priority = value ;
}
}
/// <summary>
/// Gets a value indicating the execution status of the current thread
/// </summary>
public bool IsAlive
{
get
{
return threadField . IsAlive ;
}
}
/// <summary>
/// Gets or sets a value indicating whether or not a thread is a background thread.
/// </summary>
public bool IsBackground
{
get
{
return threadField . IsBackground ;
}
set
{
threadField . IsBackground = value ;
}
}
/// <summary>
/// Blocks the calling thread until a thread terminates
/// </summary>
public void Join ( )
{
threadField . Join ( ) ;
}
/// <summary>
/// Blocks the calling thread until a thread terminates or the specified time elapses
/// </summary>
/// <param name="MiliSeconds">Time of wait in milliseconds</param>
public void Join ( long MiliSeconds )
{
lock ( this )
{
threadField . Join ( new System . TimeSpan ( MiliSeconds * 10000 ) ) ;
}
}
/// <summary>
/// Blocks the calling thread until a thread terminates or the specified time elapses
/// </summary>
/// <param name="MiliSeconds">Time of wait in milliseconds</param>
/// <param name="NanoSeconds">Time of wait in nanoseconds</param>
public void Join ( long MiliSeconds , int NanoSeconds )
{
lock ( this )
{
threadField . Join ( new System . TimeSpan ( MiliSeconds * 10000 + NanoSeconds * 100 ) ) ;
}
}
/ *
/// <summary>
/// Resumes a thread that has been suspended
/// </summary>
public void Resume ( )
{
threadField . Resume ( ) ;
}
/// <summary>
/// Raises a ThreadAbortException in the thread on which it is invoked,
/// to begin the process of terminating the thread. Calling this method
/// usually terminates the thread
/// </summary>
public void Abort ( )
{
threadField . Abort ( ) ;
}
/// <summary>
/// Raises a ThreadAbortException in the thread on which it is invoked,
/// to begin the process of terminating the thread while also providing
/// exception information about the thread termination.
/// Calling this method usually terminates the thread.
/// </summary>
/// <param name="stateInfo">An object that contains application-specific information, such as state, which can be used by the thread being aborted</param>
public void Abort ( System . Object stateInfo )
{
lock ( this )
{
threadField . Abort ( stateInfo ) ;
}
}
/// <summary>
/// Suspends the thread, if the thread is already suspended it has no effect
/// </summary>
public void Suspend ( )
{
threadField . Suspend ( ) ;
}
* /
/// <summary>
/// Obtain a String that represents the current Object
/// </summary>
/// <returns>A String that represents the current Object</returns>
public override System . String ToString ( )
{
return "Thread[" + Name + "," + Priority . ToString ( ) + "," + "" + "]" ;
}
/// <summary>
/// Gets the currently running thread
/// </summary>
/// <returns>The currently running thread</returns>
public static ThreadClass Current ( )
{
ThreadClass CurrentThread = new ThreadClass ( ) ;
CurrentThread . Instance = System . Threading . Thread . CurrentThread ;
return CurrentThread ;
}
}
/*******************************/
/// <summary>
/// SupportClass for the Stack class.
/// </summary>
public class StackSupport
{
/// <summary>
/// Removes the element at the top of the stack and returns it.
/// </summary>
/// <param name="stack">The stack where the element at the top will be returned and removed.</param>
/// <returns>The element at the top of the stack.</returns>
public static System . Object Pop ( System . Collections . ArrayList stack )
{
System . Object obj = stack [ stack . Count - 1 ] ;
stack . RemoveAt ( stack . Count - 1 ) ;
return obj ;
}
}
}