using System; using System.IO; using System.Runtime.Serialization; using System.Xml; namespace Asb.Base.V2.Serialization; public sealed class BaseV2Serializer : XmlObjectSerializer { private const string BaseV2Prefix = "ASBBaseV2"; private readonly Type elementType; private readonly bool useCustomSerialization; private readonly XmlObjectSerializer fallbackSerializer; public BaseV2Serializer(Type type, XmlObjectSerializer fallbackSerializer) { this.fallbackSerializer = fallbackSerializer; elementType = type; if (!(type == null)) { Type c = (type.IsArray ? type.GetElementType() : type); useCustomSerialization = typeof(IBaseV2CustomSerializable).IsAssignableFrom(c); } } public override bool IsStartObject(XmlDictionaryReader reader) { if (useCustomSerialization) { return string.Compare(reader.LocalName, "ASBBaseV2", StringComparison.CurrentCultureIgnoreCase) == 0; } return fallbackSerializer.IsStartObject(reader); } public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName) { if (useCustomSerialization) { using MemoryStream input = new MemoryStream(reader.ReadElementContentAsBase64()); using BinaryReader binaryReader = new BinaryReader(input); if (binaryReader.ReadBoolean()) { return null; } if (Activator.CreateInstance(elementType.IsArray ? elementType.GetElementType() : elementType) is IBaseV2CustomSerializable baseV2CustomSerializable) { if (elementType.IsArray) { int arrayLength = binaryReader.ReadInt32(); return baseV2CustomSerializable.InitializeArrayFromStream(binaryReader, arrayLength); } baseV2CustomSerializable.InitializeFromStream(binaryReader); return baseV2CustomSerializable; } } return fallbackSerializer.ReadObject(reader, verifyObjectName); } public override void WriteEndObject(XmlDictionaryWriter writer) { if (useCustomSerialization) { writer.WriteEndElement(); } else { fallbackSerializer.WriteEndObject(writer); } } public override void WriteObjectContent(XmlDictionaryWriter writer, object graph) { bool flag = false; if (useCustomSerialization) { using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(graph == null); if (graph == null) { flag = true; } else if (elementType.IsArray) { if (Activator.CreateInstance(elementType.GetElementType()) is IBaseV2CustomSerializable baseV2CustomSerializable) { baseV2CustomSerializable.WriteArrayToStream(graph, binaryWriter); flag = true; } } else if (graph is IBaseV2CustomSerializable baseV2CustomSerializable2) { baseV2CustomSerializable2.WriteToStream(binaryWriter); flag = true; } if (flag) { byte[] array = memoryStream.ToArray(); writer.WriteBase64(array, 0, array.Length); } } if (!flag) { fallbackSerializer.WriteObjectContent(writer, graph); } } public override void WriteStartObject(XmlDictionaryWriter writer, object graph) { if (useCustomSerialization) { writer.WriteStartElement("ASBBaseV2"); } else { fallbackSerializer.WriteStartObject(writer, graph); } } }