// Copyright Epic Games, Inc. All Rights Reserved. using EpicGames.Core; using System; namespace EpicGames.Serialization { /// /// Marks a class as supporting serialization to compact-binary, even if it does not have exposed fields. This suppresses errors /// when base class objects are empty. /// [AttributeUsage(AttributeTargets.Class)] public class CbObjectAttribute : Attribute { } /// /// Attribute used to mark a property that should be serialized to compact binary /// [AttributeUsage(AttributeTargets.Property)] public class CbFieldAttribute : Attribute { /// /// Name of the serialized field /// public string? Name { get; set; } /// /// Default constructor /// public CbFieldAttribute() { } /// /// Constructor /// /// public CbFieldAttribute(string name) { Name = name; } } /// /// Attribute used to indicate that this object is the base for a class hierarchy. Each derived class must have a [CbDiscriminator] attribute. /// public class CbPolymorphicAttribute : Attribute { } /// /// Sets the name used for discriminating between derived classes during serialization /// public class CbDiscriminatorAttribute : Attribute { /// /// Name used to identify this class /// public string Name { get; } /// /// Constructor /// /// Name used to identify this class public CbDiscriminatorAttribute(string name) => Name = name; } /// /// Exception thrown when serializing cb objects /// public class CbException : Exception { /// public CbException(string message) : base(message) { } /// public CbException(string message, Exception inner) : base(message, inner) { } } /// /// Exception indicating that a class does not have any fields to serialize /// public sealed class CbEmptyClassException : CbException { /// /// Type with missing field annotations /// public Type Type { get; } /// /// Constructor /// public CbEmptyClassException(Type type) : base($"{type.Name} does not have any fields marked with a [CbField] attribute. If this is intended, explicitly mark the class with a [CbObject] attribute.") { Type = type; } } /// /// Attribute-driven compact binary serializer /// public static class CbSerializer { /// /// Serialize an object /// /// Type of the object to serialize /// /// public static CbObject Serialize(Type type, object value) { CbWriter writer = new CbWriter(); CbConverter.GetConverter(type).WriteObject(writer, value); return writer.ToObject(); } /// /// Serialize an object /// /// /// /// public static CbObject Serialize(T value) { CbWriter writer = new CbWriter(); CbConverter.GetConverter().Write(writer, value); return writer.ToObject(); } /// /// Serialize an object /// /// /// /// public static byte[] SerializeToByteArray(T value) { CbWriter writer = new CbWriter(); CbConverter.GetConverter().Write(writer, value); return writer.ToByteArray(); } /// /// Serialize a property to a given writer /// /// /// /// public static void Serialize(CbWriter writer, T value) { CbConverter.GetConverter().Write(writer, value); } /// /// Serialize a named property to the given writer /// /// /// /// /// public static void Serialize(CbWriter writer, Utf8String name, T value) { CbConverter.GetConverter().WriteNamed(writer, name, value); } /// /// Deserialize an object from a /// /// /// Type of the object to read /// public static object? Deserialize(CbField field, Type type) { return CbConverter.GetConverter(type).ReadObject(field); } /// /// Deserialize an object from a /// /// /// /// public static T Deserialize(CbField field) { return CbConverter.GetConverter().Read(field); } /// /// Deserialize an object from a /// /// /// /// public static T Deserialize(CbObject obj) => Deserialize(obj.AsField()); /// /// Deserialize an object from a block of memory /// /// /// /// public static T Deserialize(ReadOnlyMemory data) => Deserialize(new CbField(data)); } }