using ln.collections; using System; using System.IO; namespace ln.parse.tokenizer { public struct TextPosition { public int LineNo; public int CursorPosition; public TextPosition(int line,int cursor) { LineNo = line; CursorPosition = cursor; } public static TextPosition First => new TextPosition(1, 1); public override string ToString() => string.Format("{0}:{1}", LineNo, CursorPosition); } public class SourceBuffer { readonly string _buffer; BTree statTextPositions = new BTree(); int linearPosition; public int LinearPosition { get => linearPosition; set => linearPosition = value; } public TextPosition TextPosition => GetTextPosition(linearPosition); public string Text => _buffer; public int Length => _buffer.Length; public SourceBuffer(char[] buffer) : this(new StringReader(new String(buffer))) { } public SourceBuffer(TextReader reader) : this(reader.ReadToEnd()) { } public SourceBuffer(string source) { _buffer = source; doStatistics(); } private void doStatistics() { TextPosition textPosition = new TextPosition(); for (int n=0;n<(_buffer.Length-1);n++) { textPosition.CursorPosition++; if (_buffer[n] == '\n') { textPosition.LineNo++; textPosition.CursorPosition = 0; } else if (textPosition.CursorPosition == 1) statTextPositions.Add(n, textPosition); } } public TextPosition GetTextPosition(int linearPosition) { statTextPositions.TryGetPreviousOrCurrentValue(linearPosition, out TextPosition textPosition); return textPosition; } public string GetText() => _buffer; public string GetText(int linearStart) => _buffer.Substring(linearStart); public string GetText(int linearStart, int length) => _buffer.Substring(linearStart, length); public string GetCurrentText() => _buffer.Substring(linearPosition); } }