namespace XFESystem.Desktop;
/// <summary>Immutable UTF-16 line offsets; materialize only lines actually used by the view.</summary>
public sealed class TextLineIndex
{
private readonly int[] starts;
private readonly string?[] lines;
private string?[]? displayed;
public string Source { get; }
public int Count => starts.Length;
public TextLineIndex(string source)
{
ArgumentNullException.ThrowIfNull(source);
Source = source;
int count = 1;
foreach (char value in source) if (value == '\n') count++;
starts = new int[count]; lines = new string?[count];
for (int at = 0, line = 1; at < source.Length; at++) if (source[at] == '\n') starts[line++] = at + 1;
}
public int Start(int line) => starts[line];
public string RawLine(int line)
{
int end = line + 1 < Count ? starts[line + 1] - 1 : Source.Length;
return lines[line] ??= Source.Substring(starts[line], end - starts[line]);
}
public string DisplayLine(int line)
{
string raw = RawLine(line);
if (!raw.Contains('\r')) return raw;
displayed ??= new string?[Count];
return displayed[line] ??= raw.Replace("\r", "", StringComparison.Ordinal);
}
}
namespace XFESystem.Desktop;
/// <summary>Immutable UTF-16 line offsets; materialize only lines actually used by the view.</summary>
public sealed class TextLineIndex
{
private readonly int[] starts;
private readonly string?[] lines;
private string?[]? displayed;
public string Source { get; }
public int Count => starts.Length;
public TextLineIndex(string source)
{
ArgumentNullException.ThrowIfNull(source);
Source = source;
int count = 1;
foreach (char value in source) if (value == '\n') count++;
starts = new int[count]; lines = new string?[count];
for (int at = 0, line = 1; at < source.Length; at++) if (source[at] == '\n') starts[line++] = at + 1;
}
public int Start(int line) => starts[line];
public string RawLine(int line)
{
int end = line + 1 < Count ? starts[line + 1] - 1 : Source.Length;
return lines[line] ??= Source.Substring(starts[line], end - starts[line]);
}
public string DisplayLine(int line)
{
string raw = RawLine(line);
if (!raw.Contains('\r')) return raw;
displayed ??= new string?[Count];
return displayed[line] ??= raw.Replace("\r", "", StringComparison.Ordinal);
}
}