Decompiled source of OdinSerializer v2022.11.9
BepInEx/plugins/Odin Serializer/OdinSerializer.dll
Decompiled 10 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Configuration.Assemblies; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using JetBrains.Annotations; using OdinSerializer; using OdinSerializer.Utilities; using OdinSerializer.Utilities.Unsafe; using UnityEngine; using UnityEngine.Events; using UnityEngine.Serialization; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RegisterFormatterLocator(typeof(ArrayFormatterLocator), -80)] [assembly: RegisterFormatterLocator(typeof(DelegateFormatterLocator), -50)] [assembly: RegisterFormatterLocator(typeof(GenericCollectionFormatterLocator), -100)] [assembly: RegisterFormatterLocator(typeof(ISerializableFormatterLocator), -110)] [assembly: RegisterFormatterLocator(typeof(SelfFormatterLocator), -60)] [assembly: RegisterFormatterLocator(typeof(TypeFormatterLocator), -70)] [assembly: RegisterFormatter(typeof(ArrayListFormatter), 0)] [assembly: RegisterFormatter(typeof(DateTimeFormatter), 0)] [assembly: RegisterFormatter(typeof(DateTimeOffsetFormatter), 0)] [assembly: RegisterFormatter(typeof(DerivedDictionaryFormatter<, , >), typeof(WeakDictionaryFormatter), -1)] [assembly: RegisterFormatter(typeof(DictionaryFormatter<, >), typeof(WeakDictionaryFormatter), 0)] [assembly: RegisterFormatter(typeof(DoubleLookupDictionaryFormatter<, , >), typeof(WeakDoubleLookupDictionaryFormatter), 0)] [assembly: RegisterFormatter(typeof(HashSetFormatter<>), typeof(WeakHashSetFormatter), 0)] [assembly: RegisterFormatter(typeof(KeyValuePairFormatter<, >), typeof(WeakKeyValuePairFormatter), 0)] [assembly: RegisterFormatter(typeof(ListFormatter<>), typeof(WeakListFormatter), 0)] [assembly: RegisterFormatter(typeof(MethodInfoFormatter<>), typeof(WeakMethodInfoFormatter), 0)] [assembly: RegisterFormatter(typeof(NullableFormatter<>), typeof(WeakNullableFormatter), 0)] [assembly: RegisterFormatter(typeof(QueueFormatter<, >), typeof(WeakQueueFormatter), 0)] [assembly: RegisterFormatter(typeof(StackFormatter<, >), typeof(WeakStackFormatter), 0)] [assembly: RegisterFormatter(typeof(TimeSpanFormatter), 0)] [assembly: RegisterFormatter(typeof(VersionFormatter), 0)] [assembly: RegisterDictionaryKeyPathProvider(typeof(Vector2DictionaryKeyPathProvider))] [assembly: RegisterDictionaryKeyPathProvider(typeof(Vector3DictionaryKeyPathProvider))] [assembly: RegisterDictionaryKeyPathProvider(typeof(Vector4DictionaryKeyPathProvider))] [assembly: RegisterFormatter(typeof(AnimationCurveFormatter), 0)] [assembly: RegisterFormatter(typeof(BoundsFormatter), 0)] [assembly: RegisterFormatter(typeof(Color32Formatter), 0)] [assembly: RegisterFormatterLocator(typeof(ColorBlockFormatterLocator), 0)] [assembly: RegisterFormatter(typeof(ColorFormatter), 0)] [assembly: RegisterFormatter(typeof(CoroutineFormatter), 0)] [assembly: RegisterFormatter(typeof(GradientAlphaKeyFormatter), 0)] [assembly: RegisterFormatter(typeof(GradientColorKeyFormatter), 0)] [assembly: RegisterFormatter(typeof(GradientFormatter), 0)] [assembly: RegisterFormatter(typeof(KeyframeFormatter), 0)] [assembly: RegisterFormatter(typeof(LayerMaskFormatter), 0)] [assembly: RegisterFormatter(typeof(QuaternionFormatter), 0)] [assembly: RegisterFormatter(typeof(RectFormatter), 0)] [assembly: RegisterFormatter(typeof(UnityEventFormatter<>), typeof(WeakUnityEventFormatter), 0)] [assembly: RegisterFormatter(typeof(Vector2Formatter), 0)] [assembly: RegisterFormatter(typeof(Vector3Formatter), 0)] [assembly: RegisterFormatter(typeof(Vector4Formatter), 0)] [assembly: RegisterFormatter(typeof(Vector2IntFormatter), 0)] [assembly: RegisterFormatter(typeof(Vector3IntFormatter), 0)] [assembly: TargetFramework(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")] [assembly: AssemblyCompany("Lordfirespeed")] [assembly: AssemblyConfiguration("Release JIT")] [assembly: AssemblyFileVersion("2022.11.9.0")] [assembly: AssemblyInformationalVersion("2022.11.9+24cbb31292337b9d9a549738169052b81ed466fb")] [assembly: AssemblyProduct("OdinSerializer")] [assembly: AssemblyTitle("OdinSerializer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2022.0.0.0")] [module: UnverifiableCode] namespace OdinSerializer { public class GlobalSerializationConfig { private static readonly GlobalSerializationConfig instance = new GlobalSerializationConfig(); public static GlobalSerializationConfig Instance => instance; public ILogger Logger => DefaultLoggers.UnityLogger; public DataFormat EditorSerializationFormat => DataFormat.Nodes; public DataFormat BuildSerializationFormat => DataFormat.Binary; public LoggingPolicy LoggingPolicy => LoggingPolicy.LogErrors; public ErrorHandlingPolicy ErrorHandlingPolicy => ErrorHandlingPolicy.Resilient; internal static bool HasInstanceLoaded => true; internal static void LoadInstanceIfAssetExists() { } } public abstract class BaseDataReader : BaseDataReaderWriter, IDataReader, IDisposable { private DeserializationContext context; private Stream stream; public int CurrentNodeId => base.CurrentNode.Id; public int CurrentNodeDepth => base.NodeDepth; public string CurrentNodeName => base.CurrentNode.Name; public virtual Stream Stream { get { return stream; } set { if (value == null) { throw new ArgumentNullException("value"); } if (!value.CanRead) { throw new ArgumentException("Cannot read from stream"); } stream = value; } } public DeserializationContext Context { get { if (context == null) { context = new DeserializationContext(); } return context; } set { context = value; } } protected BaseDataReader(Stream stream, DeserializationContext context) { this.context = context; if (stream != null) { Stream = stream; } } public abstract bool EnterNode(out Type type); public abstract bool ExitNode(); public abstract bool EnterArray(out long length); public abstract bool ExitArray(); public abstract bool ReadPrimitiveArray<T>(out T[] array) where T : struct; public abstract EntryType PeekEntry(out string name); public abstract bool ReadInternalReference(out int id); public abstract bool ReadExternalReference(out int index); public abstract bool ReadExternalReference(out Guid guid); public abstract bool ReadExternalReference(out string id); public abstract bool ReadChar(out char value); public abstract bool ReadString(out string value); public abstract bool ReadGuid(out Guid value); public abstract bool ReadSByte(out sbyte value); public abstract bool ReadInt16(out short value); public abstract bool ReadInt32(out int value); public abstract bool ReadInt64(out long value); public abstract bool ReadByte(out byte value); public abstract bool ReadUInt16(out ushort value); public abstract bool ReadUInt32(out uint value); public abstract bool ReadUInt64(out ulong value); public abstract bool ReadDecimal(out decimal value); public abstract bool ReadSingle(out float value); public abstract bool ReadDouble(out double value); public abstract bool ReadBoolean(out bool value); public abstract bool ReadNull(); public virtual void SkipEntry() { switch (PeekEntry()) { case EntryType.StartOfNode: { bool flag = true; EnterNode(out var type); try { if (type != null) { if (FormatterUtilities.IsPrimitiveType(type)) { Serializer serializer = Serializer.Get(type); object reference = serializer.ReadValueWeak(this); if (CurrentNodeId >= 0) { Context.RegisterInternalReference(CurrentNodeId, reference); } } else { IFormatter formatter = FormatterLocator.GetFormatter(type, Context.Config.SerializationPolicy); object reference2 = formatter.Deserialize(this); if (CurrentNodeId >= 0) { Context.RegisterInternalReference(CurrentNodeId, reference2); } } break; } while (true) { switch (PeekEntry()) { case EntryType.EndOfArray: ReadToNextEntry(); break; default: SkipEntry(); break; case EntryType.EndOfNode: case EntryType.EndOfStream: return; } } } catch (SerializationAbortException ex) { flag = false; throw ex; } finally { if (flag) { ExitNode(); } } } case EntryType.StartOfArray: ReadToNextEntry(); while (true) { switch (PeekEntry()) { case EntryType.EndOfArray: ReadToNextEntry(); return; case EntryType.EndOfNode: ReadToNextEntry(); break; default: SkipEntry(); break; case EntryType.EndOfStream: return; } } default: ReadToNextEntry(); break; case EntryType.EndOfNode: case EntryType.EndOfArray: break; } } public abstract void Dispose(); public virtual void PrepareNewSerializationSession() { ClearNodes(); } public abstract string GetDataDump(); protected abstract EntryType PeekEntry(); protected abstract EntryType ReadToNextEntry(); } public abstract class BaseDataReaderWriter { private NodeInfo[] nodes = new NodeInfo[32]; private int nodesLength; [Obsolete("Use the Binder member on the writer's SerializationContext/DeserializationContext instead.", false)] [EditorBrowsable(EditorBrowsableState.Never)] public TwoWaySerializationBinder Binder { get { if (this is IDataWriter) { return (this as IDataWriter).Context.Binder; } if (this is IDataReader) { return (this as IDataReader).Context.Binder; } return TwoWaySerializationBinder.Default; } set { if (this is IDataWriter) { (this as IDataWriter).Context.Binder = value; } else if (this is IDataReader) { (this as IDataReader).Context.Binder = value; } } } public bool IsInArrayNode { get { if (nodesLength != 0) { return nodes[nodesLength - 1].IsArray; } return false; } } protected int NodeDepth => nodesLength; protected NodeInfo[] NodesArray => nodes; protected NodeInfo CurrentNode { get { if (nodesLength != 0) { return nodes[nodesLength - 1]; } return NodeInfo.Empty; } } protected void PushNode(NodeInfo node) { if (nodesLength == nodes.Length) { ExpandNodes(); } nodes[nodesLength] = node; nodesLength++; } protected void PushNode(string name, int id, Type type) { if (nodesLength == nodes.Length) { ExpandNodes(); } nodes[nodesLength] = new NodeInfo(name, id, type, isArray: false); nodesLength++; } protected void PushArray() { if (nodesLength == nodes.Length) { ExpandNodes(); } if (nodesLength == 0 || nodes[nodesLength - 1].IsArray) { nodes[nodesLength] = new NodeInfo(null, -1, null, isArray: true); } else { NodeInfo nodeInfo = nodes[nodesLength - 1]; nodes[nodesLength] = new NodeInfo(nodeInfo.Name, nodeInfo.Id, nodeInfo.Type, isArray: true); } nodesLength++; } private void ExpandNodes() { NodeInfo[] array = new NodeInfo[nodes.Length * 2]; NodeInfo[] array2 = nodes; for (int i = 0; i < array2.Length; i++) { array[i] = array2[i]; } nodes = array; } protected void PopNode(string name) { if (nodesLength == 0) { throw new InvalidOperationException("There are no nodes to pop."); } nodesLength--; } protected void PopArray() { if (nodesLength == 0) { throw new InvalidOperationException("There are no nodes to pop."); } if (!nodes[nodesLength - 1].IsArray) { throw new InvalidOperationException("Was not in array when exiting array."); } nodesLength--; } protected void ClearNodes() { nodesLength = 0; } } public abstract class BaseDataWriter : BaseDataReaderWriter, IDataWriter, IDisposable { private SerializationContext context; private Stream stream; public virtual Stream Stream { get { return stream; } set { if (value == null) { throw new ArgumentNullException("value"); } if (!value.CanWrite) { throw new ArgumentException("Cannot write to stream"); } stream = value; } } public SerializationContext Context { get { if (context == null) { context = new SerializationContext(); } return context; } set { context = value; } } protected BaseDataWriter(Stream stream, SerializationContext context) { this.context = context; if (stream != null) { Stream = stream; } } public virtual void FlushToStream() { Stream.Flush(); } public abstract void BeginReferenceNode(string name, Type type, int id); public abstract void BeginStructNode(string name, Type type); public abstract void EndNode(string name); public abstract void BeginArrayNode(long length); public abstract void EndArrayNode(); public abstract void WritePrimitiveArray<T>(T[] array) where T : struct; public abstract void WriteNull(string name); public abstract void WriteInternalReference(string name, int id); public abstract void WriteExternalReference(string name, int index); public abstract void WriteExternalReference(string name, Guid guid); public abstract void WriteExternalReference(string name, string id); public abstract void WriteChar(string name, char value); public abstract void WriteString(string name, string value); public abstract void WriteGuid(string name, Guid value); public abstract void WriteSByte(string name, sbyte value); public abstract void WriteInt16(string name, short value); public abstract void WriteInt32(string name, int value); public abstract void WriteInt64(string name, long value); public abstract void WriteByte(string name, byte value); public abstract void WriteUInt16(string name, ushort value); public abstract void WriteUInt32(string name, uint value); public abstract void WriteUInt64(string name, ulong value); public abstract void WriteDecimal(string name, decimal value); public abstract void WriteSingle(string name, float value); public abstract void WriteDouble(string name, double value); public abstract void WriteBoolean(string name, bool value); public abstract void Dispose(); public virtual void PrepareNewSerializationSession() { ClearNodes(); } public abstract string GetDataDump(); } public class BinaryDataReader : BaseDataReader { private struct Struct256Bit { public decimal d1; public decimal d2; } private static readonly Dictionary<Type, Delegate> PrimitiveFromByteMethods = new Dictionary<Type, Delegate> { { typeof(char), (Func<byte[], int, char>)((byte[] b, int i) => (char)ProperBitConverter.ToUInt16(b, i)) }, { typeof(byte), (Func<byte[], int, byte>)((byte[] b, int i) => b[i]) }, { typeof(sbyte), (Func<byte[], int, sbyte>)((byte[] b, int i) => (sbyte)b[i]) }, { typeof(bool), (Func<byte[], int, bool>)((byte[] b, int i) => b[i] != 0) }, { typeof(short), new Func<byte[], int, short>(ProperBitConverter.ToInt16) }, { typeof(int), new Func<byte[], int, int>(ProperBitConverter.ToInt32) }, { typeof(long), new Func<byte[], int, long>(ProperBitConverter.ToInt64) }, { typeof(ushort), new Func<byte[], int, ushort>(ProperBitConverter.ToUInt16) }, { typeof(uint), new Func<byte[], int, uint>(ProperBitConverter.ToUInt32) }, { typeof(ulong), new Func<byte[], int, ulong>(ProperBitConverter.ToUInt64) }, { typeof(decimal), new Func<byte[], int, decimal>(ProperBitConverter.ToDecimal) }, { typeof(float), new Func<byte[], int, float>(ProperBitConverter.ToSingle) }, { typeof(double), new Func<byte[], int, double>(ProperBitConverter.ToDouble) }, { typeof(Guid), new Func<byte[], int, Guid>(ProperBitConverter.ToGuid) } }; private byte[] internalBufferBackup; private byte[] buffer = new byte[102400]; private int bufferIndex; private int bufferEnd; private EntryType? peekedEntryType; private BinaryEntryType peekedBinaryEntryType; private string peekedEntryName; private Dictionary<int, Type> types = new Dictionary<int, Type>(16); public BinaryDataReader() : base(null, null) { internalBufferBackup = buffer; } public BinaryDataReader(Stream stream, DeserializationContext context) : base(stream, context) { internalBufferBackup = buffer; } public override void Dispose() { } public override EntryType PeekEntry(out string name) { if (peekedEntryType.HasValue) { name = peekedEntryName; return peekedEntryType.Value; } peekedBinaryEntryType = (BinaryEntryType)(HasBufferData(1) ? buffer[bufferIndex++] : 49); switch (peekedBinaryEntryType) { case BinaryEntryType.EndOfStream: name = null; peekedEntryName = null; peekedEntryType = EntryType.EndOfStream; break; case BinaryEntryType.NamedStartOfReferenceNode: case BinaryEntryType.NamedStartOfStructNode: name = ReadStringValue(); peekedEntryType = EntryType.StartOfNode; break; case BinaryEntryType.UnnamedStartOfReferenceNode: case BinaryEntryType.UnnamedStartOfStructNode: name = null; peekedEntryType = EntryType.StartOfNode; break; case BinaryEntryType.EndOfNode: name = null; peekedEntryType = EntryType.EndOfNode; break; case BinaryEntryType.StartOfArray: name = null; peekedEntryType = EntryType.StartOfArray; break; case BinaryEntryType.EndOfArray: name = null; peekedEntryType = EntryType.EndOfArray; break; case BinaryEntryType.PrimitiveArray: name = null; peekedEntryType = EntryType.PrimitiveArray; break; case BinaryEntryType.NamedInternalReference: name = ReadStringValue(); peekedEntryType = EntryType.InternalReference; break; case BinaryEntryType.UnnamedInternalReference: name = null; peekedEntryType = EntryType.InternalReference; break; case BinaryEntryType.NamedExternalReferenceByIndex: name = ReadStringValue(); peekedEntryType = EntryType.ExternalReferenceByIndex; break; case BinaryEntryType.UnnamedExternalReferenceByIndex: name = null; peekedEntryType = EntryType.ExternalReferenceByIndex; break; case BinaryEntryType.NamedExternalReferenceByGuid: name = ReadStringValue(); peekedEntryType = EntryType.ExternalReferenceByGuid; break; case BinaryEntryType.UnnamedExternalReferenceByGuid: name = null; peekedEntryType = EntryType.ExternalReferenceByGuid; break; case BinaryEntryType.NamedExternalReferenceByString: name = ReadStringValue(); peekedEntryType = EntryType.ExternalReferenceByString; break; case BinaryEntryType.UnnamedExternalReferenceByString: name = null; peekedEntryType = EntryType.ExternalReferenceByString; break; case BinaryEntryType.NamedSByte: name = ReadStringValue(); peekedEntryType = EntryType.Integer; break; case BinaryEntryType.UnnamedSByte: name = null; peekedEntryType = EntryType.Integer; break; case BinaryEntryType.NamedByte: name = ReadStringValue(); peekedEntryType = EntryType.Integer; break; case BinaryEntryType.UnnamedByte: name = null; peekedEntryType = EntryType.Integer; break; case BinaryEntryType.NamedShort: name = ReadStringValue(); peekedEntryType = EntryType.Integer; break; case BinaryEntryType.UnnamedShort: name = null; peekedEntryType = EntryType.Integer; break; case BinaryEntryType.NamedUShort: name = ReadStringValue(); peekedEntryType = EntryType.Integer; break; case BinaryEntryType.UnnamedUShort: name = null; peekedEntryType = EntryType.Integer; break; case BinaryEntryType.NamedInt: name = ReadStringValue(); peekedEntryType = EntryType.Integer; break; case BinaryEntryType.UnnamedInt: name = null; peekedEntryType = EntryType.Integer; break; case BinaryEntryType.NamedUInt: name = ReadStringValue(); peekedEntryType = EntryType.Integer; break; case BinaryEntryType.UnnamedUInt: name = null; peekedEntryType = EntryType.Integer; break; case BinaryEntryType.NamedLong: name = ReadStringValue(); peekedEntryType = EntryType.Integer; break; case BinaryEntryType.UnnamedLong: name = null; peekedEntryType = EntryType.Integer; break; case BinaryEntryType.NamedULong: name = ReadStringValue(); peekedEntryType = EntryType.Integer; break; case BinaryEntryType.UnnamedULong: name = null; peekedEntryType = EntryType.Integer; break; case BinaryEntryType.NamedFloat: name = ReadStringValue(); peekedEntryType = EntryType.FloatingPoint; break; case BinaryEntryType.UnnamedFloat: name = null; peekedEntryType = EntryType.FloatingPoint; break; case BinaryEntryType.NamedDouble: name = ReadStringValue(); peekedEntryType = EntryType.FloatingPoint; break; case BinaryEntryType.UnnamedDouble: name = null; peekedEntryType = EntryType.FloatingPoint; break; case BinaryEntryType.NamedDecimal: name = ReadStringValue(); peekedEntryType = EntryType.FloatingPoint; break; case BinaryEntryType.UnnamedDecimal: name = null; peekedEntryType = EntryType.FloatingPoint; break; case BinaryEntryType.NamedChar: name = ReadStringValue(); peekedEntryType = EntryType.String; break; case BinaryEntryType.UnnamedChar: name = null; peekedEntryType = EntryType.String; break; case BinaryEntryType.NamedString: name = ReadStringValue(); peekedEntryType = EntryType.String; break; case BinaryEntryType.UnnamedString: name = null; peekedEntryType = EntryType.String; break; case BinaryEntryType.NamedGuid: name = ReadStringValue(); peekedEntryType = EntryType.Guid; break; case BinaryEntryType.UnnamedGuid: name = null; peekedEntryType = EntryType.Guid; break; case BinaryEntryType.NamedBoolean: name = ReadStringValue(); peekedEntryType = EntryType.Boolean; break; case BinaryEntryType.UnnamedBoolean: name = null; peekedEntryType = EntryType.Boolean; break; case BinaryEntryType.NamedNull: name = ReadStringValue(); peekedEntryType = EntryType.Null; break; case BinaryEntryType.UnnamedNull: name = null; peekedEntryType = EntryType.Null; break; case BinaryEntryType.TypeName: case BinaryEntryType.TypeID: peekedBinaryEntryType = BinaryEntryType.Invalid; peekedEntryType = EntryType.Invalid; throw new InvalidOperationException("Invalid binary data stream: BinaryEntryType.TypeName and BinaryEntryType.TypeID must never be peeked by the binary reader."); default: { name = null; peekedBinaryEntryType = BinaryEntryType.Invalid; peekedEntryType = EntryType.Invalid; byte b = (byte)peekedBinaryEntryType; throw new InvalidOperationException("Invalid binary data stream: could not parse peeked BinaryEntryType byte '" + b + "' into a known entry type."); } } peekedEntryName = name; return peekedEntryType.Value; } public override bool EnterArray(out long length) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedEntryType == EntryType.StartOfArray) { PushArray(); MarkEntryContentConsumed(); if (UNSAFE_Read_8_Int64(out length)) { if (length < 0) { length = 0L; base.Context.Config.DebugContext.LogError("Invalid array length: " + length + "."); return false; } return true; } return false; } SkipEntry(); length = 0L; return false; } public override bool EnterNode(out Type type) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedStartOfReferenceNode || peekedBinaryEntryType == BinaryEntryType.UnnamedStartOfReferenceNode) { MarkEntryContentConsumed(); type = ReadTypeEntry(); if (!UNSAFE_Read_4_Int32(out var value)) { type = null; return false; } PushNode(peekedEntryName, value, type); return true; } if (peekedBinaryEntryType == BinaryEntryType.NamedStartOfStructNode || peekedBinaryEntryType == BinaryEntryType.UnnamedStartOfStructNode) { type = ReadTypeEntry(); PushNode(peekedEntryName, -1, type); MarkEntryContentConsumed(); return true; } SkipEntry(); type = null; return false; } public override bool ExitArray() { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } while (peekedBinaryEntryType != BinaryEntryType.EndOfArray && peekedBinaryEntryType != BinaryEntryType.EndOfStream) { if (peekedEntryType == EntryType.EndOfNode) { base.Context.Config.DebugContext.LogError("Data layout mismatch; skipping past node boundary when exiting array."); MarkEntryContentConsumed(); } SkipEntry(); } if (peekedBinaryEntryType == BinaryEntryType.EndOfArray) { MarkEntryContentConsumed(); PopArray(); return true; } return false; } public override bool ExitNode() { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } while (peekedBinaryEntryType != BinaryEntryType.EndOfNode && peekedBinaryEntryType != BinaryEntryType.EndOfStream) { if (peekedEntryType == EntryType.EndOfArray) { base.Context.Config.DebugContext.LogError("Data layout mismatch; skipping past array boundary when exiting node."); MarkEntryContentConsumed(); } SkipEntry(); } if (peekedBinaryEntryType == BinaryEntryType.EndOfNode) { MarkEntryContentConsumed(); PopNode(base.CurrentNodeName); return true; } return false; } public unsafe override bool ReadPrimitiveArray<T>(out T[] array) { if (!FormatterUtilities.IsPrimitiveArrayType(typeof(T))) { throw new ArgumentException("Type " + typeof(T).Name + " is not a valid primitive array type."); } if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedEntryType == EntryType.PrimitiveArray) { MarkEntryContentConsumed(); if (!UNSAFE_Read_4_Int32(out var value) || !UNSAFE_Read_4_Int32(out var value2)) { array = null; return false; } int num = value * value2; if (!HasBufferData(num)) { bufferIndex = bufferEnd; array = null; return false; } if (typeof(T) == typeof(byte)) { byte[] array2 = new byte[num]; Buffer.BlockCopy(buffer, bufferIndex, array2, 0, num); array = (T[])(object)array2; bufferIndex += num; return true; } array = new T[value]; if (BitConverter.IsLittleEndian) { GCHandle gCHandle = GCHandle.Alloc(array, GCHandleType.Pinned); try { fixed (byte* ptr = buffer) { void* from = ptr + bufferIndex; void* to = gCHandle.AddrOfPinnedObject().ToPointer(); UnsafeUtilities.MemoryCopy(from, to, num); } } finally { gCHandle.Free(); } } else { Func<byte[], int, T> func = (Func<byte[], int, T>)PrimitiveFromByteMethods[typeof(T)]; for (int i = 0; i < value; i++) { array[i] = func(buffer, bufferIndex + i * value2); } } bufferIndex += num; return true; } SkipEntry(); array = null; return false; } public override bool ReadBoolean(out bool value) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedEntryType == EntryType.Boolean) { MarkEntryContentConsumed(); if (HasBufferData(1)) { value = buffer[bufferIndex++] == 1; return true; } value = false; return false; } SkipEntry(); value = false; return false; } public override bool ReadSByte(out sbyte value) { if (ReadInt64(out var value2)) { try { value = checked((sbyte)value2); } catch (OverflowException) { value = 0; } return true; } value = 0; return false; } public override bool ReadByte(out byte value) { if (ReadUInt64(out var value2)) { try { value = checked((byte)value2); } catch (OverflowException) { value = 0; } return true; } value = 0; return false; } public override bool ReadInt16(out short value) { if (ReadInt64(out var value2)) { try { value = checked((short)value2); } catch (OverflowException) { value = 0; } return true; } value = 0; return false; } public override bool ReadUInt16(out ushort value) { if (ReadUInt64(out var value2)) { try { value = checked((ushort)value2); } catch (OverflowException) { value = 0; } return true; } value = 0; return false; } public override bool ReadInt32(out int value) { if (ReadInt64(out var value2)) { try { value = checked((int)value2); } catch (OverflowException) { value = 0; } return true; } value = 0; return false; } public override bool ReadUInt32(out uint value) { if (ReadUInt64(out var value2)) { try { value = checked((uint)value2); } catch (OverflowException) { value = 0u; } return true; } value = 0u; return false; } public override bool ReadInt64(out long value) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedEntryType == EntryType.Integer) { try { switch (peekedBinaryEntryType) { case BinaryEntryType.NamedSByte: case BinaryEntryType.UnnamedSByte: { if (!UNSAFE_Read_1_SByte(out var value5)) { value = 0L; return false; } value = value5; break; } case BinaryEntryType.NamedByte: case BinaryEntryType.UnnamedByte: { if (!UNSAFE_Read_1_Byte(out var value6)) { value = 0L; return false; } value = value6; break; } case BinaryEntryType.NamedShort: case BinaryEntryType.UnnamedShort: { if (!UNSAFE_Read_2_Int16(out var value7)) { value = 0L; return false; } value = value7; break; } case BinaryEntryType.NamedUShort: case BinaryEntryType.UnnamedUShort: { if (!UNSAFE_Read_2_UInt16(out var value3)) { value = 0L; return false; } value = value3; break; } case BinaryEntryType.NamedInt: case BinaryEntryType.UnnamedInt: { if (!UNSAFE_Read_4_Int32(out var value4)) { value = 0L; return false; } value = value4; break; } case BinaryEntryType.NamedUInt: case BinaryEntryType.UnnamedUInt: { if (!UNSAFE_Read_4_UInt32(out var value8)) { value = 0L; return false; } value = value8; break; } case BinaryEntryType.NamedLong: case BinaryEntryType.UnnamedLong: if (!UNSAFE_Read_8_Int64(out value)) { return false; } break; case BinaryEntryType.NamedULong: case BinaryEntryType.UnnamedULong: { if (!UNSAFE_Read_8_UInt64(out var value2)) { value = 0L; return false; } if (value2 > long.MaxValue) { value = 0L; return false; } value = (long)value2; break; } default: throw new InvalidOperationException(); } return true; } finally { MarkEntryContentConsumed(); } } SkipEntry(); value = 0L; return false; } public override bool ReadUInt64(out ulong value) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedEntryType == EntryType.Integer) { try { switch (peekedBinaryEntryType) { case BinaryEntryType.NamedSByte: case BinaryEntryType.UnnamedSByte: case BinaryEntryType.NamedByte: case BinaryEntryType.UnnamedByte: { if (!UNSAFE_Read_1_Byte(out var value7)) { value = 0uL; return false; } value = value7; break; } case BinaryEntryType.NamedShort: case BinaryEntryType.UnnamedShort: { if (!UNSAFE_Read_2_Int16(out var value4)) { value = 0uL; return false; } if (value4 < 0) { value = 0uL; return false; } value = (ulong)value4; break; } case BinaryEntryType.NamedUShort: case BinaryEntryType.UnnamedUShort: { if (!UNSAFE_Read_2_UInt16(out var value6)) { value = 0uL; return false; } value = value6; break; } case BinaryEntryType.NamedInt: case BinaryEntryType.UnnamedInt: { if (!UNSAFE_Read_4_Int32(out var value5)) { value = 0uL; return false; } if (value5 < 0) { value = 0uL; return false; } value = (ulong)value5; break; } case BinaryEntryType.NamedUInt: case BinaryEntryType.UnnamedUInt: { if (!UNSAFE_Read_4_UInt32(out var value2)) { value = 0uL; return false; } value = value2; break; } case BinaryEntryType.NamedLong: case BinaryEntryType.UnnamedLong: { if (!UNSAFE_Read_8_Int64(out var value3)) { value = 0uL; return false; } if (value3 < 0) { value = 0uL; return false; } value = (ulong)value3; break; } case BinaryEntryType.NamedULong: case BinaryEntryType.UnnamedULong: if (!UNSAFE_Read_8_UInt64(out value)) { return false; } break; default: throw new InvalidOperationException(); } return true; } finally { MarkEntryContentConsumed(); } } SkipEntry(); value = 0uL; return false; } public override bool ReadChar(out char value) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedChar || peekedBinaryEntryType == BinaryEntryType.UnnamedChar) { MarkEntryContentConsumed(); return UNSAFE_Read_2_Char(out value); } if (peekedBinaryEntryType == BinaryEntryType.NamedString || peekedBinaryEntryType == BinaryEntryType.UnnamedString) { MarkEntryContentConsumed(); string text = ReadStringValue(); if (text == null || text.Length == 0) { value = '\0'; return false; } value = text[0]; return true; } SkipEntry(); value = '\0'; return false; } public override bool ReadSingle(out float value) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedFloat || peekedBinaryEntryType == BinaryEntryType.UnnamedFloat) { MarkEntryContentConsumed(); return UNSAFE_Read_4_Float32(out value); } if (peekedBinaryEntryType == BinaryEntryType.NamedDouble || peekedBinaryEntryType == BinaryEntryType.UnnamedDouble) { MarkEntryContentConsumed(); if (!UNSAFE_Read_8_Float64(out var value2)) { value = 0f; return false; } try { value = (float)value2; } catch (OverflowException) { value = 0f; } return true; } if (peekedBinaryEntryType == BinaryEntryType.NamedDecimal || peekedBinaryEntryType == BinaryEntryType.UnnamedDecimal) { MarkEntryContentConsumed(); if (!UNSAFE_Read_16_Decimal(out var value3)) { value = 0f; return false; } try { value = (float)value3; } catch (OverflowException) { value = 0f; } return true; } if (peekedEntryType == EntryType.Integer) { if (!ReadInt64(out var value4)) { value = 0f; return false; } try { value = value4; } catch (OverflowException) { value = 0f; } return true; } SkipEntry(); value = 0f; return false; } public override bool ReadDouble(out double value) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedDouble || peekedBinaryEntryType == BinaryEntryType.UnnamedDouble) { MarkEntryContentConsumed(); return UNSAFE_Read_8_Float64(out value); } if (peekedBinaryEntryType == BinaryEntryType.NamedFloat || peekedBinaryEntryType == BinaryEntryType.UnnamedFloat) { MarkEntryContentConsumed(); if (!UNSAFE_Read_4_Float32(out var value2)) { value = 0.0; return false; } value = value2; return true; } if (peekedBinaryEntryType == BinaryEntryType.NamedDecimal || peekedBinaryEntryType == BinaryEntryType.UnnamedDecimal) { MarkEntryContentConsumed(); if (!UNSAFE_Read_16_Decimal(out var value3)) { value = 0.0; return false; } try { value = (double)value3; } catch (OverflowException) { value = 0.0; } return true; } if (peekedEntryType == EntryType.Integer) { if (!ReadInt64(out var value4)) { value = 0.0; return false; } try { value = value4; } catch (OverflowException) { value = 0.0; } return true; } SkipEntry(); value = 0.0; return false; } public override bool ReadDecimal(out decimal value) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedDecimal || peekedBinaryEntryType == BinaryEntryType.UnnamedDecimal) { MarkEntryContentConsumed(); return UNSAFE_Read_16_Decimal(out value); } if (peekedBinaryEntryType == BinaryEntryType.NamedDouble || peekedBinaryEntryType == BinaryEntryType.UnnamedDouble) { MarkEntryContentConsumed(); if (!UNSAFE_Read_8_Float64(out var value2)) { value = default(decimal); return false; } try { value = (decimal)value2; } catch (OverflowException) { value = default(decimal); } return true; } if (peekedBinaryEntryType == BinaryEntryType.NamedFloat || peekedBinaryEntryType == BinaryEntryType.UnnamedFloat) { MarkEntryContentConsumed(); if (!UNSAFE_Read_4_Float32(out var value3)) { value = default(decimal); return false; } try { value = (decimal)value3; } catch (OverflowException) { value = default(decimal); } return true; } if (peekedEntryType == EntryType.Integer) { if (!ReadInt64(out var value4)) { value = default(decimal); return false; } try { value = value4; } catch (OverflowException) { value = default(decimal); } return true; } SkipEntry(); value = default(decimal); return false; } public override bool ReadExternalReference(out Guid guid) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedExternalReferenceByGuid || peekedBinaryEntryType == BinaryEntryType.UnnamedExternalReferenceByGuid) { MarkEntryContentConsumed(); return UNSAFE_Read_16_Guid(out guid); } SkipEntry(); guid = default(Guid); return false; } public override bool ReadGuid(out Guid value) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedGuid || peekedBinaryEntryType == BinaryEntryType.UnnamedGuid) { MarkEntryContentConsumed(); return UNSAFE_Read_16_Guid(out value); } SkipEntry(); value = default(Guid); return false; } public override bool ReadExternalReference(out int index) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedExternalReferenceByIndex || peekedBinaryEntryType == BinaryEntryType.UnnamedExternalReferenceByIndex) { MarkEntryContentConsumed(); return UNSAFE_Read_4_Int32(out index); } SkipEntry(); index = -1; return false; } public override bool ReadExternalReference(out string id) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedExternalReferenceByString || peekedBinaryEntryType == BinaryEntryType.UnnamedExternalReferenceByString) { id = ReadStringValue(); MarkEntryContentConsumed(); return id != null; } SkipEntry(); id = null; return false; } public override bool ReadNull() { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedNull || peekedBinaryEntryType == BinaryEntryType.UnnamedNull) { MarkEntryContentConsumed(); return true; } SkipEntry(); return false; } public override bool ReadInternalReference(out int id) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedInternalReference || peekedBinaryEntryType == BinaryEntryType.UnnamedInternalReference) { MarkEntryContentConsumed(); return UNSAFE_Read_4_Int32(out id); } SkipEntry(); id = -1; return false; } public override bool ReadString(out string value) { if (!peekedEntryType.HasValue) { PeekEntry(out var _); } if (peekedBinaryEntryType == BinaryEntryType.NamedString || peekedBinaryEntryType == BinaryEntryType.UnnamedString) { value = ReadStringValue(); MarkEntryContentConsumed(); return value != null; } SkipEntry(); value = null; return false; } public override void PrepareNewSerializationSession() { base.PrepareNewSerializationSession(); peekedEntryType = null; peekedEntryName = null; peekedBinaryEntryType = BinaryEntryType.Invalid; types.Clear(); bufferIndex = 0; bufferEnd = 0; buffer = internalBufferBackup; } public unsafe override string GetDataDump() { byte[] array; if (bufferEnd == buffer.Length) { array = buffer; } else { array = new byte[bufferEnd]; fixed (byte* ptr = buffer) { void* from = ptr; fixed (byte* ptr2 = array) { void* to = ptr2; UnsafeUtilities.MemoryCopy(from, to, array.Length); } } } return "Binary hex dump: " + ProperBitConverter.BytesToHexString(array); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe string ReadStringValue() { if (!UNSAFE_Read_1_Byte(out var value)) { return null; } if (!UNSAFE_Read_4_Int32(out var value2)) { return null; } string text = new string(' ', value2); if (value == 0) { fixed (byte* ptr = buffer) { fixed (char* ptr3 = text) { byte* ptr2 = ptr + bufferIndex; byte* ptr4 = (byte*)ptr3; if (BitConverter.IsLittleEndian) { for (int i = 0; i < value2; i++) { *(ptr4++) = *(ptr2++); ptr4++; } } else { for (int j = 0; j < value2; j++) { ptr4++; *(ptr4++) = *(ptr2++); } } } } bufferIndex += value2; return text; } int num = value2 * 2; fixed (byte* ptr5 = buffer) { fixed (char* ptr7 = text) { if (BitConverter.IsLittleEndian) { Struct256Bit* ptr6 = (Struct256Bit*)(ptr5 + bufferIndex); Struct256Bit* ptr8 = (Struct256Bit*)ptr7; byte* ptr9 = (byte*)ptr7 + num; while (ptr8 + 1 < ptr9) { *(ptr8++) = *(ptr6++); } byte* ptr10 = (byte*)ptr6; byte* ptr11 = (byte*)ptr8; while (ptr11 < ptr9) { *(ptr11++) = *(ptr10++); } } else { byte* ptr12 = ptr5 + bufferIndex; byte* ptr13 = (byte*)ptr7; for (int k = 0; k < value2; k++) { *ptr13 = ptr12[1]; ptr13[1] = *ptr12; ptr12 += 2; ptr13 += 2; } } } } bufferIndex += num; return text; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SkipStringValue() { if (UNSAFE_Read_1_Byte(out var value) && UNSAFE_Read_4_Int32(out var value2)) { if (value != 0) { value2 *= 2; } if (HasBufferData(value2)) { bufferIndex += value2; } else { bufferIndex = bufferEnd; } } } private void SkipPeekedEntryContent() { if (!peekedEntryType.HasValue) { return; } try { switch (peekedBinaryEntryType) { case BinaryEntryType.NamedStartOfReferenceNode: case BinaryEntryType.UnnamedStartOfReferenceNode: ReadTypeEntry(); if (SkipBuffer(4)) { } break; case BinaryEntryType.NamedStartOfStructNode: case BinaryEntryType.UnnamedStartOfStructNode: ReadTypeEntry(); break; case BinaryEntryType.StartOfArray: SkipBuffer(8); break; case BinaryEntryType.PrimitiveArray: { if (UNSAFE_Read_4_Int32(out var value) && UNSAFE_Read_4_Int32(out var value2)) { SkipBuffer(value * value2); } break; } case BinaryEntryType.NamedSByte: case BinaryEntryType.UnnamedSByte: case BinaryEntryType.NamedByte: case BinaryEntryType.UnnamedByte: case BinaryEntryType.NamedBoolean: case BinaryEntryType.UnnamedBoolean: SkipBuffer(1); break; case BinaryEntryType.NamedShort: case BinaryEntryType.UnnamedShort: case BinaryEntryType.NamedUShort: case BinaryEntryType.UnnamedUShort: case BinaryEntryType.NamedChar: case BinaryEntryType.UnnamedChar: SkipBuffer(2); break; case BinaryEntryType.NamedInternalReference: case BinaryEntryType.UnnamedInternalReference: case BinaryEntryType.NamedExternalReferenceByIndex: case BinaryEntryType.UnnamedExternalReferenceByIndex: case BinaryEntryType.NamedInt: case BinaryEntryType.UnnamedInt: case BinaryEntryType.NamedUInt: case BinaryEntryType.UnnamedUInt: case BinaryEntryType.NamedFloat: case BinaryEntryType.UnnamedFloat: SkipBuffer(4); break; case BinaryEntryType.NamedLong: case BinaryEntryType.UnnamedLong: case BinaryEntryType.NamedULong: case BinaryEntryType.UnnamedULong: case BinaryEntryType.NamedDouble: case BinaryEntryType.UnnamedDouble: SkipBuffer(8); break; case BinaryEntryType.NamedExternalReferenceByGuid: case BinaryEntryType.UnnamedExternalReferenceByGuid: case BinaryEntryType.NamedDecimal: case BinaryEntryType.UnnamedDecimal: case BinaryEntryType.NamedGuid: case BinaryEntryType.UnnamedGuid: SkipBuffer(8); break; case BinaryEntryType.NamedString: case BinaryEntryType.UnnamedString: case BinaryEntryType.NamedExternalReferenceByString: case BinaryEntryType.UnnamedExternalReferenceByString: SkipStringValue(); break; case BinaryEntryType.TypeName: base.Context.Config.DebugContext.LogError("Parsing error in binary data reader: should not be able to peek a TypeName entry."); SkipBuffer(4); ReadStringValue(); break; case BinaryEntryType.TypeID: base.Context.Config.DebugContext.LogError("Parsing error in binary data reader: should not be able to peek a TypeID entry."); SkipBuffer(4); break; case BinaryEntryType.Invalid: case BinaryEntryType.EndOfNode: case BinaryEntryType.EndOfArray: case BinaryEntryType.NamedNull: case BinaryEntryType.UnnamedNull: case BinaryEntryType.EndOfStream: break; } } finally { MarkEntryContentConsumed(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool SkipBuffer(int amount) { int num = bufferIndex + amount; if (num > bufferEnd) { bufferIndex = bufferEnd; return false; } bufferIndex = num; return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private Type ReadTypeEntry() { if (!HasBufferData(1)) { return null; } BinaryEntryType binaryEntryType = (BinaryEntryType)buffer[bufferIndex++]; int value2; Type value; switch (binaryEntryType) { case BinaryEntryType.TypeID: if (!UNSAFE_Read_4_Int32(out value2)) { return null; } if (!types.TryGetValue(value2, out value)) { base.Context.Config.DebugContext.LogError("Missing type ID during deserialization: " + value2 + " at node " + base.CurrentNodeName + " and depth " + base.CurrentNodeDepth + " and id " + base.CurrentNodeId); } break; case BinaryEntryType.TypeName: { if (!UNSAFE_Read_4_Int32(out value2)) { return null; } string text = ReadStringValue(); value = ((text == null) ? null : base.Context.Binder.BindToType(text, base.Context.Config.DebugContext)); types.Add(value2, value); break; } case BinaryEntryType.UnnamedNull: value = null; break; default: value = null; base.Context.Config.DebugContext.LogError("Expected TypeName, TypeID or UnnamedNull entry flag for reading type data, but instead got the entry flag: " + binaryEntryType.ToString() + "."); break; } return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void MarkEntryContentConsumed() { peekedEntryType = null; peekedEntryName = null; peekedBinaryEntryType = BinaryEntryType.Invalid; } protected override EntryType PeekEntry() { string name; return PeekEntry(out name); } protected override EntryType ReadToNextEntry() { SkipPeekedEntryContent(); string name; return PeekEntry(out name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool UNSAFE_Read_1_Byte(out byte value) { if (HasBufferData(1)) { value = buffer[bufferIndex++]; return true; } value = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool UNSAFE_Read_1_SByte(out sbyte value) { if (HasBufferData(1)) { value = (sbyte)buffer[bufferIndex++]; return true; } value = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_2_Int16(out short value) { if (HasBufferData(2)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { value = *(short*)(ptr + bufferIndex); } else { short num = 0; byte* ptr2 = (byte*)(&num) + 1; byte* ptr3 = ptr + bufferIndex; *(ptr2--) = *(ptr3++); *ptr2 = *ptr3; value = num; } } bufferIndex += 2; return true; } bufferIndex = bufferEnd; value = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_2_UInt16(out ushort value) { if (HasBufferData(2)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { value = *(ushort*)(ptr + bufferIndex); } else { ushort num = 0; byte* ptr2 = (byte*)(&num) + 1; byte* ptr3 = ptr + bufferIndex; *(ptr2--) = *(ptr3++); *ptr2 = *ptr3; value = num; } } bufferIndex += 2; return true; } bufferIndex = bufferEnd; value = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_2_Char(out char value) { if (HasBufferData(2)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { value = *(char*)(ptr + bufferIndex); } else { char c = '\0'; byte* ptr2 = (byte*)(&c) + 1; byte* ptr3 = ptr + bufferIndex; *(ptr2--) = *(ptr3++); *ptr2 = *ptr3; value = c; } } bufferIndex += 2; return true; } bufferIndex = bufferEnd; value = '\0'; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_4_Int32(out int value) { if (HasBufferData(4)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { value = *(int*)(ptr + bufferIndex); } else { int num = 0; byte* ptr2 = (byte*)(&num) + 3; byte* ptr3 = ptr + bufferIndex; *(ptr2--) = *(ptr3++); *(ptr2--) = *(ptr3++); *(ptr2--) = *(ptr3++); *ptr2 = *ptr3; value = num; } } bufferIndex += 4; return true; } bufferIndex = bufferEnd; value = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_4_UInt32(out uint value) { if (HasBufferData(4)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { value = *(uint*)(ptr + bufferIndex); } else { uint num = 0u; byte* ptr2 = (byte*)(&num) + 3; byte* ptr3 = ptr + bufferIndex; *(ptr2--) = *(ptr3++); *(ptr2--) = *(ptr3++); *(ptr2--) = *(ptr3++); *ptr2 = *ptr3; value = num; } } bufferIndex += 4; return true; } bufferIndex = bufferEnd; value = 0u; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_4_Float32(out float value) { if (HasBufferData(4)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_Unaligned_Float32_Reads) { value = *(float*)(ptr + bufferIndex); } else { float num = 0f; *(int*)(&num) = *(int*)(ptr + bufferIndex); value = num; } } else { float num2 = 0f; byte* ptr2 = (byte*)(&num2) + 3; byte* ptr3 = ptr + bufferIndex; *(ptr2--) = *(ptr3++); *(ptr2--) = *(ptr3++); *(ptr2--) = *(ptr3++); *ptr2 = *ptr3; value = num2; } } bufferIndex += 4; return true; } bufferIndex = bufferEnd; value = 0f; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_8_Int64(out long value) { if (HasBufferData(8)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { value = *(long*)(ptr + bufferIndex); } else { long num = 0L; int* ptr2 = (int*)(&num); int* ptr3 = (int*)(ptr + bufferIndex); *(ptr2++) = *(ptr3++); *ptr2 = *ptr3; value = num; } } else { long num2 = 0L; byte* ptr4 = (byte*)(&num2) + 7; byte* ptr5 = ptr + bufferIndex; *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *ptr4 = *ptr5; value = num2; } } bufferIndex += 8; return true; } bufferIndex = bufferEnd; value = 0L; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_8_UInt64(out ulong value) { if (HasBufferData(8)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { value = *(ulong*)(ptr + bufferIndex); } else { ulong num = 0uL; int* ptr2 = (int*)(&num); int* ptr3 = (int*)(ptr + bufferIndex); *(ptr2++) = *(ptr3++); *ptr2 = *ptr3; value = num; } } else { ulong num2 = 0uL; byte* ptr4 = (byte*)(&num2) + 7; byte* ptr5 = ptr + bufferIndex; *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *ptr4 = *ptr5; value = num2; } } bufferIndex += 8; return true; } bufferIndex = bufferEnd; value = 0uL; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_8_Float64(out double value) { if (HasBufferData(8)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { value = *(double*)(ptr + bufferIndex); } else { double num = 0.0; int* ptr2 = (int*)(&num); int* ptr3 = (int*)(ptr + bufferIndex); *(ptr2++) = *(ptr3++); *ptr2 = *ptr3; value = num; } } else { double num2 = 0.0; byte* ptr4 = (byte*)(&num2) + 7; byte* ptr5 = ptr + bufferIndex; *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *ptr4 = *ptr5; value = num2; } } bufferIndex += 8; return true; } bufferIndex = bufferEnd; value = 0.0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_16_Decimal(out decimal value) { if (HasBufferData(16)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { value = *(decimal*)(ptr + bufferIndex); } else { decimal num = default(decimal); int* ptr2 = (int*)(&num); int* ptr3 = (int*)(ptr + bufferIndex); *(ptr2++) = *(ptr3++); *(ptr2++) = *(ptr3++); *(ptr2++) = *(ptr3++); *ptr2 = *ptr3; value = num; } } else { decimal num2 = default(decimal); byte* ptr4 = (byte*)(&num2) + 15; byte* ptr5 = ptr + bufferIndex; *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *ptr4 = *ptr5; value = num2; } } bufferIndex += 16; return true; } bufferIndex = bufferEnd; value = default(decimal); return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool UNSAFE_Read_16_Guid(out Guid value) { if (HasBufferData(16)) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { value = *(Guid*)(ptr + bufferIndex); } else { Guid guid = default(Guid); int* ptr2 = (int*)(&guid); int* ptr3 = (int*)(ptr + bufferIndex); *(ptr2++) = *(ptr3++); *(ptr2++) = *(ptr3++); *(ptr2++) = *(ptr3++); *ptr2 = *ptr3; value = guid; } } else { Guid guid2 = default(Guid); byte* ptr4 = (byte*)(&guid2); byte* ptr5 = ptr + bufferIndex; *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *ptr4 = *(ptr5++); ptr4 += 6; *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *(ptr4--) = *(ptr5++); *ptr4 = *ptr5; value = guid2; } } bufferIndex += 16; return true; } bufferIndex = bufferEnd; value = default(Guid); return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool HasBufferData(int amount) { if (bufferEnd == 0) { ReadEntireStreamToBuffer(); } return bufferIndex + amount <= bufferEnd; } private void ReadEntireStreamToBuffer() { bufferIndex = 0; if (Stream is MemoryStream) { try { buffer = (Stream as MemoryStream).GetBuffer(); bufferEnd = (int)Stream.Length; bufferIndex = (int)Stream.Position; return; } catch (UnauthorizedAccessException) { } } buffer = internalBufferBackup; int num = (int)(Stream.Length - Stream.Position); if (buffer.Length >= num) { Stream.Read(buffer, 0, num); } else { buffer = new byte[num]; Stream.Read(buffer, 0, num); if (num <= 10485760) { internalBufferBackup = buffer; } } bufferIndex = 0; bufferEnd = num; } } public class BinaryDataWriter : BaseDataWriter { private struct Struct256Bit { public decimal d1; public decimal d2; } private static readonly Dictionary<Type, Delegate> PrimitiveGetBytesMethods = new Dictionary<Type, Delegate>(FastTypeComparer.Instance) { { typeof(char), (Action<byte[], int, char>)delegate(byte[] b, int i, char v) { ProperBitConverter.GetBytes(b, i, v); } }, { typeof(byte), (Action<byte[], int, byte>)delegate(byte[] b, int i, byte v) { b[i] = v; } }, { typeof(sbyte), (Action<byte[], int, sbyte>)delegate(byte[] b, int i, sbyte v) { b[i] = (byte)v; } }, { typeof(bool), (Action<byte[], int, bool>)delegate(byte[] b, int i, bool v) { b[i] = (v ? ((byte)1) : ((byte)0)); } }, { typeof(short), new Action<byte[], int, short>(ProperBitConverter.GetBytes) }, { typeof(int), new Action<byte[], int, int>(ProperBitConverter.GetBytes) }, { typeof(long), new Action<byte[], int, long>(ProperBitConverter.GetBytes) }, { typeof(ushort), new Action<byte[], int, ushort>(ProperBitConverter.GetBytes) }, { typeof(uint), new Action<byte[], int, uint>(ProperBitConverter.GetBytes) }, { typeof(ulong), new Action<byte[], int, ulong>(ProperBitConverter.GetBytes) }, { typeof(decimal), new Action<byte[], int, decimal>(ProperBitConverter.GetBytes) }, { typeof(float), new Action<byte[], int, float>(ProperBitConverter.GetBytes) }, { typeof(double), new Action<byte[], int, double>(ProperBitConverter.GetBytes) }, { typeof(Guid), new Action<byte[], int, Guid>(ProperBitConverter.GetBytes) } }; private static readonly Dictionary<Type, int> PrimitiveSizes = new Dictionary<Type, int>(FastTypeComparer.Instance) { { typeof(char), 2 }, { typeof(byte), 1 }, { typeof(sbyte), 1 }, { typeof(bool), 1 }, { typeof(short), 2 }, { typeof(int), 4 }, { typeof(long), 8 }, { typeof(ushort), 2 }, { typeof(uint), 4 }, { typeof(ulong), 8 }, { typeof(decimal), 16 }, { typeof(float), 4 }, { typeof(double), 8 }, { typeof(Guid), 16 } }; private readonly byte[] small_buffer = new byte[16]; private readonly byte[] buffer = new byte[102400]; private int bufferIndex; private readonly Dictionary<Type, int> types = new Dictionary<Type, int>(16, FastTypeComparer.Instance); public bool CompressStringsTo8BitWhenPossible; private static readonly Dictionary<Type, Action<BinaryDataWriter, object>> PrimitiveArrayWriters = new Dictionary<Type, Action<BinaryDataWriter, object>>(FastTypeComparer.Instance) { { typeof(char), WritePrimitiveArray_char }, { typeof(sbyte), WritePrimitiveArray_sbyte }, { typeof(short), WritePrimitiveArray_short }, { typeof(int), WritePrimitiveArray_int }, { typeof(long), WritePrimitiveArray_long }, { typeof(byte), WritePrimitiveArray_byte }, { typeof(ushort), WritePrimitiveArray_ushort }, { typeof(uint), WritePrimitiveArray_uint }, { typeof(ulong), WritePrimitiveArray_ulong }, { typeof(decimal), WritePrimitiveArray_decimal }, { typeof(bool), WritePrimitiveArray_bool }, { typeof(float), WritePrimitiveArray_float }, { typeof(double), WritePrimitiveArray_double }, { typeof(Guid), WritePrimitiveArray_Guid } }; public BinaryDataWriter() : base(null, null) { } public BinaryDataWriter(Stream stream, SerializationContext context) : base(stream, context) { } public override void BeginArrayNode(long length) { EnsureBufferSpace(9); buffer[bufferIndex++] = 6; UNSAFE_WriteToBuffer_8_Int64(length); PushArray(); } public override void BeginReferenceNode(string name, Type type, int id) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 1; WriteStringFast(name); } else { EnsureBufferSpace(1); buffer[bufferIndex++] = 2; } WriteType(type); EnsureBufferSpace(4); UNSAFE_WriteToBuffer_4_Int32(id); PushNode(name, id, type); } public override void BeginStructNode(string name, Type type) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 3; WriteStringFast(name); } else { EnsureBufferSpace(1); buffer[bufferIndex++] = 4; } WriteType(type); PushNode(name, -1, type); } public override void Dispose() { FlushToStream(); } public override void EndArrayNode() { PopArray(); EnsureBufferSpace(1); buffer[bufferIndex++] = 7; } public override void EndNode(string name) { PopNode(name); EnsureBufferSpace(1); buffer[bufferIndex++] = 5; } private static void WritePrimitiveArray_byte(BinaryDataWriter writer, object o) { byte[] array = o as byte[]; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(1); writer.FlushToStream(); writer.Stream.Write(array, 0, array.Length); } private unsafe static void WritePrimitiveArray_sbyte(BinaryDataWriter writer, object o) { sbyte[] array = o as sbyte[]; int num = 1; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { fixed (byte* ptr2 = writer.buffer) { fixed (sbyte* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_bool(BinaryDataWriter writer, object o) { bool[] array = o as bool[]; int num = 1; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { fixed (byte* ptr2 = writer.buffer) { fixed (bool* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_char(BinaryDataWriter writer, object o) { char[] array = o as char[]; int num = 2; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (char* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_2_Char(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_short(BinaryDataWriter writer, object o) { short[] array = o as short[]; int num = 2; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (short* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_2_Int16(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_int(BinaryDataWriter writer, object o) { int[] array = o as int[]; int num = 4; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (int* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_4_Int32(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_long(BinaryDataWriter writer, object o) { long[] array = o as long[]; int num = 8; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (long* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_8_Int64(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_ushort(BinaryDataWriter writer, object o) { ushort[] array = o as ushort[]; int num = 2; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (ushort* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_2_UInt16(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_uint(BinaryDataWriter writer, object o) { uint[] array = o as uint[]; int num = 4; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (uint* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_4_UInt32(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_ulong(BinaryDataWriter writer, object o) { ulong[] array = o as ulong[]; int num = 8; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (ulong* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_8_UInt64(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_decimal(BinaryDataWriter writer, object o) { decimal[] array = o as decimal[]; int num = 16; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (decimal* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_16_Decimal(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_float(BinaryDataWriter writer, object o) { float[] array = o as float[]; int num = 4; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (float* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_4_Float32(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_double(BinaryDataWriter writer, object o) { double[] array = o as double[]; int num = 8; int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (double* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_8_Float64(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } private unsafe static void WritePrimitiveArray_Guid(BinaryDataWriter writer, object o) { Guid[] array = o as Guid[]; int num = sizeof(Guid); int num2 = array.Length * num; writer.EnsureBufferSpace(9); writer.buffer[writer.bufferIndex++] = 8; writer.UNSAFE_WriteToBuffer_4_Int32(array.Length); writer.UNSAFE_WriteToBuffer_4_Int32(num); if (writer.TryEnsureBufferSpace(num2)) { if (BitConverter.IsLittleEndian) { fixed (byte* ptr2 = writer.buffer) { fixed (Guid* ptr = array) { void* from = ptr; void* to = ptr2 + writer.bufferIndex; UnsafeUtilities.MemoryCopy(from, to, num2); } } writer.bufferIndex += num2; } else { for (int i = 0; i < array.Length; i++) { writer.UNSAFE_WriteToBuffer_16_Guid(array[i]); } } return; } writer.FlushToStream(); using Buffer<byte> buffer = Buffer<byte>.Claim(num2); if (BitConverter.IsLittleEndian) { UnsafeUtilities.MemoryCopy(array, buffer.Array, num2, 0, 0); } else { byte[] array2 = buffer.Array; for (int j = 0; j < array.Length; j++) { ProperBitConverter.GetBytes(array2, j * num, array[j]); } } writer.Stream.Write(buffer.Array, 0, num2); } public override void WritePrimitiveArray<T>(T[] array) { if (!PrimitiveArrayWriters.TryGetValue(typeof(T), out var value)) { throw new ArgumentException("Type " + typeof(T).Name + " is not a valid primitive array type."); } value(this, array); } public override void WriteBoolean(string name, bool value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 43; WriteStringFast(name); EnsureBufferSpace(1); buffer[bufferIndex++] = (value ? ((byte)1) : ((byte)0)); } else { EnsureBufferSpace(2); buffer[bufferIndex++] = 44; buffer[bufferIndex++] = (value ? ((byte)1) : ((byte)0)); } } public override void WriteByte(string name, byte value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 17; WriteStringFast(name); EnsureBufferSpace(1); buffer[bufferIndex++] = value; } else { EnsureBufferSpace(2); buffer[bufferIndex++] = 18; buffer[bufferIndex++] = value; } } public override void WriteChar(string name, char value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 37; WriteStringFast(name); EnsureBufferSpace(2); UNSAFE_WriteToBuffer_2_Char(value); } else { EnsureBufferSpace(3); buffer[bufferIndex++] = 38; UNSAFE_WriteToBuffer_2_Char(value); } } public override void WriteDecimal(string name, decimal value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 35; WriteStringFast(name); EnsureBufferSpace(16); UNSAFE_WriteToBuffer_16_Decimal(value); } else { EnsureBufferSpace(17); buffer[bufferIndex++] = 36; UNSAFE_WriteToBuffer_16_Decimal(value); } } public override void WriteDouble(string name, double value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 33; WriteStringFast(name); EnsureBufferSpace(8); UNSAFE_WriteToBuffer_8_Float64(value); } else { EnsureBufferSpace(9); buffer[bufferIndex++] = 34; UNSAFE_WriteToBuffer_8_Float64(value); } } public override void WriteGuid(string name, Guid value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 41; WriteStringFast(name); EnsureBufferSpace(16); UNSAFE_WriteToBuffer_16_Guid(value); } else { EnsureBufferSpace(17); buffer[bufferIndex++] = 42; UNSAFE_WriteToBuffer_16_Guid(value); } } public override void WriteExternalReference(string name, Guid guid) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 13; WriteStringFast(name); EnsureBufferSpace(16); UNSAFE_WriteToBuffer_16_Guid(guid); } else { EnsureBufferSpace(17); buffer[bufferIndex++] = 14; UNSAFE_WriteToBuffer_16_Guid(guid); } } public override void WriteExternalReference(string name, int index) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 11; WriteStringFast(name); EnsureBufferSpace(4); UNSAFE_WriteToBuffer_4_Int32(index); } else { EnsureBufferSpace(5); buffer[bufferIndex++] = 12; UNSAFE_WriteToBuffer_4_Int32(index); } } public override void WriteExternalReference(string name, string id) { if (id == null) { throw new ArgumentNullException("id"); } if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 50; WriteStringFast(name); } else { EnsureBufferSpace(1); buffer[bufferIndex++] = 51; } WriteStringFast(id); } public override void WriteInt32(string name, int value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 23; WriteStringFast(name); EnsureBufferSpace(4); UNSAFE_WriteToBuffer_4_Int32(value); } else { EnsureBufferSpace(5); buffer[bufferIndex++] = 24; UNSAFE_WriteToBuffer_4_Int32(value); } } public override void WriteInt64(string name, long value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 27; WriteStringFast(name); EnsureBufferSpace(8); UNSAFE_WriteToBuffer_8_Int64(value); } else { EnsureBufferSpace(9); buffer[bufferIndex++] = 28; UNSAFE_WriteToBuffer_8_Int64(value); } } public override void WriteNull(string name) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 45; WriteStringFast(name); } else { EnsureBufferSpace(1); buffer[bufferIndex++] = 46; } } public override void WriteInternalReference(string name, int id) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 9; WriteStringFast(name); EnsureBufferSpace(4); UNSAFE_WriteToBuffer_4_Int32(id); } else { EnsureBufferSpace(5); buffer[bufferIndex++] = 10; UNSAFE_WriteToBuffer_4_Int32(id); } } public override void WriteSByte(string name, sbyte value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 15; WriteStringFast(name); EnsureBufferSpace(1); buffer[bufferIndex++] = (byte)value; } else { EnsureBufferSpace(2); buffer[bufferIndex++] = 16; buffer[bufferIndex++] = (byte)value; } } public override void WriteInt16(string name, short value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 19; WriteStringFast(name); EnsureBufferSpace(2); UNSAFE_WriteToBuffer_2_Int16(value); } else { EnsureBufferSpace(3); buffer[bufferIndex++] = 20; UNSAFE_WriteToBuffer_2_Int16(value); } } public override void WriteSingle(string name, float value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 31; WriteStringFast(name); EnsureBufferSpace(4); UNSAFE_WriteToBuffer_4_Float32(value); } else { EnsureBufferSpace(5); buffer[bufferIndex++] = 32; UNSAFE_WriteToBuffer_4_Float32(value); } } public override void WriteString(string name, string value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 39; WriteStringFast(name); } else { EnsureBufferSpace(1); buffer[bufferIndex++] = 40; } WriteStringFast(value); } public override void WriteUInt32(string name, uint value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 25; WriteStringFast(name); EnsureBufferSpace(4); UNSAFE_WriteToBuffer_4_UInt32(value); } else { EnsureBufferSpace(5); buffer[bufferIndex++] = 26; UNSAFE_WriteToBuffer_4_UInt32(value); } } public override void WriteUInt64(string name, ulong value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 29; WriteStringFast(name); EnsureBufferSpace(8); UNSAFE_WriteToBuffer_8_UInt64(value); } else { EnsureBufferSpace(9); buffer[bufferIndex++] = 30; UNSAFE_WriteToBuffer_8_UInt64(value); } } public override void WriteUInt16(string name, ushort value) { if (name != null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 21; WriteStringFast(name); EnsureBufferSpace(2); UNSAFE_WriteToBuffer_2_UInt16(value); } else { EnsureBufferSpace(3); buffer[bufferIndex++] = 22; UNSAFE_WriteToBuffer_2_UInt16(value); } } public override void PrepareNewSerializationSession() { base.PrepareNewSerializationSession(); types.Clear(); bufferIndex = 0; } public override string GetDataDump() { if (!Stream.CanRead) { return "Binary data stream for writing cannot be read; cannot dump data."; } if (!Stream.CanSeek) { return "Binary data stream cannot seek; cannot dump data."; } FlushToStream(); long position = Stream.Position; byte[] bytes = new byte[position]; Stream.Position = 0L; Stream.Read(bytes, 0, (int)position); Stream.Position = position; return "Binary hex dump: " + ProperBitConverter.BytesToHexString(bytes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void WriteType(Type type) { if (type == null) { EnsureBufferSpace(1); buffer[bufferIndex++] = 46; return; } if (types.TryGetValue(type, out var value)) { EnsureBufferSpace(5); buffer[bufferIndex++] = 48; UNSAFE_WriteToBuffer_4_Int32(value); return; } value = types.Count; types.Add(type, value); EnsureBufferSpace(5); buffer[bufferIndex++] = 47; UNSAFE_WriteToBuffer_4_Int32(value); WriteStringFast(base.Context.Binder.BindToName(type, base.Context.Config.DebugContext)); } private unsafe void WriteStringFast(string value) { bool flag = true; if (CompressStringsTo8BitWhenPossible) { flag = false; for (int i = 0; i < value.Length; i++) { if (value[i] > 'ÿ') { flag = true; break; } } } int num; if (flag) { num = value.Length * 2; if (TryEnsureBufferSpace(num + 5)) { this.buffer[bufferIndex++] = 1; UNSAFE_WriteToBuffer_4_Int32(value.Length); if (BitConverter.IsLittleEndian) { fixed (byte* ptr = this.buffer) { fixed (char* ptr3 = value) { Struct256Bit* ptr2 = (Struct256Bit*)(ptr + bufferIndex); Struct256Bit* ptr4 = (Struct256Bit*)ptr3; byte* ptr5 = (byte*)ptr2 + num; while (ptr2 + 1 <= ptr5) { *(ptr2++) = *(ptr4++); } char* ptr6 = (char*)ptr2; char* ptr7 = (char*)ptr4; while (ptr6 < ptr5) { *(ptr6++) = *(ptr7++); } } } } else { fixed (byte* ptr8 = this.buffer) { fixed (char* ptr10 = value) { byte* ptr9 = ptr8 + bufferIndex; byte* ptr11 = (byte*)ptr10; for (int j = 0; j < num; j += 2) { *ptr9 = ptr11[1]; ptr9[1] = *ptr11; ptr11 += 2; ptr9 += 2; } } } } bufferIndex += num; return; } FlushToStream(); Stream.WriteByte(1); ProperBitConverter.GetBytes(small_buffer, 0, value.Length); Stream.Write(small_buffer, 0, 4); using Buffer<byte> buffer = Buffer<byte>.Claim(num); byte[] array = buffer.Array; UnsafeUtilities.StringToBytes(array, value, needs16BitSupport: true); Stream.Write(array, 0, num); return; } num = value.Length; if (TryEnsureBufferSpace(num + 5)) { this.buffer[bufferIndex++] = 0; UNSAFE_WriteToBuffer_4_Int32(value.Length); for (int k = 0; k < num; k++) { this.buffer[bufferIndex++] = (byte)value[k]; } return; } FlushToStream(); Stream.WriteByte(0); ProperBitConverter.GetBytes(small_buffer, 0, value.Length); Stream.Write(small_buffer, 0, 4); using Buffer<byte> buffer2 = Buffer<byte>.Claim(value.Length); byte[] array2 = buffer2.Array; for (int l = 0; l < value.Length; l++) { array2[l] = (byte)value[l]; } Stream.Write(array2, 0, value.Length); } public override void FlushToStream() { if (bufferIndex > 0) { Stream.Write(buffer, 0, bufferIndex); bufferIndex = 0; } base.FlushToStream(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_2_Char(char value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { *(char*)(ptr + bufferIndex) = value; } else { byte* ptr2 = ptr + bufferIndex; byte* ptr3 = (byte*)(&value) + 1; *(ptr2++) = *(ptr3--); *ptr2 = *ptr3; } } bufferIndex += 2; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_2_Int16(short value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { *(short*)(ptr + bufferIndex) = value; } else { byte* ptr2 = ptr + bufferIndex; byte* ptr3 = (byte*)(&value) + 1; *(ptr2++) = *(ptr3--); *ptr2 = *ptr3; } } bufferIndex += 2; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_2_UInt16(ushort value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { *(ushort*)(ptr + bufferIndex) = value; } else { byte* ptr2 = ptr + bufferIndex; byte* ptr3 = (byte*)(&value) + 1; *(ptr2++) = *(ptr3--); *ptr2 = *ptr3; } } bufferIndex += 2; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_4_Int32(int value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { *(int*)(ptr + bufferIndex) = value; } else { byte* ptr2 = ptr + bufferIndex; byte* ptr3 = (byte*)(&value) + 3; *(ptr2++) = *(ptr3--); *(ptr2++) = *(ptr3--); *(ptr2++) = *(ptr3--); *ptr2 = *ptr3; } } bufferIndex += 4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_4_UInt32(uint value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { *(uint*)(ptr + bufferIndex) = value; } else { byte* ptr2 = ptr + bufferIndex; byte* ptr3 = (byte*)(&value) + 3; *(ptr2++) = *(ptr3--); *(ptr2++) = *(ptr3--); *(ptr2++) = *(ptr3--); *ptr2 = *ptr3; } } bufferIndex += 4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_4_Float32(float value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { *(float*)(ptr + bufferIndex) = value; } else { byte* ptr2 = (byte*)(&value); byte* ptr3 = ptr + bufferIndex; *(ptr3++) = *(ptr2++); *(ptr3++) = *(ptr2++); *(ptr3++) = *(ptr2++); *ptr3 = *ptr2; } } else { byte* ptr4 = ptr + bufferIndex; byte* ptr5 = (byte*)(&value) + 3; *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *ptr4 = *ptr5; } } bufferIndex += 4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_8_Int64(long value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { *(long*)(ptr + bufferIndex) = value; } else { int* ptr2 = (int*)(&value); int* ptr3 = (int*)(ptr + bufferIndex); *(ptr3++) = *(ptr2++); *ptr3 = *ptr2; } } else { byte* ptr4 = ptr + bufferIndex; byte* ptr5 = (byte*)(&value) + 7; *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *ptr4 = *ptr5; } } bufferIndex += 8; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_8_UInt64(ulong value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { *(ulong*)(ptr + bufferIndex) = value; } else { int* ptr2 = (int*)(&value); int* ptr3 = (int*)(ptr + bufferIndex); *(ptr3++) = *(ptr2++); *ptr3 = *ptr2; } } else { byte* ptr4 = ptr + bufferIndex; byte* ptr5 = (byte*)(&value) + 7; *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *ptr4 = *ptr5; } } bufferIndex += 8; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_8_Float64(double value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { *(double*)(ptr + bufferIndex) = value; } else { int* ptr2 = (int*)(&value); int* ptr3 = (int*)(ptr + bufferIndex); *(ptr3++) = *(ptr2++); *ptr3 = *ptr2; } } else { byte* ptr4 = ptr + bufferIndex; byte* ptr5 = (byte*)(&value) + 7; *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *ptr4 = *ptr5; } } bufferIndex += 8; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_16_Decimal(decimal value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { *(decimal*)(ptr + bufferIndex) = value; } else { int* ptr2 = (int*)(&value); int* ptr3 = (int*)(ptr + bufferIndex); *(ptr3++) = *(ptr2++); *(ptr3++) = *(ptr2++); *(ptr3++) = *(ptr2++); *ptr3 = *ptr2; } } else { byte* ptr4 = ptr + bufferIndex; byte* ptr5 = (byte*)(&value) + 15; *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *ptr4 = *ptr5; } } bufferIndex += 16; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe void UNSAFE_WriteToBuffer_16_Guid(Guid value) { fixed (byte* ptr = buffer) { if (BitConverter.IsLittleEndian) { if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites) { *(Guid*)(ptr + bufferIndex) = value; } else { int* ptr2 = (int*)(&value); int* ptr3 = (int*)(ptr + bufferIndex); *(ptr3++) = *(ptr2++); *(ptr3++) = *(ptr2++); *(ptr3++) = *(ptr2++); *ptr3 = *ptr2; } } else { byte* ptr4 = ptr + bufferIndex; byte* ptr5 = (byte*)(&value); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *(ptr5++); *(ptr4++) = *ptr5; ptr5 += 6; *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *(ptr4++) = *(ptr5--); *ptr4 = *ptr5; } } bufferIndex += 16; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void EnsureBufferSpace(int space) { int num = buffer.Length; if (space > num) { throw new Exception("Insufficient buffer capacity"); }