1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD licence"] 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2005-2008 Terence Parr 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved. 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Conversion to C#: 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved. 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Redistribution and use in source and binary forms, with or without 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * modification, are permitted provided that the following conditions 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are met: 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1. Redistributions of source code must retain the above copyright 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer. 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2. Redistributions in binary form must reproduce the above copyright 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer in the 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * documentation and/or other materials provided with the distribution. 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 3. The name of the author may not be used to endorse or promote products 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * derived from this software without specific prior written permission. 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace Antlr.Runtime 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver using System.Collections.Generic; 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver using ArgumentException = System.ArgumentException; 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver using ArgumentOutOfRangeException = System.ArgumentOutOfRangeException; 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver using ArgumentNullException = System.ArgumentNullException; 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * A pretty quick CharStream that pulls all data from an array 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * directly. Every method call counts in the lexer. Java's 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * strings aren't very good so I'm avoiding. 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver [System.Serializable] 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public class ANTLRStringStream : ICharStream 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>The data being scanned</summary> */ 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected char[] data; 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>How many characters are actually in the buffer</summary> */ 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected int n; 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>0..n-1 index into string of next char</summary> */ 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected int p = 0; 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>line number 1..n within the input</summary> */ 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int line = 1; 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>The index of the character relative to the beginning of the line 0..n-1</summary> */ 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int charPositionInLine = 0; 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>tracks how deep mark() calls are nested</summary> */ 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected int markDepth = 0; 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * A list of CharStreamState objects that tracks the stream state 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * values line, charPositionInLine, and p that can change as you 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * move through the input stream. Indexed from 1..markDepth. 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * A null is kept @ index 0. Create upon first call to mark(). 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected IList<CharStreamState> markers; 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>Track the last mark() call result value for use in rewind().</summary> */ 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected int lastMarker; 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>What is name or source of this char stream?</summary> */ 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public string name; 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>Copy data in string to a local char array</summary> */ 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ANTLRStringStream( string input ) 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : this( input, null ) 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ANTLRStringStream( string input, string sourceName ) 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : this( input.ToCharArray(), input.Length, sourceName ) 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>This is the preferred constructor as no data is copied</summary> */ 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ANTLRStringStream( char[] data, int numberOfActualCharsInArray ) 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : this( data, numberOfActualCharsInArray, null ) 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ANTLRStringStream( char[] data, int numberOfActualCharsInArray, string sourceName ) 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (data == null) 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new ArgumentNullException("data"); 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (numberOfActualCharsInArray < 0) 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new ArgumentOutOfRangeException(); 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (numberOfActualCharsInArray > data.Length) 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new ArgumentException(); 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.data = data; 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.n = numberOfActualCharsInArray; 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.name = sourceName; 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected ANTLRStringStream() 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.data = new char[0]; 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Return the current input symbol index 0..n where n indicates the 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * last symbol has been read. The index is the index of char to 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * be returned from LA(1). 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int Index 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return p; 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int Line 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return line; 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line = value; 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int CharPositionInLine 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return charPositionInLine; 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver charPositionInLine = value; 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Reset the stream so that it's in the same state it was 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * when the object was created *except* the data array is not 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * touched. 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Reset() 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver p = 0; 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line = 1; 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver charPositionInLine = 0; 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver markDepth = 0; 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Consume() 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("prev p="+p+", c="+(char)data[p]); 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( p < n ) 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver charPositionInLine++; 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( data[p] == '\n' ) 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver System.out.println("newline char found on line: "+line+ 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "@ pos="+charPositionInLine); 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line++; 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver charPositionInLine = 0; 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver p++; 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("p moves to "+p+" (c='"+(char)data[p]+"')"); 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int LA( int i ) 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( i == 0 ) 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 0; // undefined 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( i < 0 ) 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver i++; // e.g., translate LA(-1) to use offset i=0; then data[p+0-1] 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( ( p + i - 1 ) < 0 ) 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return CharStreamConstants.EndOfFile; // invalid; no char before first char 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( ( p + i - 1 ) >= n ) 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("char LA("+i+")=EOF; p="+p); 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return CharStreamConstants.EndOfFile; 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("char LA("+i+")="+(char)data[p+i-1]+"; p="+p); 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("LA("+i+"); p="+p+" n="+n+" data.length="+data.length); 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return data[p + i - 1]; 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int LT( int i ) 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return LA( i ); 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int Count 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return n; 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int Mark() 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( markers == null ) 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver markers = new List<CharStreamState>(); 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver markers.Add( null ); // depth 0 means no backtracking, leave blank 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver markDepth++; 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CharStreamState state = null; 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( markDepth >= markers.Count ) 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state = new CharStreamState(); 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver markers.Add( state ); 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state = markers[markDepth]; 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.p = p; 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.line = line; 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.charPositionInLine = charPositionInLine; 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver lastMarker = markDepth; 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return markDepth; 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Rewind( int m ) 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (m < 0) 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new ArgumentOutOfRangeException(); 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //if (m > markDepth) 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // throw new ArgumentException(); 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CharStreamState state = markers[m]; 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // restore stream state 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Seek( state.p ); 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line = state.line; 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver charPositionInLine = state.charPositionInLine; 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Release( m ); 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Rewind() 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Rewind( lastMarker ); 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Release( int marker ) 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // unwind any other markers made after m and release m 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver markDepth = marker; 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // release this marker 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver markDepth--; 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * consume() ahead until p==index; can't just set p=index as we must 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * update line and charPositionInLine. 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Seek( int index ) 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( index <= p ) 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver p = index; // just jump; don't update stream state (line, ...) 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // seek forward, consume until p hits index 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while ( p < index ) 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Consume(); 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual string Substring( int start, int length ) 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (start < 0) 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new ArgumentOutOfRangeException(); 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (length < 0) 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new ArgumentOutOfRangeException(); 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (start + length > data.Length) 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new ArgumentException(); 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (length == 0) 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return string.Empty; 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new string( data, start, length ); 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual string SourceName 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return name; 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public override string ToString() 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new string(data); 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 328