XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text;

namespace XFESystem.Documents;

public sealed class DocumentSession
{
    private static readonly UTF8Encoding Utf8 = new(false, true);
    private readonly SemaphoreSlim _saveLock = new(1, 1);
    private string _savedText;

    internal DocumentSession(DocumentLocation location, StoredDocument source, string text)
    {
        Location = location;
        Revision = source.Revision;
        IsReadOnly = source.IsReadOnly;
        Text = _savedText = text;
    }

    public DocumentLocation Location { get; }
    public string Revision { get; private set; }
    public bool IsReadOnly { get; }
    public string Text { get; set; }
    public bool IsModified => !string.Equals(Text, _savedText, StringComparison.Ordinal);
    public string HighlightLanguage => CodeHighlightLanguage.FromPath(Location.Value);

    internal async ValueTask SaveAsync(IDocumentStorage storage, int maximumBytes, CancellationToken cancellationToken)
    {
        await _saveLock.WaitAsync(cancellationToken).ConfigureAwait(false);
        try
        {
            if (IsReadOnly) throw new UnauthorizedAccessException("This document is read-only.");
            var snapshot = Text ?? throw new InvalidOperationException("Document text cannot be null.");
            if (Utf8.GetByteCount(snapshot) > maximumBytes) throw new IOException("The document exceeds the size limit.");
            var content = Utf8.GetBytes(snapshot);
            Revision = await storage.ReplaceAsync(Location, content, Revision, cancellationToken).ConfigureAwait(false);
            // Edits made while saving remain dirty: only the actual saved snapshot becomes the baseline.
            _savedText = snapshot;
        }
        finally { _saveLock.Release(); }
    }
}