Upsilon/Upsilon/Text/SourceText.cs

68 lines
1.9 KiB
C#

using System;
namespace Upsilon.Text
{
public class SourceText
{
private readonly string _text;
private readonly SourceTextLine[] _lines;
public SourceText(string text)
{
_text = text;
var lines = text.Split('\n');
_lines = new SourceTextLine[lines.Length];
var linePos = 0;
for (var index = 0; index < lines.Length; index++)
{
var line = lines[index];
_lines[index] = new SourceTextLine(linePos, line.Length);
linePos += line.Length;
}
}
public string GetSpan(int start, int length)
{
if (start < 0)
{
length += start;
start = 0;
};
if (start >= _text.Length)
return string.Empty;
if (start + length >= _text.Length) length = _text.Length - start;
return _text.Substring(start, length);
}
public (int Line, int Pos) GetLinePosition(int spanPos)
{
var min = 0;
var max = _lines.Length - 1;
while (min <= max)
{
var mid = (min + max) / 2 ;
var midLine = _lines[mid];
if (midLine.Start <= spanPos && midLine.End > spanPos)
{
var pos = spanPos - midLine.Start;
return (mid, pos);
}
if (spanPos >= midLine.End)
{
min = mid + 1;
}
else if (spanPos < midLine.Start)
{
max = mid - 1;
}
}
var newPos = spanPos - _lines[min].Start;
return (min, newPos);
}
public string GetSpan(TextSpan span)
{
return GetSpan(span.Start, span.Length);
}
}
}