using System; using System.Collections; using System.Globalization; using System.IO; namespace TBL.CSharp.Serialization.Marshal.Serializer { public unsafe partial class BinarySerializer : IMarshalSerializer { /// /// 使用指定上下文序列化一个可链接符号 /// private void SerializeLinkableSymbol(string symbol, BinaryWriter stream, IMarshalContext context) { // 在上下文中已链接的符号 if (context.FindLinkableSymbol(symbol, out var linkedId)) { stream.Write(Marshal.TypeId.SymbolLink); stream.Write(linkedId); return; } // 序列化符号 context.AddLinkableSymbol(symbol); stream.Write(Marshal.TypeId.Symbol); stream.Write(symbol); } /// /// 使用指定上下文序列化一个可链接对象 /// private void SerializeLinkableObject(object self, BinaryWriter stream, IMarshalContext context) { // 在上下文中已链接的对象 if (context.FindLinkableObject(self, out var linkedId)) { stream.Write(Marshal.TypeId.ObjectLink); stream.Write(linkedId); return; } // 未链接对象的原始处理 var type = self.GetType(); context.AddLinkableObject(self); switch (self) { // 字符串对象 case string stringValue: stream.Write(Marshal.TypeId.String); stream.Write(stringValue); break; // 可使用流序列化的对象 case IStreamSerializable streamSerializable: stream.Write(streamSerializable.IsShouldInitializeWhenDeserialize() ? Marshal.TypeId.SpecialStreamFull : Marshal.TypeId.SpecialStream); SerializeLinkableSymbol(type.AssemblyQualifiedName, stream, context); streamSerializable.Serialize(stream.BaseStream, _isNeedEndianConversion); break; // 可使用代理序列化的对象 case IProxiedSerializable proxiedSerializable: stream.Write(proxiedSerializable.IsShouldInitializeWhenDeserialize() ? Marshal.TypeId.SpecialProxiedFull : Marshal.TypeId.SpecialProxied); SerializeLinkableSymbol(type.AssemblyQualifiedName, stream, context); Serialize(proxiedSerializable.ProxiedSerialize(), stream, context); break; // 可非安全序列化的对象 case IUnsafeSerializable unsafeSerializable: stream.Write(unsafeSerializable.IsShouldInitializeWhenDeserialize() ? Marshal.TypeId.SpecialUnsafeFull : Marshal.TypeId.SpecialUnsafe); SerializeLinkableSymbol(type.AssemblyQualifiedName, stream, context); var size = unsafeSerializable.CalcSerializationSize(); var buffer = stackalloc byte[size]; stream.Write(size); var realSize = _isNeedEndianConversion ? unsafeSerializable.SerializeWithEndianConversion(buffer) : unsafeSerializable.Serialize(buffer); for (var i = 0; i < size; i++) stream.Write(buffer[i]); break; // 其它情况 default: // 元组 if (type.IsSerializableTuple()) { var rt = type.GetGenericArguments(); stream.Write(Marshal.TypeId.Tuple); stream.Write((byte)rt.Length); for (int i = 0, len = rt.Length; i < len; i++) { Serialize(type.GetField($"Item{i}").GetValue(self), stream, context); } } // 一般多字段对象 else { stream.Write(Marshal.TypeId.Object); SerializeLinkableSymbol(type.AssemblyQualifiedName, stream, context); var fieldInfos = Marshal.GetTypeFields(type); // 序列化列表接口部分 if (self is IList list) { stream.Write(Marshal.TypeId.List); stream.Write(list.Count); foreach (var element in list) { Serialize(element, stream, context); } } // 存储目录部分 if (self is IDictionary dictionary) { stream.Write(Marshal.TypeId.Dictionary); stream.Write(dictionary.Count); foreach (var key in dictionary.Keys) { Serialize(key, stream, context); Serialize(dictionary[key], stream, context); } } // 存储字段部分 if (fieldInfos.Length > 0) { stream.Write(Marshal.TypeId.ObjectFields); stream.Write(fieldInfos.Length); foreach (var fieldInfo in fieldInfos) { SerializeLinkableSymbol(fieldInfo.Name, stream, context); Serialize(fieldInfo.GetValue(self), stream, context); } } // 对象尾标记 stream.Write(Marshal.TypeId.ObjectEnd); } break; } } /// /// 使用指定上下文序列化对象 /// private void Serialize(object self, BinaryWriter stream, IMarshalContext context) { switch (self) { case null: stream.Write(Marshal.TypeId.Null); break; case bool boolValue: stream.Write(boolValue ? Marshal.TypeId.True : Marshal.TypeId.False); break; case sbyte int8Value: stream.Write(Marshal.TypeId.Int8); stream.Write(int8Value); break; case byte uint8Value: stream.Write(Marshal.TypeId.Int8Unsigned); stream.Write(uint8Value); break; case Int16 int16Value: stream.Write(Marshal.TypeId.Int16); stream.Write(int16Value); break; case UInt16 uint16Value: stream.Write(Marshal.TypeId.Int16Unsigned); stream.Write(uint16Value); break; case Int32 int32Value: stream.Write(Marshal.TypeId.Int32); stream.Write(int32Value); break; case UInt32 uint32Value: stream.Write(Marshal.TypeId.Int32Unsigned); stream.Write(uint32Value); break; case Int64 int64Value: stream.Write(Marshal.TypeId.Int64); stream.Write(int64Value); break; case UInt64 uint64Value: stream.Write(Marshal.TypeId.Int64Unsigned); stream.Write(uint64Value); break; case Single floatValue: stream.Write(Marshal.TypeId.Single); if (float.IsNaN(floatValue)) stream.Write(nameof(float.NaN)); else if (float.IsPositiveInfinity(floatValue)) stream.Write(nameof(float.PositiveInfinity)); else if (float.IsNegativeInfinity(floatValue)) stream.Write(nameof(float.NegativeInfinity)); else stream.Write(Convert.ToString(floatValue, CultureInfo.InvariantCulture)); break; case Double doubleValue: stream.Write(Marshal.TypeId.Double); if (double.IsNaN(doubleValue)) stream.Write(nameof(double.NaN)); else if (double.IsPositiveInfinity(doubleValue)) stream.Write(nameof(double.PositiveInfinity)); else if (double.IsNegativeInfinity(doubleValue)) stream.Write(nameof(double.NegativeInfinity)); else stream.Write(Convert.ToString(doubleValue, CultureInfo.InvariantCulture)); break; default: SerializeLinkableObject(self, stream, context); break; } } /// /// 使用指定上下文序列化对象 /// /// 要序列化的对象 /// 序列化目标流 /// 指定的序列化上下文 public void Serialize(object self, Stream stream, IMarshalContext context) { using var writer = CreateBinaryWriter(stream); Serialize(self, writer, context); } } }