Decompiled source of RPCPlugin v2.2.2
RPCPlugin.dll
Decompiled 4 months agousing System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Logging; using Bounce.ManagedCollections; using Bounce.Unmanaged; using DataModel; using HarmonyLib; using Photon; using RPCPlugin.Interfaces; using RPCPlugin.RPC; using Talespire; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("RForRotatePlugin")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("D20ArmyKnife")] [assembly: AssemblyProduct("RForRotatePlugin")] [assembly: AssemblyCopyright("Copyright © 2020")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4e4deb5e-97f9-4901-bf67-6748a9c1229a")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace RPCPlugin { [BepInPlugin("org.hollofox.plugins.rpc", "HolloFoxes' RPC Plug-In", "2.2.1.0")] public class RPCPlugin : BaseUnityPlugin { public const string Name = "HolloFoxes' RPC Plug-In"; public const string Guid = "org.hollofox.plugins.rpc"; public const string Version = "2.2.1.0"; internal static ManualLogSource InternalLogger; private bool _registerSingletons = true; public void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown InternalLogger = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Logger.LogInfo((object)"In Awake for HolloFoxes' RPC Plug-In"); Harmony val = new Harmony("org.hollofox.plugins.rpc"); val.PatchAll(); } public void Update() { if (_registerSingletons) { InitOnLoad.Initialise(); _registerSingletons = false; } if ((Object)(object)RPCInstance.Instance == (Object)null && PhotonNetwork.inRoom) { RPCInstance.Init(); } } } } namespace RPCPlugin.RPC { public sealed class RPCInstance : PunBehaviour { internal static Dictionary<string, Func<string, string, SourceRole, string>> Handlers = new Dictionary<string, Func<string, string, SourceRole, string>>(); internal static RPCInstance Instance; internal static PhotonView View; internal static BList<HideVolumeItem> hideVolumes; internal static Dictionary<Guid, IBinaryFactory> Binaries = new Dictionary<Guid, IBinaryFactory>(); internal static Dictionary<string, byte[]> Ids = new Dictionary<string, byte[]>(); public static void Init() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (!((Object)(object)Instance != (Object)null)) { GameObject val = Object.Instantiate<GameObject>(new GameObject()); Instance = val.AddComponent<RPCInstance>(); View = val.AddComponent<PhotonView>(); View.viewID = 606; } } public static void SendMessage(string message, NGuid thingThatIsTalking) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) RPCPlugin.InternalLogger.LogDebug((object)$"message: {message}, thingThatIsTalking: {thingThatIsTalking}"); PhotonView view = View; SourceRole val = (SourceRole)888; PlayerInfo value; CreatureBoardAsset val2 = default(CreatureBoardAsset); if (message.Contains("ANONYMOUS", StringComparison.OrdinalIgnoreCase)) { val = (SourceRole)999; } else if (CampaignSessionManager.PlayersInfo.TryGetValue(new PlayerGuid(thingThatIsTalking), out value)) { val = (SourceRole)((!value.Rights.CanGm) ? 1 : 0); } else if (CreaturePresenter.TryGetAsset(new CreatureGuid(thingThatIsTalking), ref val2)) { val = (SourceRole)2; } else if (hideVolumes.ToArray().Any((HideVolumeItem hv) => hv.HideVolume.Id == thingThatIsTalking)) { val = (SourceRole)3; } view.RPC("ReceivedMessage", (PhotonTargets)0, new object[3] { message, ((object)(NGuid)(ref thingThatIsTalking)).ToString(), val }); } [PunRPC] public void ReceivedMessage(string message, string thingThatIsTalking, SourceRole chatSource) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<string, Func<string, string, SourceRole, string>> handler in Handlers) { RPCPlugin.InternalLogger.LogDebug((object)("RPC Plugin: ParseMessage: Found Handler '" + handler.Key + "'")); if (message.StartsWith(handler.Key)) { RPCPlugin.InternalLogger.LogDebug((object)("RPC: ParseMessage: Applying Handler '" + handler.Key + "'")); try { message = handler.Value(message, thingThatIsTalking, chatSource); } catch (Exception ex) { RPCPlugin.InternalLogger.LogWarning((object)("RPC Plugin: ParseMessage: Exception In Handler: " + ex.Message)); RPCPlugin.InternalLogger.LogError((object)ex); message = ""; } RPCPlugin.InternalLogger.LogDebug((object)("RPC Plugin: ParseMessage: Post Handler: Title = '" + Convert.ToString(thingThatIsTalking) + "' Message = '" + Convert.ToString(message) + "'")); if (message != null && !(message.Trim() == "")) { } break; } } } public static void SendMessage(RpcMessage rpcMessage, PhotonTargets targets = 0) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)View != (Object)null) { View.RPC("ReceivedBinaryMessage", targets, new object[2] { rpcMessage.Id(), rpcMessage.Value() }); } } [PunRPC] public void ReceivedBinaryMessage(byte[] bid, byte[] message) { Guid guid = new Guid(bid); if (!Binaries.ContainsKey(guid)) { RPCPlugin.InternalLogger.LogDebug((object)$"RPC Key not found: {guid}"); } else { Binaries[guid].Handle(message); } } } public static class RPCManager { public static void AddHandler(string key, Func<string, string, SourceRole, string> callback) { RPCInstance.Handlers.Add(key, callback); } public static void RemoveHandler(string key) { RPCInstance.Handlers.Remove(key); } public static void SendMessage(string message, NGuid source) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) RPCPlugin.InternalLogger.LogDebug((object)("RPCManager: Sending " + message + " (signature " + ((object)(NGuid)(ref source)).ToString() + ")")); RPCInstance.SendMessage(message, source); } } } namespace RPCPlugin.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { ResourceManager resourceManager = new ResourceManager("RPCPlugin.Properties.Resources", typeof(Resources).Assembly); resourceMan = resourceManager; } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal Resources() { } } } namespace RPCPlugin.Patches { [HarmonyPatch(typeof(HideVolumeManager), "OnHideVolumeAdded")] internal class HVMAddPatch { public static void Postfix(ref HideVolume volume, ref BList<HideVolumeItem> ____hideVolumeItems) { RPCInstance.hideVolumes = ____hideVolumeItems; } } [HarmonyPatch(typeof(HideVolumeManager), "OnHideVolumeRemoved")] internal class HVMRemovePatch { public static void Postfix(ref HideVolume volume, ref BList<HideVolumeItem> ____hideVolumeItems) { RPCInstance.hideVolumes = ____hideVolumeItems; } } } namespace RPCPlugin.Interfaces { public abstract class RpcConsumer<T> : IBinaryFactory where T : RpcMessage, new() { private static readonly Lazy<RpcConsumer<T>> Lazy = new Lazy<RpcConsumer<T>>(() => Activator.CreateInstance(typeof(RpcConsumer<T>), nonPublic: true) as RpcConsumer<T>); public static RpcConsumer<T> Instance => Lazy.Value; public abstract void Handle(T message); public void Handle(byte[] data) { T message = (T)Activator.CreateInstance(typeof(T), data); Handle(message); } public virtual void SendMessage(T message, PhotonTargets targets = 0) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) RPCInstance.SendMessage(message, targets); } protected RpcConsumer() { string assemblyQualifiedName = typeof(T).AssemblyQualifiedName; Guid guid = new Guid(RpcMessage.CreateMD5(assemblyQualifiedName)); RPCInstance.Binaries.Add(guid, this); RPCPlugin.InternalLogger.LogDebug((object)$"Registered assembly: {guid} {assemblyQualifiedName}"); } } public abstract class RpcMessage : IBinaryMessage { public abstract byte[] Value(); public byte[] Id() { string assemblyQualifiedName = GetType().AssemblyQualifiedName; if (!RPCInstance.Ids.ContainsKey(assemblyQualifiedName)) { RPCInstance.Ids[assemblyQualifiedName] = CreateMD5(assemblyQualifiedName); } return RPCInstance.Ids[assemblyQualifiedName]; } public static byte[] CreateMD5(string input) { using MD5 mD = MD5.Create(); byte[] bytes = Encoding.ASCII.GetBytes(input); return mD.ComputeHash(bytes); } } public interface IBinaryMessage { byte[] Value(); } public interface IBinaryFactory { void Handle(byte[] message); } public class InitOnLoad : Attribute { public static void Initialise() { IEnumerable<Type> enumerable = from t in AppDomain.CurrentDomain.GetAssemblies().SelectMany((Assembly a) => a.GetTypes()) where t.GetCustomAttributes(typeof(InitOnLoad), inherit: false).Any() select t; foreach (Type type in enumerable) { FieldInfo fieldInfo = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((FieldInfo f) => f.FieldType == type); if (fieldInfo != null) { fieldInfo.GetValue(null); } } } } }
ZeroFormatter.Interfaces.dll
Decompiled 4 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ZeroFormatter.Interfaces")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ZeroFormatter.Interfaces")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("c051f473-427f-4062-94fb-cae3fa460fc8")] [assembly: AssemblyFileVersion("1.6.4.0")] [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] [assembly: AssemblyVersion("1.6.4.0")] namespace ZeroFormatter; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)] public class ZeroFormattableAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] public class IndexAttribute : Attribute { public int Index { get; private set; } public IndexAttribute(int index) { Index = index; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] public class IgnoreFormatAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] public class UnionAttribute : Attribute { public Type[] SubTypes { get; private set; } public Type FallbackType { get; private set; } public UnionAttribute(params Type[] subTypes) { SubTypes = subTypes; } public UnionAttribute(Type[] subTypes, Type fallbackType) { SubTypes = subTypes; FallbackType = fallbackType; } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class UnionKeyAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] public class DynamicUnionAttribute : Attribute { } public sealed class PreserveAttribute : Attribute { public bool AllMembers; public bool Conditional; } public interface ILazyDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable { } public interface ILazyLookup<TKey, TElement> : ILookup<TKey, TElement>, IEnumerable<IGrouping<TKey, TElement>>, IEnumerable { } public interface ILazyReadOnlyDictionary<TKey, TValue> : IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable { } public static class LazyCollectionExtensions { internal class DelegateDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, ILazyDictionary<TKey, TValue>, ILazyReadOnlyDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>> { private readonly IDictionary<TKey, TValue> dictionary; public TValue this[TKey key] { get { return dictionary[key]; } set { dictionary[key] = value; } } public int Count => dictionary.Count; public bool IsReadOnly => dictionary.IsReadOnly; public ICollection<TKey> Keys => dictionary.Keys; public ICollection<TValue> Values => dictionary.Values; IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys => dictionary.Keys; IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values => dictionary.Values; public DelegateDictionary(IDictionary<TKey, TValue> dictionary) { this.dictionary = dictionary; } public void Add(KeyValuePair<TKey, TValue> item) { dictionary.Add(item); } public void Add(TKey key, TValue value) { dictionary.Add(key, value); } public void Clear() { dictionary.Clear(); } public bool Contains(KeyValuePair<TKey, TValue> item) { return dictionary.Contains(item); } public bool ContainsKey(TKey key) { return dictionary.ContainsKey(key); } public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { dictionary.CopyTo(array, arrayIndex); } public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return dictionary.GetEnumerator(); } public bool Remove(KeyValuePair<TKey, TValue> item) { return dictionary.Remove(item); } public bool Remove(TKey key) { return dictionary.Remove(key); } public bool TryGetValue(TKey key, out TValue value) { return dictionary.TryGetValue(key, out value); } IEnumerator IEnumerable.GetEnumerator() { return dictionary.GetEnumerator(); } } internal class DelegateLookup<TKey, TElement> : ILookup<TKey, TElement>, IEnumerable<IGrouping<TKey, TElement>>, IEnumerable, ILazyLookup<TKey, TElement> { private readonly ILookup<TKey, TElement> lookup; public IEnumerable<TElement> this[TKey key] => lookup[key]; public int Count => lookup.Count; public DelegateLookup(ILookup<TKey, TElement> lookup) { this.lookup = lookup; } public bool Contains(TKey key) { return lookup.Contains(key); } public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator() { return lookup.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return lookup.GetEnumerator(); } } public static ILazyDictionary<TKey, TValue> AsLazyDictionary<TKey, TValue>(this IDictionary<TKey, TValue> dict) { return new DelegateDictionary<TKey, TValue>(dict); } public static ILazyReadOnlyDictionary<TKey, TValue> AsLazyReadOnlyDictionary<TKey, TValue>(this IDictionary<TKey, TValue> dict) { return new DelegateDictionary<TKey, TValue>(dict); } public static ILazyLookup<TKey, TElement> AsLazyLookup<TKey, TElement>(this ILookup<TKey, TElement> lookup) { return new DelegateLookup<TKey, TElement>(lookup); } } public interface IKeyTuple { new string ToString(); } public static class KeyTuple { public static KeyTuple<T1, T2, T3, T4, T5, T6, T7, KeyTuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) { return new KeyTuple<T1, T2, T3, T4, T5, T6, T7, KeyTuple<T8>>(item1, item2, item3, item4, item5, item6, item7, new KeyTuple<T8>(item8)); } public static KeyTuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { return new KeyTuple<T1, T2, T3, T4, T5, T6, T7>(item1, item2, item3, item4, item5, item6, item7); } public static KeyTuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { return new KeyTuple<T1, T2, T3, T4, T5, T6>(item1, item2, item3, item4, item5, item6); } public static KeyTuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { return new KeyTuple<T1, T2, T3, T4, T5>(item1, item2, item3, item4, item5); } public static KeyTuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4) { return new KeyTuple<T1, T2, T3, T4>(item1, item2, item3, item4); } public static KeyTuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3) { return new KeyTuple<T1, T2, T3>(item1, item2, item3); } public static KeyTuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2) { return new KeyTuple<T1, T2>(item1, item2); } public static KeyTuple<T1> Create<T1>(T1 item1) { return new KeyTuple<T1>(item1); } } public struct KeyTuple<T1> : IKeyTuple { private T1 item1; public T1 Item1 => item1; public KeyTuple(T1 item1) { this.item1 = item1; } string IKeyTuple.ToString() { return $"{item1}"; } public override string ToString() { return "(" + ((IKeyTuple)this).ToString() + ")"; } } public struct KeyTuple<T1, T2> : IKeyTuple { private T1 item1; private T2 item2; public T1 Item1 => item1; public T2 Item2 => item2; public KeyTuple(T1 item1, T2 item2) { this.item1 = item1; this.item2 = item2; } string IKeyTuple.ToString() { return $"{item1}, {item2}"; } public override string ToString() { return "(" + ((IKeyTuple)this).ToString() + ")"; } } public struct KeyTuple<T1, T2, T3> : IKeyTuple { private T1 item1; private T2 item2; private T3 item3; public T1 Item1 => item1; public T2 Item2 => item2; public T3 Item3 => item3; public KeyTuple(T1 item1, T2 item2, T3 item3) { this.item1 = item1; this.item2 = item2; this.item3 = item3; } string IKeyTuple.ToString() { return $"{item1}, {item2}, {item3}"; } public override string ToString() { return "(" + ((IKeyTuple)this).ToString() + ")"; } } public struct KeyTuple<T1, T2, T3, T4> : IKeyTuple { private T1 item1; private T2 item2; private T3 item3; private T4 item4; public T1 Item1 => item1; public T2 Item2 => item2; public T3 Item3 => item3; public T4 Item4 => item4; public KeyTuple(T1 item1, T2 item2, T3 item3, T4 item4) { this.item1 = item1; this.item2 = item2; this.item3 = item3; this.item4 = item4; } string IKeyTuple.ToString() { return $"{item1}, {item2}, {item3}, {item4}"; } public override string ToString() { return "(" + ((IKeyTuple)this).ToString() + ")"; } } public struct KeyTuple<T1, T2, T3, T4, T5> : IKeyTuple { private T1 item1; private T2 item2; private T3 item3; private T4 item4; private T5 item5; public T1 Item1 => item1; public T2 Item2 => item2; public T3 Item3 => item3; public T4 Item4 => item4; public T5 Item5 => item5; public KeyTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { this.item1 = item1; this.item2 = item2; this.item3 = item3; this.item4 = item4; this.item5 = item5; } string IKeyTuple.ToString() { return $"{item1}, {item2}, {item3}, {item4}, {item5}"; } public override string ToString() { return "(" + ((IKeyTuple)this).ToString() + ")"; } } public struct KeyTuple<T1, T2, T3, T4, T5, T6> : IKeyTuple { private T1 item1; private T2 item2; private T3 item3; private T4 item4; private T5 item5; private T6 item6; public T1 Item1 => item1; public T2 Item2 => item2; public T3 Item3 => item3; public T4 Item4 => item4; public T5 Item5 => item5; public T6 Item6 => item6; public KeyTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { this.item1 = item1; this.item2 = item2; this.item3 = item3; this.item4 = item4; this.item5 = item5; this.item6 = item6; } string IKeyTuple.ToString() { return $"{item1}, {item2}, {item3}, {item4}, {item5}, {item6}"; } public override string ToString() { return "(" + ((IKeyTuple)this).ToString() + ")"; } } public struct KeyTuple<T1, T2, T3, T4, T5, T6, T7> : IKeyTuple { private T1 item1; private T2 item2; private T3 item3; private T4 item4; private T5 item5; private T6 item6; private T7 item7; public T1 Item1 => item1; public T2 Item2 => item2; public T3 Item3 => item3; public T4 Item4 => item4; public T5 Item5 => item5; public T6 Item6 => item6; public T7 Item7 => item7; public KeyTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { this.item1 = item1; this.item2 = item2; this.item3 = item3; this.item4 = item4; this.item5 = item5; this.item6 = item6; this.item7 = item7; } string IKeyTuple.ToString() { return $"{item1}, {item2}, {item3}, {item4}, {item5}, {item6}, {item7}"; } public override string ToString() { return "(" + ((IKeyTuple)this).ToString() + ")"; } } public struct KeyTuple<T1, T2, T3, T4, T5, T6, T7, TRest> : IKeyTuple { private T1 item1; private T2 item2; private T3 item3; private T4 item4; private T5 item5; private T6 item6; private T7 item7; private TRest rest; public T1 Item1 => item1; public T2 Item2 => item2; public T3 Item3 => item3; public T4 Item4 => item4; public T5 Item5 => item5; public T6 Item6 => item6; public T7 Item7 => item7; public TRest Rest => rest; public KeyTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) { this.item1 = item1; this.item2 = item2; this.item3 = item3; this.item4 = item4; this.item5 = item5; this.item6 = item6; this.item7 = item7; this.rest = rest; if (!(rest is IKeyTuple)) { throw new ArgumentException("rest", "The last element of an eight element tuple must be a Tuple."); } } string IKeyTuple.ToString() { return $"{item1}, {item2}, {item3}, {item4}, {item5}, {item6}, {item7}, {((IKeyTuple)(object)rest).ToString()}"; } public override string ToString() { return "(" + ((IKeyTuple)this).ToString() + ")"; } } public static class KeyTupleExtensions { public static IEnumerable<TValue> Get<TKey1, TKey2, TValue>(this ILookup<KeyTuple<TKey1, TKey2>, TValue> lookup, TKey1 tKey1, TKey2 tKey2) { return lookup[KeyTuple.Create(tKey1, tKey2)]; } public static IEnumerable<TValue> Get<TKey1, TKey2, TKey3, TValue>(this ILookup<KeyTuple<TKey1, TKey2, TKey3>, TValue> lookup, TKey1 tKey1, TKey2 tKey2, TKey3 tKey3) { return lookup[KeyTuple.Create(tKey1, tKey2, tKey3)]; } public static IEnumerable<TValue> Get<TKey1, TKey2, TKey3, TKey4, TValue>(this ILookup<KeyTuple<TKey1, TKey2, TKey3, TKey4>, TValue> lookup, TKey1 tKey1, TKey2 tKey2, TKey3 tKey3, TKey4 tKey4) { return lookup[KeyTuple.Create(tKey1, tKey2, tKey3, tKey4)]; } public static IEnumerable<TValue> Get<TKey1, TKey2, TKey3, TKey4, TKey5, TValue>(this ILookup<KeyTuple<TKey1, TKey2, TKey3, TKey4, TKey5>, TValue> lookup, TKey1 tKey1, TKey2 tKey2, TKey3 tKey3, TKey4 tKey4, TKey5 tKey5) { return lookup[KeyTuple.Create(tKey1, tKey2, tKey3, tKey4, tKey5)]; } public static IEnumerable<TValue> Get<TKey1, TKey2, TKey3, TKey4, TKey5, TKey6, TValue>(this ILookup<KeyTuple<TKey1, TKey2, TKey3, TKey4, TKey5, TKey6>, TValue> lookup, TKey1 tKey1, TKey2 tKey2, TKey3 tKey3, TKey4 tKey4, TKey5 tKey5, TKey6 tKey6) { return lookup[KeyTuple.Create(tKey1, tKey2, tKey3, tKey4, tKey5, tKey6)]; } public static IEnumerable<TValue> Get<TKey1, TKey2, TKey3, TKey4, TKey5, TKey6, TKey7, TValue>(this ILookup<KeyTuple<TKey1, TKey2, TKey3, TKey4, TKey5, TKey6, TKey7>, TValue> lookup, TKey1 tKey1, TKey2 tKey2, TKey3 tKey3, TKey4 tKey4, TKey5 tKey5, TKey6 tKey6, TKey7 tKey7) { return lookup[KeyTuple.Create(tKey1, tKey2, tKey3, tKey4, tKey5, tKey6, tKey7)]; } public static TValue GetValueOrDefault<TKey1, TKey2, TValue>(this IDictionary<KeyTuple<TKey1, TKey2>, TValue> dictionary, TKey1 tKey1, TKey2 tKey2, TValue defaultValue = default(TValue)) { if (!dictionary.TryGetValue(KeyTuple.Create(tKey1, tKey2), out var value)) { return defaultValue; } return value; } public static TValue GetValueOrDefault<TKey1, TKey2, TKey3, TValue>(this IDictionary<KeyTuple<TKey1, TKey2, TKey3>, TValue> dictionary, TKey1 tKey1, TKey2 tKey2, TKey3 tKey3, TValue defaultValue = default(TValue)) { if (!dictionary.TryGetValue(KeyTuple.Create(tKey1, tKey2, tKey3), out var value)) { return defaultValue; } return value; } public static TValue GetValueOrDefault<TKey1, TKey2, TKey3, TKey4, TValue>(this IDictionary<KeyTuple<TKey1, TKey2, TKey3, TKey4>, TValue> dictionary, TKey1 tKey1, TKey2 tKey2, TKey3 tKey3, TKey4 tKey4, TValue defaultValue = default(TValue)) { if (!dictionary.TryGetValue(KeyTuple.Create(tKey1, tKey2, tKey3, tKey4), out var value)) { return defaultValue; } return value; } public static TValue GetValueOrDefault<TKey1, TKey2, TKey3, TKey4, TKey5, TValue>(this IDictionary<KeyTuple<TKey1, TKey2, TKey3, TKey4, TKey5>, TValue> dictionary, TKey1 tKey1, TKey2 tKey2, TKey3 tKey3, TKey4 tKey4, TKey5 tKey5, TValue defaultValue = default(TValue)) { if (!dictionary.TryGetValue(KeyTuple.Create(tKey1, tKey2, tKey3, tKey4, tKey5), out var value)) { return defaultValue; } return value; } public static TValue GetValueOrDefault<TKey1, TKey2, TKey3, TKey4, TKey5, TKey6, TValue>(this IDictionary<KeyTuple<TKey1, TKey2, TKey3, TKey4, TKey5, TKey6>, TValue> dictionary, TKey1 tKey1, TKey2 tKey2, TKey3 tKey3, TKey4 tKey4, TKey5 tKey5, TKey6 tKey6, TValue defaultValue = default(TValue)) { if (!dictionary.TryGetValue(KeyTuple.Create(tKey1, tKey2, tKey3, tKey4, tKey5, tKey6), out var value)) { return defaultValue; } return value; } public static TValue GetValueOrDefault<TKey1, TKey2, TKey3, TKey4, TKey5, TKey6, TKey7, TValue>(this IDictionary<KeyTuple<TKey1, TKey2, TKey3, TKey4, TKey5, TKey6, TKey7>, TValue> dictionary, TKey1 tKey1, TKey2 tKey2, TKey3 tKey3, TKey4 tKey4, TKey5 tKey5, TKey6 tKey6, TKey7 tKey7, TValue defaultValue = default(TValue)) { if (!dictionary.TryGetValue(KeyTuple.Create(tKey1, tKey2, tKey3, tKey4, tKey5, tKey6, tKey7), out var value)) { return defaultValue; } return value; } }
ZeroFormatter.dll
Decompiled 4 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.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using ZeroFormatter.Comparers; using ZeroFormatter.Formatters; using ZeroFormatter.Internal; using ZeroFormatter.Segments; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ZeroFormatter")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ZeroFormatter")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("82049afe-0913-4fa4-b924-ad5354952154")] [assembly: AssemblyFileVersion("1.6.4.0")] [assembly: InternalsVisibleTo("ZeroFormatter.Tests")] [assembly: InternalsVisibleTo("ZeroFormatter.NETCore.Tests")] [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.6.4.0")] [module: UnverifiableCode] namespace ZeroFormatter { internal static class EnumerableExtensions { public static T[] StartsWith<T>(this T[] array, T firstValue) { T[] array2 = new T[array.Length + 1]; array2[0] = firstValue; Array.Copy(array, 0, array2, 1, array.Length); return array2; } } public class DirtyTracker { private sealed class NullDirtyTracker : DirtyTracker { public override bool IsDirty => false; public override DirtyTracker CreateChild() { return this; } public override void Dirty() { } } public static readonly DirtyTracker NullTracker = new NullDirtyTracker(); private readonly DirtyTracker parent; public virtual bool IsDirty { get; private set; } public DirtyTracker() { IsDirty = false; } private DirtyTracker(DirtyTracker parent) { this.parent = parent; IsDirty = parent.IsDirty; } public virtual void Dirty() { IsDirty = true; if (parent != null) { parent.Dirty(); } } public virtual DirtyTracker CreateChild() { return new DirtyTracker(this); } } public static class ZeroFormatterSerializer { public static class NonGeneric { private delegate int RefSerialize(ref byte[] bytes, int offset, object obj); private class CompiledMethods { public readonly Func<object, byte[]> serialize1; public readonly RefSerialize serialize2; public readonly Action<Stream, object> serialize3; public readonly Func<byte[], object> deserialize1; public readonly Func<byte[], int, object> deserialize2; public readonly Func<Stream, object> deserialize3; public readonly Func<object, bool, object> convert; public CompiledMethods(Type type) { TypeInfo typeInfo = type.GetTypeInfo(); MethodInfo[] methods = typeof(ZeroFormatterSerializer).GetTypeInfo().GetMethods(); MethodInfo method = methods.First((MethodInfo x) => x.Name == "Serialize" && x.GetParameters().Length == 1).MakeGenericMethod(type); ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "obj"); serialize1 = Expression.Lambda<Func<object, byte[]>>(Expression.Call(method, typeInfo.IsValueType ? Expression.Unbox(parameterExpression, type) : Expression.Convert(parameterExpression, type)), new ParameterExpression[1] { parameterExpression }).Compile(); MethodInfo method2 = methods.First((MethodInfo x) => x.Name == "Serialize" && x.GetParameters().Length == 3).MakeGenericMethod(type); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(byte[]).MakeByRefType(), "bytes"); ParameterExpression parameterExpression3 = Expression.Parameter(typeof(int), "offset"); ParameterExpression parameterExpression4 = Expression.Parameter(typeof(object), "obj"); serialize2 = Expression.Lambda<RefSerialize>(Expression.Call(method2, parameterExpression2, parameterExpression3, typeInfo.IsValueType ? Expression.Unbox(parameterExpression4, type) : Expression.Convert(parameterExpression4, type)), new ParameterExpression[3] { parameterExpression2, parameterExpression3, parameterExpression4 }).Compile(); MethodInfo method3 = methods.First((MethodInfo x) => x.Name == "Serialize" && x.GetParameters().Length == 2).MakeGenericMethod(type); ParameterExpression parameterExpression5 = Expression.Parameter(typeof(Stream), "stream"); ParameterExpression parameterExpression6 = Expression.Parameter(typeof(object), "obj"); serialize3 = Expression.Lambda<Action<Stream, object>>(Expression.Call(method3, parameterExpression5, typeInfo.IsValueType ? Expression.Unbox(parameterExpression6, type) : Expression.Convert(parameterExpression6, type)), new ParameterExpression[2] { parameterExpression5, parameterExpression6 }).Compile(); MethodInfo method4 = methods.First((MethodInfo x) => x.Name == "Deserialize" && x.GetParameters()[0].ParameterType == typeof(byte[])).MakeGenericMethod(type); ParameterExpression parameterExpression7 = Expression.Parameter(typeof(byte[]), "bytes"); Func<byte[], object> func = Expression.Lambda<Func<byte[], object>>(Expression.Convert(Expression.Call(method4, parameterExpression7), typeof(object)), new ParameterExpression[1] { parameterExpression7 }).Compile(); deserialize1 = func; MethodInfo method5 = methods.First((MethodInfo x) => x.Name == "Deserialize" && x.GetParameters().Length == 2).MakeGenericMethod(type); ParameterExpression parameterExpression8 = Expression.Parameter(typeof(byte[]), "bytes"); ParameterExpression parameterExpression9 = Expression.Parameter(typeof(int), "offset"); Func<byte[], int, object> func2 = Expression.Lambda<Func<byte[], int, object>>(Expression.Convert(Expression.Call(method5, parameterExpression8, parameterExpression9), typeof(object)), new ParameterExpression[2] { parameterExpression8, parameterExpression9 }).Compile(); deserialize2 = func2; MethodInfo method6 = methods.First((MethodInfo x) => x.Name == "Deserialize" && x.GetParameters()[0].ParameterType == typeof(Stream)).MakeGenericMethod(type); ParameterExpression parameterExpression10 = Expression.Parameter(typeof(Stream), "stream"); Func<Stream, object> func3 = Expression.Lambda<Func<Stream, object>>(Expression.Convert(Expression.Call(method6, parameterExpression10), typeof(object)), new ParameterExpression[1] { parameterExpression10 }).Compile(); deserialize3 = func3; MethodInfo method7 = methods.First((MethodInfo x) => x.Name == "Convert").MakeGenericMethod(type); ParameterExpression parameterExpression11 = Expression.Parameter(typeof(object), "obj"); ParameterExpression parameterExpression12 = Expression.Parameter(typeof(bool), "forceConvert"); convert = Expression.Lambda<Func<object, bool, object>>(Expression.Convert(Expression.Call(method7, typeInfo.IsValueType ? Expression.Unbox(parameterExpression11, type) : Expression.Convert(parameterExpression11, type), parameterExpression12), typeof(object)), new ParameterExpression[2] { parameterExpression11, parameterExpression12 }).Compile(); } } private static readonly ConcurrentDictionary<Type, CompiledMethods> serializes = new ConcurrentDictionary<Type, CompiledMethods>(); public static byte[] Serialize(Type type, object obj) { return serializes.GetOrAdd(type, (Type t) => new CompiledMethods(t)).serialize1(obj); } public static int Serialize(Type type, ref byte[] bytes, int offset, object obj) { return serializes.GetOrAdd(type, (Type t) => new CompiledMethods(t)).serialize2(ref bytes, offset, obj); } public static void Serialize(Type type, Stream stream, object obj) { serializes.GetOrAdd(type, (Type t) => new CompiledMethods(t)).serialize3(stream, obj); } public static object Deserialize(Type type, byte[] bytes) { return serializes.GetOrAdd(type, (Type t) => new CompiledMethods(t)).deserialize1(bytes); } public static object Deserialize(Type type, byte[] bytes, int offset) { return serializes.GetOrAdd(type, (Type t) => new CompiledMethods(t)).deserialize2(bytes, offset); } public static object Deserialize(Type type, Stream stream) { return serializes.GetOrAdd(type, (Type t) => new CompiledMethods(t)).deserialize3(stream); } public static object Convert(Type type, object obj, bool forceConvert = false) { return serializes.GetOrAdd(type, (Type t) => new CompiledMethods(t)).convert(obj, forceConvert); } public static bool IsFormattedObject(object obj) { return obj is IZeroFormatterSegment; } } public static class CustomSerializer<TTypeResolver> where TTypeResolver : ITypeResolver, new() { public static byte[] Serialize<T>(T obj) { byte[] buffer = null; int num = Serialize(ref buffer, 0, obj); if (buffer.Length != num) { BinaryUtil.FastResize(ref buffer, num); } return buffer; } public static int Serialize<T>(ref byte[] buffer, int offset, T obj) { return (Formatter<TTypeResolver, T>.Default ?? throw new InvalidOperationException("Formatter not found, " + typeof(T).Name)).Serialize(ref buffer, offset, obj); } public static void Serialize<T>(Stream stream, T obj) { if (stream is MemoryStream memoryStream && memoryStream.Position == 0L && (object)obj is IZeroFormatterSegment zeroFormatterSegment && zeroFormatterSegment.CanDirectCopy()) { ArraySegment<byte> bufferReference = zeroFormatterSegment.GetBufferReference(); memoryStream.SetLength(bufferReference.Count); byte[] buffer = memoryStream.GetBuffer(); Buffer.BlockCopy(bufferReference.Array, bufferReference.Offset, buffer, 0, bufferReference.Count); } else { byte[] array = Serialize(obj); stream.Write(array, 0, array.Length); } } public static T Deserialize<T>(byte[] bytes) { Formatter<TTypeResolver, T> obj = Formatter<TTypeResolver, T>.Default ?? throw new InvalidOperationException("Formatter not found, " + typeof(T).Name); DirtyTracker tracker = (obj.NoUseDirtyTracker ? DirtyTracker.NullTracker : new DirtyTracker()); int byteSize; return obj.Deserialize(ref bytes, 0, tracker, out byteSize); } public static T Deserialize<T>(byte[] bytes, int offset) { Formatter<TTypeResolver, T> obj = Formatter<TTypeResolver, T>.Default ?? throw new InvalidOperationException("Formatter not found, " + typeof(T).Name); DirtyTracker tracker = (obj.NoUseDirtyTracker ? DirtyTracker.NullTracker : new DirtyTracker()); int byteSize; return obj.Deserialize(ref bytes, offset, tracker, out byteSize); } public static T Deserialize<T>(Stream stream) { MemoryStream memoryStream = stream as MemoryStream; Formatter<TTypeResolver, T> @default = Formatter<TTypeResolver, T>.Default; DirtyTracker tracker = (@default.NoUseDirtyTracker ? DirtyTracker.NullTracker : new DirtyTracker()); if (memoryStream != null) { byte[] bytes = memoryStream.GetBuffer(); int byteSize; return @default.Deserialize(ref bytes, (int)memoryStream.Position, tracker, out byteSize); } ArraySegment<byte> arraySegment = FillFromStream(stream); byte[] bytes2 = arraySegment.Array; int byteSize2; return @default.Deserialize(ref bytes2, arraySegment.Offset, tracker, out byteSize2); } public static T Convert<T>(T obj, bool forceConvert = false) { IZeroFormatterSegment zeroFormatterSegment = obj as IZeroFormatterSegment; if (!forceConvert && zeroFormatterSegment != null && zeroFormatterSegment.CanDirectCopy()) { return obj; } return Deserialize<T>(Serialize(obj)); } } private const int DefaultMaxSize = 67108864; private static int maxSize = 67108864; public static int MaximumLengthOfDeserialize { get { return maxSize; } set { maxSize = value; } } public static void ValidateNewLength(int length) { if (MaximumLengthOfDeserialize < length) { throw new InvalidOperationException("Reached maximum length:" + MaximumLengthOfDeserialize + " so ensure MaximumLengthOfDeserialize or handle alternate strategy."); } } public static byte[] Serialize<T>(T obj) { return CustomSerializer<DefaultResolver>.Serialize(obj); } public static int Serialize<T>(ref byte[] buffer, int offset, T obj) { return CustomSerializer<DefaultResolver>.Serialize(ref buffer, offset, obj); } public static void Serialize<T>(Stream stream, T obj) { CustomSerializer<DefaultResolver>.Serialize(stream, obj); } public static T Deserialize<T>(byte[] bytes) { return CustomSerializer<DefaultResolver>.Deserialize<T>(bytes); } public static T Deserialize<T>(byte[] bytes, int offset) { return CustomSerializer<DefaultResolver>.Deserialize<T>(bytes, offset); } public static T Deserialize<T>(Stream stream) { return CustomSerializer<DefaultResolver>.Deserialize<T>(stream); } public static T Convert<T>(T obj, bool forceConvert = false) { return CustomSerializer<DefaultResolver>.Convert(obj, forceConvert); } public static bool IsFormattedObject<T>(T obj) { return obj is IZeroFormatterSegment; } private static ArraySegment<byte> FillFromStream(Stream input) { byte[] array = new byte[input.CanSeek ? input.Length : 16]; int num = 0; int num2; while ((num2 = input.Read(array, num, array.Length - num)) > 0) { num += num2; if (num == array.Length) { BinaryUtil.FastResize(ref array, num * 2); } } return new ArraySegment<byte>(array, 0, num); } } } namespace ZeroFormatter.Segments { public interface IZeroFormatterSegment { bool CanDirectCopy(); ArraySegment<byte> GetBufferReference(); int Serialize(ref byte[] targetBytes, int offset); } public sealed class DictionarySegment<TTypeResolver, TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IZeroFormatterSegment, ILazyDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, ILazyReadOnlyDictionary<TKey, TValue> where TTypeResolver : ITypeResolver, new() { private int count; private IList<int> buckets; private IList<DictionaryEntry<TTypeResolver, TKey, TValue>> entries; private int freeCount; private int freeList; private DirtyTracker tracker; private ArraySegment<byte> originalBytes; private readonly IEqualityComparer<TKey> comparer; public int Count => count - freeCount; ICollection<TKey> IDictionary<TKey, TValue>.Keys { get { throw new NotSupportedException("ZeroFormatter Dictionary does not support Keys; use GetEnumerator instead."); } } ICollection<TValue> IDictionary<TKey, TValue>.Values { get { throw new NotSupportedException("ZeroFormatter Dictionary does not support Values; use GetEnumerator instead."); } } public IEnumerable<TKey> Keys { get { throw new NotSupportedException("ZeroFormatter Dictionary does not support Keys; use GetEnumerator instead."); } } public IEnumerable<TValue> Values { get { throw new NotSupportedException("ZeroFormatter Dictionary does not support Values; use GetEnumerator instead."); } } public TValue this[TKey key] { get { int num = FindEntry(key); if (num >= 0) { return entries[num].Value; } throw new KeyNotFoundException(); } set { Insert(key, value, add: false); } } bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => true; internal DictionarySegment(DirtyTracker tracker, int size) { tracker = tracker.CreateChild(); this.tracker = tracker; count = 0; if (size == 0) { size = HashHelpers.GetPrime(size); } int[] array = new int[size]; for (int i = 0; i < array.Length; i++) { array[i] = -1; } buckets = array; entries = new DictionaryEntry<TTypeResolver, TKey, TValue>[size]; comparer = ZeroFormatterEqualityComparer<TKey>.Default; freeList = -1; freeCount = 0; } internal static DictionarySegment<TTypeResolver, TKey, TValue> Create(DirtyTracker tracker, byte[] bytes, int offset, out int byteSize) { int num = BinaryUtil.ReadInt32(ref bytes, offset); if (num == -1) { byteSize = 4; return null; } byteSize = num; return new DictionarySegment<TTypeResolver, TKey, TValue>(tracker, new ArraySegment<byte>(bytes, offset, byteSize)); } private DictionarySegment(DirtyTracker tracker, ArraySegment<byte> originalBytes) { tracker = tracker.CreateChild(); this.tracker = tracker; this.originalBytes = originalBytes; byte[] bytes = originalBytes.Array; int num = originalBytes.Offset + 4; count = BinaryUtil.ReadInt32(ref bytes, num); num += 4; Formatter<TTypeResolver, IList<int>> @default = Formatter<TTypeResolver, IList<int>>.Default; Formatter<TTypeResolver, IList<DictionaryEntry<TTypeResolver, TKey, TValue>>> default2 = Formatter<TTypeResolver, IList<DictionaryEntry<TTypeResolver, TKey, TValue>>>.Default; buckets = @default.Deserialize(ref bytes, num, tracker, out var byteSize); num += byteSize; entries = default2.Deserialize(ref bytes, num, tracker, out byteSize); num += byteSize; if (buckets.Count == 0) { int prime = HashHelpers.GetPrime(0); Resize(prime); } comparer = ZeroFormatterEqualityComparer<TKey>.Default; freeList = -1; freeCount = 0; } public void Add(TKey key, TValue value) { Insert(key, value, add: true); } void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> keyValuePair) { Add(keyValuePair.Key, keyValuePair.Value); } bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> keyValuePair) { int num = FindEntry(keyValuePair.Key); if (num >= 0 && EqualityComparer<TValue>.Default.Equals(entries[num].Value, keyValuePair.Value)) { return true; } return false; } bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> keyValuePair) { tracker.Dirty(); int num = FindEntry(keyValuePair.Key); if (num >= 0 && EqualityComparer<TValue>.Default.Equals(entries[num].Value, keyValuePair.Value)) { Remove(keyValuePair.Key); return true; } return false; } public void Clear() { tracker.Dirty(); if (count <= 0) { return; } for (int i = 0; i < buckets.Count; i++) { buckets[i] = -1; } ListSegment<TTypeResolver, DictionaryEntry<TTypeResolver, TKey, TValue>> listSegment = entries as ListSegment<TTypeResolver, DictionaryEntry<TTypeResolver, TKey, TValue>>; DictionaryEntry<TTypeResolver, TKey, TValue>[] array = entries as DictionaryEntry<TTypeResolver, TKey, TValue>[]; if (listSegment != null) { listSegment.Clear(); } else { if (array == null) { throw new InvalidOperationException("entries type is invalid. " + entries.GetType().Name); } Array.Clear(array, 0, count); } freeList = -1; count = 0; freeCount = 0; } public bool ContainsKey(TKey key) { return FindEntry(key) >= 0; } public bool ContainsValue(TValue value) { if (value == null) { for (int i = 0; i < count; i++) { if (entries[i].HashCode >= 0 && entries[i].Value == null) { return true; } } } else { EqualityComparer<TValue> @default = EqualityComparer<TValue>.Default; for (int j = 0; j < count; j++) { if (entries[j].HashCode >= 0 && @default.Equals(entries[j].Value, value)) { return true; } } } return false; } private void CopyTo(KeyValuePair<TKey, TValue>[] array, int index) { if (array == null) { throw new ArgumentNullException("array"); } if (index < 0 || index > array.Length) { throw new ArgumentOutOfRangeException("index", index, "ArgumentOutOfRange_Index"); } if (array.Length - index < Count) { throw new ArgumentException("Arg_ArrayPlusOffTooSmall"); } int num = count; for (int i = 0; i < num; i++) { if (entries[i].HashCode >= 0) { array[index++] = new KeyValuePair<TKey, TValue>(entries[i].Key, entries[i].Value); } } } private int FindEntry(TKey key) { if (key == null) { throw new ArgumentNullException("key"); } if (buckets != null) { int num = comparer.GetHashCode(key) & 0x7FFFFFFF; for (int num2 = buckets[num % buckets.Count]; num2 >= 0; num2 = entries[num2].Next) { if (entries[num2].HashCode == num && comparer.Equals(entries[num2].Key, key)) { return num2; } } } return -1; } public bool Remove(TKey key) { tracker.Dirty(); if (key == null) { throw new ArgumentNullException("key"); } if (buckets != null) { int num = comparer.GetHashCode(key) & 0x7FFFFFFF; int index = num % buckets.Count; int num2 = -1; for (int num3 = buckets[index]; num3 >= 0; num3 = entries[num3].Next) { if (entries[num3].HashCode == num && comparer.Equals(entries[num3].Key, key)) { if (num2 < 0) { buckets[index] = entries[num3].Next; } else { entries[num2] = entries[num2].WithNext(entries[num3].Next); } entries[num3] = new DictionaryEntry<TTypeResolver, TKey, TValue>(-1, freeList, default(TKey), default(TValue)); freeList = num3; freeCount++; return true; } num2 = num3; } } return false; } public bool TryGetValue(TKey key, out TValue value) { int num = FindEntry(key); if (num >= 0) { value = entries[num].Value; return true; } value = default(TValue); return false; } void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int index) { CopyTo(array, index); } public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { int index = 0; while ((uint)index < (uint)count) { if (entries[index].HashCode >= 0) { yield return new KeyValuePair<TKey, TValue>(entries[index].Key, entries[index].Value); index++; } else { index++; } } } IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private void Insert(TKey key, TValue value, bool add) { tracker.Dirty(); if (key == null) { throw new ArgumentNullException("key"); } int num = comparer.GetHashCode(key) & 0x7FFFFFFF; int index = num % buckets.Count; for (int num2 = buckets[index]; num2 >= 0; num2 = entries[num2].Next) { if (entries[num2].HashCode == num && comparer.Equals(entries[num2].Key, key)) { if (add) { throw new ArgumentException(SR.Format("Argument_AddingDuplicate", key)); } entries[num2] = entries[num2].WithValue(value); return; } } int num3; if (freeCount > 0) { num3 = freeList; freeList = entries[num3].Next; freeCount--; } else { if (count == entries.Count) { Resize(); index = num % buckets.Count; } num3 = count; count++; } entries[num3] = new DictionaryEntry<TTypeResolver, TKey, TValue>(num, buckets[index], key, value); buckets[index] = num3; } private void Resize() { Resize(HashHelpers.ExpandPrime(count)); } private void Resize(int newSize) { tracker.Dirty(); int[] array = new int[newSize]; for (int i = 0; i < array.Length; i++) { array[i] = -1; } DictionaryEntry<TTypeResolver, TKey, TValue>[] array2 = new DictionaryEntry<TTypeResolver, TKey, TValue>[newSize]; entries.CopyTo(array2, 0); for (int j = 0; j < count; j++) { if (array2[j].HashCode >= 0) { int num = array2[j].HashCode % newSize; array2[j] = array2[j].WithNext(array[num]); array[num] = j; } } buckets = array; entries = array2; } public bool CanDirectCopy() { if (tracker != null) { if (!tracker.IsDirty) { return originalBytes.Array != null; } return false; } return false; } public ArraySegment<byte> GetBufferReference() { return originalBytes; } public int Serialize(ref byte[] bytes, int offset) { if (CanDirectCopy()) { BinaryUtil.EnsureCapacity(ref bytes, offset, originalBytes.Count); Buffer.BlockCopy(originalBytes.Array, originalBytes.Offset, bytes, offset, originalBytes.Count); return originalBytes.Count; } if (freeCount != 0 || freeList != -1) { Resize(count); } Formatter<TTypeResolver, IList<int>> @default = Formatter<TTypeResolver, IList<int>>.Default; Formatter<TTypeResolver, IList<DictionaryEntry<TTypeResolver, TKey, TValue>>> default2 = Formatter<TTypeResolver, IList<DictionaryEntry<TTypeResolver, TKey, TValue>>>.Default; int num = offset; offset += 4; BinaryUtil.WriteInt32(ref bytes, offset, count); offset += 4; offset += @default.Serialize(ref bytes, offset, buckets); offset += default2.Serialize(ref bytes, offset, entries); int num2 = offset - num; BinaryUtil.WriteInt32(ref bytes, num, num2); return num2; } } public static class DictionaryEntry { public static DictionaryEntry<TTypeResolver, TKey, TValue> Create<TTypeResolver, TKey, TValue>(byte[] bytes, int offset, DirtyTracker tracker, out int byteSize) where TTypeResolver : ITypeResolver, new() { byteSize = 0; int hashCode = BinaryUtil.ReadInt32(ref bytes, offset); offset += 4; byteSize += 4; int next = BinaryUtil.ReadInt32(ref bytes, offset); offset += 4; byteSize += 4; int byteSize2; TKey key = Formatter<TTypeResolver, TKey>.Default.Deserialize(ref bytes, offset, tracker, out byteSize2); offset += byteSize2; byteSize += byteSize2; TValue value = Formatter<TTypeResolver, TValue>.Default.Deserialize(ref bytes, offset, tracker, out byteSize2); byteSize += byteSize2; return new DictionaryEntry<TTypeResolver, TKey, TValue>(hashCode, next, key, value); } } public struct DictionaryEntry<TTypeResolver, TKey, TValue> where TTypeResolver : ITypeResolver, new() { public readonly int HashCode; public readonly int Next; public readonly TKey Key; public readonly TValue Value; public DictionaryEntry(int hashCode, int next, TKey key, TValue value) { HashCode = hashCode; Next = next; Key = key; Value = value; } public DictionaryEntry<TTypeResolver, TKey, TValue> WithNext(int next) { return new DictionaryEntry<TTypeResolver, TKey, TValue>(HashCode, next, Key, Value); } public DictionaryEntry<TTypeResolver, TKey, TValue> WithValue(TValue value) { return new DictionaryEntry<TTypeResolver, TKey, TValue>(HashCode, Next, Key, value); } public int Serialize(ref byte[] bytes, int offset) { int num = 0; num += BinaryUtil.WriteInt32(ref bytes, offset, HashCode); num += BinaryUtil.WriteInt32(ref bytes, offset + num, Next); num += Formatter<TTypeResolver, TKey>.Default.Serialize(ref bytes, offset + num, Key); return num + Formatter<TTypeResolver, TValue>.Default.Serialize(ref bytes, offset + num, Value); } } public class LookupSegment<TTypeResolver, TKey, TElement> : ILookup<TKey, TElement>, IEnumerable<IGrouping<TKey, TElement>>, IEnumerable, ILazyLookup<TKey, TElement>, IZeroFormatterSegment where TTypeResolver : ITypeResolver, new() { private static TElement[] EmptyArray = new TElement[0]; private readonly IEqualityComparer<TKey> comparer; private int count; private IList<IList<GroupingSegment<TTypeResolver, TKey, TElement>>> groupings; internal DirtyTracker tracker; private ArraySegment<byte> originalBytes; public int Count => count; public IEnumerable<TElement> this[TKey key] { get { GroupingSegment<TTypeResolver, TKey, TElement> grouping = GetGrouping(key, create: false); if (grouping != null) { return grouping; } return EmptyArray; } } internal LookupSegment(ILookup<TKey, TElement> source) { comparer = ZeroFormatterEqualityComparer<TKey>.Default; groupings = new List<IList<GroupingSegment<TTypeResolver, TKey, TElement>>>(source.Count); for (int i = 0; i < source.Count; i++) { groupings.Add(null); } foreach (IGrouping<TKey, TElement> item in source) { GroupingSegment<TTypeResolver, TKey, TElement> grouping = GetGrouping(item.Key, create: true); foreach (TElement item2 in item) { grouping.Add(item2); } } count = source.Count; } public static LookupSegment<TTypeResolver, TKey, TElement> Create(DirtyTracker tracker, byte[] bytes, int offset, out int byteSize) { tracker = tracker.CreateChild(); int num = BinaryUtil.ReadInt32(ref bytes, offset); if (num == -1) { byteSize = 4; return null; } LookupSegment<TTypeResolver, TKey, TElement> lookupSegment = new LookupSegment<TTypeResolver, TKey, TElement>(); byteSize = num; lookupSegment.count = BinaryUtil.ReadInt32(ref bytes, offset + 4); Formatter<TTypeResolver, IList<IList<GroupingSegment<TTypeResolver, TKey, TElement>>>> @default = Formatter<TTypeResolver, IList<IList<GroupingSegment<TTypeResolver, TKey, TElement>>>>.Default; lookupSegment.groupings = @default.Deserialize(ref bytes, offset + 8, tracker, out var _); lookupSegment.tracker = tracker; lookupSegment.originalBytes = new ArraySegment<byte>(bytes, offset, byteSize); return lookupSegment; } private LookupSegment() { comparer = ZeroFormatterEqualityComparer<TKey>.Default; } public bool Contains(TKey key) { return GetGrouping(key, create: false) != null; } public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator() { for (int i = 0; i < groupings.Count; i++) { IList<GroupingSegment<TTypeResolver, TKey, TElement>> list = groupings[i]; if (list == null) { continue; } foreach (GroupingSegment<TTypeResolver, TKey, TElement> item in list) { yield return item; } } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private GroupingSegment<TTypeResolver, TKey, TElement> GetGrouping(TKey key, bool create) { int num = ((key != null) ? (comparer.GetHashCode(key) & 0x7FFFFFFF) : 0); IList<GroupingSegment<TTypeResolver, TKey, TElement>> list = groupings[num % groupings.Count]; if (list != null) { for (int i = 0; i < list.Count; i++) { GroupingSegment<TTypeResolver, TKey, TElement> groupingSegment = list[i]; if (groupingSegment.hashCode == num && comparer.Equals(groupingSegment.key, key)) { return groupingSegment; } } } if (create) { int index = num % groupings.Count; GroupingSegment<TTypeResolver, TKey, TElement> groupingSegment2 = new GroupingSegment<TTypeResolver, TKey, TElement>(key, num); IList<GroupingSegment<TTypeResolver, TKey, TElement>> list2 = groupings[index]; if (list2 == null) { IList<GroupingSegment<TTypeResolver, TKey, TElement>> list4 = (groupings[index] = new List<GroupingSegment<TTypeResolver, TKey, TElement>>()); list2 = list4; } list2.Add(groupingSegment2); count++; return groupingSegment2; } return null; } public bool CanDirectCopy() { if (tracker != null) { if (!tracker.IsDirty) { return originalBytes.Array != null; } return false; } return false; } public ArraySegment<byte> GetBufferReference() { return originalBytes; } public int Serialize(ref byte[] bytes, int offset) { if (CanDirectCopy()) { BinaryUtil.EnsureCapacity(ref bytes, offset, originalBytes.Count); Buffer.BlockCopy(originalBytes.Array, originalBytes.Offset, bytes, offset, originalBytes.Count); return originalBytes.Count; } int num = 4; num += BinaryUtil.WriteInt32(ref bytes, offset + 4, count); Formatter<TTypeResolver, IList<IList<GroupingSegment<TTypeResolver, TKey, TElement>>>> @default = Formatter<TTypeResolver, IList<IList<GroupingSegment<TTypeResolver, TKey, TElement>>>>.Default; num += @default.Serialize(ref bytes, offset + 8, groupings); BinaryUtil.WriteInt32(ref bytes, offset, num); return num; } } public class GroupingSegment<TTypeResolver, TKey, TElement> : IGrouping<TKey, TElement>, IEnumerable<TElement>, IEnumerable, IList<TElement>, ICollection<TElement>, IZeroFormatterSegment where TTypeResolver : ITypeResolver, new() { internal TKey key; internal int hashCode; internal IList<TElement> elements; internal DirtyTracker tracker; private ArraySegment<byte> originalBytes; public TKey Key => key; int ICollection<TElement>.Count => elements.Count; bool ICollection<TElement>.IsReadOnly => true; TElement IList<TElement>.this[int index] { get { if (index < 0 || index >= elements.Count) { throw new ArgumentOutOfRangeException("index"); } return elements[index]; } set { throw new NotSupportedException(); } } internal static GroupingSegment<TTypeResolver, TKey, TElement> Create(DirtyTracker tracker, byte[] bytes, int offset, out int byteSize) { GroupingSegment<TTypeResolver, TKey, TElement> groupingSegment = new GroupingSegment<TTypeResolver, TKey, TElement>(); tracker = tracker.CreateChild(); groupingSegment.tracker = tracker; Formatter<TTypeResolver, TKey> @default = Formatter<TTypeResolver, TKey>.Default; Formatter<TTypeResolver, IList<TElement>> default2 = Formatter<TTypeResolver, IList<TElement>>.Default; groupingSegment.key = @default.Deserialize(ref bytes, offset, tracker, out var byteSize2); groupingSegment.hashCode = BinaryUtil.ReadInt32(ref bytes, offset + byteSize2); groupingSegment.elements = default2.Deserialize(ref bytes, offset + byteSize2 + 4, tracker, out var byteSize3); byteSize = byteSize2 + 4 + byteSize3; groupingSegment.originalBytes = new ArraySegment<byte>(bytes, offset, byteSize); return groupingSegment; } private GroupingSegment() { } internal GroupingSegment(TKey key, int hashCode) { this.key = key; this.hashCode = hashCode; elements = new List<TElement>(); } internal void Add(TElement element) { elements.Add(element); } public IEnumerator<TElement> GetEnumerator() { return elements.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } void ICollection<TElement>.Add(TElement item) { throw new NotSupportedException(); } void ICollection<TElement>.Clear() { throw new NotSupportedException(); } bool ICollection<TElement>.Contains(TElement item) { return elements.Contains(item); } void ICollection<TElement>.CopyTo(TElement[] array, int arrayIndex) { elements.CopyTo(array, arrayIndex); } bool ICollection<TElement>.Remove(TElement item) { throw new NotSupportedException(); } int IList<TElement>.IndexOf(TElement item) { return elements.IndexOf(item); } void IList<TElement>.Insert(int index, TElement item) { throw new NotSupportedException(); } void IList<TElement>.RemoveAt(int index) { throw new NotSupportedException(); } public bool CanDirectCopy() { if (tracker != null) { if (!tracker.IsDirty) { return originalBytes.Array != null; } return false; } return false; } public ArraySegment<byte> GetBufferReference() { return originalBytes; } public int Serialize(ref byte[] bytes, int offset) { if (CanDirectCopy()) { BinaryUtil.EnsureCapacity(ref bytes, offset, originalBytes.Count); Buffer.BlockCopy(originalBytes.Array, originalBytes.Offset, bytes, offset, originalBytes.Count); return originalBytes.Count; } Formatter<TTypeResolver, TKey> @default = Formatter<TTypeResolver, TKey>.Default; Formatter<TTypeResolver, IList<TElement>> default2 = Formatter<TTypeResolver, IList<TElement>>.Default; int num = offset; offset += @default.Serialize(ref bytes, offset, key); BinaryUtil.WriteInt32(ref bytes, offset, hashCode); offset += 4; offset += default2.Serialize(ref bytes, offset, elements); return offset - num; } } public abstract class ListSegment<TTypeResolver, T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>, IReadOnlyCollection<T> where TTypeResolver : ITypeResolver, new() { protected readonly ArraySegment<byte> originalBytes; protected readonly Formatter<TTypeResolver, T> formatter; protected DirtyTracker tracker; protected int length; protected T[] cache; protected bool[] isCached; protected bool isAllCached; public abstract T this[int index] { get; set; } public int Count => length; public bool IsReadOnly => false; internal ListSegment(DirtyTracker tracker, int length) { isAllCached = true; cache = new T[length]; this.length = length; this.tracker = tracker.CreateChild(); formatter = Formatter<TTypeResolver, T>.Default; } public ListSegment(DirtyTracker tracker, ArraySegment<byte> originalBytes, int length) { this.originalBytes = originalBytes; formatter = Formatter<TTypeResolver, T>.Default; this.length = length; this.tracker = tracker.CreateChild(); } protected void CreateCacheWhenNotYet() { if (cache == null) { cache = new T[length]; isCached = new bool[length]; } } protected void CacheAllWhenNotYet() { CreateCacheWhenNotYet(); if (isAllCached) { return; } ArraySegment<byte> arraySegment = originalBytes; byte[] bytes = arraySegment.Array; for (int i = 0; i < length; i++) { if (!isCached[i]) { int offset = GetOffset(i); cache[i] = formatter.Deserialize(ref bytes, offset, tracker, out var _); isCached[i] = true; } } isAllCached = true; } protected abstract int GetOffset(int index); public bool Contains(T item) { return IndexOf(item) != -1; } public int IndexOf(T item) { EqualityComparer<T> @default = EqualityComparer<T>.Default; for (int i = 0; i < length; i++) { if (@default.Equals(this[i], item)) { return i; } } return -1; } public void CopyTo(T[] array, int arrayIndex) { if (!isAllCached) { int num = 0; int num2 = arrayIndex; while (num < length) { array[num2] = this[num]; num++; num2++; } } else { Array.Copy(cache, 0, array, arrayIndex, length); } } public IEnumerator<T> GetEnumerator() { for (int i = 0; i < Count; i++) { yield return this[i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Add(T item) { CacheAllWhenNotYet(); if (cache.Length == length) { Array.Resize(ref cache, (length == 0) ? 4 : (length * 2)); } cache[length] = item; length++; tracker.Dirty(); } public void Clear() { isAllCached = true; if (cache != null) { Array.Clear(cache, 0, cache.Length); } else { cache = new T[0]; } length = 0; tracker.Dirty(); } public void Insert(int index, T item) { if (index > length) { throw new ArgumentOutOfRangeException("index is out of range:" + index); } CacheAllWhenNotYet(); if (cache.Length == length) { Array.Resize(ref cache, (length == 0) ? 4 : (length * 2)); } if (index < length) { Array.Copy(cache, index, cache, index + 1, length - index); } cache[index] = item; length++; tracker.Dirty(); } public bool Remove(T item) { CacheAllWhenNotYet(); int num = IndexOf(item); if (num != -1) { RemoveAt(num); return true; } return false; } public void RemoveAt(int index) { tracker.Dirty(); if (index >= length) { throw new ArgumentOutOfRangeException("index is out of range:" + index); } CacheAllWhenNotYet(); length--; if (index < length) { Array.Copy(cache, index + 1, cache, index, length - index); } cache[length] = default(T); tracker.Dirty(); } } public class FixedListSegment<TTypeResolver, T> : ListSegment<TTypeResolver, T>, IZeroFormatterSegment where TTypeResolver : ITypeResolver, new() { private readonly int elementSize; public override T this[int index] { get { if (index > length) { throw new ArgumentOutOfRangeException("index > Count"); } if (!isAllCached) { ArraySegment<byte> arraySegment = originalBytes; byte[] bytes = arraySegment.Array; int offset = GetOffset(index); int byteSize; return formatter.Deserialize(ref bytes, offset, tracker, out byteSize); } return cache[index]; } set { if (index > base.Count) { throw new ArgumentOutOfRangeException("index > Count"); } if (!isAllCached) { ArraySegment<byte> arraySegment = originalBytes; byte[] bytes = arraySegment.Array; int num = 4 + elementSize * index; Formatter<TTypeResolver, T> obj = formatter; arraySegment = originalBytes; obj.Serialize(ref bytes, arraySegment.Offset + num, value); } else { cache[index] = value; tracker.Dirty(); } } } internal static FixedListSegment<TTypeResolver, T> Create(DirtyTracker tracker, byte[] bytes, int offset, out int byteSize) { int? num = Formatter<TTypeResolver, T>.Default.GetLength(); if (!num.HasValue) { throw new InvalidOperationException("T should be fixed length. Type: " + typeof(T).Name); } int num2 = BinaryUtil.ReadInt32(ref bytes, offset); if (num2 == -1) { byteSize = 4; return null; } byteSize = num.Value * num2 + 4; return new FixedListSegment<TTypeResolver, T>(tracker, new ArraySegment<byte>(bytes, offset, byteSize), num2); } private FixedListSegment(DirtyTracker tracker, ArraySegment<byte> originalBytes, int length) : base(tracker, originalBytes, length) { int? num = formatter.GetLength(); if (!num.HasValue) { throw new InvalidOperationException("T should be fixed length. Type: " + typeof(T).Name); } elementSize = num.Value; } protected override int GetOffset(int index) { ArraySegment<byte> arraySegment = originalBytes; return arraySegment.Offset + 4 + elementSize * index; } public bool CanDirectCopy() { if (tracker != null) { if (!tracker.IsDirty) { ArraySegment<byte> arraySegment = originalBytes; return arraySegment.Array != null; } return false; } return false; } public ArraySegment<byte> GetBufferReference() { return originalBytes; } public int Serialize(ref byte[] bytes, int offset) { if (CanDirectCopy()) { int offset2 = offset; ArraySegment<byte> arraySegment = originalBytes; BinaryUtil.EnsureCapacity(ref bytes, offset2, arraySegment.Count); arraySegment = originalBytes; byte[]? array = arraySegment.Array; arraySegment = originalBytes; int offset3 = arraySegment.Offset; byte[] dst = bytes; int dstOffset = offset; arraySegment = originalBytes; Buffer.BlockCopy(array, offset3, dst, dstOffset, arraySegment.Count); arraySegment = originalBytes; return arraySegment.Count; } int num = base.Count * elementSize + 4; if (bytes == null) { bytes = new byte[num]; } offset += BinaryUtil.WriteInt32(ref bytes, offset, base.Count); for (int i = 0; i < base.Count; i++) { offset += formatter.Serialize(ref bytes, offset, this[i]); } return num; } } public class VariableListSegment<TTypeResolver, T> : ListSegment<TTypeResolver, T>, IZeroFormatterSegment where TTypeResolver : ITypeResolver, new() { public override T this[int index] { get { if (index > length) { throw new ArgumentOutOfRangeException("index > Count"); } CreateCacheWhenNotYet(); if (!isAllCached && !isCached[index]) { ArraySegment<byte> arraySegment = originalBytes; byte[] bytes = arraySegment.Array; int offset = GetOffset(index); cache[index] = formatter.Deserialize(ref bytes, offset, tracker, out var _); isCached[index] = true; } return cache[index]; } set { if (index > base.Count) { throw new ArgumentOutOfRangeException("index > Count"); } CreateCacheWhenNotYet(); cache[index] = value; if (!isAllCached) { isCached[index] = true; } tracker.Dirty(); } } internal static VariableListSegment<TTypeResolver, T> Create(DirtyTracker tracker, byte[] bytes, int offset, out int byteSize) { byteSize = BinaryUtil.ReadInt32(ref bytes, offset); if (byteSize == -1) { byteSize = 4; return null; } int num = BinaryUtil.ReadInt32(ref bytes, offset + 4); return new VariableListSegment<TTypeResolver, T>(tracker, new ArraySegment<byte>(bytes, offset, byteSize), num); } private VariableListSegment(DirtyTracker tracker, ArraySegment<byte> originalBytes, int length) : base(tracker, originalBytes, length) { if (formatter.GetLength().HasValue) { throw new InvalidOperationException("T has fixed length, use FixedListSegement instead. Type: " + typeof(T).Name); } } protected override int GetOffset(int index) { ArraySegment<byte> arraySegment = originalBytes; byte[] bytes = arraySegment.Array; arraySegment = originalBytes; int num = BinaryUtil.ReadInt32(ref bytes, arraySegment.Offset + 8 + 4 * index); arraySegment = originalBytes; return arraySegment.Offset + num; } public bool CanDirectCopy() { if (tracker != null) { if (!tracker.IsDirty) { ArraySegment<byte> arraySegment = originalBytes; return arraySegment.Array != null; } return false; } return false; } public ArraySegment<byte> GetBufferReference() { return originalBytes; } public int Serialize(ref byte[] bytes, int offset) { if (CanDirectCopy()) { int offset2 = offset; ArraySegment<byte> arraySegment = originalBytes; BinaryUtil.EnsureCapacity(ref bytes, offset2, arraySegment.Count); arraySegment = originalBytes; byte[]? array = arraySegment.Array; arraySegment = originalBytes; int offset3 = arraySegment.Offset; byte[] dst = bytes; int dstOffset = offset; arraySegment = originalBytes; Buffer.BlockCopy(array, offset3, dst, dstOffset, arraySegment.Count); arraySegment = originalBytes; return arraySegment.Count; } int num = offset; int num2 = 0; offset = num + 8 + base.Count * 4; for (int i = 0; i < base.Count; i++) { T value = this[i]; int num3 = formatter.Serialize(ref bytes, offset, value); BinaryUtil.WriteInt32(ref bytes, num + 8 + num2 * 4, offset - num); offset += num3; num2++; } BinaryUtil.WriteInt32(ref bytes, num + 4, base.Count); int num4 = offset - num; BinaryUtil.WriteInt32(ref bytes, num, num4); return num4; } } internal enum SegmentState { Original, Cached, Dirty } public struct CacheSegment<TTypeResolver, T> : IZeroFormatterSegment where TTypeResolver : ITypeResolver, new() { private readonly DirtyTracker tracker; private SegmentState state; private ArraySegment<byte> serializedBytes; private T cached; public T Value { get { if (state == SegmentState.Original) { byte[] bytes = serializedBytes.Array; cached = Formatter<TTypeResolver, T>.Default.Deserialize(ref bytes, serializedBytes.Offset, tracker, out var _); state = SegmentState.Cached; return cached; } return cached; } set { tracker.Dirty(); state = SegmentState.Dirty; cached = value; } } public CacheSegment(DirtyTracker tracker, ArraySegment<byte> originalBytes) { this.tracker = tracker.CreateChild(); state = SegmentState.Original; serializedBytes = originalBytes; cached = default(T); if (originalBytes.Array == null) { state = SegmentState.Dirty; } } public bool CanDirectCopy() { if (Formatter<TTypeResolver, T>.Default.NoUseDirtyTracker) { if (state != 0) { return state == SegmentState.Cached; } return true; } return state == SegmentState.Original; } public ArraySegment<byte> GetBufferReference() { return serializedBytes; } public int Serialize(ref byte[] targetBytes, int offset) { if (targetBytes == null) { throw new ArgumentNullException("targetBytes"); } if (!CanDirectCopy()) { Formatter<TTypeResolver, T> @default = Formatter<TTypeResolver, T>.Default; if (!@default.NoUseDirtyTracker) { return @default.Serialize(ref targetBytes, offset, Value); } byte[] bytes = null; @default.Serialize(ref bytes, 0, Value); serializedBytes = new ArraySegment<byte>(bytes, 0, bytes.Length); state = SegmentState.Cached; } BinaryUtil.EnsureCapacity(ref targetBytes, offset, serializedBytes.Count); Buffer.BlockCopy(serializedBytes.Array, serializedBytes.Offset, targetBytes, offset, serializedBytes.Count); return serializedBytes.Count; } } public static class ObjectSegmentHelper { public static int GetByteSize(ArraySegment<byte> originalBytes) { byte[] bytes = originalBytes.Array; return BinaryUtil.ReadInt32(ref bytes, originalBytes.Offset); } public static int GetOffset(ArraySegment<byte> originalBytes, int index, int lastIndex, DirtyTracker tracker) { if (index > lastIndex) { return -1; } byte[] bytes = originalBytes.Array; int num = BinaryUtil.ReadInt32(ref bytes, originalBytes.Offset + 8 + 4 * index); if (num == 0) { return -1; } return originalBytes.Offset + num; } public static ArraySegment<byte> GetSegment(ArraySegment<byte> originalBytes, int index, int lastIndex, DirtyTracker tracker) { int offset = GetOffset(originalBytes, index, lastIndex, tracker); if (offset == -1) { return default(ArraySegment<byte>); } int num = originalBytes.Offset + originalBytes.Count; return new ArraySegment<byte>(originalBytes.Array, offset, num - offset); } public static T DeserializeSegment<TTypeResolver, T>(ArraySegment<byte> originalBytes, int index, int lastIndex, DirtyTracker tracker) where TTypeResolver : ITypeResolver, new() { int offset = GetOffset(originalBytes, index, lastIndex, tracker); if (offset == -1) { return default(T); } byte[] bytes = originalBytes.Array; int byteSize; return Formatter<TTypeResolver, T>.Default.Deserialize(ref bytes, offset, tracker, out byteSize); } public static int SerializeFixedLength<TTypeResolver, T>(ref byte[] targetBytes, int startOffset, int offset, int index, int lastIndex, ArraySegment<byte> originalBytes, byte[] extraBytes, DirtyTracker tracker) where TTypeResolver : ITypeResolver, new() { BinaryUtil.WriteInt32(ref targetBytes, startOffset + (8 + 4 * index), offset - startOffset); int? length = Formatter<TTypeResolver, T>.Default.GetLength(); BinaryUtil.EnsureCapacity(ref targetBytes, offset, length.Value); int offset2 = GetOffset(originalBytes, index, lastIndex, tracker); if (offset2 != -1) { Buffer.BlockCopy(originalBytes.Array, offset2, targetBytes, offset, length.Value); } else { int extraBytesOffset = GetExtraBytesOffset(extraBytes, lastIndex, index); Buffer.BlockCopy(extraBytes, extraBytesOffset, targetBytes, offset, length.Value); } return length.Value; } public static int SerializeSegment<TTypeResolver, T>(ref byte[] targetBytes, int startOffset, int offset, int index, T segment) where TTypeResolver : ITypeResolver, new() { BinaryUtil.WriteInt32(ref targetBytes, startOffset + (8 + 4 * index), offset - startOffset); return Formatter<TTypeResolver, T>.Default.Serialize(ref targetBytes, offset, segment); } public static int SerializeCacheSegment<TTypeResolver, T>(ref byte[] targetBytes, int startOffset, int offset, int index, ref CacheSegment<TTypeResolver, T> segment) where TTypeResolver : ITypeResolver, new() { BinaryUtil.WriteInt32(ref targetBytes, startOffset + (8 + 4 * index), offset - startOffset); return segment.Serialize(ref targetBytes, offset); } public static T GetFixedProperty<TTypeResolver, T>(ArraySegment<byte> bytes, int index, int lastIndex, byte[] extraBytes, DirtyTracker tracker) where TTypeResolver : ITypeResolver, new() { if (index <= lastIndex) { byte[] bytes2 = bytes.Array; int byteSize; return Formatter<TTypeResolver, T>.Default.Deserialize(ref bytes2, GetOffset(bytes, index, lastIndex, tracker), tracker, out byteSize); } int extraBytesOffset = GetExtraBytesOffset(extraBytes, lastIndex, index); int byteSize2; return Formatter<TTypeResolver, T>.Default.Deserialize(ref extraBytes, extraBytesOffset, tracker, out byteSize2); } public static void SetFixedProperty<TTypeResolver, T>(ArraySegment<byte> bytes, int index, int lastIndex, byte[] extraBytes, T value, DirtyTracker tracker) where TTypeResolver : ITypeResolver, new() { if (index <= lastIndex) { byte[] bytes2 = bytes.Array; Formatter<TTypeResolver, T>.Default.Serialize(ref bytes2, GetOffset(bytes, index, lastIndex, tracker), value); } else { int extraBytesOffset = GetExtraBytesOffset(extraBytes, lastIndex, index); Formatter<TTypeResolver, T>.Default.Serialize(ref extraBytes, extraBytesOffset, value); } } public static int WriteSize(ref byte[] targetBytes, int startOffset, int lastOffset, int lastIndex) { BinaryUtil.WriteInt32(ref targetBytes, startOffset + 4, lastIndex); int num = lastOffset - startOffset; BinaryUtil.WriteInt32Unsafe(ref targetBytes, startOffset, num); return num; } public static int DirectCopyAll(ArraySegment<byte> originalBytes, ref byte[] targetBytes, int targetOffset) { byte[] bytes = originalBytes.Array; int num = BinaryUtil.ReadInt32(ref bytes, originalBytes.Offset); BinaryUtil.EnsureCapacity(ref targetBytes, targetOffset, num); Buffer.BlockCopy(bytes, originalBytes.Offset, targetBytes, targetOffset, num); return num; } private static int GetExtraBytesOffset(byte[] extraBytes, int binaryLastIndex, int index) { int offset = (index - binaryLastIndex - 1) * 4; return BinaryUtil.ReadInt32(ref extraBytes, offset); } public static byte[] CreateExtraFixedBytes(int binaryLastIndex, int schemaLastIndex, int[] elementSizes) { if (binaryLastIndex < schemaLastIndex) { int num = (schemaLastIndex - binaryLastIndex) * 4; int num2 = elementSizes.Sum(); byte[] bytes = new byte[num + num2]; int num3 = num + 4; for (int i = binaryLastIndex + 1; i < elementSizes.Length; i++) { if (elementSizes[i] != 0) { BinaryUtil.WriteInt32(ref bytes, (i - binaryLastIndex - 1) * 4, num3); num3 += elementSizes[i]; } } return bytes; } return null; } public static int SerializeFromFormatter<TTypeResolver, T>(ref byte[] bytes, int startOffset, int offset, int index, T value) where TTypeResolver : ITypeResolver, new() { BinaryUtil.WriteInt32(ref bytes, startOffset + (8 + 4 * index), offset - startOffset); return Formatter<TTypeResolver, T>.Default.Serialize(ref bytes, offset, value); } public static Exception GetException1(string msgFormat, object o) { return new Exception(string.Format(msgFormat, o)); } public static bool IsLazySegment(Type type) { TypeInfo typeInfo = type.GetTypeInfo(); if (typeInfo.IsClass && ((MemberInfo)typeInfo).GetCustomAttributes<ZeroFormattableAttribute>().Any()) { return true; } if (typeInfo.IsGenericType) { Type genericTypeDefinition = typeInfo.GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(IList<>)) { return true; } if (genericTypeDefinition == typeof(ILazyLookup<, >)) { return true; } if (genericTypeDefinition == typeof(ILazyDictionary<, >)) { return true; } if (genericTypeDefinition == typeof(ILazyReadOnlyDictionary<, >)) { return true; } } return false; } } internal static class DynamicAssemblyHolder { public const string ModuleName = "ZeroFormatter.DynamicObjectSegments"; private static readonly DynamicAssembly assembly; public static ModuleBuilder Module => assembly.ModuleBuilder; static DynamicAssemblyHolder() { assembly = new DynamicAssembly("ZeroFormatter.DynamicObjectSegments"); } } internal static class DynamicObjectSegmentBuilder<TTypeResolver, T> where TTypeResolver : ITypeResolver, new() { private class PropertyTuple { public int Index; public PropertyInfo PropertyInfo; public FieldInfo SegmentField; public bool IsCacheSegment; public bool IsFixedSize; public int FixedSize; } private static readonly MethodInfo ArraySegmentArrayGet = typeof(ArraySegment<byte>).GetTypeInfo().GetProperty("Array").GetGetMethod(); private static readonly MethodInfo ArraySegmentOffsetGet = typeof(ArraySegment<byte>).GetTypeInfo().GetProperty("Offset").GetGetMethod(); private static readonly MethodInfo ReadInt32 = typeof(BinaryUtil).GetTypeInfo().GetMethod("ReadInt32"); private static readonly MethodInfo CreateChild = typeof(DirtyTracker).GetTypeInfo().GetMethod("CreateChild"); private static readonly MethodInfo Dirty = typeof(DirtyTracker).GetTypeInfo().GetMethod("Dirty"); private static readonly MethodInfo IsDirty = typeof(DirtyTracker).GetTypeInfo().GetProperty("IsDirty").GetGetMethod(); private static readonly MethodInfo GetSegment = typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("GetSegment"); private static readonly MethodInfo GetOffset = typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("GetOffset"); private static readonly Lazy<TypeInfo> lazyBuild = new Lazy<TypeInfo>(() => Build(), isThreadSafe: true); public static TypeInfo GetProxyType() { return lazyBuild.Value; } private static TypeInfo Build() { return GenerateObjectSegmentImplementation(DynamicAssemblyHolder.Module); } private static TypeInfo GenerateObjectSegmentImplementation(ModuleBuilder moduleBuilder) { TypeBuilder typeBuilder = moduleBuilder.DefineType("ZeroFormatter.DynamicObjectSegments." + typeof(TTypeResolver).FullName.Replace(".", "_") + "." + typeof(T).FullName, TypeAttributes.Public, typeof(T)); FieldBuilder originalBytesField = typeBuilder.DefineField("<>_originalBytes", typeof(ArraySegment<byte>), FieldAttributes.Private | FieldAttributes.InitOnly); FieldBuilder trackerField = typeBuilder.DefineField("<>_tracker", typeof(DirtyTracker), FieldAttributes.Private | FieldAttributes.InitOnly); FieldBuilder fieldBuilder = typeBuilder.DefineField("<>_binaryLastIndex", typeof(int), FieldAttributes.Private | FieldAttributes.InitOnly); FieldBuilder fieldBuilder2 = typeBuilder.DefineField("<>_extraFixedBytes", typeof(byte[]), FieldAttributes.Private | FieldAttributes.InitOnly); PropertyTuple[] propertiesWithVerify = GetPropertiesWithVerify(typeBuilder); BuildConstructor(typeBuilder, originalBytesField, trackerField, fieldBuilder, fieldBuilder2, propertiesWithVerify); PropertyTuple[] array = propertiesWithVerify; foreach (PropertyTuple propertyTuple in array) { if (propertyTuple.IsFixedSize) { BuildFixedProperty(typeBuilder, originalBytesField, trackerField, fieldBuilder, fieldBuilder2, propertyTuple); } else if (propertyTuple.IsCacheSegment) { BuildCacheSegmentProperty(typeBuilder, originalBytesField, trackerField, propertyTuple); } else { BuildSegmentProperty(typeBuilder, originalBytesField, trackerField, propertyTuple); } } BuildInterfaceMethod(typeBuilder, originalBytesField, trackerField, fieldBuilder, fieldBuilder2, propertiesWithVerify); return typeBuilder.CreateTypeInfo(); } private static PropertyTuple[] GetPropertiesWithVerify(TypeBuilder typeBuilder) { Type typeFromHandle = typeof(TTypeResolver); List<PropertyTuple> list = new List<PropertyTuple>(); Tuple<int, EmittableMemberInfo>[] members = DynamicObjectDescriptor.GetMembers(typeFromHandle, typeof(T), isClass: true); foreach (Tuple<int, EmittableMemberInfo> obj in members) { EmittableMemberInfo item = obj.Item2; int item2 = obj.Item1; IFormatter formatter = (IFormatter)typeof(Formatter<, >).MakeGenericType(typeFromHandle, item.MemberType).GetTypeInfo().GetProperty("Default") .GetValue(null, Type.EmptyTypes); if (formatter == null) { throw new InvalidOperationException("Circular reference does not supported. " + typeof(T).Name + "." + item.Name); } if (!formatter.GetLength().HasValue) { if (!ObjectSegmentHelper.IsLazySegment(item.MemberType)) { FieldBuilder segmentField = typeBuilder.DefineField("<>_" + item.Name, typeof(CacheSegment<, >).MakeGenericType(typeFromHandle, item.MemberType), FieldAttributes.Private); list.Add(new PropertyTuple { Index = item2, PropertyInfo = item.PropertyInfoUnsafe, IsFixedSize = false, SegmentField = segmentField, IsCacheSegment = true }); } else { FieldBuilder segmentField2 = typeBuilder.DefineField("<>_" + item.Name, item.MemberType, FieldAttributes.Private); list.Add(new PropertyTuple { Index = item2, PropertyInfo = item.PropertyInfoUnsafe, IsFixedSize = false, SegmentField = segmentField2 }); } } else { list.Add(new PropertyTuple { Index = item2, PropertyInfo = item.PropertyInfoUnsafe, IsFixedSize = true, FixedSize = formatter.GetLength().Value }); } } return list.OrderBy((PropertyTuple x) => x.Index).ToArray(); } private static void BuildConstructor(TypeBuilder type, FieldInfo originalBytesField, FieldInfo trackerField, FieldInfo lastIndexField, FieldInfo extraFixedBytes, PropertyTuple[] properties) { MethodBuilder methodBuilder = type.DefineMethod(".ctor", MethodAttributes.Public | MethodAttributes.HideBySig); ConstructorInfo constructor = typeof(T).GetTypeInfo().GetConstructor(Type.EmptyTypes); methodBuilder.SetReturnType(typeof(void)); methodBuilder.SetParameters(typeof(DirtyTracker), typeof(ArraySegment<byte>)); ILGenerator iLGenerator = methodBuilder.GetILGenerator(); iLGenerator.DeclareLocal(typeof(byte[])); iLGenerator.DeclareLocal(typeof(int)); iLGenerator.DeclareLocal(typeof(int[])); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Call, constructor); iLGenerator.Emit(OpCodes.Ldarga_S, (byte)2); iLGenerator.Emit(OpCodes.Call, ArraySegmentArrayGet); iLGenerator.Emit(OpCodes.Stloc_0); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_2); iLGenerator.Emit(OpCodes.Stfld, originalBytesField); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Callvirt, CreateChild); iLGenerator.Emit(OpCodes.Dup); iLGenerator.Emit(OpCodes.Starg_S, (byte)1); iLGenerator.Emit(OpCodes.Stfld, trackerField); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldloca_S, (byte)0); iLGenerator.Emit(OpCodes.Ldarga_S, (byte)2); iLGenerator.Emit(OpCodes.Call, ArraySegmentOffsetGet); iLGenerator.Emit(OpCodes.Ldc_I4_4); iLGenerator.Emit(OpCodes.Add); iLGenerator.Emit(OpCodes.Call, ReadInt32); iLGenerator.Emit(OpCodes.Stfld, lastIndexField); int num = properties.Select((PropertyTuple x) => x.Index).LastOrDefault(); Dictionary<int, int> dictionary = properties.Where((PropertyTuple x) => x.IsFixedSize).ToDictionary((PropertyTuple x) => x.Index, (PropertyTuple x) => x.FixedSize); int[] array = new int[num + 1]; for (int i = 0; i < num + 1; i++) { if (!dictionary.TryGetValue(i, out array[i])) { array[i] = 0; } } EmitNewArray(iLGenerator, array); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldfld, lastIndexField); iLGenerator.Emit(OpCodes.Ldc_I4, num); iLGenerator.Emit(OpCodes.Ldloc_2); iLGenerator.Emit(OpCodes.Call, typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("CreateExtraFixedBytes")); iLGenerator.Emit(OpCodes.Stfld, extraFixedBytes); foreach (PropertyTuple propertyTuple in properties) { if (!propertyTuple.IsFixedSize) { if (propertyTuple.IsCacheSegment) { AssignCacheSegment(iLGenerator, propertyTuple.Index, trackerField, lastIndexField, propertyTuple.SegmentField); } else { AssignSegment(iLGenerator, propertyTuple.Index, trackerField, lastIndexField, propertyTuple.SegmentField); } } } iLGenerator.Emit(OpCodes.Ret); } private static void EmitNewArray(ILGenerator il, int[] array) { il.Emit(OpCodes.Ldc_I4, array.Length); il.Emit(OpCodes.Newarr, typeof(int)); il.Emit(OpCodes.Stloc_2); for (int i = 0; i < array.Length; i++) { il.Emit(OpCodes.Ldloc_2); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldc_I4, array[i]); il.Emit(OpCodes.Stelem_I4); } } private static void AssignCacheSegment(ILGenerator il, int index, FieldInfo tracker, FieldInfo lastIndex, FieldInfo field) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, tracker); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldc_I4, index); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, lastIndex); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, tracker); il.Emit(OpCodes.Call, GetSegment); il.Emit(OpCodes.Newobj, field.FieldType.GetTypeInfo().GetConstructors().First()); il.Emit(OpCodes.Stfld, field); } private static void AssignSegment(ILGenerator il, int index, FieldInfo tracker, FieldInfo lastIndex, FieldInfo field) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldc_I4, index); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, lastIndex); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, tracker); il.Emit(OpCodes.Call, typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("DeserializeSegment").MakeGenericMethod(typeof(TTypeResolver), field.FieldType)); il.Emit(OpCodes.Stfld, field); } private static void BuildFixedProperty(TypeBuilder type, FieldInfo originalBytesField, FieldInfo trackerField, FieldInfo binaryLastIndex, FieldInfo extraBytes, PropertyTuple property) { PropertyBuilder propertyBuilder = type.DefineProperty(property.PropertyInfo.Name, property.PropertyInfo.Attributes, property.PropertyInfo.PropertyType, Type.EmptyTypes); MethodInfo getMethod = property.PropertyInfo.GetGetMethod(); if (getMethod != null) { MethodBuilder methodBuilder = type.DefineMethod(getMethod.Name, getMethod.Attributes & ~MethodAttributes.VtableLayoutMask, getMethod.ReturnType, Type.EmptyTypes); ILGenerator iLGenerator = methodBuilder.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldfld, originalBytesField); iLGenerator.Emit(OpCodes.Ldc_I4, property.Index); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldfld, binaryLastIndex); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldfld, extraBytes); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldfld, trackerField); iLGenerator.Emit(OpCodes.Call, typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("GetFixedProperty").MakeGenericMethod(typeof(TTypeResolver), getMethod.ReturnType)); iLGenerator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(methodBuilder); } MethodInfo setMethod = property.PropertyInfo.GetSetMethod(); if (setMethod != null) { MethodBuilder methodBuilder2 = type.DefineMethod(setMethod.Name, setMethod.Attributes & ~MethodAttributes.VtableLayoutMask, null, new Type[1] { setMethod.GetParameters()[0].ParameterType }); ILGenerator iLGenerator2 = methodBuilder2.GetILGenerator(); iLGenerator2.Emit(OpCodes.Ldarg_0); iLGenerator2.Emit(OpCodes.Ldfld, originalBytesField); iLGenerator2.Emit(OpCodes.Ldc_I4, property.Index); iLGenerator2.Emit(OpCodes.Ldarg_0); iLGenerator2.Emit(OpCodes.Ldfld, binaryLastIndex); iLGenerator2.Emit(OpCodes.Ldarg_0); iLGenerator2.Emit(OpCodes.Ldfld, extraBytes); iLGenerator2.Emit(OpCodes.Ldarg_1); iLGenerator2.Emit(OpCodes.Ldarg_0); iLGenerator2.Emit(OpCodes.Ldfld, trackerField); iLGenerator2.Emit(OpCodes.Call, typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("SetFixedProperty").MakeGenericMethod(typeof(TTypeResolver), getMethod.ReturnType)); iLGenerator2.Emit(OpCodes.Ret); propertyBuilder.SetSetMethod(methodBuilder2); } } private static void BuildCacheSegmentProperty(TypeBuilder type, FieldInfo originalBytesField, FieldInfo trackerField, PropertyTuple property) { PropertyBuilder propertyBuilder = type.DefineProperty(property.PropertyInfo.Name, property.PropertyInfo.Attributes, property.PropertyInfo.PropertyType, Type.EmptyTypes); MethodInfo getMethod = property.PropertyInfo.GetGetMethod(); if (getMethod != null) { MethodBuilder methodBuilder = type.DefineMethod(getMethod.Name, getMethod.Attributes & ~MethodAttributes.VtableLayoutMask, getMethod.ReturnType, Type.EmptyTypes); ILGenerator iLGenerator = methodBuilder.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldflda, property.SegmentField); iLGenerator.Emit(OpCodes.Call, property.SegmentField.FieldType.GetTypeInfo().GetProperty("Value").GetGetMethod()); iLGenerator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(methodBuilder); } MethodInfo setMethod = property.PropertyInfo.GetSetMethod(); if (setMethod != null) { MethodBuilder methodBuilder2 = type.DefineMethod(setMethod.Name, setMethod.Attributes & ~MethodAttributes.VtableLayoutMask, null, new Type[1] { setMethod.GetParameters()[0].ParameterType }); ILGenerator iLGenerator2 = methodBuilder2.GetILGenerator(); iLGenerator2.Emit(OpCodes.Ldarg_0); iLGenerator2.Emit(OpCodes.Ldflda, property.SegmentField); iLGenerator2.Emit(OpCodes.Ldarg_1); iLGenerator2.Emit(OpCodes.Call, property.SegmentField.FieldType.GetTypeInfo().GetProperty("Value").GetSetMethod()); iLGenerator2.Emit(OpCodes.Ret); propertyBuilder.SetSetMethod(methodBuilder2); } } private static void BuildSegmentProperty(TypeBuilder type, FieldInfo originalBytesField, FieldInfo trackerField, PropertyTuple property) { PropertyBuilder propertyBuilder = type.DefineProperty(property.PropertyInfo.Name, property.PropertyInfo.Attributes, property.PropertyInfo.PropertyType, Type.EmptyTypes); MethodInfo getMethod = property.PropertyInfo.GetGetMethod(); if (getMethod != null) { MethodBuilder methodBuilder = type.DefineMethod(getMethod.Name, getMethod.Attributes & ~MethodAttributes.VtableLayoutMask, getMethod.ReturnType, Type.EmptyTypes); ILGenerator iLGenerator = methodBuilder.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldfld, property.SegmentField); iLGenerator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(methodBuilder); } MethodInfo setMethod = property.PropertyInfo.GetSetMethod(); if (setMethod != null) { MethodBuilder methodBuilder2 = type.DefineMethod(setMethod.Name, setMethod.Attributes & ~MethodAttributes.VtableLayoutMask, null, new Type[1] { setMethod.GetParameters()[0].ParameterType }); ILGenerator iLGenerator2 = methodBuilder2.GetILGenerator(); iLGenerator2.Emit(OpCodes.Ldarg_0); iLGenerator2.Emit(OpCodes.Ldfld, trackerField); iLGenerator2.Emit(OpCodes.Callvirt, Dirty); iLGenerator2.Emit(OpCodes.Ldarg_0); iLGenerator2.Emit(OpCodes.Ldarg_1); iLGenerator2.Emit(OpCodes.Stfld, property.SegmentField); iLGenerator2.Emit(OpCodes.Ret); propertyBuilder.SetSetMethod(methodBuilder2); } } private static void BuildInterfaceMethod(TypeBuilder type, FieldInfo originalBytesField, FieldInfo trackerField, FieldInfo binaryLastIndexField, FieldInfo extraBytes, PropertyTuple[] properties) { type.AddInterfaceImplementation(typeof(IZeroFormatterSegment)); ILGenerator iLGenerator = type.DefineMethod("CanDirectCopy", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, typeof(bool), Type.EmptyTypes).GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldfld, trackerField); iLGenerator.Emit(OpCodes.Callvirt, IsDirty); iLGenerator.Emit(OpCodes.Ldc_I4_0); iLGenerator.Emit(OpCodes.Ceq); iLGenerator.Emit(OpCodes.Ret); ILGenerator iLGenerator2 = type.DefineMethod("GetBufferReference", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, typeof(ArraySegment<byte>), Type.EmptyTypes).GetILGenerator(); iLGenerator2.Emit(OpCodes.Ldarg_0); iLGenerator2.Emit(OpCodes.Ldfld, originalBytesField); iLGenerator2.Emit(OpCodes.Ret); ILGenerator iLGenerator3 = type.DefineMethod("Serialize", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, typeof(int), new Type[2] { typeof(byte[]).MakeByRefType(), typeof(int) }).GetILGenerator(); iLGenerator3.DeclareLocal(typeof(int)); Label label = iLGenerator3.DefineLabel(); Label label2 = iLGenerator3.DefineLabel(); iLGenerator3.Emit(OpCodes.Ldarg_0); iLGenerator3.Emit(OpCodes.Ldfld, extraBytes); iLGenerator3.Emit(OpCodes.Brtrue, label); iLGenerator3.Emit(OpCodes.Ldarg_0); iLGenerator3.Emit(OpCodes.Ldfld, trackerField); iLGenerator3.Emit(OpCodes.Callvirt, IsDirty); iLGenerator3.Emit(OpCodes.Brfalse, label2); int num = properties.Select((PropertyTuple x) => x.Index).LastOrDefault(); int arg = 8 + 4 * (num + 1); iLGenerator3.MarkLabel(label); iLGenerator3.Emit(OpCodes.Ldarg_2); iLGenerator3.Emit(OpCodes.Stloc_0); iLGenerator3.Emit(OpCodes.Ldarg_2); iLGenerator3.Emit(OpCodes.Ldc_I4, arg); iLGenerator3.Emit(OpCodes.Add); foreach (PropertyTuple propertyTuple in properties) { iLGenerator3.Emit(OpCodes.Starg_S, (byte)2); iLGenerator3.Emit(OpCodes.Ldarg_2); iLGenerator3.Emit(OpCodes.Ldarg_1); iLGenerator3.Emit(OpCodes.Ldloc_0); iLGenerator3.Emit(OpCodes.Ldarg_2); iLGenerator3.Emit(OpCodes.Ldc_I4, propertyTuple.Index); if (propertyTuple.IsFixedSize) { iLGenerator3.Emit(OpCodes.Ldarg_0); iLGenerator3.Emit(OpCodes.Ldfld, binaryLastIndexField); iLGenerator3.Emit(OpCodes.Ldarg_0); iLGenerator3.Emit(OpCodes.Ldfld, originalBytesField); iLGenerator3.Emit(OpCodes.Ldarg_0); iLGenerator3.Emit(OpCodes.Ldfld, extraBytes); iLGenerator3.Emit(OpCodes.Ldarg_0); iLGenerator3.Emit(OpCodes.Ldfld, trackerField); iLGenerator3.Emit(OpCodes.Call, typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("SerializeFixedLength").MakeGenericMethod(typeof(TTypeResolver), propertyTuple.PropertyInfo.PropertyType)); } else if (propertyTuple.IsCacheSegment) { iLGenerator3.Emit(OpCodes.Ldarg_0); iLGenerator3.Emit(OpCodes.Ldflda, propertyTuple.SegmentField); iLGenerator3.Emit(OpCodes.Call, typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("SerializeCacheSegment").MakeGenericMethod(typeof(TTypeResolver), propertyTuple.PropertyInfo.PropertyType)); } else { iLGenerator3.Emit(OpCodes.Ldarg_0); iLGenerator3.Emit(OpCodes.Ldfld, propertyTuple.SegmentField); iLGenerator3.Emit(OpCodes.Call, typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("SerializeSegment").MakeGenericMethod(typeof(TTypeResolver), propertyTuple.PropertyInfo.PropertyType)); } iLGenerator3.Emit(OpCodes.Add); } iLGenerator3.Emit(OpCodes.Starg_S, (byte)2); iLGenerator3.Emit(OpCodes.Ldarg_1); iLGenerator3.Emit(OpCodes.Ldloc_0); iLGenerator3.Emit(OpCodes.Ldarg_2); iLGenerator3.Emit(OpCodes.Ldc_I4, num); iLGenerator3.Emit(OpCodes.Call, typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("WriteSize")); iLGenerator3.Emit(OpCodes.Ret); iLGenerator3.MarkLabel(label2); iLGenerator3.Emit(OpCodes.Ldarg_0); iLGenerator3.Emit(OpCodes.Ldfld, originalBytesField); iLGenerator3.Emit(OpCodes.Ldarg_1); iLGenerator3.Emit(OpCodes.Ldarg_2); iLGenerator3.Emit(OpCodes.Call, typeof(ObjectSegmentHelper).GetTypeInfo().GetMethod("DirectCopyAll")); iLGenerator3.Emit(OpCodes.Ret); } } } namespace ZeroFormatter.Internal { public static class BinaryUtil { internal static class Timestamp { internal static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); internal const long BclSecondsAtUnixEpoch = 62135596800L; internal const long UnixSecondsAtBclMaxValue = 253402300799L; internal const long UnixSecondsAtBclMinValue = -62135596800L; internal const int MaxNanos = 999999999; internal static bool IsNormalized(long seconds, int nanoseconds) { if (nanoseconds >= 0 && nanoseconds <= 999999999 && seconds >= -62135596800L) { return seconds <= 253402300799L; } return false; } } internal static class Duration { public const int NanosecondsPerSecond = 1000000000; public const int NanosecondsPerTick = 100; public const long MaxSeconds = 315576000000L; public const long MinSeconds = -315576000000L; internal const int MaxNanoseconds = 999999999; internal const int MinNanoseconds = -999999999; internal static bool IsNormalized(long seconds, int nanoseconds) { if (seconds < -315576000000L || seconds > 315576000000L || nanoseconds < -999999999 || nanoseconds > 999999999) { return false; } return Math.Sign(seconds) * Math.Sign(nanoseconds) != -1; } } static BinaryUtil() { if (!BitConverter.IsLittleEndian) { throw new Exception("Currently ZeroFormatter only supports Little-Endian environments. If you need supports, please report your envitonments to https://github.com/neuecc/ZeroFormatter/issues ."); } } public static void EnsureCapacity(ref byte[] bytes, int offset, int appendLength) { int num = offset + appendLength; if (bytes == null) { bytes = new byte[num]; return; } int num2 = bytes.Length; if (num <= num2) { return; } int num3 = num; if (num3 < 256) { num3 = 256; FastResize(ref bytes, num3); return; } if (num3 < num2 * 2) { num3 = num2 * 2; } FastResize(ref bytes, num3); } public static void FastResize(ref byte[] array, int newSize) { if (newSize < 0) { throw new ArgumentOutOfRangeException("newSize"); } byte[] array2 = array; if (array2 == null) { array = new byte[newSize]; } else if (array2.Length != newSize) { byte[] array3 = new byte[newSize]; Buffer.BlockCopy(array2, 0, array3, 0, (array2.Length > newSize) ? newSize : array2.Length); array = array3; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteBoolean(ref byte[] bytes, int offset, bool value) { EnsureCapacity(ref bytes, offset, 1); bytes[offset] = (byte)(value ? 1u : 0u); return 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteBooleanUnsafe(ref byte[] bytes, int offset, bool value) { bytes[offset] = (byte)(value ? 1u : 0u); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteBooleanTrueUnsafe(ref byte[] bytes, int offset) { bytes[offset] = 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteBooleanFalseUnsafe(ref byte[] bytes, int offset) { bytes[offset] = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ReadBoolean(ref byte[] bytes, int offset) { if (bytes[offset] != 0) { return true; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteByte(ref byte[] bytes, int offset, byte value) { EnsureCapacity(ref bytes, offset, 1); bytes[offset] = value; return 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte ReadByte(ref byte[] bytes, int offset) { return bytes[offset]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteBytes(ref byte[] bytes, int offset, byte[] value) { EnsureCapacity(ref bytes, offset, value.Length); Buffer.BlockCopy(value, 0, bytes, offset, value.Length); return value.Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] ReadBytes(ref byte[] bytes, int offset, int count) { byte[] array = new byte[count]; Buffer.BlockCopy(bytes, offset, array, 0, count); return array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteSByte(ref byte[] bytes, int offset, sbyte value) { EnsureCapacity(ref bytes, offset, 1); bytes[offset] = (byte)value; return 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte ReadSByte(ref byte[] bytes, int offset) { return (sbyte)bytes[offset]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int WriteSingle(ref byte[] bytes, int offset, float value) { EnsureCapacity(ref bytes, offset, 4); if (offset % 4 == 0) { fixed (byte* ptr = bytes) { *(float*)(ptr + offset) = value; } } else { uint num = *(uint*)(&value); bytes[offset] = (byte)num; bytes[offset + 1] = (byte)(num >> 8); bytes[offset + 2] = (byte)(num >> 16); bytes[offset + 3] = (byte)(num >> 24); } return 4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static float ReadSingle(ref byte[] bytes, int offset) { if (offset % 4 == 0) { fixed (byte* ptr = bytes) { return *(float*)(ptr + offset); } } uint num = (uint)(bytes[offset] | (bytes[offset + 1] << 8) | (bytes[offset + 2] << 16) | (bytes[offset + 3] << 24)); return *(float*)(&num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int WriteDouble(ref byte[] bytes, int offset, double value) { EnsureCapacity(ref bytes, offset, 8); if (offset % 8 == 0) { fixed (byte* ptr = bytes) { *(double*)(ptr + offset) = value; } } else { ulong num = *(ulong*)(&value); bytes[offset] = (byte)num; bytes[offset + 1] = (byte)(num >> 8); bytes[offset + 2] = (byte)(num >> 16); bytes[offset + 3] = (byte)(num >> 24); bytes[offset + 4] = (byte)(num >> 32); bytes[offset + 5] = (byte)(num >> 40); bytes[offset + 6] = (byte)(num >> 48); bytes[offset + 7] = (byte)(num >> 56); } return 8; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static double ReadDouble(ref byte[] bytes, int offset) { if (offset % 8 == 0) { fixed (byte* ptr = bytes) { return *(double*)(ptr + offset); } } uint num = (uint)(bytes[offset] | (bytes[offset + 1] << 8) | (bytes[offset + 2] << 16) | (bytes[offset + 3] << 24)); ulong num2 = (ulong)(((long)(bytes[offset + 4] | (bytes[offset + 5] << 8) | (bytes[offset + 6] << 16) | (bytes[offset + 7] << 24)) << 32) | num); return *(double*)(&num2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int WriteInt16(ref byte[] bytes, int offset, short value) { EnsureCapacity(ref bytes, offset, 2); fixed (byte* ptr = bytes) { *(short*)(ptr + offset) = value; } return 2; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static short ReadInt16(ref byte[] bytes, int offset) { fixed (byte* ptr = bytes) { return *(short*)(ptr + offset); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int WriteInt32(ref byte[] bytes, int offset, int value) { EnsureCapacity(ref bytes, offset, 4); fixed (byte* ptr = bytes) { *(int*)(ptr + offset) = value; } return 4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void WriteInt32Unsafe(ref byte[] bytes, int offset, int value) { fixed (byte* ptr = bytes) { *(int*)(ptr + offset) = value; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int ReadInt32(ref byte[] bytes, int offset) { fixed (byte* ptr = bytes) { return *(int*)(ptr + offset); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int WriteInt64(ref byte[] bytes, int offset, long value) { EnsureCapacity(ref bytes, offset, 8); fixed (byte* ptr = bytes) { *(long*)(ptr + offset) = value; } return 8; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static long ReadInt64(ref byte[] bytes, int offset) { fixed (byte* ptr = bytes) { return *(long*)(ptr + offset); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int WriteUInt16(ref byte[] bytes, int offset, ushort value) { EnsureCapacity(ref bytes, offset, 2); fixed (byte* ptr = bytes) { *(ushort*)(ptr + offset) = value; } return 2; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static ushort ReadUInt16(ref byte[] bytes, int offset) { fixed (byte* ptr = bytes) { return *(ushort*)(ptr + offset); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int WriteUInt32(ref byte[] bytes, int offset, uint value) { EnsureCapacity(ref bytes, offset, 4); fixed (byte* ptr = bytes) { *(uint*)(ptr + offset) = value; } return 4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static uint ReadUInt32(ref byte[] bytes, int offset) { fixed (byte* ptr = bytes) { return *(uint*)(ptr + offset); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int WriteUInt64(ref byte[] bytes, int offset, ulong value) { EnsureCapacity(ref bytes, offset, 8); fixed (byte* ptr = bytes) { *(ulong*)(ptr + offset) = value; } return 8; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static ulong ReadUInt64(ref byte[] bytes, int offset) { fixed (byte* ptr = bytes) { return *(ulong*)(ptr + offset); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteChar(ref byte[] bytes, int offset, char value) { return WriteUInt16(ref bytes, offset, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static char ReadChar(ref byte[] bytes, int offset) { return (char)ReadUInt16(ref bytes, offset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteString(ref byte[] bytes, int offset, string value) { int maxByteCount = StringEncoding.UTF8.GetMaxByteCount(value.Length); EnsureCapacity(ref bytes, offset, maxByteCount); return StringEncoding.UTF8.GetBytes(value, 0, value.Length, bytes, offset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ReadString(ref byte[] bytes, int offset, int count) { return StringEncoding.UTF8.GetString(bytes, offset, count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int WriteDecimal(ref byte[] bytes, int offset, decimal value) { EnsureCapacity(ref bytes, offset, 16); fixed (byte* ptr = bytes) { *(decimal*)(ptr + offset) = value; } return 16; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static decimal ReadDecimal(ref byte[] bytes, int offset) { fixed (byte* ptr = bytes) { return *(decimal*)(ptr + offset); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static int WriteGuid(ref byte[] bytes, int offset, Guid value) { EnsureCapacity(ref bytes, offset, 16); fixed (byte* ptr = bytes) { *(Guid*)(ptr + offset) = value; } return 16; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static Guid ReadGuid(ref byte[] bytes, int offset) { fixed (byte* ptr = bytes) { return *(Guid*)(ptr + offset); } } public unsafe static int WriteTimeSpan(ref byte[] bytes, int offset, TimeSpan timeSpan) { long ticks = timeSpan.Ticks; long num = ticks / 10000000; int num2; checked { num2 = (int)unchecked(ticks % 10000000) * 100; EnsureCapacity(ref bytes, offset, 12); } fixed (byte* ptr = bytes) { *(long*)checked(unchecked((nuint)ptr) + unchecked((nuint)offset)) = num; *(int*)checked(unchecked((nuint)ptr) + unchecked((nuint)offset) + 8) = num2; } return 12; } public unsafe static TimeSpan ReadTimeSpan(ref byte[] bytes, int offset) { fixed (byte* ptr = bytes) { long num = *(long*)checked(unchecked((nuint)ptr) + unchecked((nuint)offset)); int num2 = *(int*)checked(unchecked((nuint)ptr) + unchecked((nuint)offset) + 8); if (!Duration.IsNormalized(num, num2)) { throw new InvalidOperationException("Duration was not a valid normalized duration"); } checked { return TimeSpan.FromTicks(num * 10000000 + unchecked(num2 / 100)); } } } public unsafe static int WriteDateTime(ref byte[] bytes, int offset, DateTime dateTime) { dateTime = dateTime.ToUniversalTime(); long num = dateTime.Ticks / 10000000; int num2 = (int)(dateTime.Ticks % 10000000) * 100; EnsureCapacity(ref bytes, offset, 12); fixed (byte* ptr = bytes) { *(long*)(ptr + offset) = num - 62135596800L; *(int*)(ptr + offset + 8) = num2; } return 12; } public unsafe static DateTime ReadDateTime(ref byte[] bytes, int offset) { fixed (byte* ptr = bytes) { long num = *(long*)(ptr + offset); int num2 = *(int*)(ptr + offset + 8); if (!Timestamp.IsNormalized(num, num2)) { throw new InvalidOperationException($"Timestamp contains invalid values: Seconds={num}; Nanos={num2}"); } DateTime unixEpoch = Timestamp.UnixEpoch; return unixEpoch.AddSeconds(num).AddTicks(num2 / 100); } } } internal class DynamicAssembly { private readonly object gate = new object(); private readonly string moduleName; private readonly AssemblyBuilder assemblyBuilder; private readonly ModuleBuilder moduleBuilder; public ModuleBuilder ModuleBuilder => moduleBuilder; public DynamicAssembly(string moduleName) { this.moduleName = moduleName; assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(moduleName), AssemblyBuilderAccess.Run); moduleBuilder = assemblyBuilder.DefineDynamicModule(moduleName); } } internal static class HashHelpers { public static readonly int[] primes = new int[104] { 3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919, 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437, 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369, 8639249, 10367101, 12440537, 14928671, 17914409, 21497293, 25796759, 30956117, 37147349, 44576837, 53492207, 64190669, 77028803, 92434613, 110921543, 133105859, 159727031, 191672443, 230006941, 276008387, 331210079, 397452101, 476942527, 572331049, 686797261, 824156741, 988988137, 1186785773, 1424142949, 1708971541, 2050765853, 2146435069 }; public const int MaxPrimeArrayLength = 2146435069; public static int GetPrime(int min) { if (min < 0) { throw new ArgumentException("Arg_HTCapacityOverflow"); } for (int i = 0; i < primes.Length; i++) { int num = primes[i]; if (num >= min) { return num; } } return min; } public static int GetMinPrime() { return primes[0]; } public static int ExpandPrime(int oldSize) { int num = 2 * oldSize; if ((uint)num > 2146435069u && 2146435069 > oldSize) { return 2146435069; } return GetPrime(num); } } internal static class ILGeneratorExtensions { public static void EmitLdloc(this ILGenerator il, int index) { switch (index) { case 0: il.Emit(OpCodes.Ldloc_0); return; case 1: il.Emit(OpCodes.Ldloc_1); return; case 2: il.Emit(OpCodes.Ldloc_2); return; case 3: il.Emit(OpCodes.Ldloc_3); return; } if (index <= 255) { il.Emit(OpCodes.Ldloc_S, (byte)index); } else { il.Emit(OpCodes.Ldloc, (short)index); } } public static void EmitStloc(this ILGenerator il, int index) { switch (index) { case 0: il.Emit(OpCodes.Stloc_0); return; case 1: il.Emit(OpCodes.Stloc_1); return; case 2: il.Emit(OpCodes.Stloc_2); return; case 3: il.Emit(OpCodes.Stloc_3); return; } if (index <= 255) { il.Emit(OpCodes.Stloc_S, (byte)index); } else { il.Emit(OpCodes.Stloc, (short)index); } } public static void EmitLdloca(this ILGenerator il, int index) { if (index <= 255) { il.Emit(OpCodes.Ldloca_S, (byte)index); } else { il.Emit(OpCodes.Ldloca, (short)index); } } public static void EmitLdc_I4(this ILGenerator il, int value) { switch (value) { case -1: il.Emit(OpCodes.Ldc_I4_M1); return; case 0: il.Emit(OpCodes.Ldc_I4_0); return; case 1: il.Emit(OpCodes.Ldc_I4_1); return; case 2: il.Emit(OpCodes.Ldc_I4_2); return; case 3: il.Emit(OpCodes.Ldc_I4_3); return; case 4: il.Emit(OpCodes.Ldc_I4_4); return; case 5: il.Emit(OpCodes.Ldc_I4_5); return; case 6: il.Emit(OpCodes.Ldc_I4_6); return; case 7: il.Emit(OpCodes.Ldc_I4_7); return; case 8: il.Emit(OpCodes.Ldc_I4_8); return; } if (value >= -128 && value <= 127) { il.Emit(OpCodes.Ldc_I4_S, (sbyte)value); } else { il.Emit(OpCodes.Ldc_I4, value); } } } internal static class ReflectionExtensions { public static bool IsNullable(this TypeInfo type) { if (type.IsGenericType) { return type.GetGenericTypeDefinition() == typeof(Nullable<>); } return false; } } internal static class SR { public const string InvalidOperation_EnumFailedVersion = "InvalidOperation_EnumFailedVersion"; public const string InvalidOperation_EnumOpCantHappen = "InvalidOperation_EnumOpCantHappen"; public const string ArgumentOutOfRange_Index = "ArgumentOutOfRange_Index"; public const string Argument_InvalidArrayType = "Argument_InvalidArrayType"; public const string NotSupported_ValueCollectionSet = "NotSupported_ValueCollectionSet"; public const string Arg_RankMultiDimNotSupported = "Arg_RankMultiDimNotSupported"; public const string Arg_ArrayPlusOffTooSmall = "Arg_ArrayPlusOffTooSmall"; public const string Arg_NonZeroLowerBound = "Arg_NonZeroLowerBound"; public const string NotSupported_KeyCollectionSet = "NotSupported_KeyCollectionSet"; public const string Arg_WrongType = "Arg_WrongType"; public const string ArgumentOutOfRange_NeedNonNegNum = "ArgumentOutOfRange_NeedNonNegNum"; public const string Arg_HTCapacityOverflow = "Arg_HTCapacityOverflow"; public const string Argument_AddingDuplicate = "Argument_AddingDuplicate"; public static string Format(string f, params object[] args) { return string.Format(f, args); } } internal static class StringEncoding { public static Encoding UTF8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); } } namespace ZeroFormatter.Formatters { internal class DateTimeOffsetFormatter<TTypeResolver> : Formatter<TTypeResolver, DateTimeOffset> where TTypeResolver : ITypeResolver, new() { public override bool NoUseDirtyTracker => true; public override int? GetLength() { return 14; } public override int Serialize(ref byte[] bytes, int offset, DateTimeOffset value) { BinaryUtil.WriteDateTime(ref bytes, offset, new DateTime(value.Ticks, DateTimeKind.Utc)); BinaryUtil.WriteInt16(ref bytes, offset + 12, (short)value.Offset.TotalMinutes); return 14; } public override DateTimeOffset Deserialize(ref byte[] bytes, int offset, DirtyTracker tracker, out int byteSize) { byteSize = 14; DateTime dateTime = BinaryUtil.ReadDateTime(ref bytes, offset); short num = BinaryUtil.ReadInt16(ref bytes, offset + 12); return new DateTimeOffset(dateTime.Ticks, TimeSpan.FromMinutes(num)); } } internal class NullableDateTimeOffsetFormatter<TTypeResolver> : Formatter<TTypeResolver, DateTimeOffset?> where TTypeResolver : ITypeResolver, new() { public override bool NoUseDirtyTracker => true; public override int? GetLength() { return 15; } public override int Serialize(ref byte[] bytes, int offset, DateTimeOffset? value) { BinaryUtil.EnsureCapacity(ref bytes, offset, 13); if (value.HasValue) { BinaryUtil.WriteBooleanTrueUnsafe(ref bytes, offset); BinaryUtil.WriteDateTime(ref bytes, offset + 1, new DateTime(value.Value.Ticks, DateTimeKind.Utc)); BinaryUtil.WriteInt16(ref bytes, offset + 13, (short)value.Value.Offset.TotalMinutes); } else { BinaryUtil.WriteBooleanFalseUnsafe(ref bytes, offset); } return 15; } public override DateTimeOffset? Deserialize(ref byte[] bytes, int offset, DirtyTracker tracker, out int byteSize) { byteSize = 15; if (!BinaryUtil.ReadBoolean(ref bytes, offset)) { return null; } DateTime dateTime = BinaryUtil.ReadDateTime(ref bytes, offset + 1); short num = BinaryUtil.ReadInt16(ref bytes, offset + 13); return new DateTimeOffset(dateTime.Ticks, TimeSpan.FromMinutes(num)); } } internal class Int16ArrayFormatter<TTypeResolver> : Formatter<TTypeResolver, short[]> where TTypeResolver : ITypeResolver, new() { public override bool NoUseDirtyTracker => true; public override int? GetLength() { return null; } public override int Serialize(ref byte[] bytes, int offset, short[] value) { if (value == null) { BinaryUtil.WriteInt32(ref bytes, offset, -1); return 4; } int num = value.Length * 2; BinaryUtil.EnsureCapacity(ref bytes, offset, num + 4); BinaryUtil.WriteInt32Unsafe(ref bytes, offset, value.Length); Buffer.BlockCopy(value, 0, bytes, offset + 4, num); return num + 4; } public override short[] Deserialize(ref byte[] bytes, int offset, DirtyTracker tracker, out int byteSize) { tracker.Dirty(); int num = BinaryUtil.ReadInt32(ref bytes, offset); if (num == -1) { byteSize = 4; return null; } byteSize = num * 2 + 4; int num2 = num * 2; ZeroFormatterSerializer.ValidateNewLength(num2); short[] array = new short[num]; Buffer.BlockCopy(bytes, offset + 4, array, 0, num2); return array; } } internal class Int32ArrayFormatter<TTypeResolver> : Formatter<TTypeResolver, int[]> where TTypeResolver : ITypeResolver, new() { public override bool NoUseDirtyTracker => true; public override int? GetLength() { return null; } public override int Serialize(ref byte[] bytes, int offset, int[] value) { if (value == null) { BinaryUtil.WriteInt32(ref bytes, offset, -1); return 4; } int num = value.Length * 4; BinaryUtil.EnsureCapacity(ref bytes, offset, num + 4); BinaryUtil.WriteInt32Unsafe(ref bytes, offset, value.Length); Buffer.BlockCopy(value, 0, bytes, offset + 4, num); return num + 4; } public override int[] Deserialize(ref byte[] bytes, int offset, DirtyTracker tracker, out int byteSize) { tracker.Dirty(); int num = BinaryUtil.ReadInt32(ref bytes, offset); if (num == -1) { byteSize = 4; return null; } byteSize = num * 4 + 4; int num2 = num * 4; ZeroFormatterSerializer.ValidateNewLength(num2); int[] array = new int[num]; Buffer.BlockCopy(bytes, offset + 4, array, 0, num2); return array; } } internal class Int64ArrayFormatter<TTypeResolver> : Formatter<TTypeResolver, long[]> where TTypeResolver : ITypeResolver, new() { public override bool NoUseDirtyTracker => true; public override int? GetLength() { return null; } public override int Serialize(ref byte[] bytes, int offset, long[] value) { if (value == null) { BinaryUtil.WriteInt32(ref bytes, offset, -1); return 4; } int num = value.Length * 8; BinaryUtil.EnsureCapacity(ref bytes, offset, num + 4); BinaryUtil.WriteInt32Unsafe(ref bytes, offset, value.Length); Buffer.BlockCopy(value, 0, bytes, offset + 4, num); return num + 4; } public override long[] Deserialize(ref byte[] bytes, int offset, DirtyTracker tracker, out int byteSize) { tracker.Dirty(); int num = BinaryUtil.ReadInt32(ref bytes, offset); if (num == -1) { byteSize = 4; return null; } byteSize = num * 8 + 4; int num2 = num * 8; ZeroFormatterSerializer.ValidateNewLength(num2); long[] array = new long[num]; Buffer.BlockCopy(bytes, offset + 4, array, 0, num2); return array; } } internal class UInt16ArrayFormatter<TTypeResolver> : Formatter<TTypeResolver, ushort[]> where TTypeResolver : ITypeResolver, new() { public override bool NoUseDirtyTracker => true; public override int? GetLength() { return null; } public override int Serialize(ref byte[] bytes, int offset, ushort[] value) { if (value == null) { BinaryUtil.WriteInt32(ref bytes, offset, -1); r
SourceRole.dll
Decompiled 4 months agousing System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("SourceRole")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SourceRole")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("08b45a92-bf19-40cb-9712-436e153d8fcf")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace Talespire; public enum SourceRole { gm = 0, player = 1, creature = 2, hideVolume = 3, other = 888, anonymous = 999 }