Decompiled source of RPCPlugin v2.2.2

RPCPlugin.dll

Decompiled 4 months ago
using 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 ago
using 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
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 ago
using 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
}