namespace XFESystem.Desktop;
/// <summary>UI-owned diagnostic state. Unchanged readbacks allocate nothing;
/// the cache never retains a window or its complete large source.</summary>
public sealed class EditorReadbackTracker
{
public const int MaximumPrefixCharacters = 8192;
private bool hasState;
private int windowId, sourceLength;
private string path = "", prefix = "";
public bool TryUpdate(int id, string location, string content, out string sourcePrefix)
{
ArgumentNullException.ThrowIfNull(location);
ArgumentNullException.ThrowIfNull(content);
int prefixLength = Math.Min(content.Length, MaximumPrefixCharacters);
if (hasState && id == windowId && location == path && content.Length == sourceLength &&
content.AsSpan(0, prefixLength).SequenceEqual(prefix.AsSpan()))
{
sourcePrefix = prefix;
return false;
}
// Copy only after the comparison, independently of the original string.
// Even a closed large editor therefore leaves at most this bounded prefix.
prefix = content.AsSpan(0, prefixLength).ToString();
path = location;
windowId = id;
sourceLength = content.Length;
hasState = true;
sourcePrefix = prefix;
return true;
}
public void Reset()
{
hasState = false;
windowId = sourceLength = 0;
path = prefix = "";
}
}
namespace XFESystem.Desktop;
/// <summary>UI-owned diagnostic state. Unchanged readbacks allocate nothing;
/// the cache never retains a window or its complete large source.</summary>
public sealed class EditorReadbackTracker
{
public const int MaximumPrefixCharacters = 8192;
private bool hasState;
private int windowId, sourceLength;
private string path = "", prefix = "";
public bool TryUpdate(int id, string location, string content, out string sourcePrefix)
{
ArgumentNullException.ThrowIfNull(location);
ArgumentNullException.ThrowIfNull(content);
int prefixLength = Math.Min(content.Length, MaximumPrefixCharacters);
if (hasState && id == windowId && location == path && content.Length == sourceLength &&
content.AsSpan(0, prefixLength).SequenceEqual(prefix.AsSpan()))
{
sourcePrefix = prefix;
return false;
}
// Copy only after the comparison, independently of the original string.
// Even a closed large editor therefore leaves at most this bounded prefix.
prefix = content.AsSpan(0, prefixLength).ToString();
path = location;
windowId = id;
sourceLength = content.Length;
hasState = true;
sourcePrefix = prefix;
return true;
}
public void Reset()
{
hasState = false;
windowId = sourceLength = 0;
path = prefix = "";
}
}