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);
}
}
}