146 lines
4.7 KiB
C#
146 lines
4.7 KiB
C#
|
|
using System;
|
||
|
|
using GameCult.Caching;
|
||
|
|
using MessagePack;
|
||
|
|
using MessagePack.Formatters;
|
||
|
|
using MessagePack.Resolvers;
|
||
|
|
|
||
|
|
namespace GameCult.Caching.MessagePack;
|
||
|
|
|
||
|
|
public sealed class CultRecordRefFormatter<T> : IMessagePackFormatter<CultRecordRef<T>>
|
||
|
|
{
|
||
|
|
public void Serialize(ref MessagePackWriter writer, CultRecordRef<T> value, MessagePackSerializerOptions options)
|
||
|
|
{
|
||
|
|
options.Resolver.GetFormatterWithVerify<string>().Serialize(ref writer, value.Key.Value, options);
|
||
|
|
}
|
||
|
|
|
||
|
|
public CultRecordRef<T> Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||
|
|
{
|
||
|
|
var key = options.Resolver.GetFormatterWithVerify<string>().Deserialize(ref reader, options) ?? string.Empty;
|
||
|
|
return new CultRecordRef<T>(new CultRecordKey(key));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public sealed class CultDocumentResolver : IFormatterResolver
|
||
|
|
{
|
||
|
|
public static readonly CultDocumentResolver Instance = new();
|
||
|
|
private CultDocumentResolver() { }
|
||
|
|
|
||
|
|
public IMessagePackFormatter<T>? GetFormatter<T>()
|
||
|
|
{
|
||
|
|
var generated = GeneratedCultDocumentResolvers.GetFormatter<T>();
|
||
|
|
if (generated != null)
|
||
|
|
{
|
||
|
|
return generated;
|
||
|
|
}
|
||
|
|
|
||
|
|
var type = typeof(T);
|
||
|
|
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(CultRecordRef<>))
|
||
|
|
{
|
||
|
|
var formatterType = typeof(CultRecordRefFormatter<>).MakeGenericType(type.GetGenericArguments()[0]);
|
||
|
|
return (IMessagePackFormatter<T>)Activator.CreateInstance(formatterType)!;
|
||
|
|
}
|
||
|
|
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static class CultDocumentMessagePackSerialization
|
||
|
|
{
|
||
|
|
public static readonly MessagePackSerializerOptions Options =
|
||
|
|
MessagePackSerializerOptions.Standard
|
||
|
|
.WithResolver(CompositeResolver.Create(
|
||
|
|
CultDocumentResolver.Instance,
|
||
|
|
StandardResolver.Instance))
|
||
|
|
.WithSecurity(MessagePackSecurity.UntrustedData);
|
||
|
|
|
||
|
|
public static byte[] Serialize<T>(T value)
|
||
|
|
{
|
||
|
|
return MessagePackSerializer.Serialize(value, Options);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static T Deserialize<T>(byte[] payload)
|
||
|
|
{
|
||
|
|
return MessagePackSerializer.Deserialize<T>(payload, Options);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static byte[] SerializeUntyped(object value, Type type)
|
||
|
|
{
|
||
|
|
return MessagePackSerializer.Serialize(type, value, Options);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static object DeserializeUntyped(Type type, byte[] payload)
|
||
|
|
{
|
||
|
|
return MessagePackSerializer.Deserialize(type, payload, Options);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static class GeneratedCultDocumentResolvers
|
||
|
|
{
|
||
|
|
public static IMessagePackFormatter<T>? GetFormatter<T>() => null;
|
||
|
|
}
|
||
|
|
|
||
|
|
public class SingleFileMessagePackBackingStore : SingleFileBackingStore
|
||
|
|
{
|
||
|
|
public SingleFileMessagePackBackingStore(string filePath) : base(filePath)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override byte[] SerializeSnapshot(CultPersistedStoreSnapshot snapshot)
|
||
|
|
{
|
||
|
|
return CultDocumentMessagePackSerialization.Serialize(snapshot);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override CultPersistedStoreSnapshot DeserializeSnapshot(byte[] data)
|
||
|
|
{
|
||
|
|
return CultDocumentMessagePackSerialization.Deserialize<CultPersistedStoreSnapshot>(data);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override byte[] SerializePayload(object document)
|
||
|
|
{
|
||
|
|
return CultDocumentMessagePackSerialization.SerializeUntyped(document, document.GetType());
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override object DeserializePayload(Type documentType, byte[] payload)
|
||
|
|
{
|
||
|
|
return CultDocumentMessagePackSerialization.DeserializeUntyped(documentType, payload);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public class MultiFileMessagePackBackingStore : MultiFileBackingStore
|
||
|
|
{
|
||
|
|
public MultiFileMessagePackBackingStore(string path) : base(path)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override byte[] SerializeRecord(CultPersistedRecord record)
|
||
|
|
{
|
||
|
|
return CultDocumentMessagePackSerialization.Serialize(record);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override CultPersistedRecord DeserializeRecord(byte[] data)
|
||
|
|
{
|
||
|
|
return CultDocumentMessagePackSerialization.Deserialize<CultPersistedRecord>(data);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override byte[] SerializeCatalog(CultSchemaCatalogEntry[] catalog)
|
||
|
|
{
|
||
|
|
return CultDocumentMessagePackSerialization.Serialize(catalog);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override CultSchemaCatalogEntry[] DeserializeCatalog(byte[] data)
|
||
|
|
{
|
||
|
|
return CultDocumentMessagePackSerialization.Deserialize<CultSchemaCatalogEntry[]>(data);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override byte[] SerializePayload(object document)
|
||
|
|
{
|
||
|
|
return CultDocumentMessagePackSerialization.SerializeUntyped(document, document.GetType());
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override object DeserializePayload(Type documentType, byte[] payload)
|
||
|
|
{
|
||
|
|
return CultDocumentMessagePackSerialization.DeserializeUntyped(documentType, payload);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override string Extension => "msgpack";
|
||
|
|
}
|