using System; using System.IO; using Vellum; namespace Amphora.Vellum { /// /// Saves a StringView as the whole of the string it looks into, and where in it the view starts and ends. /// /// /// The string is saved the way any string is, so views of one string, and the string itself, share it in the save /// and load over a single string. /// public sealed class StringViewConverter : SaveConverter { public const string TextKey = "text"; public const string StartIndexKey = "startIndex"; public const string EndIndexKey = "endIndex"; public override SaveNode Write(StringView value, SaveSession session) { // A default view has no text at all, and saves as a view of an empty one. string text = value.Text ?? ""; SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries[TextKey] = session.ToNode(text); returnMe.Entries[StartIndexKey] = session.ToNode(value.StartIndex); returnMe.Entries[EndIndexKey] = session.ToNode(value.EndIndex); return returnMe; } public override StringView Read(SaveNode node, SaveSession session) { var reader = new SaveReader(node, session); string text = reader.Require(TextKey); int startIndex = reader.Require(StartIndexKey); int endIndex = reader.Require(EndIndexKey); if (text == null) { throw new InvalidDataException("A saved string view has no text to look into."); } try { return new StringView(text, startIndex, endIndex); } catch (ArgumentException exception) { throw new InvalidDataException("A saved string view runs from " + startIndex + " to " + endIndex + ", which doesn't fit the " + text.Length + " characters it looks into.", exception); } } public override bool TryListChildren(SaveNode node, ChildList children) { // Everything it reads is built-in, and so left out. SaveNode text; return node.TryGetEntry(TextKey, out text); } } }