ln.parse/ln.parse/tokenizer/SourceBuffer.cs

78 lines
2.2 KiB
C#

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<int, TextPosition> statTextPositions = new BTree<int, TextPosition>();
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);
}
}