Decompiled source of Custom Car Mod v1.0.0
Distance.CustomCar.dll
Decompiled 5 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Distance.CustomCar.Data.Car; using Distance.CustomCar.Data.Errors; using Distance.CustomCar.Data.Materials; using Events; using Events.Car; using Events.MainMenu; using HarmonyLib; using Newtonsoft.Json; using Newtonsoft.Json.Linq; 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("Distance.ModTemplate")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Distance.ModTemplate")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("7bcb2908-b003-45d9-be68-50cba5217603")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] public static class GameObjectExtensions { public static string FullName(this GameObject obj) { if (!Object.op_Implicit((Object)(object)obj.transform.parent)) { return ((Object)obj).name; } return ((Component)obj.transform.parent).gameObject.FullName() + "/" + ((Object)obj).name; } } namespace Distance.CustomCar { public class Assets { private string _filePath = null; private string RootDirectory { get; } private string FileName { get; set; } private string FilePath => _filePath ?? Path.Combine(Path.Combine(RootDirectory, "Assets"), FileName); public object Bundle { get; private set; } private Assets() { } public Assets(string fileName) { RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location); FileName = fileName; if (!File.Exists(FilePath)) { Mod.Log.LogInfo((object)("Couldn't find requested asset bundle at " + FilePath)); } else { Bundle = Load(); } } public static Assets FromUnsafePath(string filePath) { if (!File.Exists(filePath)) { Mod.Log.LogInfo((object)("Could not find requested asset bundle at " + filePath)); return null; } Assets assets = new Assets { _filePath = filePath, FileName = Path.GetFileName(filePath) }; assets.Bundle = assets.Load(); if (assets.Bundle == null) { return null; } return assets; } private object Load() { try { object result = AssetBundleBridge.LoadFrom(FilePath); Mod.Log.LogInfo((object)("Loaded asset bundle " + FilePath)); return result; } catch (Exception ex) { Mod.Log.LogInfo((object)ex); return null; } } } internal static class AssetBundleBridge { public static Type AssetBundleType => Kernel.FindTypeByFullName("UnityEngine.AssetBundle", "UnityEngine"); private static MethodInfo LoadFromFile => AssetBundleType.GetMethod("LoadFromFile", new Type[1] { typeof(string) }); public static object LoadFrom(string path) { MethodInfo loadFromFile = LoadFromFile; object[] parameters = new string[1] { path }; return loadFromFile.Invoke(null, parameters); } } internal static class Kernel { internal static Type FindTypeByFullName(string fullName, string assemblyFilter) { IEnumerable<Assembly> enumerable = from a in AppDomain.CurrentDomain.GetAssemblies() where a.GetName().Name.Contains(assemblyFilter) select a; foreach (Assembly item in enumerable) { Type type = item.GetTypes().FirstOrDefault((Type t) => t.FullName == fullName); if ((object)type == null) { continue; } return type; } Mod.Log.LogInfo((object)("Type " + fullName + " wasn't found in the main AppDomain at this moment.")); throw new Exception("Type " + fullName + " wasn't found in the main AppDomain at this moment."); } } public class FileSystem { public string RootDirectory { get; } public string VirtualFileSystemRoot => Path.Combine(RootDirectory, "Data"); public FileSystem() { RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location); if (!Directory.Exists(VirtualFileSystemRoot)) { Directory.CreateDirectory(VirtualFileSystemRoot); } } public bool FileExists(string path) { string path2 = Path.Combine(VirtualFileSystemRoot, path); return File.Exists(path2); } public bool DirectoryExists(string path) { string path2 = Path.Combine(VirtualFileSystemRoot, path); return Directory.Exists(path2); } public bool PathExists(string path) { return FileExists(path) || DirectoryExists(path); } public byte[] ReadAllBytes(string filePath) { string text = Path.Combine(VirtualFileSystemRoot, filePath); if (!File.Exists(text)) { Mod.Log.LogInfo((object)("Couldn't read a file for path '" + text + "'. File does not exist.")); return null; } return File.ReadAllBytes(text); } public FileStream CreateFile(string filePath, bool overwrite = false) { string text = Path.Combine(VirtualFileSystemRoot, filePath); if (File.Exists(text)) { if (!overwrite) { Mod.Log.LogInfo((object)("Couldn't create a mod VFS file for path '" + text + "'. The file already exists.")); return null; } Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'. File does not exist.")); RemoveFile(filePath); } try { return File.Create(text); } catch (Exception ex) { Mod.Log.LogInfo((object)("Couldn't create a mod VFS file for path '" + text + "'.")); Mod.Log.LogInfo((object)ex); return null; } } public void RemoveFile(string filePath) { string text = Path.Combine(VirtualFileSystemRoot, filePath); if (!File.Exists(text)) { Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'. File does not exist.")); return; } try { File.Delete(text); } catch (Exception ex) { Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'.")); Mod.Log.LogInfo((object)ex); } } public void IterateOver(string directoryPath, Action<string, bool> action, bool sort = true) { string text = Path.Combine(VirtualFileSystemRoot, directoryPath); if (!Directory.Exists(text)) { Mod.Log.LogInfo((object)("Cannot iterate over directory at '" + text + "'. It doesn't exist.")); return; } List<string> list = Directory.GetFiles(text).ToList(); list.AddRange(Directory.GetDirectories(text)); if (sort) { list = list.OrderBy((string x) => x).ToList(); } foreach (string item in list) { try { bool arg = Directory.Exists(item); action(item, arg); } catch (Exception ex) { Mod.Log.LogInfo((object)("Action for the element at path '" + item + "' failed. See file system exception log for details.")); Mod.Log.LogInfo((object)ex); break; } } } public List<string> GetDirectories(string directoryPath, string searchPattern) { string text = Path.Combine(VirtualFileSystemRoot, directoryPath); if (!Directory.Exists(text)) { Mod.Log.LogInfo((object)("Cannot get directories in directory at '" + text + "'. It doesn't exist.")); return null; } return Directory.GetDirectories(text, searchPattern).ToList(); } public List<string> GetDirectories(string directoryPath) { return GetDirectories(directoryPath, "*"); } public List<string> GetFiles(string directoryPath, string searchPattern) { string text = Path.Combine(VirtualFileSystemRoot, directoryPath); if (!Directory.Exists(text)) { Mod.Log.LogInfo((object)("Cannot get files in directory at '" + text + "'. It doesn't exist.")); return null; } return Directory.GetFiles(text, searchPattern).ToList(); } public List<string> GetFiles(string directoryPath) { return GetFiles(directoryPath, "*"); } public FileStream OpenFile(string filePath, FileMode fileMode, FileAccess fileAccess, FileShare fileShare) { string text = Path.Combine(VirtualFileSystemRoot, filePath); if (!File.Exists(text)) { Mod.Log.LogInfo((object)("Couldn't open a VFS file. The requested file: '" + text + "' does not exist.")); return null; } try { return File.Open(text, fileMode, fileAccess, fileShare); } catch (Exception ex) { Mod.Log.LogInfo((object)("Couldn't open a VFS file for path '" + text + "'.")); Mod.Log.LogInfo((object)ex); return null; } } public FileStream OpenFile(string filePath) { return OpenFile(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); } public string CreateDirectory(string directoryName) { string text = Path.Combine(VirtualFileSystemRoot, directoryName); try { Directory.CreateDirectory(text); return text; } catch (Exception ex) { Mod.Log.LogInfo((object)("Couldn't create a VFS directory for path '" + text + "'.")); Mod.Log.LogInfo((object)ex); return string.Empty; } } public void RemoveDirectory(string directoryPath) { string text = Path.Combine(VirtualFileSystemRoot, directoryPath); if (!Directory.Exists(text)) { Mod.Log.LogInfo((object)("Couldn't remove a VFS directory for path '" + text + "'. Directory does not exist.")); return; } try { Directory.Delete(text, recursive: true); } catch (Exception ex) { Mod.Log.LogInfo((object)("Couldn't remove a VFS directory for path '" + text + "'.")); Mod.Log.LogInfo((object)ex); } } public static string GetValidFileName(string dirtyFileName, string replaceInvalidCharsWith = "_") { return Regex.Replace(dirtyFileName, "[^\\w\\s\\.]", replaceInvalidCharsWith, RegexOptions.None); } public static string GetValidFileNameToLower(string dirtyFileName, string replaceInvalidCharsWith = "_") { return GetValidFileName(dirtyFileName, replaceInvalidCharsWith).ToLower(); } } public sealed class MessageBox { private readonly string Message = ""; private readonly string Title = ""; private float Time = 0f; private ButtonType Buttons = (ButtonType)0; private Action Confirm; private Action Cancel; private MessageBox(string message, string title) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) Message = message; Title = title; Confirm = EmptyAction; Cancel = EmptyAction; } public static MessageBox Create(string content, string title = "") { return new MessageBox(content, title); } public MessageBox SetButtons(MessageButtons buttons) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) Buttons = (ButtonType)buttons; return this; } public MessageBox SetTimeout(float delay) { Time = delay; return this; } public MessageBox OnConfirm(Action action) { Confirm = action; return this; } public MessageBox OnCancel(Action action) { Cancel = action; return this; } public void Show() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0042: Expected O, but got Unknown G.Sys.MenuPanelManager_.ShowMessage(Message, Title, (OnButtonClicked)delegate { Confirm(); }, (OnButtonClicked)delegate { Cancel(); }, Buttons, false, (Pivot)4, Time); } private void EmptyAction() { } } [Flags] public enum MessageButtons { Ok = 0, OkCancel = 1, YesNo = 2 } [BepInPlugin("Distance.CustomCar", "Custom Car", "1.0")] public sealed class Mod : BaseUnityPlugin { private const string modGUID = "Distance.CustomCar"; private const string modName = "Custom Car"; private const string modVersion = "1.0"; public static string UseTrumpetKey = "Use Trumpet Horn"; private static readonly Harmony harmony = new Harmony("Distance.CustomCar"); public static ManualLogSource Log = new ManualLogSource("Custom Car"); public static Mod Instance; private bool displayErrors_ = true; public static ConfigEntry<bool> UseTrumpetHorn { get; set; } public static int DefaultCarCount { get; private set; } public static int ModdedCarCount => TotalCarCount - DefaultCarCount; public static int TotalCarCount { get; private set; } public ErrorList Errors { get; set; } public ProfileCarColors CarColors { get; set; } private void Awake() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown if ((Object)(object)Instance == (Object)null) { Instance = this; } Log = Logger.CreateLogSource("Distance.CustomCar"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Thanks for using Custom Cars!"); Errors = new ErrorList(((BaseUnityPlugin)this).Logger); CarColors = ((Component)this).gameObject.AddComponent<ProfileCarColors>(); UseTrumpetHorn = ((BaseUnityPlugin)this).Config.Bind<bool>("General", UseTrumpetKey, false, new ConfigDescription("Custom car models will use the encryptor horn (the \"doot!\" trumpet).", (AcceptableValueBase)null, new object[0])); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading..."); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded!"); } public void Start() { ProfileManager profileManager_ = G.Sys.ProfileManager_; DefaultCarCount = profileManager_.CarInfos_.Length; CarInfos carInfos = new CarInfos(); carInfos.CollectInfos(); CarBuilder carBuilder = new CarBuilder(); carBuilder.CreateCars(carInfos); TotalCarCount = profileManager_.CarInfos_.Length; CarColors.LoadAll(); Errors.Show(); } private void OnEnable() { StaticEvent<Data>.Subscribe((Delegate<Data>)OnMainMenuLoaded); } private void OnDisable() { StaticEvent<Data>.Unsubscribe((Delegate<Data>)OnMainMenuLoaded); } private void OnMainMenuLoaded(Data _) { if (displayErrors_) { Errors.Show(); displayErrors_ = false; } } private void OnConfigChanged(object sender, EventArgs e) { SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); if (val != null) { } } } public class ProfileCarColors : MonoBehaviour { internal Settings Config; public event Action<ProfileCarColors> OnChanged; protected void Load() { Config = new Settings("CustomCars"); } protected void Awake() { Load(); Save(); } protected Section Profile(string profileName) { return Config.GetOrCreate(profileName, new Section()); } protected Section Vehicle(string profileName, string vehicleName) { return Profile(profileName).GetOrCreate(vehicleName, new Section()); } protected CarColors GetCarColors(string profileName, string vehicleName) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) Section vehicle = Vehicle(profileName, vehicleName); CarColors val = default(CarColors); val.primary_ = GetColor(vehicle, "primary", Colors.whiteSmoke); val.secondary_ = GetColor(vehicle, "secondary", Colors.darkGray); val.glow_ = GetColor(vehicle, "glow", Colors.cyan); val.sparkle_ = GetColor(vehicle, "sparkle", Colors.lightSlateGray); CarColors val2 = val; SetCarColors(profileName, vehicleName, val2); return val2; } protected Color GetColor(Section vehicle, string category, Color defaultColor) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Section orCreate = vehicle.GetOrCreate(category, new Section()); float orCreate2 = orCreate.GetOrCreate("r", defaultColor.r); float orCreate3 = orCreate.GetOrCreate("g", defaultColor.g); float orCreate4 = orCreate.GetOrCreate("b", defaultColor.b); float orCreate5 = orCreate.GetOrCreate("a", defaultColor.a); return new Color(orCreate2, orCreate3, orCreate4, orCreate5); } protected void SetCarColors(string profileName, string vehicleName, CarColors colors) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) Section section = Vehicle(profileName, vehicleName); section["primary"] = ToSection(colors.primary_); section["secondary"] = ToSection(colors.secondary_); section["glow"] = ToSection(colors.glow_); section["sparkle"] = ToSection(colors.sparkle_); Section section2 = Profile(profileName); section2[vehicleName] = section; Config[profileName] = section2; } protected Section ToSection(Color color) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0051: Unknown result type (might be due to invalid IL or missing references) return new Section { ["r"] = color.r, ["g"] = color.g, ["b"] = color.b, ["a"] = color.a }; } protected void Save() { Config.Save(); this.OnChanged?.Invoke(this); } public void LoadAll() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) ProfileManager profileManager_ = G.Sys.ProfileManager_; List<Profile> profiles_ = profileManager_.profiles_; foreach (Profile item in profiles_) { CarColors[] array = (CarColors[])(object)new CarColors[Mod.TotalCarCount]; for (int i = 0; i < profileManager_.CarInfos_.Length; i++) { if (i < Mod.DefaultCarCount) { array[i] = item.carColorsList_[i]; continue; } CarInfo val = profileManager_.CarInfos_[i]; CarColors carColors = GetCarColors(item.FileName_, val.name_); array[i] = carColors; } item.carColorsList_ = array; } } public void SaveAll() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) ProfileManager profileManager_ = G.Sys.ProfileManager_; List<Profile> profiles_ = profileManager_.profiles_; foreach (Profile item in profiles_) { for (int i = 0; i < profileManager_.CarInfos_.Length; i++) { if (i >= Mod.DefaultCarCount) { CarInfo val = profileManager_.CarInfos_[i]; CarColors colors = item.carColorsList_[i]; SetCarColors(item.FileName_, val.name_, colors); } } } Save(); } } public class Section : Dictionary<string, object> { public bool Dirty { get; protected set; } public new object this[string key] { get { if (!ContainsKey(key)) { return null; } return base[key]; } set { if (!ContainsKey(key)) { Add(key, value); this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, base[key])); } else { object oldValue = base[key]; base[key] = value; this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, oldValue, base[key])); } Dirty = true; } } public event EventHandler<SettingsChangedEventArgs> ValueChanged; public T GetItem<T>(string key) { //IL_0084: Expected O, but got Unknown if (!ContainsKey(key)) { Mod.Log.LogInfo((object)("The key requested doesn't exist in store: '" + key + "'.")); throw new KeyNotFoundException("The key requested doesn't exist in store: '" + key + "'."); } try { object obj = this[key]; JToken val = (JToken)((obj is JToken) ? obj : null); if (val != null) { return val.ToObject<T>(); } return (T)Convert.ChangeType(this[key], typeof(T)); } catch (JsonException val2) { JsonException val3 = val2; Mod.Log.LogInfo((object)$"Failed to convert a JSON token to the requested type. String: {key} \n{val3}"); throw new SettingsException("Failed to convert a JSON token to the requested type.", key, isJsonFailure: true, (Exception)(object)val3); } catch (Exception ex) { try { return (T)Enum.ToObject(typeof(T), (long)this[key]); } catch { Mod.Log.LogInfo((object)$".NET type conversion exception has been thrown. String: {key} \n{ex}"); throw new SettingsException(".NET type conversion exception has been thrown.", key, isJsonFailure: false, ex); } } } public T GetOrCreate<T>(string key) where T : new() { if (!ContainsKey(key)) { this[key] = new T(); this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key])); } return GetItem<T>(key); } public T GetOrCreate<T>(string key, T defaultValue) { if (!ContainsKey(key)) { this[key] = defaultValue; this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key])); } return GetItem<T>(key); } public bool ContainsKey<T>(string key) { try { GetItem<T>(key); return true; } catch { return false; } } } public class Settings : Section { private string FileName { get; } private string RootDirectory { get; } private string SettingsDirectory => Path.Combine(RootDirectory, "Settings"); private string FilePath => Path.Combine(SettingsDirectory, FileName); public Settings(string fileName) { //IL_0084: Expected O, but got Unknown RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location); FileName = fileName + ".json"; Mod.Log.LogInfo((object)("Settings instance for '" + FilePath + "' initializing...")); if (File.Exists(FilePath)) { using StreamReader streamReader = new StreamReader(FilePath); string text = streamReader.ReadToEnd(); Section section = null; try { section = JsonConvert.DeserializeObject<Section>(text); } catch (JsonException val) { JsonException val2 = val; Mod.Log.LogInfo((object)val2); } catch (Exception ex) { Mod.Log.LogInfo((object)ex); } Mod.Log.LogInfo((object)"Just Deserialized the json"); if (section != null) { foreach (string key in section.Keys) { Add(key, section[key]); } } } base.Dirty = false; } public void Save(bool formatJson = true) { //IL_0057: Expected O, but got Unknown if (!Directory.Exists(SettingsDirectory)) { Directory.CreateDirectory(SettingsDirectory); } try { using (StreamWriter streamWriter = new StreamWriter(FilePath, append: false)) { streamWriter.WriteLine(JsonConvert.SerializeObject((object)this, (Formatting)1)); } base.Dirty = false; } catch (JsonException val) { JsonException val2 = val; Mod.Log.LogInfo((object)val2); } catch (Exception ex) { Mod.Log.LogInfo((object)ex); } } public void SaveIfDirty(bool formatJson = true) { if (base.Dirty) { Save(formatJson); } } } public class SettingsChangedEventArgs : EventArgs { public string Key { get; } public object OldValue { get; } public object NewValue { get; } public SettingsChangedEventArgs(string key, object oldValue = null, object newValue = null) { Key = key; OldValue = oldValue; NewValue = newValue; } } public class SettingsException : Exception { public string Key { get; } public bool IsJsonFailure { get; } public SettingsException(string message, string key, bool isJsonFailure, Exception innerException) : base(message, innerException) { Key = key; IsJsonFailure = isJsonFailure; } public SettingsException(string message, string key, bool isJsonFailure) : this(message, key, isJsonFailure, null) { } } } namespace Distance.CustomCar.Patches { [HarmonyPatch(typeof(CarAudio), "OnCarHornEvent")] internal static class OnCarHornEvent { [HarmonyPrefix] internal static bool Prefix(CarAudio __instance, Data data) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) int num = G.Sys.ProfileManager_.knownCars_[__instance.carLogic_.PlayerData_.CarName_]; if (num >= Mod.DefaultCarCount && Mod.UseTrumpetHorn.Value) { __instance.phantom_.SetRTPCValue("Horn_volume", Mathf.Clamp01(data.hornPercent_ + 0.5f)); __instance.phantom_.Play("SpookyHorn", 0f, true); return false; } return true; } } [HarmonyPatch(typeof(GadgetWithAnimation), "SetAnimationStateValues")] internal static class GadgetWithAnimation__SetAnimationStateValues { [HarmonyPrefix] internal static bool Prefix(GadgetWithAnimation __instance) { Animation componentInChildren = ((Component)__instance).GetComponentInChildren<Animation>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { return PatchAnimations(componentInChildren, __instance.animationName_); } return false; } private static bool PatchAnimations(Animation animation, string name) { if (Object.op_Implicit((Object)(object)animation)) { if (!ChangeBlendModeToBlend(((Component)animation).transform, name)) { return true; } AnimationState val = animation[name]; if (TrackedReference.op_Implicit((TrackedReference)(object)val)) { val.layer = 3; val.blendMode = (AnimationBlendMode)0; val.wrapMode = (WrapMode)8; val.enabled = true; val.weight = 1f; val.speed = 0f; } } return false; } private static bool ChangeBlendModeToBlend(Transform obj, string animationName) { for (int i = 0; i < obj.childCount; i++) { string text = ((Object)((Component)obj.GetChild(i)).gameObject).name.ToLower(); if (!text.StartsWith("#")) { continue; } text = text.Remove(0, 1); string[] array = text.Split(new char[1] { ';' }); if (array.Length == 1) { if (array[0] == "additive") { return false; } if (array[0] == "blend") { return true; } } if (array[1] == animationName.ToLower()) { if (array[0] == "additive") { return false; } if (array[0] == "blend") { return true; } } } return false; } } [HarmonyPatch(typeof(Profile), "Awake")] internal static class Profile__Awake { [HarmonyPostfix] internal static void Postfix(Profile __instance) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) CarColors[] array = (CarColors[])(object)new CarColors[G.Sys.ProfileManager_.carInfos_.Length]; for (int i = 0; i < array.Length; i++) { array[i] = G.Sys.ProfileManager_.carInfos_[i].colors_; } __instance.carColorsList_ = array; } } [HarmonyPatch(typeof(Profile), "Save")] internal static class Profile__Save { [HarmonyPostfix] internal static void Postfix() { Mod.Instance.CarColors.SaveAll(); } } [HarmonyPatch(typeof(Profile), "SetColorsForAllCars", new Type[] { typeof(CarColors) })] internal static class Profile__SetColorsForAllCars { [HarmonyPrefix] internal static bool Prefix(Profile __instance, CarColors cc) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) CarColors[] array = (CarColors[])(object)new CarColors[G.Sys.ProfileManager_.carInfos_.Length]; for (int i = 0; i < array.Length; i++) { array[i] = cc; } __instance.carColorsList_ = array; __instance.dataModified_ = true; return false; } } } namespace Distance.CustomCar.Data.Materials { public class MaterialInfos { public Material material; public int diffuseIndex = -1; public int normalIndex = -1; public int emitIndex = -1; public void ReplaceMaterialInRenderer(Renderer renderer, int materialIndex) { if (!((Object)(object)material == (Object)null) && !((Object)(object)renderer == (Object)null) && materialIndex < renderer.materials.Length) { ref Material reference = ref renderer.materials[materialIndex]; Material val = Object.Instantiate<Material>(material); if (diffuseIndex >= 0) { val.SetTexture(diffuseIndex, reference.GetTexture("_MainTex")); } if (emitIndex >= 0) { val.SetTexture(emitIndex, reference.GetTexture("_EmissionMap")); } if (normalIndex >= 0) { val.SetTexture(normalIndex, reference.GetTexture("_BumpMap")); } renderer.materials[materialIndex] = val; } } } public class MaterialPropertyExport { public string fromName; public string toName; public int fromID = -1; public int toID = -1; public PropertyType type; } public class MaterialPropertyInfo { public string shaderName; public string name; public int diffuseIndex = -1; public int normalIndex = -1; public int emitIndex = -1; public MaterialPropertyInfo(string _shaderName, string _name, int _diffuseIndex, int _normalIndex, int _emitIndex) { shaderName = _shaderName; name = _name; diffuseIndex = _diffuseIndex; normalIndex = _normalIndex; emitIndex = _emitIndex; } } public enum PropertyType { Color, ColorArray, Float, FloatArray, Int, Matrix, MatrixArray, Texture, Vector, VectorArray } } namespace Distance.CustomCar.Data.Errors { public class ErrorList : List<string> { private readonly ManualLogSource logger_; public ErrorList(ManualLogSource logger) { logger_ = logger; } public new void Add(string value) { base.Add(value); logger_.LogInfo((object)value); } public void Add(Exception value) { base.Add(value.ToString()); logger_.LogInfo((object)value); } public void Show() { if (this.Any()) { string arg = ((base.Count < 15) ? string.Join(Environment.NewLine, ToArray()) : "There were too many errors when loading custom cars to be displayed here, please check the logs in your mod installation directory."); MessageBox.Create($"Can't load the cars correctly: {base.Count} error(s)\n{arg}", "CUSTOM CARS - ERRORS").SetButtons(MessageButtons.Ok).Show(); } } } } namespace Distance.CustomCar.Data.Car { public class CarBuilder { private CarInfos infos_; public void CreateCars(CarInfos infos) { infos_ = infos; Dictionary<string, GameObject> dictionary = LoadAssetsBundles(); List<CreateCarReturnInfos> list = new List<CreateCarReturnInfos>(); foreach (KeyValuePair<string, GameObject> item in dictionary) { try { Mod.Log.LogInfo((object)("Creating car prefab for " + item.Key + " ...")); CreateCarReturnInfos createCarReturnInfos = CreateCar(item.Value); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item.Key.Substring(0, item.Key.LastIndexOf('(') - 1)); ((Object)createCarReturnInfos.car).name = fileNameWithoutExtension; list.Add(createCarReturnInfos); } catch (Exception value) { Mod.Log.LogInfo((object)("Could not load car prefab: " + item.Key)); Mod.Instance.Errors.Add("Could not load car prefab: " + item.Key); Mod.Instance.Errors.Add(value); } } RegisterCars(list); } private void RegisterCars(List<CreateCarReturnInfos> carsInfos) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) Mod.Log.LogInfo((object)$"Registering {carsInfos.Count} car(s)..."); ProfileManager profileManager_ = G.Sys.ProfileManager_; CarInfo[] array = ICollectionEx.ToArray<CarInfo>((ICollection<CarInfo>)profileManager_.carInfos_); profileManager_.carInfos_ = (CarInfo[])(object)new CarInfo[array.Length + carsInfos.Count]; ref Dictionary<string, int> unlockedCars_ = ref profileManager_.unlockedCars_; ref Dictionary<string, int> knownCars_ = ref profileManager_.knownCars_; for (int i = 0; i < profileManager_.carInfos_.Length; i++) { if (i < array.Length) { profileManager_.carInfos_[i] = array[i]; continue; } int index = i - array.Length; CarInfo val = new CarInfo { name_ = ((Object)carsInfos[index].car).name, prefabs_ = new CarPrefabs { carPrefab_ = carsInfos[index].car }, colors_ = carsInfos[index].colors }; if (!knownCars_.ContainsKey(val.name_) && !unlockedCars_.ContainsKey(val.name_)) { unlockedCars_.Add(val.name_, i); knownCars_.Add(val.name_, i); } else { Mod.Instance.Errors.Add("A car with the name " + val.name_ + " is already registered, rename the car file if they're the same."); Mod.Log.LogInfo((object)("Generating unique name for car " + val.name_)); string text = $"#{Guid.NewGuid():B}"; Mod.Log.LogInfo((object)("Using GUID: " + text)); val.name_ = "[FFFF00]![-] " + val.name_ + " " + text; unlockedCars_.Add(val.name_, i); knownCars_.Add(val.name_, i); } profileManager_.carInfos_[i] = val; } CarColors[] array2 = (CarColors[])(object)new CarColors[array.Length + carsInfos.Count]; for (int j = 0; j < array2.Length; j++) { array2[j] = G.Sys.ProfileManager_.carInfos_[j].colors_; } for (int k = 0; k < profileManager_.ProfileCount_; k++) { Profile profile = profileManager_.GetProfile(k); CarColors[] carColorsList_ = profile.carColorsList_; for (int l = 0; l < carColorsList_.Length && l < array2.Length; l++) { array2[l] = carColorsList_[l]; } profile.carColorsList_ = array2; } } private Dictionary<string, GameObject> LoadAssetsBundles() { Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(); DirectoryInfo localFolder = GetLocalFolder("Assets"); DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(Resource.personalDistanceDirPath_, "CustomCars")); if (!directoryInfo.Exists) { try { directoryInfo.Create(); } catch (Exception ex) { Mod.Instance.Errors.Add("Could not create the following folder: " + directoryInfo.FullName); Mod.Log.LogInfo((object)("Could not create the following folder: " + directoryInfo.FullName)); Mod.Instance.Errors.Add(ex); Mod.Log.LogInfo((object)ex); } } foreach (FileInfo item in from x in ArrayEx.Concat<FileInfo>(localFolder.GetFiles("*", SearchOption.AllDirectories), directoryInfo.GetFiles("*", SearchOption.AllDirectories)) orderby x.Name select x) { try { Assets assets = Assets.FromUnsafePath(item.FullName); object bundle = assets.Bundle; AssetBundle val = (AssetBundle)((bundle is AssetBundle) ? bundle : null); int num = 0; foreach (string item2 in from name in val.GetAllAssetNames() where name.EndsWith(".prefab", StringComparison.InvariantCultureIgnoreCase) select name) { GameObject value = val.LoadAsset<GameObject>(item2); string key = item.FullName + " (" + item2 + ")"; if (!dictionary.ContainsKey(key)) { dictionary.Add(key, value); num++; } } if (num == 0) { Mod.Instance.Errors.Add("Can't find a prefab in the asset bundle: " + item.FullName); Mod.Log.LogInfo((object)("Can't find a prefab in the asset bundle: " + item.FullName)); } } catch (Exception ex2) { Mod.Instance.Errors.Add("Could not load assets file: " + item.FullName); Mod.Log.LogInfo((object)("Could not load assets file: " + item.FullName)); Mod.Instance.Errors.Add(ex2); Mod.Log.LogInfo((object)ex2); } } try { DirectoryInfo directoryInfo2 = new DirectoryInfo(Path.Combine(Directory.GetParent(Directory.GetParent(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location)).ToString()).ToString(), "Assets")); foreach (FileInfo item3 in from x in ArrayEx.Concat<FileInfo>(directoryInfo2.GetFiles("*", SearchOption.AllDirectories), directoryInfo.GetFiles("*", SearchOption.AllDirectories)) orderby x.Name select x) { try { Assets assets2 = Assets.FromUnsafePath(item3.FullName); object bundle2 = assets2.Bundle; AssetBundle val2 = (AssetBundle)((bundle2 is AssetBundle) ? bundle2 : null); int num2 = 0; foreach (string item4 in from name in val2.GetAllAssetNames() where name.EndsWith(".prefab", StringComparison.InvariantCultureIgnoreCase) select name) { GameObject value2 = val2.LoadAsset<GameObject>(item4); string key2 = item3.FullName + " (" + item4 + ")"; if (!dictionary.ContainsKey(key2)) { dictionary.Add(key2, value2); num2++; } } if (num2 == 0) { Mod.Instance.Errors.Add("Can't find a prefab in the asset bundle: " + item3.FullName); Mod.Log.LogInfo((object)("Can't find a prefab in the asset bundle: " + item3.FullName)); } } catch (Exception ex3) { Mod.Instance.Errors.Add("Could not load assets file: " + item3.FullName); Mod.Log.LogInfo((object)("Could not load assets file: " + item3.FullName)); Mod.Instance.Errors.Add(ex3); Mod.Log.LogInfo((object)ex3); } } } catch (Exception ex4) { Mod.Log.LogInfo((object)"Could not find assets file in the top level directory. This is not bad, this just means no cars were downloaded from the Thunderstore"); Mod.Log.LogInfo((object)ex4); } return dictionary; } public DirectoryInfo GetLocalFolder(string dir) { FileSystem fileSystem = new FileSystem(); return new DirectoryInfo(Path.GetDirectoryName(Path.Combine(fileSystem.RootDirectory, dir + (dir.EndsWith($"{Path.DirectorySeparatorChar}") ? string.Empty : $"{Path.DirectorySeparatorChar}")))); } private CreateCarReturnInfos CreateCar(GameObject car) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) CreateCarReturnInfos createCarReturnInfos = new CreateCarReturnInfos(); GameObject val = Object.Instantiate<GameObject>(infos_.baseCar); ((Object)val).name = ((Object)car).name; Object.DontDestroyOnLoad((Object)(object)val); val.SetActive(false); RemoveOldCar(val); GameObject car2 = AddNewCarOnPrefab(val, car); SetCarDatas(val, car2); createCarReturnInfos.car = val; createCarReturnInfos.colors = LoadDefaultColors(car2); return createCarReturnInfos; } private void RemoveOldCar(GameObject obj) { List<GameObject> list = new List<GameObject>(); for (int i = 0; i < obj.transform.childCount; i++) { GameObject gameObject = ((Component)obj.transform.GetChild(i)).gameObject; if (((Object)gameObject).name.IndexOf("wheel", StringComparison.InvariantCultureIgnoreCase) >= 0) { list.Add(gameObject); } } if (list.Count != 4) { Mod.Instance.Errors.Add($"Found {list.Count} wheels on base prefabs, expected 4"); Mod.Log.LogInfo((object)$"Found {list.Count} wheels on base prefabs, expected 4"); } Transform val = obj.transform.Find("Refractor"); if ((Object)(object)val == (Object)null) { Mod.Instance.Errors.Add("Can't find the Refractor object on the base car prefab"); Mod.Log.LogInfo((object)"Can't find the Refractor object on the base car prefab"); return; } Object.Destroy((Object)(object)((Component)val).gameObject); foreach (GameObject item in list) { Object.Destroy((Object)(object)item); } } private GameObject AddNewCarOnPrefab(GameObject obj, GameObject car) { return Object.Instantiate<GameObject>(car, obj.transform); } private void SetCarDatas(GameObject obj, GameObject car) { SetColorChanger(obj.GetComponent<ColorChanger>(), car); SetCarVisuals(obj.GetComponent<CarVisuals>(), car); } private void SetColorChanger(ColorChanger colorChanger, GameObject car) { if ((Object)(object)colorChanger == (Object)null) { Mod.Instance.Errors.Add("Can't find the ColorChanger component on the base car"); Mod.Log.LogInfo((object)"Can't find the ColorChanger component on the base car"); return; } colorChanger.rendererChangers_ = (RendererChanger[])(object)new RendererChanger[0]; Renderer[] componentsInChildren = car.GetComponentsInChildren<Renderer>(); foreach (Renderer val in componentsInChildren) { ReplaceMaterials(val); if ((Object)(object)colorChanger != (Object)null) { AddMaterialColorChanger(colorChanger, ((Component)val).transform); } } } private void ReplaceMaterials(Renderer renderer) { string[] array = new string[renderer.materials.Length]; for (int i = 0; i < array.Length; i++) { array[i] = "wheel"; } List<MaterialPropertyExport>[] array2 = new List<MaterialPropertyExport>[renderer.materials.Length]; for (int j = 0; j < array2.Length; j++) { array2[j] = new List<MaterialPropertyExport>(); } FillMaterialInfos(renderer, array, array2); Material[] array3 = ICollectionEx.ToArray<Material>((ICollection<Material>)renderer.materials); for (int k = 0; k < renderer.materials.Length; k++) { if (!infos_.materials.TryGetValue(array[k], out var value)) { Mod.Instance.Errors.Add("Can't find the material " + array[k] + " on " + ((Component)renderer).gameObject.FullName()); Mod.Log.LogInfo((object)("Can't find the material " + array[k] + " on " + ((Component)renderer).gameObject.FullName())); } else { if (value == null || (Object)(object)value.material == (Object)null) { continue; } Material val = Object.Instantiate<Material>(value.material); if (value.diffuseIndex >= 0) { val.SetTexture(value.diffuseIndex, renderer.materials[k].GetTexture("_MainTex")); } if (value.normalIndex >= 0) { val.SetTexture(value.normalIndex, renderer.materials[k].GetTexture("_BumpMap")); } if (value.emitIndex >= 0) { val.SetTexture(value.emitIndex, renderer.materials[k].GetTexture("_EmissionMap")); } foreach (MaterialPropertyExport item in array2[k]) { CopyMaterialProperty(renderer.materials[k], val, item); } array3[k] = val; } } renderer.materials = array3; } private void FillMaterialInfos(Renderer renderer, string[] matNames, List<MaterialPropertyExport>[] materialProperties) { int childCount = ((Component)renderer).transform.childCount; for (int i = 0; i < childCount; i++) { string text = ((Object)((Component)renderer).transform.GetChild(i)).name.ToLower(); if (!text.StartsWith("#")) { continue; } text = text.Remove(0, 1); string[] array = text.Split(new char[1] { ';' }); if (array.Length == 0) { continue; } if (array[0].Contains("mat")) { int result; if (array.Length != 3) { Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 2 arguments"); Mod.Log.LogInfo((object)(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 2 arguments")); } else if (!int.TryParse(array[1], out result)) { Mod.Instance.Errors.Add("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number"); Mod.Log.LogInfo((object)("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number")); } else if (result < matNames.Length) { matNames[result] = array[2]; } } else { if (!array[0].Contains("export")) { continue; } int result2; if (array.Length != 5) { Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 4 arguments"); Mod.Log.LogInfo((object)(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 4 arguments")); } else if (!int.TryParse(array[1], out result2)) { Mod.Instance.Errors.Add("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number"); Mod.Log.LogInfo((object)("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number")); } else { if (result2 >= matNames.Length) { continue; } MaterialPropertyExport materialPropertyExport = new MaterialPropertyExport(); bool flag = false; foreach (PropertyType value in Enum.GetValues(typeof(PropertyType))) { if (array[2] == value.ToString().ToLower()) { flag = true; materialPropertyExport.type = value; break; } } if (!flag) { Mod.Instance.Errors.Add("The property " + array[2] + " on " + ((Component)renderer).gameObject.FullName() + " is not valid"); Mod.Log.LogInfo((object)("The property " + array[2] + " on " + ((Component)renderer).gameObject.FullName() + " is not valid")); } else { if (!int.TryParse(array[3], out materialPropertyExport.fromID)) { materialPropertyExport.fromName = array[3]; } if (!int.TryParse(array[4], out materialPropertyExport.toID)) { materialPropertyExport.toName = array[4]; } materialProperties[result2].Add(materialPropertyExport); } } } } } private void CopyMaterialProperty(Material from, Material to, MaterialPropertyExport property) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) int num = property.fromID; if (num == -1) { num = Shader.PropertyToID(property.fromName); } int num2 = property.toID; if (num2 == -1) { num2 = Shader.PropertyToID(property.toName); } switch (property.type) { case PropertyType.Color: to.SetColor(num2, from.GetColor(num)); break; case PropertyType.ColorArray: to.SetColorArray(num2, from.GetColorArray(num)); break; case PropertyType.Float: to.SetFloat(num2, from.GetFloat(num)); break; case PropertyType.FloatArray: to.SetFloatArray(num2, from.GetFloatArray(num)); break; case PropertyType.Int: to.SetInt(num2, from.GetInt(num)); break; case PropertyType.Matrix: to.SetMatrix(num2, from.GetMatrix(num)); break; case PropertyType.MatrixArray: to.SetMatrixArray(num2, from.GetMatrixArray(num)); break; case PropertyType.Texture: to.SetTexture(num2, from.GetTexture(num)); break; case PropertyType.Vector: to.SetVector(num2, from.GetVector(num)); break; case PropertyType.VectorArray: to.SetVectorArray(num2, from.GetVectorArray(num)); break; } } private void AddMaterialColorChanger(ColorChanger colorChanger, Transform transform) { //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) Renderer component = ((Component)transform).GetComponent<Renderer>(); if ((Object)(object)component == (Object)null) { return; } List<UniformChanger> list = new List<UniformChanger>(); for (int i = 0; i < transform.childCount; i++) { GameObject gameObject = ((Component)transform.GetChild(i)).gameObject; string text = ((Object)gameObject).name.ToLower(); if (!text.StartsWith("#")) { continue; } text = text.Remove(0, 1); string[] array = text.Split(new char[1] { ';' }); if (array.Length != 0 && array[0].Contains("color")) { if (array.Length != 6) { Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)transform).gameObject.FullName() + " must have 5 arguments"); Mod.Log.LogInfo((object)(array[0] + " property on " + ((Component)transform).gameObject.FullName() + " must have 5 arguments")); continue; } UniformChanger val = new UniformChanger(); int.TryParse(array[1], out var result); val.materialIndex_ = result; val.colorType_ = ColorType(array[2]); val.name_ = UniformName(array[3]); float.TryParse(array[4], out var result2); val.mul_ = result2; val.alpha_ = string.Equals(array[5], "true", StringComparison.InvariantCultureIgnoreCase); list.Add(val); } } if (list.Count != 0) { RendererChanger item = new RendererChanger { renderer_ = component, uniformChangers_ = list.ToArray() }; List<RendererChanger> list2 = colorChanger.rendererChangers_.ToList(); list2.Add(item); colorChanger.rendererChangers_ = list2.ToArray(); } } private ColorType ColorType(string name) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) name = name.ToLower(); return (ColorType)(name switch { "primary" => 0, "secondary" => 1, "glow" => 2, "sparkle" => 3, _ => 0, }); } private SupportedUniform UniformName(string name) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) name = name.ToLower(); return (SupportedUniform)(name switch { "color" => 0, "color2" => 1, "emitcolor" => 2, "reflectcolor" => 4, "speccolor" => 5, _ => 0, }); } private void SetCarVisuals(CarVisuals visuals, GameObject car) { if ((Object)(object)visuals == (Object)null) { Mod.Instance.Errors.Add("Can't find the CarVisuals component on the base car"); Mod.Log.LogInfo((object)"Can't find the CarVisuals component on the base car"); return; } SkinnedMeshRenderer componentInChildren = car.GetComponentInChildren<SkinnedMeshRenderer>(); MakeMeshSkinned(componentInChildren); visuals.carBodyRenderer_ = componentInChildren; List<JetFlame> list = new List<JetFlame>(); List<JetFlame> list2 = new List<JetFlame>(); List<JetFlame> list3 = new List<JetFlame>(); PlaceJets(car, list, list2, list3); visuals.boostJetFlames_ = list.ToArray(); visuals.wingJetFlames_ = list2.ToArray(); visuals.rotationJetFlames_ = list3.ToArray(); visuals.driverPosition_ = FindCarDriver(car.transform); PlaceCarWheelsVisuals(visuals, car); } private void MakeMeshSkinned(SkinnedMeshRenderer renderer) { //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) Mesh sharedMesh = renderer.sharedMesh; if ((Object)(object)sharedMesh == (Object)null) { Mod.Instance.Errors.Add("The mesh on " + ((Component)renderer).gameObject.FullName() + " is null"); Mod.Log.LogInfo((object)("The mesh on " + ((Component)renderer).gameObject.FullName() + " is null")); } else if (!sharedMesh.isReadable) { Mod.Instance.Errors.Add("Can't read the car mesh " + ((Object)sharedMesh).name + " on " + ((Component)renderer).gameObject.FullName() + "You must allow reading on it's unity inspector !"); Mod.Log.LogInfo((object)("Can't read the car mesh " + ((Object)sharedMesh).name + " on " + ((Component)renderer).gameObject.FullName() + "You must allow reading on it's unity inspector !")); } else if (sharedMesh.vertices.Length != sharedMesh.boneWeights.Length) { BoneWeight[] array = (BoneWeight[])(object)new BoneWeight[sharedMesh.vertices.Length]; for (int i = 0; i < array.Length; i++) { ((BoneWeight)(ref array[i])).weight0 = 1f; } sharedMesh.boneWeights = array; Transform transform = ((Component)renderer).transform; sharedMesh.bindposes = (Matrix4x4[])(object)new Matrix4x4[1] { transform.worldToLocalMatrix * ((Component)renderer).transform.localToWorldMatrix }; renderer.bones = (Transform[])(object)new Transform[1] { transform }; } } private void PlaceJets(GameObject obj, List<JetFlame> boostJets, List<JetFlame> wingJets, List<JetFlame> rotationJets) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) int childCount = obj.transform.childCount; for (int i = 0; i < childCount; i++) { GameObject gameObject = GameObjectEx.GetChild(obj, i).gameObject; string text = ((Object)gameObject).name.ToLower(); if ((Object)(object)infos_.boostJet != (Object)null && text.Contains("boostjet")) { GameObject val = Object.Instantiate<GameObject>(infos_.boostJet, gameObject.transform); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; boostJets.Add(val.GetComponentInChildren<JetFlame>()); } else if ((Object)(object)infos_.wingJet != (Object)null && text.Contains("wingjet")) { GameObject val2 = Object.Instantiate<GameObject>(infos_.wingJet, gameObject.transform); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; wingJets.Add(val2.GetComponentInChildren<JetFlame>()); ListEx.Last<JetFlame>(wingJets).rotationAxis_ = JetDirection(gameObject.transform); } else if ((Object)(object)infos_.rotationJet != (Object)null && text.Contains("rotationjet")) { GameObject val3 = Object.Instantiate<GameObject>(infos_.rotationJet, gameObject.transform); val3.transform.localPosition = Vector3.zero; val3.transform.localRotation = Quaternion.identity; rotationJets.Add(val3.GetComponentInChildren<JetFlame>()); ListEx.Last<JetFlame>(rotationJets).rotationAxis_ = JetDirection(gameObject.transform); } else if ((Object)(object)infos_.wingTrail != (Object)null && text.Contains("wingtrail")) { GameObject val4 = Object.Instantiate<GameObject>(infos_.wingTrail, gameObject.transform); val4.transform.localPosition = Vector3.zero; val4.transform.localRotation = Quaternion.identity; } else { PlaceJets(gameObject, boostJets, wingJets, rotationJets); } } } private Vector3 JetDirection(Transform transform) { //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) int childCount = transform.childCount; for (int i = 0; i < childCount; i++) { string text = ((Object)((Component)transform.GetChild(i)).gameObject).name.ToLower(); if (!text.StartsWith("#")) { continue; } text = text.Remove(0, 1); string[] array = text.Split(new char[1] { ';' }); if (array.Length != 0 && array[0].Contains("dir") && array.Length >= 2) { if (array[1] == "front") { return new Vector3(-1f, 0f, 0f); } if (array[1] == "back") { return new Vector3(1f, 0f, 0f); } if (array[1] == "left") { return new Vector3(0f, 1f, -1f); } if (array[1] == "right") { return new Vector3(0f, -1f, 1f); } if (array.Length == 4 && array[0].Contains("dir")) { Vector3 zero = Vector3.zero; float.TryParse(array[1], out zero.x); float.TryParse(array[2], out zero.y); float.TryParse(array[3], out zero.z); return zero; } } } return Vector3.zero; } private Transform FindCarDriver(Transform parent) { for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); Transform val = ((((Object)((Component)child).gameObject).name.IndexOf("driverposition", StringComparison.InvariantCultureIgnoreCase) >= 0) ? child : FindCarDriver(child)); if ((Object)(object)val != (Object)null) { return val; } } return null; } private void PlaceCarWheelsVisuals(CarVisuals visual, GameObject car) { for (int i = 0; i < car.transform.childCount; i++) { GameObject gameObject = ((Component)car.transform.GetChild(i)).gameObject; string text = ((Object)gameObject).name.ToLower(); if (!text.Contains("wheel")) { continue; } CarWheelVisuals val = gameObject.AddComponent<CarWheelVisuals>(); MeshRenderer[] componentsInChildren = gameObject.GetComponentsInChildren<MeshRenderer>(); foreach (MeshRenderer val2 in componentsInChildren) { if (((Object)((Component)val2).gameObject).name.IndexOf("tire", StringComparison.InvariantCultureIgnoreCase) >= 0) { val.tire_ = val2; break; } } if (text.Contains("front")) { if (text.Contains("left")) { visual.wheelFL_ = val; } else if (text.Contains("right")) { visual.wheelFR_ = val; } } else if (text.Contains("back")) { if (text.Contains("left")) { visual.wheelBL_ = val; } else if (text.Contains("right")) { visual.wheelBR_ = val; } } } } private CarColors LoadDefaultColors(GameObject car) { //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) CarColors val2 = default(CarColors); for (int i = 0; i < car.transform.childCount; i++) { GameObject gameObject = ((Component)car.transform.GetChild(i)).gameObject; string text = ((Object)gameObject).name.ToLower(); if (!text.Contains("defaultcolor")) { continue; } for (int j = 0; j < gameObject.transform.childCount; j++) { GameObject gameObject2 = ((Component)gameObject.transform.GetChild(j)).gameObject; string text2 = ((Object)gameObject2).name.ToLower(); if (!text2.StartsWith("#")) { continue; } text2 = text2.Remove(0, 1); string[] array = text2.Split(new char[1] { ';' }); if (array.Length == 2) { Color val = ColorEx.HexToColor(array[1], byte.MaxValue); val.a = 1f; if (array[0] == "primary") { val2.primary_ = val; } else if (array[0] == "secondary") { val2.secondary_ = val; } else if (array[0] == "glow") { val2.glow_ = val; } else if (array[0] == "sparkle") { val2.sparkle_ = val; } } } } return infos_.defaultColors; } } public class CarInfos { public Dictionary<string, MaterialInfos> materials = new Dictionary<string, MaterialInfos>(); public GameObject boostJet = null; public GameObject wingJet = null; public GameObject rotationJet = null; public GameObject wingTrail = null; public GameObject baseCar = null; public CarColors defaultColors; public void CollectInfos() { GetBaseCar(); GetJetsAndTrail(); GetMaterials(); } private void GetBaseCar() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) GameObject carPrefab_ = G.Sys.ProfileManager_.carInfos_[0].prefabs_.carPrefab_; if ((Object)(object)carPrefab_ == (Object)null) { Mod.Instance.Errors.Add("Can't find the refractor base car prefab"); return; } baseCar = carPrefab_; defaultColors = G.Sys.ProfileManager_.carInfos_[0].colors_; } private void GetJetsAndTrail() { if ((Object)(object)baseCar == (Object)null) { return; } JetFlame[] componentsInChildren = baseCar.GetComponentsInChildren<JetFlame>(); foreach (JetFlame val in componentsInChildren) { switch (((Object)((Component)val).gameObject).name) { case "BoostJetFlameCenter": boostJet = ((Component)val).gameObject; break; case "JetFlameBackLeft": rotationJet = ((Component)val).gameObject; break; case "WingJetFlameLeft1": wingJet = ((Component)val).gameObject; break; } } wingTrail = ((Component)baseCar.GetComponentInChildren<WingTrail>()).gameObject; if ((Object)(object)boostJet == (Object)null) { Mod.Instance.Errors.Add("No valid BoostJet found on Refractor"); } if ((Object)(object)rotationJet == (Object)null) { Mod.Instance.Errors.Add("No valid RotationJet found on Refractor"); } if ((Object)(object)wingJet == (Object)null) { Mod.Instance.Errors.Add("No valid WingJet found on Refractor"); } if ((Object)(object)wingTrail == (Object)null) { Mod.Instance.Errors.Add("No valid WingTrail found on Refractor"); } } private void GetMaterials() { List<MaterialPropertyInfo> list = new List<MaterialPropertyInfo> { new MaterialPropertyInfo("Custom/LaserCut/CarPaint", "carpaint", 5, -1, -1), new MaterialPropertyInfo("Custom/LaserCut/CarWindow", "carwindow", -1, 218, 219), new MaterialPropertyInfo("Custom/Reflective/Bump Glow LaserCut", "wheel", 5, 218, 255), new MaterialPropertyInfo("Custom/LaserCut/CarPaintBump", "carpaintbump", 5, 218, -1), new MaterialPropertyInfo("Custom/Reflective/Bump Glow Interceptor Special", "interceptor", 5, 218, 255), new MaterialPropertyInfo("Custom/LaserCut/CarWindowTrans2Sided", "transparentglow", -1, 218, 219) }; CarInfo[] carInfos_ = G.Sys.ProfileManager_.carInfos_; foreach (CarInfo val in carInfos_) { GameObject carPrefab_ = val.prefabs_.carPrefab_; Renderer[] componentsInChildren = carPrefab_.GetComponentsInChildren<Renderer>(); foreach (Renderer val2 in componentsInChildren) { Material[] array = val2.materials; foreach (Material val3 in array) { foreach (MaterialPropertyInfo item in list) { if (!materials.ContainsKey(item.name) && ((Object)val3.shader).name == item.shaderName) { MaterialInfos value = new MaterialInfos { material = val3, diffuseIndex = item.diffuseIndex, normalIndex = item.normalIndex, emitIndex = item.emitIndex }; materials.Add(item.name, value); } } } } } foreach (MaterialPropertyInfo item2 in list) { if (!materials.ContainsKey(item2.name)) { Mod.Instance.Errors.Add("Can't find the material: " + item2.name + " - shader: " + item2.shaderName); } } materials.Add("donotreplace", new MaterialInfos()); } } public class CreateCarReturnInfos { public GameObject car; public CarColors colors; } }
Newtonsoft.Json.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using Newtonsoft.Json.Bson; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq.JsonPath; using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Json.NET Unity3D")] [assembly: AllowPartiallyTrustedCallers] [assembly: InternalsVisibleTo("Newtonsoft.Json.Schema")] [assembly: InternalsVisibleTo("Newtonsoft.Json.Tests")] [assembly: InternalsVisibleTo("Assembly-CSharp")] [assembly: InternalsVisibleTo("Assembly-CSharp-Editor")] [assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")] [assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Newtonsoft")] [assembly: AssemblyProduct("Json.NET")] [assembly: AssemblyCopyright("Copyright © James Newton-King 2008")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")] [assembly: AssemblyFileVersion("9.0.1.19813")] [assembly: CLSCompliant(true)] [assembly: AssemblyVersion("9.0.0.0")] namespace Newtonsoft.Json { public enum ConstructorHandling { Default, AllowNonPublicDefaultConstructor } public enum DateFormatHandling { IsoDateFormat, MicrosoftDateFormat } public enum DateParseHandling { None, DateTime, DateTimeOffset } public enum DateTimeZoneHandling { Local, Utc, Unspecified, RoundtripKind } [Flags] public enum DefaultValueHandling { Include = 0, Ignore = 1, Populate = 2, IgnoreAndPopulate = 3 } public enum FloatFormatHandling { String, Symbol, DefaultValue } public enum FloatParseHandling { Double, Decimal } public enum Formatting { None, Indented } public interface IArrayPool<T> { T[] Rent(int minimumLength); void Return(T[] array); } public interface IJsonLineInfo { int LineNumber { get; } int LinePosition { get; } bool HasLineInfo(); } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonArrayAttribute : JsonContainerAttribute { private bool _allowNullItems; public bool AllowNullItems { get { return _allowNullItems; } set { _allowNullItems = value; } } public JsonArrayAttribute() { } public JsonArrayAttribute(bool allowNullItems) { _allowNullItems = allowNullItems; } public JsonArrayAttribute(string id) : base(id) { } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)] public sealed class JsonConstructorAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public abstract class JsonContainerAttribute : Attribute { internal bool? _isReference; internal bool? _itemIsReference; internal ReferenceLoopHandling? _itemReferenceLoopHandling; internal TypeNameHandling? _itemTypeNameHandling; private Type _namingStrategyType; private object[] _namingStrategyParameters; public string Id { get; set; } public string Title { get; set; } public string Description { get; set; } public Type ItemConverterType { get; set; } public object[] ItemConverterParameters { get; set; } public Type NamingStrategyType { get { return _namingStrategyType; } set { _namingStrategyType = value; NamingStrategyInstance = null; } } public object[] NamingStrategyParameters { get { return _namingStrategyParameters; } set { _namingStrategyParameters = value; NamingStrategyInstance = null; } } internal NamingStrategy NamingStrategyInstance { get; set; } public bool IsReference { get { return _isReference ?? false; } set { _isReference = value; } } public bool ItemIsReference { get { return _itemIsReference ?? false; } set { _itemIsReference = value; } } public ReferenceLoopHandling ItemReferenceLoopHandling { get { return _itemReferenceLoopHandling ?? ReferenceLoopHandling.Error; } set { _itemReferenceLoopHandling = value; } } public TypeNameHandling ItemTypeNameHandling { get { return _itemTypeNameHandling ?? TypeNameHandling.None; } set { _itemTypeNameHandling = value; } } protected JsonContainerAttribute() { } protected JsonContainerAttribute(string id) { Id = id; } } public static class JsonConvert { public static readonly string True = "true"; public static readonly string False = "false"; public static readonly string Null = "null"; public static readonly string Undefined = "undefined"; public static readonly string PositiveInfinity = "Infinity"; public static readonly string NegativeInfinity = "-Infinity"; public static readonly string NaN = "NaN"; public static Func<JsonSerializerSettings> DefaultSettings { get; set; } public static string ToString(DateTime value) { return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind); } public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling) { DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling); using StringWriter stringWriter = StringUtils.CreateStringWriter(64); stringWriter.Write('"'); DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture); stringWriter.Write('"'); return stringWriter.ToString(); } public static string ToString(DateTimeOffset value) { return ToString(value, DateFormatHandling.IsoDateFormat); } public static string ToString(DateTimeOffset value, DateFormatHandling format) { using StringWriter stringWriter = StringUtils.CreateStringWriter(64); stringWriter.Write('"'); DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture); stringWriter.Write('"'); return stringWriter.ToString(); } public static string ToString(bool value) { if (!value) { return False; } return True; } public static string ToString(char value) { return ToString(char.ToString(value)); } public static string ToString(Enum value) { return value.ToString("D"); } public static string ToString(int value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(short value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(ushort value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(uint value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(long value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(ulong value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(float value) { return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); } internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); } private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value))) { return text; } if (floatFormatHandling == FloatFormatHandling.DefaultValue) { if (nullable) { return Null; } return "0.0"; } return quoteChar + text + quoteChar; } public static string ToString(double value) { return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); } internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); } private static string EnsureDecimalPlace(double value, string text) { if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1) { return text; } return text + ".0"; } private static string EnsureDecimalPlace(string text) { if (text.IndexOf('.') != -1) { return text; } return text + ".0"; } public static string ToString(byte value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(sbyte value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(decimal value) { return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture)); } public static string ToString(Guid value) { return ToString(value, '"'); } internal static string ToString(Guid value, char quoteChar) { string text = value.ToString("D", CultureInfo.InvariantCulture); string text2 = quoteChar.ToString(CultureInfo.InvariantCulture); return text2 + text + text2; } public static string ToString(TimeSpan value) { return ToString(value, '"'); } internal static string ToString(TimeSpan value, char quoteChar) { return ToString(value.ToString(), quoteChar); } public static string ToString(Uri value) { if (value == null) { return Null; } return ToString(value, '"'); } internal static string ToString(Uri value, char quoteChar) { return ToString(value.OriginalString, quoteChar); } public static string ToString(string value) { return ToString(value, '"'); } public static string ToString(string value, char delimiter) { return ToString(value, delimiter, StringEscapeHandling.Default); } public static string ToString(string value, char delimiter, StringEscapeHandling stringEscapeHandling) { if (delimiter != '"' && delimiter != '\'') { throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter"); } return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling); } public static string ToString(object value) { if (value == null) { return Null; } return ConvertUtils.GetTypeCode(value.GetType()) switch { PrimitiveTypeCode.String => ToString((string)value), PrimitiveTypeCode.Char => ToString((char)value), PrimitiveTypeCode.Boolean => ToString((bool)value), PrimitiveTypeCode.SByte => ToString((sbyte)value), PrimitiveTypeCode.Int16 => ToString((short)value), PrimitiveTypeCode.UInt16 => ToString((ushort)value), PrimitiveTypeCode.Int32 => ToString((int)value), PrimitiveTypeCode.Byte => ToString((byte)value), PrimitiveTypeCode.UInt32 => ToString((uint)value), PrimitiveTypeCode.Int64 => ToString((long)value), PrimitiveTypeCode.UInt64 => ToString((ulong)value), PrimitiveTypeCode.Single => ToString((float)value), PrimitiveTypeCode.Double => ToString((double)value), PrimitiveTypeCode.DateTime => ToString((DateTime)value), PrimitiveTypeCode.Decimal => ToString((decimal)value), PrimitiveTypeCode.DBNull => Null, PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), PrimitiveTypeCode.Guid => ToString((Guid)value), PrimitiveTypeCode.Uri => ToString((Uri)value), PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), _ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), }; } public static string SerializeObject(object value) { return SerializeObject(value, (Type)null, (JsonSerializerSettings)null); } public static string SerializeObject(object value, Formatting formatting) { return SerializeObject(value, formatting, (JsonSerializerSettings)null); } public static string SerializeObject(object value, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return SerializeObject(value, null, settings); } public static string SerializeObject(object value, Formatting formatting, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return SerializeObject(value, null, formatting, settings); } public static string SerializeObject(object value, JsonSerializerSettings settings) { return SerializeObject(value, null, settings); } public static string SerializeObject(object value, Type type, JsonSerializerSettings settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); return SerializeObjectInternal(value, type, jsonSerializer); } public static string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings) { return SerializeObject(value, null, formatting, settings); } public static string SerializeObject(object value, Type type, Formatting formatting, JsonSerializerSettings settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); jsonSerializer.Formatting = formatting; return SerializeObjectInternal(value, type, jsonSerializer); } private static string SerializeObjectInternal(object value, Type type, JsonSerializer jsonSerializer) { StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture); using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter)) { jsonTextWriter.Formatting = jsonSerializer.Formatting; jsonSerializer.Serialize(jsonTextWriter, value, type); } return stringWriter.ToString(); } public static object DeserializeObject(string value) { return DeserializeObject(value, (Type)null, (JsonSerializerSettings)null); } public static object DeserializeObject(string value, JsonSerializerSettings settings) { return DeserializeObject(value, null, settings); } public static object DeserializeObject(string value, Type type) { return DeserializeObject(value, type, (JsonSerializerSettings)null); } public static T DeserializeObject<T>(string value) { return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings)null); } public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject) { return DeserializeObject<T>(value); } public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings) { return DeserializeObject<T>(value, settings); } public static T DeserializeObject<T>(string value, params JsonConverter[] converters) { return (T)DeserializeObject(value, typeof(T), converters); } public static T DeserializeObject<T>(string value, JsonSerializerSettings settings) { return (T)DeserializeObject(value, typeof(T), settings); } public static object DeserializeObject(string value, Type type, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return DeserializeObject(value, type, settings); } public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings) { ValidationUtils.ArgumentNotNull(value, "value"); JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); if (!jsonSerializer.IsCheckAdditionalContentSet()) { jsonSerializer.CheckAdditionalContent = true; } using JsonTextReader reader = new JsonTextReader(new StringReader(value)); return jsonSerializer.Deserialize(reader, type); } public static void PopulateObject(string value, object target) { PopulateObject(value, target, null); } public static void PopulateObject(string value, object target, JsonSerializerSettings settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); using JsonReader jsonReader = new JsonTextReader(new StringReader(value)); jsonSerializer.Populate(jsonReader, target); if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment) { throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object."); } } } public abstract class JsonConverter { public virtual bool CanRead => true; public virtual bool CanWrite => true; public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer); public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer); public abstract bool CanConvert(Type objectType); } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)] public sealed class JsonConverterAttribute : Attribute { private readonly Type _converterType; public Type ConverterType => _converterType; public object[] ConverterParameters { get; private set; } public JsonConverterAttribute(Type converterType) { if ((object)converterType == null) { throw new ArgumentNullException("converterType"); } _converterType = converterType; } public JsonConverterAttribute(Type converterType, params object[] converterParameters) : this(converterType) { ConverterParameters = converterParameters; } } public class JsonConverterCollection : Collection<JsonConverter> { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonDictionaryAttribute : JsonContainerAttribute { public JsonDictionaryAttribute() { } public JsonDictionaryAttribute(string id) : base(id) { } } [Serializable] public class JsonException : Exception { public JsonException() { } public JsonException(string message) : base(message) { } public JsonException(string message, Exception innerException) : base(message, innerException) { } public JsonException(SerializationInfo info, StreamingContext context) : base(info, context) { } internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message) { message = JsonPosition.FormatMessage(lineInfo, path, message); return new JsonException(message); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public class JsonExtensionDataAttribute : Attribute { public bool WriteData { get; set; } public bool ReadData { get; set; } public JsonExtensionDataAttribute() { WriteData = true; ReadData = true; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class JsonIgnoreAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonObjectAttribute : JsonContainerAttribute { private MemberSerialization _memberSerialization; internal Required? _itemRequired; public MemberSerialization MemberSerialization { get { return _memberSerialization; } set { _memberSerialization = value; } } public Required ItemRequired { get { return _itemRequired ?? Required.Default; } set { _itemRequired = value; } } public JsonObjectAttribute() { } public JsonObjectAttribute(MemberSerialization memberSerialization) { MemberSerialization = memberSerialization; } public JsonObjectAttribute(string id) : base(id) { } } internal enum JsonContainerType { None, Object, Array, Constructor } internal struct JsonPosition { private static readonly char[] SpecialCharacters = new char[6] { '.', ' ', '[', ']', '(', ')' }; internal JsonContainerType Type; internal int Position; internal string PropertyName; internal bool HasIndex; public JsonPosition(JsonContainerType type) { Type = type; HasIndex = TypeHasIndex(type); Position = -1; PropertyName = null; } internal int CalculateLength() { switch (Type) { case JsonContainerType.Object: return PropertyName.Length + 5; case JsonContainerType.Array: case JsonContainerType.Constructor: return MathUtils.IntLength((ulong)Position) + 2; default: throw new ArgumentOutOfRangeException("Type"); } } internal void WriteTo(StringBuilder sb) { switch (Type) { case JsonContainerType.Object: { string propertyName = PropertyName; if (propertyName.IndexOfAny(SpecialCharacters) != -1) { sb.Append("['"); sb.Append(propertyName); sb.Append("']"); break; } if (sb.Length > 0) { sb.Append('.'); } sb.Append(propertyName); break; } case JsonContainerType.Array: case JsonContainerType.Constructor: sb.Append('['); sb.Append(Position); sb.Append(']'); break; } } internal static bool TypeHasIndex(JsonContainerType type) { if (type != JsonContainerType.Array) { return type == JsonContainerType.Constructor; } return true; } internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition) { int num = 0; if (positions != null) { for (int i = 0; i < positions.Count; i++) { num += positions[i].CalculateLength(); } } if (currentPosition.HasValue) { num += currentPosition.GetValueOrDefault().CalculateLength(); } StringBuilder stringBuilder = new StringBuilder(num); if (positions != null) { foreach (JsonPosition position in positions) { position.WriteTo(stringBuilder); } } currentPosition?.WriteTo(stringBuilder); return stringBuilder.ToString(); } internal static string FormatMessage(IJsonLineInfo lineInfo, string path, string message) { if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal)) { message = message.Trim(); if (!StringUtils.EndsWith(message, '.')) { message += "."; } message += " "; } message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path); if (lineInfo != null && lineInfo.HasLineInfo()) { message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition); } message += "."; return message; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] public sealed class JsonPropertyAttribute : Attribute { internal NullValueHandling? _nullValueHandling; internal DefaultValueHandling? _defaultValueHandling; internal ReferenceLoopHandling? _referenceLoopHandling; internal ObjectCreationHandling? _objectCreationHandling; internal TypeNameHandling? _typeNameHandling; internal bool? _isReference; internal int? _order; internal Required? _required; internal bool? _itemIsReference; internal ReferenceLoopHandling? _itemReferenceLoopHandling; internal TypeNameHandling? _itemTypeNameHandling; public Type ItemConverterType { get; set; } public object[] ItemConverterParameters { get; set; } public Type NamingStrategyType { get; set; } public object[] NamingStrategyParameters { get; set; } public NullValueHandling NullValueHandling { get { return _nullValueHandling ?? NullValueHandling.Include; } set { _nullValueHandling = value; } } public DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling ?? DefaultValueHandling.Include; } set { _defaultValueHandling = value; } } public ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling ?? ReferenceLoopHandling.Error; } set { _referenceLoopHandling = value; } } public ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling ?? ObjectCreationHandling.Auto; } set { _objectCreationHandling = value; } } public TypeNameHandling TypeNameHandling { get { return _typeNameHandling ?? TypeNameHandling.None; } set { _typeNameHandling = value; } } public bool IsReference { get { return _isReference ?? false; } set { _isReference = value; } } public int Order { get { return _order ?? 0; } set { _order = value; } } public Required Required { get { return _required ?? Required.Default; } set { _required = value; } } public string PropertyName { get; set; } public ReferenceLoopHandling ItemReferenceLoopHandling { get { return _itemReferenceLoopHandling ?? ReferenceLoopHandling.Error; } set { _itemReferenceLoopHandling = value; } } public TypeNameHandling ItemTypeNameHandling { get { return _itemTypeNameHandling ?? TypeNameHandling.None; } set { _itemTypeNameHandling = value; } } public bool ItemIsReference { get { return _itemIsReference ?? false; } set { _itemIsReference = value; } } public JsonPropertyAttribute() { } public JsonPropertyAttribute(string propertyName) { PropertyName = propertyName; } } public abstract class JsonReader : IDisposable { protected internal enum State { Start, Complete, Property, ObjectStart, Object, ArrayStart, Array, Closed, PostValue, ConstructorStart, Constructor, Error, Finished } private JsonToken _tokenType; private object _value; internal char _quoteChar; internal State _currentState; private JsonPosition _currentPosition; private CultureInfo _culture; private DateTimeZoneHandling _dateTimeZoneHandling; private int? _maxDepth; private bool _hasExceededMaxDepth; internal DateParseHandling _dateParseHandling; internal FloatParseHandling _floatParseHandling; private string _dateFormatString; private List<JsonPosition> _stack; protected State CurrentState => _currentState; public bool CloseInput { get; set; } public bool SupportMultipleContent { get; set; } public virtual char QuoteChar { get { return _quoteChar; } protected internal set { _quoteChar = value; } } public DateTimeZoneHandling DateTimeZoneHandling { get { return _dateTimeZoneHandling; } set { if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind) { throw new ArgumentOutOfRangeException("value"); } _dateTimeZoneHandling = value; } } public DateParseHandling DateParseHandling { get { return _dateParseHandling; } set { if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset) { throw new ArgumentOutOfRangeException("value"); } _dateParseHandling = value; } } public FloatParseHandling FloatParseHandling { get { return _floatParseHandling; } set { if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal) { throw new ArgumentOutOfRangeException("value"); } _floatParseHandling = value; } } public string DateFormatString { get { return _dateFormatString; } set { _dateFormatString = value; } } public int? MaxDepth { get { return _maxDepth; } set { if (value <= 0) { throw new ArgumentException("Value must be positive.", "value"); } _maxDepth = value; } } public virtual JsonToken TokenType => _tokenType; public virtual object Value => _value; public virtual Type ValueType { get { if (_value == null) { return null; } return _value.GetType(); } } public virtual int Depth { get { int num = ((_stack != null) ? _stack.Count : 0); if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None) { return num; } return num + 1; } } public virtual string Path { get { if (_currentPosition.Type == JsonContainerType.None) { return string.Empty; } JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null); return JsonPosition.BuildPath(_stack, currentPosition); } } public CultureInfo Culture { get { return _culture ?? CultureInfo.InvariantCulture; } set { _culture = value; } } internal JsonPosition GetPosition(int depth) { if (_stack != null && depth < _stack.Count) { return _stack[depth]; } return _currentPosition; } protected JsonReader() { _currentState = State.Start; _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; _dateParseHandling = DateParseHandling.DateTime; _floatParseHandling = FloatParseHandling.Double; CloseInput = true; } private void Push(JsonContainerType value) { UpdateScopeWithFinishedValue(); if (_currentPosition.Type == JsonContainerType.None) { _currentPosition = new JsonPosition(value); return; } if (_stack == null) { _stack = new List<JsonPosition>(); } _stack.Add(_currentPosition); _currentPosition = new JsonPosition(value); if (_maxDepth.HasValue) { int num = Depth + 1; int? maxDepth = _maxDepth; if (num > maxDepth.GetValueOrDefault() && maxDepth.HasValue && !_hasExceededMaxDepth) { _hasExceededMaxDepth = true; throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth)); } } } private JsonContainerType Pop() { JsonPosition currentPosition; if (_stack != null && _stack.Count > 0) { currentPosition = _currentPosition; _currentPosition = _stack[_stack.Count - 1]; _stack.RemoveAt(_stack.Count - 1); } else { currentPosition = _currentPosition; _currentPosition = default(JsonPosition); } if (_maxDepth.HasValue && Depth <= _maxDepth) { _hasExceededMaxDepth = false; } return currentPosition.Type; } private JsonContainerType Peek() { return _currentPosition.Type; } public abstract bool Read(); public virtual int? ReadAsInt32() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: if (!(Value is int)) { SetToken(JsonToken.Integer, Convert.ToInt32(Value, CultureInfo.InvariantCulture), updateIndex: false); } return (int)Value; case JsonToken.String: { string s = (string)Value; return ReadInt32String(s); } default: throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal int? ReadInt32String(string s) { if (string.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (int.TryParse(s, NumberStyles.Integer, Culture, out var result)) { SetToken(JsonToken.Integer, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual string ReadAsString() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.String: return (string)Value; default: if (JsonTokenUtils.IsPrimitiveToken(contentToken) && Value != null) { string text = ((Value is IFormattable) ? ((IFormattable)Value).ToString(null, Culture) : ((!(Value is Uri)) ? Value.ToString() : ((Uri)Value).OriginalString)); SetToken(JsonToken.String, text, updateIndex: false); return text; } throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } public virtual byte[] ReadAsBytes() { JsonToken contentToken = GetContentToken(); if (contentToken == JsonToken.None) { return null; } if (TokenType == JsonToken.StartObject) { ReadIntoWrappedTypeObject(); byte[] array = ReadAsBytes(); ReaderReadAndAssert(); if (TokenType != JsonToken.EndObject) { throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } SetToken(JsonToken.Bytes, array, updateIndex: false); return array; } switch (contentToken) { case JsonToken.String: { string text = (string)Value; Guid g; byte[] array3 = ((text.Length == 0) ? new byte[0] : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray())); SetToken(JsonToken.Bytes, array3, updateIndex: false); return array3; } case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Bytes: if ((object)ValueType == typeof(Guid)) { byte[] array2 = ((Guid)Value).ToByteArray(); SetToken(JsonToken.Bytes, array2, updateIndex: false); return array2; } return (byte[])Value; case JsonToken.StartArray: return ReadArrayIntoByteArray(); default: throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal byte[] ReadArrayIntoByteArray() { List<byte> list = new List<byte>(); while (true) { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: throw JsonReaderException.Create(this, "Unexpected end when reading bytes."); case JsonToken.Integer: break; case JsonToken.EndArray: { byte[] array = list.ToArray(); SetToken(JsonToken.Bytes, array, updateIndex: false); return array; } default: throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } list.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture)); } } public virtual double? ReadAsDouble() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: if (!(Value is double)) { double num = Convert.ToDouble(Value, CultureInfo.InvariantCulture); SetToken(JsonToken.Float, num, updateIndex: false); } return (double)Value; case JsonToken.String: return ReadDoubleString((string)Value); default: throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal double? ReadDoubleString(string s) { if (string.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result)) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual bool? ReadAsBoolean() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { bool flag = Convert.ToBoolean(Value, CultureInfo.InvariantCulture); SetToken(JsonToken.Boolean, flag, updateIndex: false); return flag; } case JsonToken.String: return ReadBooleanString((string)Value); case JsonToken.Boolean: return (bool)Value; default: throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal bool? ReadBooleanString(string s) { if (string.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (bool.TryParse(s, out var result)) { SetToken(JsonToken.Boolean, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual decimal? ReadAsDecimal() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: if (!(Value is decimal)) { SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture), updateIndex: false); } return (decimal)Value; case JsonToken.String: return ReadDecimalString((string)Value); default: throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal decimal? ReadDecimalString(string s) { if (string.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result)) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual DateTime? ReadAsDateTime() { switch (GetContentToken()) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Date: if (Value is DateTimeOffset) { SetToken(JsonToken.Date, ((DateTimeOffset)Value).DateTime, updateIndex: false); } return (DateTime)Value; case JsonToken.String: { string s = (string)Value; return ReadDateTimeString(s); } default: throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } } internal DateTime? ReadDateTimeString(string s) { if (string.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt)) { dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) { dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual DateTimeOffset? ReadAsDateTimeOffset() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Date: if (Value is DateTime) { SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value), updateIndex: false); } return (DateTimeOffset)Value; case JsonToken.String: { string s = (string)Value; return ReadDateTimeOffsetString(s); } default: throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal DateTimeOffset? ReadDateTimeOffsetString(string s) { if (string.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt)) { SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) { SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } internal void ReaderReadAndAssert() { if (!Read()) { throw CreateUnexpectedEndException(); } } internal JsonReaderException CreateUnexpectedEndException() { return JsonReaderException.Create(this, "Unexpected end when reading JSON."); } internal void ReadIntoWrappedTypeObject() { ReaderReadAndAssert(); if (Value.ToString() == "$type") { ReaderReadAndAssert(); if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal)) { ReaderReadAndAssert(); if (Value.ToString() == "$value") { return; } } } throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject)); } public void Skip() { if (TokenType == JsonToken.PropertyName) { Read(); } if (JsonTokenUtils.IsStartToken(TokenType)) { int depth = Depth; while (Read() && depth < Depth) { } } } protected void SetToken(JsonToken newToken) { SetToken(newToken, null, updateIndex: true); } protected void SetToken(JsonToken newToken, object value) { SetToken(newToken, value, updateIndex: true); } internal void SetToken(JsonToken newToken, object value, bool updateIndex) { _tokenType = newToken; _value = value; switch (newToken) { case JsonToken.StartObject: _currentState = State.ObjectStart; Push(JsonContainerType.Object); break; case JsonToken.StartArray: _currentState = State.ArrayStart; Push(JsonContainerType.Array); break; case JsonToken.StartConstructor: _currentState = State.ConstructorStart; Push(JsonContainerType.Constructor); break; case JsonToken.EndObject: ValidateEnd(JsonToken.EndObject); break; case JsonToken.EndArray: ValidateEnd(JsonToken.EndArray); break; case JsonToken.EndConstructor: ValidateEnd(JsonToken.EndConstructor); break; case JsonToken.PropertyName: _currentState = State.Property; _currentPosition.PropertyName = (string)value; break; case JsonToken.Raw: case JsonToken.Integer: case JsonToken.Float: case JsonToken.String: case JsonToken.Boolean: case JsonToken.Null: case JsonToken.Undefined: case JsonToken.Date: case JsonToken.Bytes: SetPostValueState(updateIndex); break; case JsonToken.Comment: break; } } internal void SetPostValueState(bool updateIndex) { if (Peek() != 0) { _currentState = State.PostValue; } else { SetFinished(); } if (updateIndex) { UpdateScopeWithFinishedValue(); } } private void UpdateScopeWithFinishedValue() { if (_currentPosition.HasIndex) { _currentPosition.Position++; } } private void ValidateEnd(JsonToken endToken) { JsonContainerType jsonContainerType = Pop(); if (GetTypeForCloseToken(endToken) != jsonContainerType) { throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType)); } if (Peek() != 0) { _currentState = State.PostValue; } else { SetFinished(); } } protected void SetStateBasedOnCurrent() { JsonContainerType jsonContainerType = Peek(); switch (jsonContainerType) { case JsonContainerType.Object: _currentState = State.Object; break; case JsonContainerType.Array: _currentState = State.Array; break; case JsonContainerType.Constructor: _currentState = State.Constructor; break; case JsonContainerType.None: SetFinished(); break; default: throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType)); } } private void SetFinished() { if (SupportMultipleContent) { _currentState = State.Start; } else { _currentState = State.Finished; } } private JsonContainerType GetTypeForCloseToken(JsonToken token) { return token switch { JsonToken.EndObject => JsonContainerType.Object, JsonToken.EndArray => JsonContainerType.Array, JsonToken.EndConstructor => JsonContainerType.Constructor, _ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), }; } void IDisposable.Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_currentState != State.Closed && disposing) { Close(); } } public virtual void Close() { _currentState = State.Closed; _tokenType = JsonToken.None; _value = null; } internal void ReadAndAssert() { if (!Read()) { throw JsonSerializationException.Create(this, "Unexpected end when reading JSON."); } } internal bool ReadAndMoveToContent() { if (Read()) { return MoveToContent(); } return false; } internal bool MoveToContent() { JsonToken tokenType = TokenType; while (tokenType == JsonToken.None || tokenType == JsonToken.Comment) { if (!Read()) { return false; } tokenType = TokenType; } return true; } private JsonToken GetContentToken() { JsonToken tokenType; do { if (!Read()) { SetToken(JsonToken.None); return JsonToken.None; } tokenType = TokenType; } while (tokenType == JsonToken.Comment); return tokenType; } } [Serializable] public class JsonReaderException : JsonException { public int LineNumber { get; private set; } public int LinePosition { get; private set; } public string Path { get; private set; } public JsonReaderException() { } public JsonReaderException(string message) : base(message) { } public JsonReaderException(string message, Exception innerException) : base(message, innerException) { } public JsonReaderException(SerializationInfo info, StreamingContext context) : base(info, context) { } internal JsonReaderException(string message, Exception innerException, string path, int lineNumber, int linePosition) : base(message, innerException) { Path = path; LineNumber = lineNumber; LinePosition = linePosition; } internal static JsonReaderException Create(JsonReader reader, string message) { return Create(reader, message, null); } internal static JsonReaderException Create(JsonReader reader, string message, Exception ex) { return Create(reader as IJsonLineInfo, reader.Path, message, ex); } internal static JsonReaderException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex) { message = JsonPosition.FormatMessage(lineInfo, path, message); int lineNumber; int linePosition; if (lineInfo != null && lineInfo.HasLineInfo()) { lineNumber = lineInfo.LineNumber; linePosition = lineInfo.LinePosition; } else { lineNumber = 0; linePosition = 0; } return new JsonReaderException(message, ex, path, lineNumber, linePosition); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class JsonRequiredAttribute : Attribute { } [Serializable] public class JsonSerializationException : JsonException { public JsonSerializationException() { } public JsonSerializationException(string message) : base(message) { } public JsonSerializationException(string message, Exception innerException) : base(message, innerException) { } public JsonSerializationException(SerializationInfo info, StreamingContext context) : base(info, context) { } internal static JsonSerializationException Create(JsonReader reader, string message) { return Create(reader, message, null); } internal static JsonSerializationException Create(JsonReader reader, string message, Exception ex) { return Create(reader as IJsonLineInfo, reader.Path, message, ex); } internal static JsonSerializationException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex) { message = JsonPosition.FormatMessage(lineInfo, path, message); return new JsonSerializationException(message, ex); } } public class JsonSerializer { internal TypeNameHandling _typeNameHandling; internal FormatterAssemblyStyle _typeNameAssemblyFormat; internal PreserveReferencesHandling _preserveReferencesHandling; internal ReferenceLoopHandling _referenceLoopHandling; internal MissingMemberHandling _missingMemberHandling; internal ObjectCreationHandling _objectCreationHandling; internal NullValueHandling _nullValueHandling; internal DefaultValueHandling _defaultValueHandling; internal ConstructorHandling _constructorHandling; internal MetadataPropertyHandling _metadataPropertyHandling; internal JsonConverterCollection _converters; internal IContractResolver _contractResolver; internal ITraceWriter _traceWriter; internal IEqualityComparer _equalityComparer; internal SerializationBinder _binder; internal StreamingContext _context; private IReferenceResolver _referenceResolver; private Formatting? _formatting; private DateFormatHandling? _dateFormatHandling; private DateTimeZoneHandling? _dateTimeZoneHandling; private DateParseHandling? _dateParseHandling; private FloatFormatHandling? _floatFormatHandling; private FloatParseHandling? _floatParseHandling; private StringEscapeHandling? _stringEscapeHandling; private CultureInfo _culture; private int? _maxDepth; private bool _maxDepthSet; private bool? _checkAdditionalContent; private string _dateFormatString; private bool _dateFormatStringSet; public virtual IReferenceResolver ReferenceResolver { get { return GetReferenceResolver(); } set { if (value == null) { throw new ArgumentNullException("value", "Reference resolver cannot be null."); } _referenceResolver = value; } } public virtual SerializationBinder Binder { get { return _binder; } set { if (value == null) { throw new ArgumentNullException("value", "Serialization binder cannot be null."); } _binder = value; } } public virtual ITraceWriter TraceWriter { get { return _traceWriter; } set { _traceWriter = value; } } public virtual IEqualityComparer EqualityComparer { get { return _equalityComparer; } set { _equalityComparer = value; } } public virtual TypeNameHandling TypeNameHandling { get { return _typeNameHandling; } set { if (value < TypeNameHandling.None || value > TypeNameHandling.Auto) { throw new ArgumentOutOfRangeException("value"); } _typeNameHandling = value; } } public virtual FormatterAssemblyStyle TypeNameAssemblyFormat { get { return _typeNameAssemblyFormat; } set { if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full) { throw new ArgumentOutOfRangeException("value"); } _typeNameAssemblyFormat = value; } } public virtual PreserveReferencesHandling PreserveReferencesHandling { get { return _preserveReferencesHandling; } set { if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All) { throw new ArgumentOutOfRangeException("value"); } _preserveReferencesHandling = value; } } public virtual ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling; } set { if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize) { throw new ArgumentOutOfRangeException("value"); } _referenceLoopHandling = value; } } public virtual MissingMemberHandling MissingMemberHandling { get { return _missingMemberHandling; } set { if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error) { throw new ArgumentOutOfRangeException("value"); } _missingMemberHandling = value; } } public virtual NullValueHandling NullValueHandling { get { return _nullValueHandling; } set { if (value < NullValueHandling.Include || value > NullValueHandling.Ignore) { throw new ArgumentOutOfRangeException("value"); } _nullValueHandling = value; } } public virtual DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling; } set { if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate) { throw new ArgumentOutOfRangeException("value"); } _defaultValueHandling = value; } } public virtual ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling; } set { if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace) { throw new ArgumentOutOfRangeException("value"); } _objectCreationHandling = value; } } public virtual ConstructorHandling ConstructorHandling { get { return _constructorHandling; } set { if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor) { throw new ArgumentOutOfRangeException("value"); } _constructorHandling = value; } } public virtual MetadataPropertyHandling MetadataPropertyHandling { get { return _metadataPropertyHandling; } set { if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore) { throw new ArgumentOutOfRangeException("value"); } _metadataPropertyHandling = value; } } public virtual JsonConverterCollection Converters { get { if (_converters == null) { _converters = new JsonConverterCollection(); } return _converters; } } public virtual IContractResolver ContractResolver { get { return _contractResolver; } set { _contractResolver = value ?? DefaultContractResolver.Instance; } } public virtual StreamingContext Context { get { return _context; } set { _context = value; } } public virtual Formatting Formatting { get { return _formatting ?? Formatting.None; } set { _formatting = value; } } public virtual DateFormatHandling DateFormatHandling { get { return _dateFormatHandling ?? DateFormatHandling.IsoDateFormat; } set { _dateFormatHandling = value; } } public virtual DateTimeZoneHandling DateTimeZoneHandling { get { return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind; } set { _dateTimeZoneHandling = value; } } public virtual DateParseHandling DateParseHandling { get { return _dateParseHandling ?? DateParseHandling.DateTime; } set { _dateParseHandling = value; } } public virtual FloatParseHandling FloatParseHandling { get { return _floatParseHandling ?? FloatParseHandling.Double; } set { _floatParseHandling = value; } } public virtual FloatFormatHandling FloatFormatHandling { get { return _floatFormatHandling ?? FloatFormatHandling.String; } set { _floatFormatHandling = value; } } public virtual StringEscapeHandling StringEscapeHandling { get { return _stringEscapeHandling ?? StringEscapeHandling.Default; } set { _stringEscapeHandling = value; } } public virtual string DateFormatString { get { return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; } set { _dateFormatString = value; _dateFormatStringSet = true; } } public virtual CultureInfo Culture { get { return _culture ?? JsonSerializerSettings.DefaultCulture; } set { _culture = value; } } public virtual int? MaxDepth { get { return _maxDepth; } set { if (value <= 0) { throw new ArgumentException("Value must be positive.", "value"); } _maxDepth = value; _maxDepthSet = true; } } public virtual bool CheckAdditionalContent { get { return _checkAdditionalContent ?? false; } set { _checkAdditionalContent = value; } } public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> Error; internal bool IsCheckAdditionalContentSet() { return _checkAdditionalContent.HasValue; } public JsonSerializer() { _referenceLoopHandling = ReferenceLoopHandling.Error; _missingMemberHandling = MissingMemberHandling.Ignore; _nullValueHandling = NullValueHandling.Include; _defaultValueHandling = DefaultValueHandling.Include; _objectCreationHandling = ObjectCreationHandling.Auto; _preserveReferencesHandling = PreserveReferencesHandling.None; _constructorHandling = ConstructorHandling.Default; _typeNameHandling = TypeNameHandling.None; _metadataPropertyHandling = MetadataPropertyHandling.Default; _context = JsonSerializerSettings.DefaultContext; _binder = DefaultSerializationBinder.Instance; _culture = JsonSerializerSettings.DefaultCulture; _contractResolver = DefaultContractResolver.Instance; } public static JsonSerializer Create() { return new JsonSerializer(); } public static JsonSerializer Create(JsonSerializerSettings settings) { JsonSerializer jsonSerializer = Create(); if (settings != null) { ApplySerializerSettings(jsonSerializer, settings); } return jsonSerializer; } public static JsonSerializer CreateDefault() { return Create(JsonConvert.DefaultSettings?.Invoke()); } public static JsonSerializer CreateDefault(JsonSerializerSettings settings) { JsonSerializer jsonSerializer = CreateDefault(); if (settings != null) { ApplySerializerSettings(jsonSerializer, settings); } return jsonSerializer; } private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings) { if (!CollectionUtils.IsNullOrEmpty(settings.Converters)) { for (int i = 0; i < settings.Converters.Count; i++) { serializer.Converters.Insert(i, settings.Converters[i]); } } if (settings._typeNameHandling.HasValue) { serializer.TypeNameHandling = settings.TypeNameHandling; } if (settings._metadataPropertyHandling.HasValue) { serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling; } if (settings._typeNameAssemblyFormat.HasValue) { serializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat; } if (settings._preserveReferencesHandling.HasValue) { serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling; } if (settings._referenceLoopHandling.HasValue) { serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling; } if (settings._missingMemberHandling.HasValue) { serializer.MissingMemberHandling = settings.MissingMemberHandling; } if (settings._objectCreationHandling.HasValue) { serializer.ObjectCreationHandling = settings.ObjectCreationHandling; } if (settings._nullValueHandling.HasValue) { serializer.NullValueHandling = settings.NullValueHandling; } if (settings._defaultValueHandling.HasValue) { serializer.DefaultValueHandling = settings.DefaultValueHandling; } if (settings._constructorHandling.HasValue) { serializer.ConstructorHandling = settings.ConstructorHandling; } if (settings._context.HasValue) { serializer.Context = settings.Context; } if (settings._checkAdditionalContent.HasValue) { serializer._checkAdditionalContent = settings._checkAdditionalContent; } if (settings.Error != null) { serializer.Error += settings.Error; } if (settings.ContractResolver != null) { serializer.ContractResolver = settings.ContractResolver; } if (settings.ReferenceResolverProvider != null) { serializer.ReferenceResolver = settings.ReferenceResolverProvider(); } if (settings.TraceWriter != null) { serializer.TraceWriter = settings.TraceWriter; } if (settings.EqualityComparer != null) { serializer.EqualityComparer = settings.EqualityComparer; } if (settings.Binder != null) { serializer.Binder = settings.Binder; } if (settings._formatting.HasValue) { serializer._formatting = settings._formatting; } if (settings._dateFormatHandling.HasValue) { serializer._dateFormatHandling = settings._dateFormatHandling; } if (settings._dateTimeZoneHandling.HasValue) { serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling; } if (settings._dateParseHandling.HasValue) { serializer._dateParseHandling = settings._dateParseHandling; } if (settings._dateFormatStringSet) { serializer._dateFormatString = settings._dateFormatString; serializer._dateFormatStringSet = settings._dateFormatStringSet; } if (settings._floatFormatHandling.HasValue) { serializer._floatFormatHandling = settings._floatFormatHandling; } if (settings._floatParseHandling.HasValue) { serializer._floatParseHandling = settings._floatParseHandling; } if (settings._stringEscapeHandling.HasValue) { serializer._stringEscapeHandling = settings._stringEscapeHandling; } if (settings._culture != null) { serializer._culture = settings._culture; } if (settings._maxDepthSet) { serializer._maxDepth = settings._maxDepth; serializer._maxDepthSet = settings._maxDepthSet; } } public void Populate(TextReader reader, object target) { Populate(new JsonTextReader(reader), target); } public void Populate(JsonReader reader, object target) { PopulateInternal(reader, target); } internal virtual void PopulateInternal(JsonReader reader, object target) { ValidationUtils.ArgumentNotNull(reader, "reader"); ValidationUtils.ArgumentNotNull(target, "target"); SetupReader(reader, out var previousCulture, out var previousDateTimeZoneHandling, out var previousDateParseHandling, out var previousFloatParseHandling, out var previousMaxDepth, out var previousDateFormatString); TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonReader(reader) : null); new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target); if (traceJsonReader != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null); } ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString); } public object Deserialize(JsonReader reader) { return Deserialize(reader, null); } public object Deserialize(TextReader reader, Type objectType) { return Deserialize(new JsonTextReader(reader), objectType); } public T Deserialize<T>(JsonReader reader) { return (T)Deserialize(reader, typeof(T)); } public object Deserialize(JsonReader reader, Type objectType) { return DeserializeInternal(reader, objectType); } internal virtual object DeserializeInternal(JsonReader reader, Type objectType) { ValidationUtils.ArgumentNotNull(reader, "reader"); SetupReader(reader, out var previousCulture, out var previousDateTimeZoneHandling, out var previousDateParseHandling, out var previousFloatParseHandling, out var previousMaxDepth, out var previousDateFormatString); TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonReader(reader) : null); object result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent); if (traceJsonReader != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null); } ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString); return result; } private void SetupReader(JsonReader reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString) { if (_culture != null && !_culture.Equals(reader.Culture)) { previousCulture = reader.Culture; reader.Culture = _culture; } else { previousCulture = null; } if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling) { previousDateTimeZoneHandling = reader.DateTimeZoneHandling; reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault(); } else { previousDateTimeZoneHandling = null; } if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling) { previousDateParseHandling = reader.DateParseHandling; reader.DateParseHandling = _dateParseHandling.GetValueOrDefault(); } else { previousDateParseHandling = null; } if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling) { previousFloatParseHandling = reader.FloatParseHandling; reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault(); } else { previousFloatParseHandling = null; } if (_maxDepthSet && reader.MaxDepth != _maxDepth) { previousMaxDepth = reader.MaxDepth; reader.MaxDepth = _maxDepth; } else { previousMaxDepth = null; } if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString) { previousDateFormatString = reader.DateFormatString; reader.DateFormatString = _dateFormatString; } else { previousDateFormatString = null; } if (reader is JsonTextReader jsonTextReader && _contractResolver is DefaultContractResolver defaultContractResolver) { jsonTextReader.NameTable = defaultContractResolver.GetState().NameTable; } } private void ResetReader(JsonReader reader, CultureInfo previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string previousDateFormatString) { if (previousCulture != null) { reader.Culture = previousCulture; } if (previousDateTimeZoneHandling.HasValue) { reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault(); } if (previousDateParseHandling.HasValue) { reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault(); } if (previousFloatParseHandling.HasValue) { reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault(); } if (_maxDepthSet) { reader.MaxDepth = previousMaxDepth; } if (_dateFormatStringSet) { reader.DateFormatString = previousDateFormatString; } if (reader is JsonTextReader jsonTextReader) { jsonTextReader.NameTable = null; } } public void Serialize(TextWriter textWriter, object value) { Serialize(new JsonTextWriter(textWriter), value); } public void Serialize(JsonWriter jsonWriter, object value, Type objectType) { SerializeInternal(jsonWriter, value, objectType); } public void Serialize(TextWriter textWriter, object value, Type objectType) { Serialize(new JsonTextWriter(textWriter), value, objectType); } public void Serialize(JsonWriter jsonWriter, object value) { SerializeInternal(jsonWriter, value, null); } internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Type objectType) { ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter"); Formatting? formatting = null; if (_formatting.HasValue && jsonWriter.Formatting != _formatting) { formatting = jsonWriter.Formatting; jsonWriter.Formatting = _formatting.GetValueOrDefault(); } DateFormatHandling? dateFormatHandling = null; if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling) { dateFormatHandling = jsonWriter.DateFormatHandling; jsonWriter.DateFormatHandling = _dateFormatHandling.GetValueOrDefault(); } DateTimeZoneHandling? dateTimeZoneHandling = null; if (_dateTimeZoneHandling.HasValue && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling) { dateTimeZoneHandling = jsonWriter.DateTimeZoneHandling; jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault(); } FloatFormatHandling? floatFormatHandling = null; if (_floatFormatHandling.HasValue && jsonWriter.FloatFormatHandling != _floatFormatHandling) { floatFormatHandling = jsonWriter.FloatFormatHandling; jsonWriter.FloatFormatHandling = _floatFormatHandling.GetValueOrDefault(); } StringEscapeHandling? stringEscapeHandling = null; if (_stringEscapeHandling.HasValue && jsonWriter.StringEscapeHandling != _stringEscapeHandling) { stringEscapeHandling = jsonWriter.StringEscapeHandling; jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault(); } CultureInfo cultureInfo = null; if (_culture != null && !_culture.Equals(jsonWriter.Culture)) { cultureInfo = jsonWriter.Culture; jsonWriter.Culture = _culture; } string dateFormatString = null; if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString) { dateFormatString = jsonWriter.DateFormatString; jsonWriter.DateFormatString = _dateFormatString; } TraceJsonWriter traceJsonWriter = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonWriter(jsonWriter) : null); new JsonSerializerInternalWriter(this).Serialize(traceJsonWriter ?? jsonWriter, value, objectType); if (traceJsonWriter != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null); } if (formatting.HasValue) { jsonWriter.Formatting = formatting.GetValueOrDefault(); } if (dateFormatHandling.HasValue) { jsonWriter.DateFormatHandling = dateFormatHandling.GetValueOrDefault(); } if (dateTimeZoneHandling.HasValue) { jsonWriter.DateTimeZoneHandling = dateTimeZoneHandling.GetValueOrDefault(); } if (floatFormatHandling.HasValue) { jsonWriter.FloatFormatHandling = floatFormatHandling.GetValueOrDefault(); } if (stringEscapeHandling.HasValue) { jsonWriter.StringEscapeHandling = stringEscapeHandling.GetValueOrDefault(); } if (_dateFormatStringSet) { jsonWriter.DateFormatString = dateFormatString; } if (cultureInfo != null) { jsonWriter.Culture = cultureInfo; } } internal IReferenceResolver GetReferenceResolver() { if (_referenceResolver == null) { _referenceResolver = new DefaultReferenceResolver(); } return _referenceResolver; } internal JsonConverter GetMatchingConverter(Type type) { return GetMatchingConverter(_converters, type); } internal static JsonConverter GetMatchingConverter(IList<JsonConverter> converters, Type objectType) { if (converters != null) { for (int i = 0; i < converters.Count; i++) { JsonConverter jsonConverter = converters[i]; if (jsonConverter.CanConvert(objectType)) { return jsonConverter; } } } return null; } internal void OnError(Newtonsoft.Json.Serialization.ErrorEventArgs e) { this.Error?.Invoke(this, e); } } public class JsonSerializerSettings { internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error; internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore; internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include; internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include; internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto; internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None; internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default; internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None; internal const MetadataPropertyHandling DefaultMetadataPropertyHandling = MetadataPropertyHandling.Default; internal const FormatterAssemblyStyle DefaultTypeNameAssemblyFormat = FormatterAssemblyStyle.Simple; internal static readonly StreamingContext DefaultContext; internal const Formatting DefaultFormatting = Formatting.None; internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat; internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime; internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double; internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String; internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default; internal const FormatterAssemblyStyle DefaultFormatterAssemblyStyle = FormatterAssemblyStyle.Simple; internal static readonly CultureInfo DefaultCulture; internal const bool DefaultCheckAdditionalContent = false; internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; internal Formatting? _formatting; internal DateFormatHandling? _dateFormatHandling; internal DateTimeZoneHandling? _dateTimeZoneHandling; internal DateParseHandling? _dateParseHandling; internal FloatFormatHandling? _floatFormatHandling; internal FloatParseHandling? _floatParseHandling; internal StringEscapeHandling? _stringEscapeHandling; internal CultureInfo _culture; internal bool? _checkAdditionalContent; internal int? _maxDepth; internal bool _maxDepthSet; internal string _dateFormatString; internal bool _dateFormatStringSet; internal FormatterAssemblyStyle? _typeNameAssemblyFormat; internal DefaultValueHandling? _defaultValueHandling; internal PreserveReferencesHandling? _preserveReferencesHandling; internal NullValueHandling? _nullValueHandling; internal ObjectCreationHandling? _objectCreationHandling; internal MissingMemberHandling? _missingMemberHandling; internal ReferenceLoopHandling? _referenceLoopHandling; internal StreamingContext? _context; internal ConstructorHandling? _constructorHandling; internal TypeNameHandling? _typeNameHandling; internal MetadataPropertyHandling? _metadataPropertyHandling; public ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling ?? ReferenceLoopHandling.Error; } set { _referenceLoopHandling = value; } } public MissingMemberHandling MissingMemberHandling { get { return _missingMemberHandling ?? MissingMemberHandling.Ignore; } set { _missingMemberHandling = value; } } public ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling ?? ObjectCreationHandling.Auto; } set { _objectCreationHandling = value; } } public NullValueHandling NullValueHandling { get { return _nullValueHandling ?? NullValueHandling.Include; } set { _nullValueHandling = value; } } public DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling ?? DefaultValueHandling.Include; } set { _defaultValueHandling = value; } } public IList<JsonConverter> Converters { get; set; } public PreserveReferencesHandling PreserveReferencesHandling { get { return _preserveReferencesHandling ?? PreserveReferencesHandling.None; } set { _preserveReferencesHandling = value; } } public TypeNameHandling TypeNameHandling { get { return _typeNameHandling ?? TypeNameHandling.None; } set { _typeNameHandling = value; } } public MetadataPropertyHandling MetadataPropertyHandling { get { return _metadataPropertyHandling ?? MetadataPropertyHandling.Default; } set { _metadataPropertyHandling = value; } } public FormatterAssemblyStyle TypeNameAssemblyFormat { get { return _typeNameAssemblyFormat ?? FormatterAssemblyStyle.Simple; } set { _typeNameAssemblyFormat = value; } } public ConstructorHandling ConstructorHandling { get { return _constructorHandling ?? ConstructorHandling.Default; } set { _constructorHandling = value; } } public IContractResolver ContractResolver { get; set; } public IEqualityComparer EqualityComparer { get; set; } [Obsolete("ReferenceResolver property is obsolete. Use the ReferenceResolverProvider property to set the IReferenceResolver: settings.ReferenceResolverProvider = () => resolver")] public IReferenceResolver ReferenceResolver { get { if (ReferenceResolverProvider == null) { return null; } return ReferenceResolverProvider(); } set { ReferenceResolverProvider = ((value != null) ? ((Func<IReferenceResolver>)(() => value)) : null); } } public Func<IReferenceResolver> ReferenceResolverProvider { get; set; } public ITraceWriter TraceWriter { get; set; } public SerializationBinder Binder { get; set; } public EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> Error { get; set; } public StreamingContext Context { get { return _context ?? DefaultContext; } set { _context = value; } } public string DateFormatString { get { return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; } set { _dateFormatString = value; _dateFormatStringSet = true; } } public int? MaxDepth { get { return _maxDepth; } set { if (value <= 0) { throw new ArgumentException("Value must be positive.", "value"); } _maxDepth = value; _maxDepthSet = true; } } public Formatting Formatting { get { return _formatting ?? Formatting.None; } set { _formatting = value; } } public DateFormatHandling DateFormatHandling { get { return _dateFormatHandling ?? DateFormatHandling.IsoDateFormat; } set { _dateFormatHandling = value; } } public DateTimeZoneHandling DateTimeZoneHandling { get { return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind; } set { _dateTimeZoneHandling = value; } } public DateParseHandling DateParseHandling { get { return _dateParseHandling ?? DateParseHandling.DateTime; } set { _dateParseHandling = value; } } public FloatFormatHandling FloatFormatHandling { get { return _floatFormatHandling ?? FloatFormatHandling.String; } set { _floatFormatHandling = value; } } public FloatParseHandling FloatParseHandling { get { return _floatParseHandling ?? FloatParseHandling.Double; } set { _floatParseHandling = value; } } public StringEscapeHandling StringEscapeHandling { get { return _stringEscapeHandling ?? StringEscapeHandling.Default; } set { _stringEscapeHandling = value; } } public CultureInfo Culture { get { return _culture ?? DefaultCulture; } set { _culture = value; } } public bool CheckAdditionalContent { get { return _checkAdditionalContent ?? false; } set { _checkAdditionalContent = value; } } static JsonSerializerSettings() { DefaultContext = default(StreamingContext); DefaultCulture = CultureInfo.InvariantCulture; } public JsonSerializerSettings() { Converters = new List<JsonConverter>(); } } internal enum ReadType { Read, ReadAsInt32, ReadAsBytes, ReadAsString, ReadAsDecimal, ReadAsDateTime, ReadAsDateTimeOffset, ReadAsDouble, ReadAsBoolean } public class JsonTextReader : JsonReader, IJsonLineInfo { private const char UnicodeReplacementChar = '\ufffd'; private const int MaximumJavascriptIntegerCharacterLength = 380; private readonly TextReader _reader; private char[] _chars; private int _charsUsed; private int _charPos; private int _lineStartPos; private int _lineNumber; private bool _isEndOfFile; private StringBuffer _stringBuffer; private StringReference _stringReference; private IArrayPool<char> _arrayPool; internal PropertyNameTable NameTable; public IArrayPool<char> ArrayPool { get { return _arrayPool; } set { if (value == null) { throw new ArgumentNullException("value"); } _arrayPool = value; } } public int LineNumber { get { if (base.CurrentState == State.Start && LinePosition == 0 && TokenType != JsonToken.Comment) { return 0; } return _lineNumber; } } public int LinePosition => _charPos - _lineStartPos; public JsonTextReader(TextReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } _reader = reader; _lineNumber = 1; } private void EnsureBufferNotEmpty() { if (_stringBuffer.IsEmpty) { _stringBuffer = new StringBuffer(_arrayPool, 1024); } } private void OnNewLine(int pos) { _lineNumber++; _lineStartPos = pos; } private void ParseString(char quote, ReadType readType) { _charPos++; ShiftBufferIfNeeded(); ReadStringIntoBuffer(quote); SetPostValueState(updateIndex: true); switch (readType) { case ReadType.ReadAsBytes: { Guid g; byte[] value2 = ((_stringReference.Length == 0) ? new byte[0] : ((_stringReference.Length != 36 || !ConvertUtils.TryConvertGuid(_stringReference.ToString(), out g)) ? Convert.FromBase64CharArray(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length) : g.ToByteArray())); SetToken(JsonToken.Bytes, value2, updateIndex: false); return; } case ReadType.ReadAsString: { string value = _stringReference.ToString(); SetToken(JsonToken.String, value, updateIndex: false); _quoteChar = quote; return; } case ReadType.ReadAsInt32: case ReadType.ReadAsDecimal: case ReadType.ReadAsBoolean: return; } if (_dateParseHandling != 0) { DateTimeOffset dt2; if (readType switch { ReadType.ReadAsDateTime => 1, ReadType.ReadAsDateTimeOffset => 2, _ => (int)_dateParseHandling, } == 1) { if (DateTimeUtils.TryParseDateTime(_stringReference, base.DateTimeZoneHandling, base.DateFormatString, base.Culture, out var dt)) { SetToken(JsonToken.Date, dt, updateIndex: false); return; } } else if (DateTimeUtils.TryParseDateTimeOffset(_stringReference, base.DateFormatString, base.Culture, out dt2)) { SetToken(JsonToken.Date, dt2, updateIndex: false); return; } } SetToken(JsonToken.String, _stringReference.ToString(), updateIndex: false); _quoteChar = quote; } private static void BlockCopyChars(char[] src, int srcOffset, char[] dst, int dstOffset, int count) { Buffer.BlockCopy(src, srcOffset * 2, dst, dstOffset * 2, count * 2); } private void ShiftBufferIfNeeded() { int num = _chars.Length; if ((double)(num - _charPos) <= (double)num * 0.1) { int num2 = _charsUsed - _charPos; if (num2 > 0) { BlockCopyChars(_chars, _charPos, _chars, 0, num2); } _lineStartPos -= _charPos; _charPos = 0; _charsUsed = num2; _chars[_charsUsed] = '\0'; } } private int ReadData(bool append) { return ReadData(append, 0); } private int ReadData(bool append, int charsRequired) { if (_isEndOfFile) { return 0; } if (_charsUsed + charsRequired >= _chars.Length - 1) { if (append) { int minSize = Math.Max(_chars.Length * 2, _charsUsed + charsRequired + 1); char[] array = BufferUtils.RentBuffer(_arrayPool, minSize); BlockCopyChars(_chars, 0, array, 0, _chars.Length); BufferUtils.ReturnBuffer(_arrayPool, _chars); _chars = array; } else { int num = _charsUsed - _charPos; if (num + charsRequired + 1 >= _chars.Length) { char[] array2 = BufferUtils.RentBuffer(_arrayPool, num + charsRequired + 1); if (num > 0) { BlockCopyChars(_chars, _charPos, array2, 0, num); } BufferUtils.ReturnBuffer(_arrayPool, _chars); _chars = array2; } else if (num > 0) { BlockCopyChars(_chars, _charPos, _chars, 0, num); } _lineStartPos -= _charPos; _charPos = 0; _charsUsed = num; } } int count = _chars.Length - _charsUsed - 1; int num2 = _reader.Read(_chars, _charsUsed, count); _charsUsed += num2; if (num2 == 0) { _isEndOfFile = true; } _chars[_charsUsed] = '\0'; return num2; } private bool EnsureChars(int relativePosition, bool append) { if (_charPos + relativePosition >= _charsUsed) { return ReadChars(relativePosition, append); } return true; } private bool ReadChars(int relativePosition, bool append) { if (_isEndOfFile) { return false; } int num = _charPos + relativePosition - _charsUsed + 1; int num2 = 0; do { int num3 = ReadData(append, num - num2); if (num3 == 0) { break; } num2 += num3; } while (num2 < num); if (num2 < num) { return false; } return true; } public override bool Read() { EnsureBuffer(); do { switch (_currentState) { case State.Start: case State.Property: case State.ArrayStart: case State.Array: case State.ConstructorStart: case State.Constructor: return ParseValue(); case State.ObjectStart: case State.Object: return ParseObject(); case State.PostValue: break; case State.Finished: if (EnsureChars(0, append: false)) { EatWhitespace(oneOrMore: false); if (_isEndOfFile) { SetToken(JsonToken.None); return false; } if (_chars[_charPos] == '/') { ParseComment(setToken: true); return true; } throw JsonReaderException.Create(this, "Additional text encountered after finished reading JSON content: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); } SetToken(JsonToken.None); return false; default: throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState)); } } while (!ParsePostValue()); return true; } public override int? ReadAsInt32() { return (int?)ReadNumberValue(ReadType.ReadAsInt32); } public override DateTime? ReadAsDateTime() { return (DateTime?)ReadStringValue(ReadType.ReadAsDateTime); } public override string ReadAsString() { return (string)ReadStringValue(ReadType.ReadAsString); } public override byte[] ReadAsBytes() { EnsureBuffer(); bool flag = false; switch (_currentState) { case State.Start: case State.Property: case State.ArrayStart: case State.Array: case State.PostValue: case State.ConstructorStart: case State.Constructor: while (true) { char c = _chars[_charPos]; switch (c) { case '\0': if (ReadNullChar()) { SetToken(JsonToken.None, null, updateIndex: false); return null; } break; case '"': case '\'': { ParseString(c, ReadType.ReadAsBytes); byte[] array = (byte[])Value; if (flag) { ReaderReadAndAssert(); if (TokenType != JsonToken.EndObject) { throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } SetToken(JsonToken.Bytes, array, updateIndex: false); } return array; } case '{': _charPos++; SetToken(JsonToken.StartObject); ReadIntoWrappedTypeObject(); flag = true; break; case '[': _charPos++; SetToken(JsonToken.StartArray); return ReadArrayIntoByteArray(); case 'n': HandleNull(); return null; case '/': ParseComment(setToken: false); break; case ',': ProcessValueComma(); break; case ']': _charPos++; if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue) { SetToken(JsonToken.EndArray); return null; } throw CreateUnexpectedCharacterException(c); case '\r': ProcessCarriageReturn(append: false); break; case '\n': ProcessLineFeed(); break; case '\t': case ' ': _charPos++; break; default: _charPos++; if (!char.IsWhiteSpace(c)) { throw CreateUnexpectedCharacterException(c); } break; } } case State.Finished: ReadFinished(); return null; default: throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState)); } } private object ReadStringValue(ReadType readType) { EnsureBuffer(); switch (_currentState) { case State.Start: case State.Property: case State.ArrayStart: case State.Array: case State.PostValue: case State.ConstructorStart: case State.Constructor: while (true) { char c = _chars[_charPos]; switch (c) { case '\0': if (ReadNullChar()) { SetToken(JsonToken.None, null, updateIndex: false); return null; } break; case '"': case '\'': ParseString(c, readType); switch (readType) { case ReadType.ReadAsBytes: return Value; case ReadType.ReadAsString: return Value; case ReadType.ReadAsDateTime: if (Value is DateTime) { return (DateTime)Value; } return ReadDateTimeString((string)Value); case ReadType.ReadAsDateTimeOffset: if (Value is DateTimeOffset) { return (DateTimeOffset)Value; } return ReadDateTimeOffsetString((string)Value); default: throw new ArgumentOutOfRangeException("readType"); } case '-': if (EnsureChars(1, append: true) && _chars[_charPos + 1] == 'I') { return ParseNumberNegativeInfinity(readType); } ParseNumber(readType); return Value; case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (readType != ReadType.ReadAsString) { _charPos++; throw CreateUnexpectedCharacterException(c); } ParseNumber(ReadType.ReadAsString); return Value; case 'f': case 't': { if (readType != ReadType.ReadAsString) { _charPos++; throw CreateUnexpectedCharacterException(c); } string text = ((c == 't') ? JsonConvert.True : JsonConvert.False); if (!MatchValueWithTrailingSeparator(text)) { throw CreateUnexpectedCharacterException(_chars[_charPos]); } SetToken(JsonToken.String, text); return text; } case 'I': return ParseNumberPositiveInfinity(readType); case 'N': return ParseNumberNaN(readType); case 'n': HandleNull(); return null; case '/': ParseComment(setToken: false); break; case ',': ProcessValueComma(); break; case ']': _charPos++; if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue) { SetToken(JsonToken.EndArray); return null; } throw CreateUnexpectedCharacterException(c); case '\r': ProcessCarriageReturn(append: false); break; case '\n': ProcessLineFeed(); break; case '\t': case ' ': _charPos++; break; default: _charPos++; if (!char.IsWhiteSpace(c)) { throw CreateUnexpectedCharacterException(c); } break; } } case State.Finished: ReadFinished(); return null; default: throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState)); } } private JsonReaderException CreateUnexpectedCharacterException(char c) { return JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, c)); } public override bool? ReadAsBoolean() { EnsureBuffer(); switch (_currentState) { case State.Start: case State.Property: case State.ArrayStart: case State.Array: case State.PostValue: case State.ConstructorStart: case State.Constructor: while (true) { char c = _chars[_charPos]; switch (c) { case '\0': if (ReadNullChar()) { SetToken(JsonToken.None, null, updateIndex: false); return null; } break; case '"': case '\'': ParseString(c, ReadType.Read); return ReadBooleanString(_stringReference.ToString()); case 'n': HandleNull(); return null; case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { ParseNumber(ReadType.Read); bool flag2 = Convert.ToBoolean(Value, CultureInfo.InvariantCulture); SetToken(JsonToken.Boolean, flag2, updateIndex: false); return flag2; } case 'f': case 't': { bool flag = c == 't'; string value = (flag ? JsonConvert.True : JsonConvert.False); if (!MatchValueWithTrailingSeparator(value)) { throw CreateUnexpectedCharacterException(_chars[_charPos]); } SetToken(JsonToken.Boolean, flag); return flag; } case '/': ParseComment(setToken: false); break; case ',': ProcessValueComma(); break; case ']': _charPos++; if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue) { SetToken(JsonToken.EndArray); return null; } throw CreateUnexpectedCharacterException(c); case '\r': ProcessCarriageReturn(append: false); break; case '\n': ProcessLineFeed(); break; case '\t': case ' ': _charPos++; break; default: _charPos++; if (!char.IsWhiteSpace(c)) { throw CreateUnexpectedCharacterException(c); } break; } } case State.Finished: ReadFinished(); return null; default: throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState)); } } private void ProcessValueComma() { _charPos++; if (_currentState != State.PostValue) { SetToken(JsonToken.Undefined); throw CreateUnexpectedCharacterException(','); } SetStateBasedOnCurrent(); } private object ReadNumberValue(ReadType readType) { EnsureBuffer(); switch (_currentState) { case State.Start: case State.Property: case State.ArrayStart: case State.Array: case State.PostValue: case State.ConstructorStart: case State.Constructor: while (true) { char c = _chars[_charPos]; switch (c) { case '\0': if (ReadNullChar()) { SetToken(JsonToken.None, null, updateIndex: false); return null; } break; case '"': case '\'': ParseString(c, readType); return readType switch { ReadType.ReadAsInt32 => ReadInt32String(_stringReference.ToString()), ReadType.ReadAsDecimal => ReadDecimalString(_stringReference.ToString()), ReadType.ReadAsDouble => ReadDoubleString(_stringReference.ToString()), _ => throw new ArgumentOutOfRangeException("readType"), }; case 'n': HandleNull(); return null; case 'N': return ParseNumberNaN(readType); case 'I': return ParseNumberPositiveInfinity(readType); case '-': if (EnsureChars(1, append: true) && _chars[_charPos + 1] == 'I') { return ParseNumberNegativeInfinity(readType); } ParseNumber(readType); return Value; case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ParseNumber(readType); return Value; case '/': ParseComment(setToken: false); break; case ',': ProcessValueComma(); break; case ']': _charPos++; if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue) { SetToken(JsonToken.EndArray); return null; } throw CreateUnexpectedCharacterException(c); case '\r': ProcessCarriageReturn(append: false); break; case '\n': ProcessLineFeed(); break; case '\t': case ' ': _charPos++; break; default: _charPos++; if (!char.IsWhiteSpace(c)) { throw CreateUnexpectedCharacterException(c); } break; } } case State.Finished: ReadFinished(); return null; default: throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState)); } } public override DateTimeOffset? ReadAsDateTimeOffset() { return (DateTimeOffset?)ReadStringValue(ReadType.ReadAsDateTimeOffset); } public override decimal? ReadAsDecimal() { return (decimal?)ReadNumberValue(ReadType.ReadAsDecimal); } public override double? ReadAsDouble() { return (double?)ReadNumberValue(ReadType.ReadAsDouble); } private void HandleNull() { if (EnsureChars(1, append: true)) { if (_chars[_charPos + 1] == 'u') { ParseNull(); return; } _charPos += 2; throw CreateUnexpectedCharacterException(_chars[_charPos - 1]); } _charPos = _charsUsed; throw CreateUnexpectedEndException(); } private void ReadF
System.Runtime.Serialization.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters; using System.Text; using System.Xml; using System.Xml.Serialization; [assembly: AssemblyTitle("System.Runtime.Serialization.dll")] [assembly: AssemblyDescription("System.Runtime.Serialization.dll")] [assembly: AssemblyDefaultAlias("System.Runtime.Serialization.dll")] [assembly: AssemblyCompany("MONO development team")] [assembly: AssemblyProduct("MONO Common language infrastructure")] [assembly: AssemblyCopyright("(c) various MONO Authors")] [assembly: SatelliteContractVersion("2.0.5.0")] [assembly: AssemblyInformationalVersion("3.0.40818.0")] [assembly: AssemblyFileVersion("3.0.40818.0")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: CLSCompliant(true)] [assembly: AssemblyDelaySign(true)] [assembly: AssemblyKeyFile("../silverlight.pub")] [assembly: InternalsVisibleTo("System.ServiceModel, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] [assembly: InternalsVisibleTo("System.ServiceModel.Web, PublicKey=00240000048000009400000006020000002400005253413100040000010001008D56C76F9E8649383049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B37AB")] [assembly: ComVisible(false)] [assembly: CompilationRelaxations(CompilationRelaxations.NoStringInterning)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("2.0.5.0")] namespace System.Runtime.Serialization { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] public sealed class CollectionDataContractAttribute : Attribute { private string name; private string ns; private string item_name; private string key_name; private string value_name; private bool is_reference; public string Name { get { return name; } set { name = value; } } public string Namespace { get { return ns; } set { ns = value; } } public string ItemName { get { return item_name; } set { item_name = value; } } public string KeyName { get { return key_name; } set { key_name = value; } } public string ValueName { get { return value_name; } set { value_name = value; } } public bool IsReference { get; set; } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module, Inherited = false, AllowMultiple = true)] public sealed class ContractNamespaceAttribute : Attribute { private string clr_ns; private string contract_ns; public string ClrNamespace { get { return clr_ns; } set { clr_ns = value; } } public string ContractNamespace => contract_ns; public ContractNamespaceAttribute(string ns) { contract_ns = ns; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, Inherited = false, AllowMultiple = false)] public sealed class DataContractAttribute : Attribute { private string name; private string ns; public string Name { get { return name; } set { name = value; } } public string Namespace { get { return ns; } set { ns = value; } } public bool IsReference { get; set; } } public sealed class DataContractSerializer : XmlObjectSerializer { private const string xmlns = "http://www.w3.org/2000/xmlns/"; private Type type; private bool ignore_ext; private bool preserve_refs; private StreamingContext context; private ReadOnlyCollection<Type> known_runtime_types; private KnownTypeCollection known_types; private IDataContractSurrogate surrogate; private int max_items = 65536; private bool names_filled; private XmlDictionaryString root_name; private XmlDictionaryString root_ns; public bool IgnoreExtensionDataObject => ignore_ext; public ReadOnlyCollection<Type> KnownTypes => known_runtime_types; public IDataContractSurrogate DataContractSurrogate => surrogate; public int MaxItemsInObjectGraph => max_items; public bool PreserveObjectReferences => preserve_refs; public DataContractSerializer(Type type) : this(type, Type.EmptyTypes) { } public DataContractSerializer(Type type, IEnumerable<Type> knownTypes) { if ((object)type == null) { throw new ArgumentNullException("type"); } this.type = type; known_types = new KnownTypeCollection(); PopulateTypes(knownTypes); known_types.TryRegister(type); XmlQualifiedName qName = known_types.GetQName(type); FillDictionaryString(qName.Name, qName.Namespace); } public DataContractSerializer(Type type, string rootName, string rootNamespace) : this(type, rootName, rootNamespace, Type.EmptyTypes) { } public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace) : this(type, rootName, rootNamespace, Type.EmptyTypes) { } public DataContractSerializer(Type type, string rootName, string rootNamespace, IEnumerable<Type> knownTypes) { if ((object)type == null) { throw new ArgumentNullException("type"); } if (rootName == null) { throw new ArgumentNullException("rootName"); } if (rootNamespace == null) { throw new ArgumentNullException("rootNamespace"); } this.type = type; PopulateTypes(knownTypes); FillDictionaryString(rootName, rootNamespace); } public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace, IEnumerable<Type> knownTypes) { if ((object)type == null) { throw new ArgumentNullException("type"); } if (rootName == null) { throw new ArgumentNullException("rootName"); } if (rootNamespace == null) { throw new ArgumentNullException("rootNamespace"); } this.type = type; PopulateTypes(knownTypes); root_name = rootName; root_ns = rootNamespace; } public DataContractSerializer(Type type, IEnumerable<Type> knownTypes, int maxObjectsInGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate) : this(type, knownTypes) { Initialize(maxObjectsInGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate); } public DataContractSerializer(Type type, string rootName, string rootNamespace, IEnumerable<Type> knownTypes, int maxObjectsInGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate) : this(type, rootName, rootNamespace, knownTypes) { Initialize(maxObjectsInGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate); } public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace, IEnumerable<Type> knownTypes, int maxObjectsInGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate) : this(type, rootName, rootNamespace, knownTypes) { Initialize(maxObjectsInGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate); } private void PopulateTypes(IEnumerable<Type> knownTypes) { if (known_types == null) { known_types = new KnownTypeCollection(); } if (knownTypes != null) { foreach (Type knownType in knownTypes) { known_types.TryRegister(knownType); } } Type elementType = type; if (type.HasElementType) { elementType = type.GetElementType(); } object[] customAttributes = elementType.GetCustomAttributes(typeof(KnownTypeAttribute), inherit: true); for (int i = 0; i < customAttributes.Length; i++) { KnownTypeAttribute knownTypeAttribute = (KnownTypeAttribute)customAttributes[i]; known_types.TryRegister(knownTypeAttribute.Type); } } private void FillDictionaryString(string name, string ns) { XmlDictionary xmlDictionary = new XmlDictionary(); root_name = xmlDictionary.Add(name); root_ns = xmlDictionary.Add(ns); names_filled = true; } private void Initialize(int maxObjectsInGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate) { if (maxObjectsInGraph < 0) { throw new ArgumentOutOfRangeException("maxObjectsInGraph must not be negative."); } max_items = maxObjectsInGraph; ignore_ext = ignoreExtensionDataObject; preserve_refs = preserveObjectReferences; surrogate = dataContractSurrogate; PopulateTypes(Type.EmptyTypes); } [MonoTODO] public override bool IsStartObject(XmlDictionaryReader reader) { throw new NotImplementedException(); } public override bool IsStartObject(XmlReader reader) { return IsStartObject(XmlDictionaryReader.CreateDictionaryReader(reader)); } public override object ReadObject(XmlReader reader) { return ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader)); } public override object ReadObject(XmlReader reader, bool verifyObjectName) { return ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader), verifyObjectName); } [MonoTODO] public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName) { int count = known_types.Count; known_types.Add(type); bool isEmptyElement = reader.IsEmptyElement; object result = XmlFormatterDeserializer.Deserialize(reader, type, known_types, surrogate, root_name.Value, root_ns.Value, verifyObjectName); while (known_types.Count > count) { known_types.RemoveAt(count); } return result; } private void ReadRootStartElement(XmlReader reader, Type type) { SerializationMap serializationMap = known_types.FindUserMap(type); XmlQualifiedName xmlQualifiedName = ((serializationMap == null) ? KnownTypeCollection.GetPredefinedTypeName(type) : serializationMap.XmlName); reader.MoveToContent(); reader.ReadStartElement(xmlQualifiedName.Name, xmlQualifiedName.Namespace); reader.Read(); } public override void WriteObject(XmlWriter writer, object graph) { XmlDictionaryWriter writer2 = XmlDictionaryWriter.CreateDictionaryWriter(writer); WriteObject(writer2, graph); } [MonoTODO("support arrays; support Serializable; support SharedType; use DataContractSurrogate")] public override void WriteObjectContent(XmlDictionaryWriter writer, object graph) { if (graph != null) { int count = known_types.Count; XmlFormatterSerializer.Serialize(writer, graph, known_types, ignore_ext, max_items, root_ns.Value); while (known_types.Count > count) { known_types.RemoveAt(count); } } } public override void WriteObjectContent(XmlWriter writer, object graph) { XmlDictionaryWriter writer2 = XmlDictionaryWriter.CreateDictionaryWriter(writer); WriteObjectContent(writer2, graph); } public override void WriteStartObject(XmlWriter writer, object graph) { WriteStartObject(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph); } public override void WriteStartObject(XmlDictionaryWriter writer, object graph) { Type type = this.type; if (root_name.Value == string.Empty) { throw new InvalidDataContractException("Type '" + this.type.ToString() + "' cannot have a DataContract attribute Name set to null or empty string."); } if (graph == null) { if (names_filled) { writer.WriteStartElement(root_name.Value, root_ns.Value); } else { writer.WriteStartElement(root_name, root_ns); } writer.WriteAttributeString("i", "nil", "http://www.w3.org/2001/XMLSchema-instance", "true"); return; } XmlQualifiedName xmlQualifiedName = null; XmlQualifiedName qName = known_types.GetQName(type); XmlQualifiedName qName2 = known_types.GetQName(graph.GetType()); known_types.Add(graph.GetType()); if (names_filled) { writer.WriteStartElement(root_name.Value, root_ns.Value); } else { writer.WriteStartElement(root_name, root_ns); } if (root_ns.Value != qName.Namespace && qName.Namespace != "http://schemas.microsoft.com/2003/10/Serialization/") { writer.WriteXmlnsAttribute(null, qName.Namespace); } if (qName == qName2) { if (qName.Namespace != "http://schemas.microsoft.com/2003/10/Serialization/" && !type.IsEnum) { writer.WriteXmlnsAttribute("i", "http://www.w3.org/2001/XMLSchema-instance"); } return; } known_types.Add(type); xmlQualifiedName = KnownTypeCollection.GetPredefinedTypeName(graph.GetType()); xmlQualifiedName = ((!(xmlQualifiedName == XmlQualifiedName.Empty)) ? new XmlQualifiedName(xmlQualifiedName.Name, "http://www.w3.org/2001/XMLSchema") : qName2); writer.WriteStartAttribute("i", "type", "http://www.w3.org/2001/XMLSchema-instance"); writer.WriteQualifiedName(xmlQualifiedName.Name, xmlQualifiedName.Namespace); writer.WriteEndAttribute(); } public override void WriteEndObject(XmlDictionaryWriter writer) { writer.WriteEndElement(); } public override void WriteEndObject(XmlWriter writer) { WriteEndObject(XmlDictionaryWriter.CreateDictionaryWriter(writer)); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] public sealed class DataMemberAttribute : Attribute { private bool is_required; private bool emit_default = true; private string name; private int order = -1; public bool EmitDefaultValue { get { return emit_default; } set { emit_default = value; } } public bool IsRequired { get { return is_required; } set { is_required = value; } } public string Name { get { return name; } set { name = value; } } public int Order { get { return order; } set { order = value; } } } [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] public sealed class EnumMemberAttribute : Attribute { private string value; public string Value { get { return value; } set { this.value = value; } } } public class ExportOptions { private IDataContractSurrogate surrogate; private KnownTypeCollection known_types; public IDataContractSurrogate DataContractSurrogate { get { return surrogate; } set { surrogate = value; } } public Collection<Type> KnownTypes => known_types; } public sealed class ExtensionDataObject { private object target; internal ExtensionDataObject(object target) { this.target = target; } } public interface IDataContractSurrogate { object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType); object GetCustomDataToExport(Type clrType, Type dataContractType); Type GetDataContractType(Type type); object GetDeserializedObject(object obj, Type targetType); void GetKnownCustomDataTypes(Collection<Type> customDataTypes); object GetObjectToSerialize(object obj, Type targetType); } public interface IExtensibleDataObject { ExtensionDataObject ExtensionData { get; set; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] public sealed class IgnoreDataMemberAttribute : Attribute { } [Serializable] public class InvalidDataContractException : Exception { public InvalidDataContractException() { } public InvalidDataContractException(string message) : base(message) { } protected InvalidDataContractException(SerializationInfo info, StreamingContext context) : base(info, context) { } public InvalidDataContractException(string message, Exception innerException) : base(message, innerException) { } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = true)] public sealed class KnownTypeAttribute : Attribute { private string method_name; private Type type; public string MethodName => method_name; public Type Type => type; public KnownTypeAttribute(string methodName) { method_name = methodName; } public KnownTypeAttribute(Type type) { this.type = type; } } internal static class TypeExtensions { public static T GetCustomAttribute<T>(this Type type, bool inherit) { object[] customAttributes = type.GetCustomAttributes(typeof(T), inherit); return (customAttributes == null || customAttributes.Length != 1) ? default(T) : ((T)customAttributes[0]); } } internal sealed class KnownTypeCollection : Collection<Type> { internal const string MSSimpleNamespace = "http://schemas.microsoft.com/2003/10/Serialization/"; internal const string MSArraysNamespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"; internal const string DefaultClrNamespaceBase = "http://schemas.datacontract.org/2004/07/"; private static XmlQualifiedName any_type; private static XmlQualifiedName bool_type; private static XmlQualifiedName byte_type; private static XmlQualifiedName date_type; private static XmlQualifiedName decimal_type; private static XmlQualifiedName double_type; private static XmlQualifiedName float_type; private static XmlQualifiedName string_type; private static XmlQualifiedName short_type; private static XmlQualifiedName int_type; private static XmlQualifiedName long_type; private static XmlQualifiedName ubyte_type; private static XmlQualifiedName ushort_type; private static XmlQualifiedName uint_type; private static XmlQualifiedName ulong_type; private static XmlQualifiedName any_uri_type; private static XmlQualifiedName base64_type; private static XmlQualifiedName duration_type; private static XmlQualifiedName qname_type; private static XmlQualifiedName char_type; private static XmlQualifiedName guid_type; private static XmlQualifiedName dbnull_type; private List<SerializationMap> contracts = new List<SerializationMap>(); static KnownTypeCollection() { string ns = "http://schemas.microsoft.com/2003/10/Serialization/"; any_type = new XmlQualifiedName("anyType", ns); any_uri_type = new XmlQualifiedName("anyURI", ns); bool_type = new XmlQualifiedName("boolean", ns); base64_type = new XmlQualifiedName("base64Binary", ns); date_type = new XmlQualifiedName("dateTime", ns); duration_type = new XmlQualifiedName("duration", ns); qname_type = new XmlQualifiedName("QName", ns); decimal_type = new XmlQualifiedName("decimal", ns); double_type = new XmlQualifiedName("double", ns); float_type = new XmlQualifiedName("float", ns); byte_type = new XmlQualifiedName("byte", ns); short_type = new XmlQualifiedName("short", ns); int_type = new XmlQualifiedName("int", ns); long_type = new XmlQualifiedName("long", ns); ubyte_type = new XmlQualifiedName("unsignedByte", ns); ushort_type = new XmlQualifiedName("unsignedShort", ns); uint_type = new XmlQualifiedName("unsignedInt", ns); ulong_type = new XmlQualifiedName("unsignedLong", ns); string_type = new XmlQualifiedName("string", ns); guid_type = new XmlQualifiedName("guid", ns); char_type = new XmlQualifiedName("char", ns); dbnull_type = new XmlQualifiedName("DBNull", "http://schemas.microsoft.com/2003/10/Serialization/System"); } internal XmlQualifiedName GetXmlName(Type type) { SerializationMap serializationMap = FindUserMap(type); if (serializationMap != null) { return serializationMap.XmlName; } return GetPredefinedTypeName(type); } internal static XmlQualifiedName GetPredefinedTypeName(Type type) { XmlQualifiedName primitiveTypeName = GetPrimitiveTypeName(type); if (primitiveTypeName != XmlQualifiedName.Empty) { return primitiveTypeName; } if ((object)type == typeof(DBNull)) { return dbnull_type; } return XmlQualifiedName.Empty; } internal static XmlQualifiedName GetPrimitiveTypeName(Type type) { if (type.IsGenericType && (object)type.GetGenericTypeDefinition() == typeof(Nullable<>)) { return GetPrimitiveTypeName(type.GetGenericArguments()[0]); } if (type.IsEnum) { return XmlQualifiedName.Empty; } switch (Type.GetTypeCode(type)) { default: if ((object)type == typeof(object)) { return any_type; } if ((object)type == typeof(Guid)) { return guid_type; } if ((object)type == typeof(TimeSpan)) { return duration_type; } if ((object)type == typeof(byte[])) { return base64_type; } if ((object)type == typeof(Uri)) { return any_uri_type; } return XmlQualifiedName.Empty; case TypeCode.Boolean: return bool_type; case TypeCode.Byte: return ubyte_type; case TypeCode.Char: return char_type; case TypeCode.DateTime: return date_type; case TypeCode.Decimal: return decimal_type; case TypeCode.Double: return double_type; case TypeCode.Int16: return short_type; case TypeCode.Int32: return int_type; case TypeCode.Int64: return long_type; case TypeCode.SByte: return byte_type; case TypeCode.Single: return float_type; case TypeCode.String: return string_type; case TypeCode.UInt16: return ushort_type; case TypeCode.UInt32: return uint_type; case TypeCode.UInt64: return ulong_type; } } internal static string PredefinedTypeObjectToString(object obj) { Type type = obj.GetType(); switch (Type.GetTypeCode(type)) { default: if ((object)type == typeof(object)) { return string.Empty; } if ((object)type == typeof(Guid)) { return XmlConvert.ToString((Guid)obj); } if ((object)type == typeof(TimeSpan)) { return XmlConvert.ToString((TimeSpan)obj); } if ((object)type == typeof(byte[])) { return Convert.ToBase64String((byte[])obj); } if ((object)type == typeof(Uri)) { return ((Uri)obj).ToString(); } throw new Exception("Internal error: missing predefined type serialization for type " + type.FullName); case TypeCode.DBNull: return string.Empty; case TypeCode.Boolean: return XmlConvert.ToString((bool)obj); case TypeCode.Byte: return XmlConvert.ToString((int)(byte)obj); case TypeCode.Char: return XmlConvert.ToString((uint)(char)obj); case TypeCode.DateTime: return XmlConvert.ToString((DateTime)obj, XmlDateTimeSerializationMode.RoundtripKind); case TypeCode.Decimal: return XmlConvert.ToString((decimal)obj); case TypeCode.Double: return XmlConvert.ToString((double)obj); case TypeCode.Int16: return XmlConvert.ToString((short)obj); case TypeCode.Int32: return XmlConvert.ToString((int)obj); case TypeCode.Int64: return XmlConvert.ToString((long)obj); case TypeCode.SByte: return XmlConvert.ToString((sbyte)obj); case TypeCode.Single: return XmlConvert.ToString((float)obj); case TypeCode.String: return (string)obj; case TypeCode.UInt16: return XmlConvert.ToString((int)(ushort)obj); case TypeCode.UInt32: return XmlConvert.ToString((uint)obj); case TypeCode.UInt64: return XmlConvert.ToString((ulong)obj); } } internal static Type GetPrimitiveTypeFromName(string name) { return name switch { "anyURI" => typeof(Uri), "boolean" => typeof(bool), "base64Binary" => typeof(byte[]), "dateTime" => typeof(DateTime), "duration" => typeof(TimeSpan), "QName" => typeof(XmlQualifiedName), "decimal" => typeof(decimal), "double" => typeof(double), "float" => typeof(float), "byte" => typeof(sbyte), "short" => typeof(short), "int" => typeof(int), "long" => typeof(long), "unsignedByte" => typeof(byte), "unsignedShort" => typeof(ushort), "unsignedInt" => typeof(uint), "unsignedLong" => typeof(ulong), "string" => typeof(string), "anyType" => typeof(object), "guid" => typeof(Guid), "char" => typeof(char), _ => null, }; } internal static object PredefinedTypeStringToObject(string s, string name, XmlReader reader) { switch (name) { case "anyURI": return new Uri(s, UriKind.RelativeOrAbsolute); case "boolean": return XmlConvert.ToBoolean(s); case "base64Binary": return Convert.FromBase64String(s); case "dateTime": return XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.RoundtripKind); case "duration": return XmlConvert.ToTimeSpan(s); case "QName": { int num = s.IndexOf(':'); string name2 = ((num >= 0) ? s.Substring(num + 1) : s); return (num >= 0) ? new XmlQualifiedName(name2, reader.LookupNamespace(s.Substring(0, num))) : new XmlQualifiedName(name2); } case "decimal": return XmlConvert.ToDecimal(s); case "double": return XmlConvert.ToDouble(s); case "float": return XmlConvert.ToSingle(s); case "byte": return XmlConvert.ToSByte(s); case "short": return XmlConvert.ToInt16(s); case "int": return XmlConvert.ToInt32(s); case "long": return XmlConvert.ToInt64(s); case "unsignedByte": return XmlConvert.ToByte(s); case "unsignedShort": return XmlConvert.ToUInt16(s); case "unsignedInt": return XmlConvert.ToUInt32(s); case "unsignedLong": return XmlConvert.ToUInt64(s); case "string": return s; case "guid": return XmlConvert.ToGuid(s); case "anyType": return s; case "char": return (char)XmlConvert.ToUInt32(s); default: throw new Exception("Unanticipated primitive type: " + name); } } protected override void ClearItems() { Clear(); } protected override void InsertItem(int index, Type type) { if (TryRegister(type)) { base.InsertItem(index, type); } } protected override void RemoveItem(int index) { Type type = base[index]; List<SerializationMap> list = new List<SerializationMap>(); foreach (SerializationMap contract in contracts) { if ((object)contract.RuntimeType == type) { list.Add(contract); } } foreach (SerializationMap item in list) { contracts.Remove(item); base.RemoveItem(index); } } protected override void SetItem(int index, Type type) { if (index == Count) { InsertItem(index, type); return; } RemoveItem(index); if (TryRegister(type)) { base.InsertItem(index - 1, type); } } internal SerializationMap FindUserMap(XmlQualifiedName qname) { for (int i = 0; i < contracts.Count; i++) { if (qname == contracts[i].XmlName) { return contracts[i]; } } return null; } internal Type GetSerializedType(Type type) { Type collectionElementType = GetCollectionElementType(type); if ((object)collectionElementType == null) { return type; } XmlQualifiedName qName = GetQName(type); SerializationMap serializationMap = FindUserMap(qName); if (serializationMap != null) { return serializationMap.RuntimeType; } return type; } internal SerializationMap FindUserMap(Type type) { for (int i = 0; i < contracts.Count; i++) { if ((object)type == contracts[i].RuntimeType) { return contracts[i]; } } return null; } internal XmlQualifiedName GetQName(Type type) { if (IsPrimitiveNotEnum(type)) { return GetPrimitiveTypeName(type); } SerializationMap serializationMap = FindUserMap(type); if (serializationMap != null) { return serializationMap.XmlName; } if (type.IsEnum) { return GetEnumQName(type); } XmlQualifiedName contractQName = GetContractQName(type); if (contractQName != null) { return contractQName; } if ((object)type.GetInterface("System.Xml.Serialization.IXmlSerializable") != null) { return GetSerializableQName(type); } contractQName = GetCollectionContractQName(type); if (contractQName != null) { return contractQName; } Type collectionElementType = GetCollectionElementType(type); if ((object)collectionElementType != null) { return GetCollectionQName(collectionElementType); } if (GetAttribute<SerializableAttribute>(type) != null) { return GetSerializableQName(type); } return XmlQualifiedName.Empty; } private XmlQualifiedName GetContractQName(Type type) { DataContractAttribute attribute = GetAttribute<DataContractAttribute>(type); return (attribute != null) ? GetContractQName(type, attribute.Name, attribute.Namespace) : null; } private XmlQualifiedName GetCollectionContractQName(Type type) { CollectionDataContractAttribute attribute = GetAttribute<CollectionDataContractAttribute>(type); return (attribute != null) ? GetContractQName(type, attribute.Name, attribute.Namespace) : null; } internal static XmlQualifiedName GetContractQName(Type type, string name, string ns) { if (name == null) { name = ((type.Namespace != null && type.Namespace.Length != 0) ? type.FullName.Substring(type.Namespace.Length + 1).Replace('+', '.') : type.Name); if (type.IsGenericType) { name = name.Substring(0, name.IndexOf('`')) + "Of"; Type[] genericArguments = type.GetGenericArguments(); foreach (Type type2 in genericArguments) { name += type2.Name; } } } if (ns == null) { ns = "http://schemas.datacontract.org/2004/07/" + type.Namespace; } return new XmlQualifiedName(name, ns); } private XmlQualifiedName GetEnumQName(Type type) { string text = null; string text2 = null; if (!type.IsEnum) { return null; } DataContractAttribute attribute = GetAttribute<DataContractAttribute>(type); if (attribute != null) { text2 = attribute.Namespace; text = attribute.Name; } if (text2 == null) { text2 = "http://schemas.datacontract.org/2004/07/" + type.Namespace; } if (text == null) { text = ((type.Namespace != null) ? type.FullName.Substring(type.Namespace.Length + 1).Replace('+', '.') : type.Name); } return new XmlQualifiedName(text, text2); } private XmlQualifiedName GetCollectionQName(Type element) { XmlQualifiedName qName = GetQName(element); string ns = qName.Namespace; if (qName.Namespace == "http://schemas.microsoft.com/2003/10/Serialization/") { ns = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"; } return new XmlQualifiedName("ArrayOf" + XmlConvert.EncodeLocalName(qName.Name), ns); } private XmlQualifiedName GetSerializableQName(Type type) { string text = type.Name; if (type.IsGenericType) { text = text.Substring(0, text.IndexOf('`')) + "Of"; Type[] genericArguments = type.GetGenericArguments(); foreach (Type type2 in genericArguments) { text += GetQName(type2).Name; } } string ns = "http://schemas.datacontract.org/2004/07/" + type.Namespace; XmlRootAttribute attribute = GetAttribute<XmlRootAttribute>(type); if (attribute != null) { text = attribute.ElementName; ns = attribute.Namespace; } return new XmlQualifiedName(XmlConvert.EncodeLocalName(text), ns); } internal bool IsPrimitiveNotEnum(Type type) { if (type.IsEnum) { return false; } if (Type.GetTypeCode(type) != TypeCode.Object) { return true; } if ((object)type == typeof(Guid) || (object)type == typeof(object) || (object)type == typeof(TimeSpan) || (object)type == typeof(byte[]) || (object)type == typeof(Uri)) { return true; } if (type.IsGenericType && (object)type.GetGenericTypeDefinition() == typeof(Nullable<>)) { return IsPrimitiveNotEnum(type.GetGenericArguments()[0]); } return false; } internal bool TryRegister(Type type) { if (IsPrimitiveNotEnum(type)) { return false; } if (FindUserMap(type) != null) { return false; } if (RegisterEnum(type) != null) { return true; } if (RegisterContract(type) != null) { return true; } if (RegisterIXmlSerializable(type) != null) { return true; } if (RegisterDictionary(type) != null) { return true; } if (RegisterCollectionContract(type) != null) { return true; } if (RegisterCollection(type) != null) { return true; } if (GetAttribute<SerializableAttribute>(type) != null) { RegisterSerializable(type); return true; } RegisterDefaultTypeMap(type); return true; } internal static Type GetCollectionElementType(Type type) { if (type.IsArray) { return type.GetElementType(); } Type[] interfaces = type.GetInterfaces(); Type[] array = interfaces; foreach (Type type2 in array) { if (type2.IsGenericType && type2.GetGenericTypeDefinition().Equals(typeof(ICollection<>))) { return type2.GetGenericArguments()[0]; } } Type[] array2 = interfaces; foreach (Type type3 in array2) { if ((object)type3 == typeof(IList)) { return typeof(object); } } return null; } internal T GetAttribute<T>(MemberInfo mi) where T : Attribute { object[] customAttributes = mi.GetCustomAttributes(typeof(T), inherit: false); return (customAttributes.Length != 0) ? ((T)customAttributes[0]) : ((T)null); } private CollectionContractTypeMap RegisterCollectionContract(Type type) { CollectionDataContractAttribute attribute = GetAttribute<CollectionDataContractAttribute>(type); if (attribute == null) { return null; } Type collectionElementType = GetCollectionElementType(type); if ((object)collectionElementType == null) { throw new InvalidOperationException($"Type '{type}' is marked as collection contract, but it is not a collection"); } TryRegister(collectionElementType); XmlQualifiedName collectionContractQName = GetCollectionContractQName(type); CheckStandardQName(collectionContractQName); if (FindUserMap(collectionContractQName) != null) { throw new InvalidOperationException($"Failed to add type {type} to known type collection. There already is a registered type for XML name {collectionContractQName}"); } CollectionContractTypeMap collectionContractTypeMap = new CollectionContractTypeMap(type, attribute, collectionElementType, collectionContractQName, this); contracts.Add(collectionContractTypeMap); return collectionContractTypeMap; } private CollectionTypeMap RegisterCollection(Type type) { Type collectionElementType = GetCollectionElementType(type); if ((object)collectionElementType == null) { return null; } TryRegister(collectionElementType); XmlQualifiedName collectionQName = GetCollectionQName(collectionElementType); SerializationMap serializationMap = FindUserMap(collectionQName); if (serializationMap != null) { if (!(serializationMap is CollectionTypeMap collectionTypeMap) || (object)collectionTypeMap.RuntimeType != type) { throw new InvalidOperationException($"Failed to add type {type} to known type collection. There already is a registered type for XML name {collectionQName}"); } return collectionTypeMap; } CollectionTypeMap collectionTypeMap2 = new CollectionTypeMap(type, collectionElementType, collectionQName, this); contracts.Add(collectionTypeMap2); return collectionTypeMap2; } private static bool TypeImplementsIDictionary(Type type) { Type[] interfaces = type.GetInterfaces(); foreach (Type type2 in interfaces) { if ((object)type2 == typeof(IDictionary) || (type2.IsGenericType && (object)type2.GetGenericTypeDefinition() == typeof(IDictionary<, >))) { return true; } } return false; } private DictionaryTypeMap RegisterDictionary(Type type) { if (!TypeImplementsIDictionary(type)) { return null; } CollectionDataContractAttribute attribute = GetAttribute<CollectionDataContractAttribute>(type); DictionaryTypeMap dictionaryTypeMap = new DictionaryTypeMap(type, attribute, this); if (FindUserMap(dictionaryTypeMap.XmlName) != null) { throw new InvalidOperationException($"Failed to add type {type} to known type collection. There already is a registered type for XML name {dictionaryTypeMap.XmlName}"); } contracts.Add(dictionaryTypeMap); TryRegister(dictionaryTypeMap.KeyType); TryRegister(dictionaryTypeMap.ValueType); return dictionaryTypeMap; } private SerializationMap RegisterSerializable(Type type) { XmlQualifiedName serializableQName = GetSerializableQName(type); if (FindUserMap(serializableQName) != null) { throw new InvalidOperationException($"There is already a registered type for XML name {serializableQName}"); } SharedTypeMap sharedTypeMap = new SharedTypeMap(type, serializableQName, this); contracts.Add(sharedTypeMap); return sharedTypeMap; } private SerializationMap RegisterIXmlSerializable(Type type) { if ((object)type.GetInterface("System.Xml.Serialization.IXmlSerializable") == null) { return null; } XmlQualifiedName serializableQName = GetSerializableQName(type); if (FindUserMap(serializableQName) != null) { throw new InvalidOperationException($"There is already a registered type for XML name {serializableQName}"); } XmlSerializableMap xmlSerializableMap = new XmlSerializableMap(type, serializableQName, this); contracts.Add(xmlSerializableMap); return xmlSerializableMap; } private void CheckStandardQName(XmlQualifiedName qname) { switch (qname.Namespace) { case "http://www.w3.org/2001/XMLSchema": case "http://www.w3.org/2001/XMLSchema-instance": case "http://schemas.microsoft.com/2003/10/Serialization/": case "http://schemas.microsoft.com/2003/10/Serialization/Arrays": throw new InvalidOperationException($"Namespace {qname.Namespace} is reserved and cannot be used for user serialization"); } } private SharedContractMap RegisterContract(Type type) { XmlQualifiedName contractQName = GetContractQName(type); if (contractQName == null) { return null; } CheckStandardQName(contractQName); if (FindUserMap(contractQName) != null) { throw new InvalidOperationException($"There is already a registered type for XML name {contractQName}"); } SharedContractMap sharedContractMap = new SharedContractMap(type, contractQName, this); contracts.Add(sharedContractMap); sharedContractMap.Initialize(); object[] customAttributes = type.GetCustomAttributes(typeof(KnownTypeAttribute), inherit: true); for (int i = 0; i < customAttributes.Length; i++) { KnownTypeAttribute knownTypeAttribute = (KnownTypeAttribute)customAttributes[i]; TryRegister(knownTypeAttribute.Type); } return sharedContractMap; } private DefaultTypeMap RegisterDefaultTypeMap(Type type) { DefaultTypeMap defaultTypeMap = new DefaultTypeMap(type, this); contracts.Add(defaultTypeMap); return defaultTypeMap; } private EnumMap RegisterEnum(Type type) { XmlQualifiedName enumQName = GetEnumQName(type); if (enumQName == null) { return null; } if (FindUserMap(enumQName) != null) { throw new InvalidOperationException($"There is already a registered type for XML name {enumQName}"); } EnumMap enumMap = new EnumMap(type, enumQName, this); contracts.Add(enumMap); return enumMap; } } public sealed class NetDataContractSerializer : XmlObjectSerializer, IFormatter { private const string xmlns = "http://www.w3.org/2000/xmlns/"; private const string default_ns = "http://schemas.datacontract.org/2004/07/"; private StreamingContext context; private SerializationBinder binder; private ISurrogateSelector selector; private int max_items = 65536; private bool ignore_extensions; private FormatterAssemblyStyle ass_style; private XmlDictionaryString root_name; private XmlDictionaryString root_ns; public FormatterAssemblyStyle AssemblyFormat { get { return ass_style; } set { ass_style = value; } } public SerializationBinder Binder { get { return binder; } set { binder = value; } } public bool IgnoreExtensionDataObject => ignore_extensions; public ISurrogateSelector SurrogateSelector { get { return selector; } set { selector = value; } } public StreamingContext Context { get { return context; } set { context = value; } } public int MaxItemsInObjectGraph => max_items; public NetDataContractSerializer() { } public NetDataContractSerializer(StreamingContext context) { this.context = context; } public NetDataContractSerializer(string rootName, string rootNamespace) { FillDictionaryString(rootName, rootNamespace); } public NetDataContractSerializer(XmlDictionaryString rootName, XmlDictionaryString rootNamespace) { if (rootName == null) { throw new ArgumentNullException("rootName"); } if (rootNamespace == null) { throw new ArgumentNullException("rootNamespace"); } root_name = rootName; root_ns = rootNamespace; } public NetDataContractSerializer(StreamingContext context, int maxItemsInObjectGraph, bool ignoreExtensibleDataObject, FormatterAssemblyStyle assemblyFormat, ISurrogateSelector surrogateSelector) { this.context = context; max_items = maxItemsInObjectGraph; ignore_extensions = ignoreExtensibleDataObject; ass_style = assemblyFormat; selector = surrogateSelector; } public NetDataContractSerializer(string rootName, string rootNamespace, StreamingContext context, int maxItemsInObjectGraph, bool ignoreExtensibleDataObject, FormatterAssemblyStyle assemblyFormat, ISurrogateSelector surrogateSelector) : this(context, maxItemsInObjectGraph, ignoreExtensibleDataObject, assemblyFormat, surrogateSelector) { FillDictionaryString(rootName, rootNamespace); } public NetDataContractSerializer(XmlDictionaryString rootName, XmlDictionaryString rootNamespace, StreamingContext context, int maxItemsInObjectGraph, bool ignoreExtensibleDataObject, FormatterAssemblyStyle assemblyFormat, ISurrogateSelector surrogateSelector) : this(context, maxItemsInObjectGraph, ignoreExtensibleDataObject, assemblyFormat, surrogateSelector) { if (rootName == null) { throw new ArgumentNullException("rootName"); } if (rootNamespace == null) { throw new ArgumentNullException("rootNamespace"); } root_name = rootName; root_ns = rootNamespace; } private void FillDictionaryString(string rootName, string rootNamespace) { if (rootName == null) { throw new ArgumentNullException("rootName"); } if (rootNamespace == null) { throw new ArgumentNullException("rootNamespace"); } XmlDictionary xmlDictionary = new XmlDictionary(); root_name = xmlDictionary.Add(rootName); root_ns = xmlDictionary.Add(rootNamespace); } public object Deserialize(Stream stream) { return ReadObject(stream); } [MonoTODO] public override bool IsStartObject(XmlDictionaryReader reader) { throw new NotImplementedException(); } public override object ReadObject(XmlDictionaryReader reader, bool readContentOnly) { throw new NotImplementedException(); } public void Serialize(Stream stream, object graph) { using XmlWriter writer = XmlWriter.Create(stream); WriteObject(writer, graph); } [MonoTODO("support arrays; support Serializable; support SharedType; use DataContractSurrogate")] public override void WriteObjectContent(XmlDictionaryWriter writer, object graph) { throw new NotImplementedException(); } public override void WriteStartObject(XmlDictionaryWriter writer, object graph) { throw new NotImplementedException(); } public override void WriteEndObject(XmlDictionaryWriter writer) { writer.WriteEndElement(); } } internal abstract class SerializationMap { public const BindingFlags AllInstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; public readonly KnownTypeCollection KnownTypes; public readonly Type RuntimeType; public bool IsReference; public List<DataMemberInfo> Members; private Dictionary<Type, XmlQualifiedName> qname_table = new Dictionary<Type, XmlQualifiedName>(); public virtual bool OutputXsiType => true; public XmlQualifiedName XmlName { get; set; } protected SerializationMap(Type type, XmlQualifiedName qname, KnownTypeCollection knownTypes) { KnownTypes = knownTypes; RuntimeType = type; if (qname.Namespace == null) { qname = new XmlQualifiedName(qname.Name, "http://schemas.datacontract.org/2004/07/" + type.Namespace); } XmlName = qname; Members = new List<DataMemberInfo>(); } public CollectionDataContractAttribute GetCollectionDataContractAttribute(Type type) { object[] customAttributes = type.GetCustomAttributes(typeof(CollectionDataContractAttribute), inherit: false); return (customAttributes.Length != 0) ? ((CollectionDataContractAttribute)customAttributes[0]) : null; } public DataMemberAttribute GetDataMemberAttribute(MemberInfo mi) { object[] customAttributes = mi.GetCustomAttributes(typeof(DataMemberAttribute), inherit: false); if (customAttributes.Length == 0) { return null; } return (DataMemberAttribute)customAttributes[0]; } private bool IsPrimitive(Type type) { return Type.GetTypeCode(type) != TypeCode.Object || (object)type == typeof(object); } public virtual List<DataMemberInfo> GetMembers() { throw new NotImplementedException($"Implement me for {this}"); } public virtual void Serialize(object graph, XmlFormatterSerializer serializer) { string text = null; if (IsReference) { text = (string)serializer.References[graph]; if (text != null) { serializer.Writer.WriteAttributeString("z", "Ref", "http://schemas.microsoft.com/2003/10/Serialization/", text); return; } text = "i" + (serializer.References.Count + 1); serializer.References.Add(graph, text); } else if (serializer.SerializingObjects.Contains(graph)) { throw new SerializationException($"Circular reference of an object in the object graph was found: '{graph}' of type {graph.GetType()}"); } serializer.SerializingObjects.Add(graph); if (text != null) { serializer.Writer.WriteAttributeString("z", "Id", "http://schemas.microsoft.com/2003/10/Serialization/", text); } SerializeNonReference(graph, serializer); serializer.SerializingObjects.Remove(graph); } public virtual void SerializeNonReference(object graph, XmlFormatterSerializer serializer) { foreach (DataMemberInfo member in Members) { FieldInfo fieldInfo = member.Member as FieldInfo; PropertyInfo propertyInfo = (((object)fieldInfo != null) ? null : ((PropertyInfo)member.Member)); Type type = (((object)fieldInfo == null) ? propertyInfo.PropertyType : fieldInfo.FieldType); object graph2 = (((object)fieldInfo == null) ? propertyInfo.GetValue(graph, null) : fieldInfo.GetValue(graph)); serializer.WriteStartElement(member.XmlName, member.XmlRootNamespace, member.XmlNamespace); serializer.Serialize(type, graph2); serializer.WriteEndElement(); } } public virtual object DeserializeObject(XmlReader reader, XmlFormatterDeserializer deserializer) { bool isEmptyElement = reader.IsEmptyElement; reader.ReadStartElement(); reader.MoveToContent(); object result = ((!isEmptyElement) ? DeserializeContent(reader, deserializer) : DeserializeEmptyContent(reader, deserializer)); reader.MoveToContent(); if (!isEmptyElement && reader.NodeType == XmlNodeType.EndElement) { reader.ReadEndElement(); } else if (!isEmptyElement && reader.NodeType != 0) { IXmlLineInfo xmlLineInfo = reader as IXmlLineInfo; throw new SerializationException(string.Format("Deserializing type '{3}'. Expecting state 'EndElement'. Encountered state '{0}' with name '{1}' with namespace '{2}'.{4}", reader.NodeType, reader.Name, reader.NamespaceURI, RuntimeType.FullName, (xmlLineInfo == null || !xmlLineInfo.HasLineInfo()) ? string.Empty : $" {reader.BaseURI}({xmlLineInfo.LineNumber},{xmlLineInfo.LinePosition})")); } return result; } public virtual object DeserializeEmptyContent(XmlReader reader, XmlFormatterDeserializer deserializer) { return DeserializeContent(reader, deserializer, empty: true); } public virtual object DeserializeContent(XmlReader reader, XmlFormatterDeserializer deserializer) { return DeserializeContent(reader, deserializer, empty: false); } private object DeserializeContent(XmlReader reader, XmlFormatterDeserializer deserializer, bool empty) { object uninitializedObject = FormatterServices.GetUninitializedObject(RuntimeType); int num = ((reader.NodeType != 0) ? (reader.Depth - 1) : reader.Depth); bool[] array = new bool[Members.Count]; int num2 = -1; int val = -1; while (!empty && reader.NodeType == XmlNodeType.Element && reader.Depth > num) { DataMemberInfo dataMemberInfo = null; int i; for (i = 0; i < Members.Count && Members[i].Order < 0; i++) { if (reader.LocalName == Members[i].XmlName && reader.NamespaceURI == Members[i].XmlRootNamespace) { num2 = i; dataMemberInfo = Members[i]; break; } } for (i = Math.Max(i, val); i < Members.Count; i++) { if (dataMemberInfo != null) { break; } if (reader.LocalName == Members[i].XmlName && reader.NamespaceURI == Members[i].XmlRootNamespace) { num2 = i; val = i; dataMemberInfo = Members[i]; break; } } if (dataMemberInfo == null) { reader.Skip(); continue; } SetValue(dataMemberInfo, uninitializedObject, deserializer.Deserialize(dataMemberInfo.MemberType, reader)); array[num2] = true; reader.MoveToContent(); } for (int j = 0; j < Members.Count; j++) { if (!array[j] && Members[j].IsRequired) { throw MissingRequiredMember(Members[j], reader); } } return uninitializedObject; } protected Exception MissingRequiredMember(DataMemberInfo dmi, XmlReader reader) { IXmlLineInfo xmlLineInfo = reader as IXmlLineInfo; return new ArgumentException($"Data contract member {new XmlQualifiedName(dmi.XmlName, dmi.XmlNamespace)} for the type {RuntimeType} is required, but missing in the input XML.{((xmlLineInfo == null || !xmlLineInfo.HasLineInfo()) ? null : $" {reader.BaseURI}({xmlLineInfo.LineNumber},{xmlLineInfo.LinePosition})")}"); } protected void SetValue(DataMemberInfo dmi, object obj, object value) { try { if (dmi.Member is PropertyInfo) { ((PropertyInfo)dmi.Member).SetValue(obj, value, null); } else { ((FieldInfo)dmi.Member).SetValue(obj, value); } } catch (Exception innerException) { throw new InvalidOperationException($"Failed to set value of type {value?.GetType()} for property {dmi.Member}", innerException); } } protected DataMemberInfo CreateDataMemberInfo(DataMemberAttribute dma, MemberInfo mi, Type type) { KnownTypes.Add(type); XmlQualifiedName qName = KnownTypes.GetQName(type); string @namespace = KnownTypes.GetQName(mi.DeclaringType).Namespace; if ((object)KnownTypeCollection.GetPrimitiveTypeFromName(qName.Name) != null) { return new DataMemberInfo(mi, dma, @namespace, null); } return new DataMemberInfo(mi, dma, @namespace, qName.Namespace); } } internal class XmlSerializableMap : SerializationMap { public XmlSerializableMap(Type type, XmlQualifiedName qname, KnownTypeCollection knownTypes) : base(type, qname, knownTypes) { } public override void Serialize(object graph, XmlFormatterSerializer serializer) { if (!(graph is IXmlSerializable xmlSerializable)) { throw new SerializationException(); } xmlSerializable.WriteXml(serializer.Writer); } public override object DeserializeObject(XmlReader reader, XmlFormatterDeserializer deserializer) { IXmlSerializable xmlSerializable = (IXmlSerializable)FormatterServices.GetUninitializedObject(RuntimeType); xmlSerializable.ReadXml(reader); return xmlSerializable; } } internal class SharedContractMap : SerializationMap { public SharedContractMap(Type type, XmlQualifiedName qname, KnownTypeCollection knownTypes) : base(type, qname, knownTypes) { } internal void Initialize() { Type type = RuntimeType; List<DataMemberInfo> list = new List<DataMemberInfo>(); object[] customAttributes = type.GetCustomAttributes(typeof(DataContractAttribute), inherit: false); IsReference = customAttributes.Length > 0 && ((DataContractAttribute)customAttributes[0]).IsReference; while ((object)type != null) { XmlQualifiedName qName = KnownTypes.GetQName(type); list = GetMembers(type, qName, declared_only: true); list.Sort(DataMemberInfo.DataMemberInfoComparer.Instance); Members.InsertRange(0, list); list.Clear(); type = type.BaseType; } } private List<DataMemberInfo> GetMembers(Type type, XmlQualifiedName qname, bool declared_only) { List<DataMemberInfo> list = new List<DataMemberInfo>(); BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; if (declared_only) { bindingFlags |= BindingFlags.DeclaredOnly; } PropertyInfo[] properties = type.GetProperties(bindingFlags); foreach (PropertyInfo propertyInfo in properties) { DataMemberAttribute dataMemberAttribute = GetDataMemberAttribute(propertyInfo); if (dataMemberAttribute != null) { KnownTypes.TryRegister(propertyInfo.PropertyType); SerializationMap serializationMap = KnownTypes.FindUserMap(propertyInfo.PropertyType); if (!propertyInfo.CanRead || (!propertyInfo.CanWrite && !(serializationMap is ICollectionTypeMap))) { throw new InvalidDataContractException($"DataMember property '{propertyInfo}' on type '{propertyInfo.DeclaringType}' must have both getter and setter."); } list.Add(CreateDataMemberInfo(dataMemberAttribute, propertyInfo, propertyInfo.PropertyType)); } } FieldInfo[] fields = type.GetFields(bindingFlags); foreach (FieldInfo fieldInfo in fields) { DataMemberAttribute dataMemberAttribute2 = GetDataMemberAttribute(fieldInfo); if (dataMemberAttribute2 != null) { list.Add(CreateDataMemberInfo(dataMemberAttribute2, fieldInfo, fieldInfo.FieldType)); } } return list; } public override List<DataMemberInfo> GetMembers() { return Members; } } internal class DefaultTypeMap : SerializationMap { public DefaultTypeMap(Type type, KnownTypeCollection knownTypes) : base(type, KnownTypeCollection.GetContractQName(type, null, null), knownTypes) { Members.AddRange(GetDefaultMembers()); } private List<DataMemberInfo> GetDefaultMembers() { List<DataMemberInfo> list = new List<DataMemberInfo>(); MemberInfo[] members = RuntimeType.GetMembers(); foreach (MemberInfo memberInfo in members) { Type type = null; type = ((memberInfo is FieldInfo fieldInfo) ? fieldInfo.FieldType : null); if (memberInfo is PropertyInfo propertyInfo && propertyInfo.CanRead && propertyInfo.CanWrite && propertyInfo.GetIndexParameters().Length == 0) { type = propertyInfo.PropertyType; } if ((object)type != null && memberInfo.GetCustomAttributes(typeof(IgnoreDataMemberAttribute), inherit: false).Length == 0) { list.Add(new DataMemberInfo(memberInfo, new DataMemberAttribute(), null, null)); } } list.Sort(DataMemberInfo.DataMemberInfoComparer.Instance); return list; } } internal class CollectionContractTypeMap : CollectionTypeMap { internal override string CurrentNamespace => base.XmlName.Namespace; public CollectionContractTypeMap(Type type, CollectionDataContractAttribute a, Type elementType, XmlQualifiedName qname, KnownTypeCollection knownTypes) : base(type, elementType, qname, knownTypes) { IsReference = a.IsReference; } } internal interface ICollectionTypeMap { } internal class CollectionTypeMap : SerializationMap, ICollectionTypeMap { private Type element_type; internal XmlQualifiedName element_qname; private MethodInfo add_method; public override bool OutputXsiType => false; internal virtual string CurrentNamespace { get { string text = element_qname.Namespace; if (text == "http://schemas.microsoft.com/2003/10/Serialization/") { text = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"; } return text; } } public CollectionTypeMap(Type type, Type elementType, XmlQualifiedName qname, KnownTypeCollection knownTypes) : base(type, qname, knownTypes) { element_type = elementType; element_qname = KnownTypes.GetQName(element_type); Type genericCollectionInterface = GetGenericCollectionInterface(RuntimeType); if ((object)genericCollectionInterface == null) { return; } if (RuntimeType.IsInterface) { add_method = RuntimeType.GetMethod("Add", genericCollectionInterface.GetGenericArguments()); return; } InterfaceMapping interfaceMap = RuntimeType.GetInterfaceMap(genericCollectionInterface); for (int i = 0; i < interfaceMap.InterfaceMethods.Length; i++) { if (interfaceMap.InterfaceMethods[i].Name == "Add") { add_method = interfaceMap.TargetMethods[i]; break; } } if ((object)add_method == null) { add_method = type.GetMethod("Add", genericCollectionInterface.GetGenericArguments()); } } private static Type GetGenericCollectionInterface(Type type) { Type[] interfaces = type.GetInterfaces(); foreach (Type type2 in interfaces) { if (type2.IsGenericType && (object)type2.GetGenericTypeDefinition() == typeof(ICollection<>)) { return type2; } } return null; } public override void SerializeNonReference(object graph, XmlFormatterSerializer serializer) { foreach (object item in (IEnumerable)graph) { serializer.WriteStartElement(element_qname.Name, base.XmlName.Namespace, CurrentNamespace); serializer.Serialize(element_type, item); serializer.WriteEndElement(); } } private object CreateInstance() { if (RuntimeType.IsArray) { return new ArrayList(); } if (RuntimeType.IsInterface) { Type genericCollectionInterface = GetGenericCollectionInterface(RuntimeType); if ((object)genericCollectionInterface != null) { return Activator.CreateInstance(typeof(List<>).MakeGenericType(RuntimeType.GetGenericArguments()[0])); } return new ArrayList(); } return Activator.CreateInstance(RuntimeType); } public override object DeserializeEmptyContent(XmlReader reader, XmlFormatterDeserializer deserializer) { return CreateInstance(); } public override object DeserializeContent(XmlReader reader, XmlFormatterDeserializer deserializer) { object obj = CreateInstance(); int num = ((reader.NodeType != 0) ? (reader.Depth - 1) : reader.Depth); while (reader.NodeType == XmlNodeType.Element && reader.Depth > num) { object obj2 = deserializer.Deserialize(element_type, reader); if (obj is IList) { ((IList)obj).Add(obj2); } else { if ((object)add_method == null) { throw new NotImplementedException($"Type {RuntimeType} is not supported"); } add_method.Invoke(obj, new object[1] { obj2 }); } reader.MoveToContent(); } if (RuntimeType.IsArray) { return ((ArrayList)obj).ToArray(element_type); } return obj; } public override List<DataMemberInfo> GetMembers() { throw new NotImplementedException(); } } internal class DictionaryTypeMap : SerializationMap, ICollectionTypeMap { private Type key_type; private Type value_type; private XmlQualifiedName dict_qname; private XmlQualifiedName item_qname; private XmlQualifiedName key_qname; private XmlQualifiedName value_qname; private MethodInfo add_method; private CollectionDataContractAttribute a; private static readonly XmlQualifiedName kvpair_key_qname = new XmlQualifiedName("Key", "http://schemas.microsoft.com/2003/10/Serialization/Arrays"); private static readonly XmlQualifiedName kvpair_value_qname = new XmlQualifiedName("Value", "http://schemas.microsoft.com/2003/10/Serialization/Arrays"); private Type pair_type; private PropertyInfo pair_key_property; private PropertyInfo pair_value_property; private string ContractNamespace => (a == null || string.IsNullOrEmpty(a.Namespace)) ? "http://schemas.microsoft.com/2003/10/Serialization/Arrays" : a.Namespace; public Type KeyType => key_type; public Type ValueType => value_type; internal virtual string CurrentNamespace { get { string text = item_qname.Namespace; if (text == "http://schemas.microsoft.com/2003/10/Serialization/") { text = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"; } return text; } } public DictionaryTypeMap(Type type, CollectionDataContractAttribute a, KnownTypeCollection knownTypes) : base(type, XmlQualifiedName.Empty, knownTypes) { this.a = a; key_type = typeof(object); value_type = typeof(object); Type genericDictionaryInterface = GetGenericDictionaryInterface(RuntimeType); if ((object)genericDictionaryInterface != null) { InterfaceMapping interfaceMap = RuntimeType.GetInterfaceMap(genericDictionaryInterface); for (int i = 0; i < interfaceMap.InterfaceMethods.Length; i++) { if (interfaceMap.InterfaceMethods[i].Name == "Add") { add_method = interfaceMap.TargetMethods[i]; break; } } Type[] genericArguments = genericDictionaryInterface.GetGenericArguments(); key_type = genericArguments[0]; value_type = genericArguments[1]; if ((object)add_method == null) { add_method = type.GetMethod("Add", genericArguments); } } base.XmlName = GetDictionaryQName(); item_qname = GetItemQName(); key_qname = GetKeyQName(); value_qname = GetValueQName(); } private static Type GetGenericDictionaryInterface(Type type) { Type[] interfaces = type.GetInterfaces(); foreach (Type type2 in interfaces) { if (type2.IsGenericType && (object)type2.GetGenericTypeDefinition() == typeof(IDictionary<, >)) { return type2; } } return null; } internal virtual XmlQualifiedName GetDictionaryQName() { if (a != null && !string.IsNullOrEmpty(a.Name)) { return new XmlQualifiedName(a.Name, ContractNamespace); } return new XmlQualifiedName("ArrayOf" + GetItemQName().Name, "http://schemas.microsoft.com/2003/10/Serialization/Arrays"); } internal virtual XmlQualifiedName GetItemQName() { if (a != null && !string.IsNullOrEmpty(a.ItemName)) { return new XmlQualifiedName(a.ItemName, ContractNamespace); } return new XmlQualifiedName("KeyValueOf" + KnownTypes.GetQName(key_type).Name + KnownTypes.GetQName(value_type).Name, "http://schemas.microsoft.com/2003/10/Serialization/Arrays"); } internal virtual XmlQualifiedName GetKeyQName() { if (a != null && !string.IsNullOrEmpty(a.KeyName)) { return new XmlQualifiedName(a.KeyName, ContractNamespace); } return kvpair_key_qname; } internal virtual XmlQualifiedName GetValueQName() { if (a != null && !string.IsNullOrEmpty(a.ValueName)) { return new XmlQualifiedName(a.ValueName, ContractNamespace); } return kvpair_value_qname; } public override void SerializeNonReference(object graph, XmlFormatterSerializer serializer) { if ((object)add_method != null) { if ((object)pair_type == null) { pair_type = typeof(KeyValuePair<, >).MakeGenericType(add_method.DeclaringType.GetGenericArguments()); pair_key_property = pair_type.GetProperty("Key"); pair_value_property = pair_type.GetProperty("Value"); } { foreach (object item in (IEnumerable)graph) { serializer.WriteStartElement(item_qname.Name, item_qname.Namespace, CurrentNamespace); serializer.WriteStartElement(key_qname.Name, key_qname.Namespace, CurrentNamespace); serializer.Serialize(pair_key_property.PropertyType, pair_key_property.GetValue(item, null)); serializer.WriteEndElement(); serializer.WriteStartElement(value_qname.Name, value_qname.Namespace, CurrentNamespace); serializer.Serialize(pair_value_property.PropertyType, pair_value_property.GetValue(item, null)); serializer.WriteEndElement(); serializer.WriteEndElement(); } return; } } foreach (DictionaryEntry item2 in (IEnumerable)graph) { serializer.WriteStartElement(item_qname.Name, item_qname.Namespace, CurrentNamespace); serializer.WriteStartElement(key_qname.Name, key_qname.Namespace, CurrentNamespace); serializer.Serialize(key_type, item2.Key); serializer.WriteEndElement(); serializer.WriteStartElement(value_qname.Name, value_qname.Namespace, CurrentNamespace); serializer.Serialize(value_type, item2.Value); serializer.WriteEndElement(); serializer.WriteEndElement(); } } private object CreateInstance() { if (RuntimeType.IsInterface) { if (RuntimeType.IsGenericType && Array.IndexOf(RuntimeType.GetGenericTypeDefinition().GetInterfaces(), typeof(IDictionary<, >)) >= 0) { Type[] genericArguments = RuntimeType.GetGenericArguments(); return Activator.CreateInstance(typeof(Dictionary<, >).MakeGenericType(genericArguments[0], genericArguments[1])); } return new Hashtable(); } return Activator.CreateInstance(RuntimeType); } public override object DeserializeEmptyContent(XmlReader reader, XmlFormatterDeserializer deserializer) { return DeserializeContent(reader, deserializer); } public override object DeserializeContent(XmlReader reader, XmlFormatterDeserializer deserializer) { object obj = CreateInstance(); int num = ((reader.NodeType != 0) ? (reader.Depth - 1) : reader.Depth); while (reader.NodeType == XmlNodeType.Element && reader.Depth > num) { if (reader.IsEmptyElement) { throw new XmlException($"Unexpected empty element for dictionary entry: name {reader.Name}"); } reader.ReadStartElement(); reader.MoveToContent(); object obj2 = deserializer.Deserialize(key_type, reader); reader.MoveToContent(); object obj3 = deserializer.Deserialize(value_type, reader); reader.ReadEndElement(); if (obj is IDictionary) { ((IDictionary)obj).Add(obj2, obj3); continue; } if ((object)add_method != null) { add_method.Invoke(obj, new object[2] { obj2, obj3 }); continue; } throw new NotImplementedException($"Type {RuntimeType} is not supported"); } return obj; } public override List<DataMemberInfo> GetMembers() { throw new NotImplementedException(); } } internal class SharedTypeMap : SerializationMap { public SharedTypeMap(Type type, XmlQualifiedName qname, KnownTypeCollection knownTypes) : base(type, qname, knownTypes) { Members = GetMembers(type, base.XmlName, declared_only: false); } private List<DataMemberInfo> GetMembers(Type type, XmlQualifiedName qname, bool declared_only) { List<DataMemberInfo> list = new List<DataMemberInfo>(); BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; if (declared_only) { bindingFlags |= BindingFlags.DeclaredOnly; } FieldInfo[] fields = type.GetFields(bindingFlags); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.GetCustomAttributes(typeof(NonSerializedAttribute), inherit: false).Length <= 0) { if (fieldInfo.IsInitOnly) { throw new InvalidDataContractException($"DataMember field {fieldInfo} must not be read-only."); } DataMemberAttribute dma = new DataMemberAttribute(); list.Add(CreateDataMemberInfo(dma, fieldInfo, fieldInfo.FieldType)); } } list.Sort(DataMemberInfo.DataMemberInfoComparer.Instance); return list; } public override List<DataMemberInfo> GetMembers() { return Members; } } internal class EnumMap : SerializationMap { private List<EnumMemberInfo> enum_members; private bool flag_attr; public EnumMap(Type type, XmlQualifiedName qname, KnownTypeCollection knownTypes) : base(type, qname, knownTypes) { bool flag = false; object[] customAttributes = RuntimeType.GetCustomAttributes(typeof(DataContractAttribute), inherit: false); if (customAttributes.Length != 0) { flag = true; } flag_attr = type.GetCustomAttributes(typeof(FlagsAttribute), inherit: false).Length > 0; enum_members = new List<EnumMemberInfo>(); BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public; FieldInfo[] fields = RuntimeType.GetFields(bindingAttr); foreach (FieldInfo fieldInfo in fields) { string name = fieldInfo.Name; if (flag) { EnumMemberAttribute enumMemberAttribute = GetEnumMemberAttribute(fieldInfo); if (enumMemberAttribute == null) { continue; } if (enumMemberAttribute.Value != null) { name = enumMemberAttribute.Value; } } enum_members.Add(new EnumMemberInfo(name, fieldInfo.GetValue(null))); } } private EnumMemberAttribute GetEnumMemberAttribute(MemberInfo mi) { object[] customAttributes = mi.GetCustomAttributes(typeof(EnumMemberAttribute), inherit: false); if (customAttributes.Length == 0) { return null; } return (EnumMemberAttribute)customAttributes[0]; } public override void Serialize(object graph, XmlFormatterSerializer serializer) { foreach (EnumMemberInfo enum_member in enum_members) { if (object.Equals(enum_member.Value, graph)) { serializer.Writer.WriteString(enum_member.XmlName); return; } } throw new SerializationException($"Enum value '{graph}' is invalid for type '{RuntimeType}' and cannot be serialized."); } public override object DeserializeEmptyContent(XmlReader reader, XmlFormatterDeserializer deserializer) { if (!flag_attr) { throw new SerializationException($"Enum value '' is invalid for type '{RuntimeType}' and cannot be deserialized."); } return Enum.ToObject(RuntimeType, 0); } public override object DeserializeContent(XmlReader reader, XmlFormatterDeserializer deserializer) { string text = ((reader.NodeType == XmlNodeType.Text) ? reader.ReadContentAsString() : string.Empty); if (text != string.Empty) { foreach (EnumMemberInfo enum_member in enum_members) { if (enum_member.XmlName == text) { return enum_member.Value; } } } if (!flag_attr) { throw new SerializationException($"Enum value '{text}' is invalid for type '{RuntimeType}' and cannot be deserialized."); } return Enum.ToObject(RuntimeType, 0); } } internal struct EnumMemberInfo { public readonly string XmlName; public readonly object Value; public EnumMemberInfo(string name, object value) { XmlName = name; Value = value; } } internal class DataMemberInfo { public class DataMemberInfoComparer : IComparer<DataMemberInfo>, IComparer { public static readonly DataMemberInfoComparer Instance = new DataMemberInfoComparer(); private DataMemberInfoComparer() { } public int Compare(object o1, object o2) { return Compare((DataMemberInfo)o1, (DataMemberInfo)o2); } public int Compare(DataMemberInfo d1, DataMemberInfo d2) { if (d1.Order == d2.Order) { return string.CompareOrdinal(d1.XmlName, d2.XmlName); } return d1.Order - d2.Order; } } public readonly int Order; public readonly bool IsRequired; public readonly string XmlName; public readonly MemberInfo Member; public readonly string XmlNamespace; public readonly string XmlRootNamespace; public readonly Type MemberType; public DataMemberInfo(MemberInfo member, DataMemberAttribute dma, string rootNamespce, string ns) { if (dma == null) { throw new ArgumentNullException("dma"); } Order = dma.Order; Member = member; IsRequired = dma.IsRequired; XmlName = ((dma.Name == null) ? member.Name : dma.Name); XmlNamespace = ns; XmlRootNamespace = rootNamespce; if (Member is FieldInfo) { MemberType = ((FieldInfo)Member).FieldType; } else { MemberType = ((PropertyInfo)Member).PropertyType; } } } internal class XmlFormatterDeserializer { private KnownTypeCollection types; private IDataContractSurrogate surrogate; private Hashtable references = new Hashtable(); public Hashtable References => references; private XmlFormatterDeserializer(KnownTypeCollection knownTypes, IDataContractSurrogate surrogate) { types = knownTypes; this.surrogate = surrogate; } public static object Deserialize(XmlReader reader, Type type, KnownTypeCollection knownTypes, IDataContractSurrogate surrogate, string name, string ns, bool verifyObjectName) { reader.MoveToContent(); if (verifyObjectName && (reader.NodeType != XmlNodeType.Element || reader.LocalName != name || reader.NamespaceURI != ns)) { throw new SerializationException($"Expected element '{name}' in namespace '{ns}', but found {reader.NodeType} node '{reader.LocalName}' in namespace '{reader.NamespaceURI}'"); } return new XmlFormatterDeserializer(knownTypes, surrogate).Deserialize(type, reader); } private static void Verify(KnownTypeCollection knownTypes, Type type, string name, string Namespace, XmlReader reader) { XmlQualifiedName xmlQualifiedName = new XmlQualifiedName(reader.Name, reader.NamespaceURI); if (xmlQualifiedName.Name == name && xmlQualifiedName.Namespace == Namespace) { return; } Type type2 = type; while ((object)type2 != null) { if (knownTypes.GetQName(type2) == xmlQualifiedName) { return; } type2 = type2.BaseType; } XmlQualifiedName qName = knownTypes.GetQName(type); throw new SerializationException($"Expecting element '{qName.Name}' from namespace '{qName.Namespace}'. Encountered 'Element' with name '{xmlQualifiedName.Name}', namespace '{xmlQualifiedName.Namespace}'"); } public object Deserialize(Type type, XmlReader reader) { string attribute = reader.GetAttribute("Id", "http://schemas.microsoft.com/2003/10/Serialization/"); object obj = DeserializeCore(type, reader); if (attribute != null) { references.Add(attribute, obj); } return obj; } public object DeserializeCore(Type type, XmlReader reader) { XmlQualifiedName xmlQualifiedName = types.GetQName(type); string attribute = reader.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance"); if (attribute != null) { string[] array = attribute.Split(new char[1] { ':' }); xmlQualifiedName = ((array.Length <= 1) ? new XmlQualifiedName(attribute, reader.NamespaceURI) : new XmlQualifiedName(array[1], reader.LookupNamespace(reader.NameTable.Get(array[0])))); } string attribute2 = reader.GetAttribute("Ref", "http://schemas.microsoft.com/2003/10/Serialization/"); if (attribute2 != null) { object obj = references[attribute2]; if (obj == null) { throw new SerializationException($"Deserialized object with reference Id '{attribute2}' was not found"); } reader.Skip(); return obj; } if (reader.GetAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance") == "true") { reader.Skip(); if (!type.IsValueType) { return null; } if (type.IsGenericType && (object)type.GetGenericTypeDefinition() == typeof(Nullable<>)) { return null; } throw new SerializationException($"Value type {type} cannot be null."); } if ((object)KnownTypeCollection.GetPrimitiveTypeFromName(xmlQualifiedName.Name) != null) { string s; if (reader.IsEmptyElement) { reader.Read(); if (type.IsValueType) { return Activator.CreateInstance(type); } s = string.Empty; } else { s = reader.ReadElementContentAsString(); } return KnownTypeCollection.PredefinedTypeStringToObject(s, xmlQualifiedName.Name, reader); } return DeserializeByMap(xmlQualifiedName, type, reader); } private object DeserializeByMap(XmlQualifiedName name, Type type, XmlReader reader) { SerializationMap serializationMap = types.FindUserMap(name); if (serializationMap == null && (name.Namespace == "http://schemas.microsoft.com/2003/10/Serialization/Arrays" || name.Namespace.StartsWith("http://schemas.datacontract.org/2004/07/", StringComparison.Ordinal))) { Type typeFromNamePair = GetTypeFromNamePair(name.Name, name.Namespace); types.TryRegister(typeFromNamePair); serializationMap = types.FindUserMap(name); } if (serializationMap == null) { throw new SerializationException($"Unknown type {type} is used for DataContract with reference of name {name}. Any derived types of a data contract or a data member should be added to KnownTypes."); } return serializationMap.DeserializeObject(reader, this); } private Type GetTypeFromNamePair(string name, string ns) { Type primitiveTypeFromName = KnownTypeCollection.GetPrimitiveTypeFromName(name); if ((object)primitiveTypeFromName != null) { return primitiveTypeFromName; } if (name.StartsWith("ArrayOf", StringComparison.Ordinal) && ns == "http://schemas.microsoft.com/2003/10/Serialization/Arrays") { return GetTypeFromNamePair(name.Substring(7), string.Empty).MakeArrayType(); } int length = "http://schemas.datacontract.org/2004/07/".Length; string text = ((ns.Length <= length) ? null : ns.Substring(length)); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type[] array = assembly.GetTypes(); foreach (Type type in array) { DataContractAttribute customAttribute = type.GetCustomAttribute<DataContractAttribute>(inherit: true); if (customAttribute != null && customAttribute.Name == name && customAttribute.Namespace == ns) { return type; } if (text != null && type.Name == name && type.Namespace == text) { return type; } } } throw new XmlException($"Type not found; name: {name}, namespace: {ns}"); } } internal class XmlFormatterSerializer { private XmlDictionaryWriter writer; private object graph; private KnownTypeCollection types; private bool save_id; private bool ignore_unknown; private IDataContractSurrogate surrogate; private int max_items; private ArrayList objects = new ArrayList(); private Hashtable references = new Hashtable(); public ArrayList SerializingObjects => objects; public IDictionary References => references; public XmlDictionaryWriter Writer => writer; public XmlFormatterSerializer(XmlDictionaryWriter writer, KnownTypeCollection types, bool ignoreUnknown, int maxItems, string root_ns) { this.writer = writer; this.types = types; ignore_unknown = ignoreUnknown; max_items = maxItems; } public static void Serialize(XmlDictionaryWriter writer, object graph, KnownTypeCollection types, bool ignoreUnknown, int maxItems, string root_ns) { new XmlFormatterSerializer(writer, types, ignoreUnknown, maxItems, root_ns).Serialize(graph?.GetType(), graph); } public void Serialize(Type type, object graph) { if (graph == null) { writer.WriteAttributeString("nil", "http://www.w3.org/2001/XMLSchema-instance", "true"); return; } Type type2 = graph.GetType(); SerializationMap serializationMap = types.FindUserMap(type2); if (serializationMap == null) { type2 = types.GetSerializedType(type2); serializationMap = types.FindUserMap(type2); } if (serializationMap == null) { types.Add(type2); serializationMap = types.FindUserMap(type2); } if ((object)type2 != type && (serializationMap == null || serializationMap.OutputXsiType)) { XmlQualifiedName xmlName = types.GetXmlName(type2); string localName = xmlName.Name; string text = xmlName.Namespace; if (xmlName == XmlQualifiedName.Empty) { localName = XmlConvert.EncodeLocalName(type2.Name); text = "http://schemas.datacontract.org/2004/07/" + type2.Namespace; } else if (xmlName.Namespace == "http://schemas.microsoft.com/2003/10/Serialization/") { text = "http://www.w3.org/2001/XMLSchema"; } if (writer.LookupPrefix(text) == null) { writer.WriteXmlnsAttribute(null, text); } writer.WriteStartAttribute("type", "http://www.w3.org/2001/XMLSchema-instance"); writer.WriteQualifiedName(localName, text); writer.WriteEndAttribute(); } XmlQualifiedName predefinedTypeName = KnownTypeCollection.GetPredefinedTypeName(type2); if (predefinedTypeName != XmlQualifiedName.Empty) { SerializePrimitive(type, graph, predefinedTypeName); } else { serializationMap.Serialize(graph, this); } } public void SerializePrimitive(Type type, object graph, XmlQualifiedName qname) { writer.WriteString(KnownTypeCollection.PredefinedTypeObjectToString(graph)); } public void WriteStartElement(string rootName, string rootNamespace, string currentNamespace) { writer.WriteStartElement(rootName, rootNamespace); if (!string.IsNullOrEmpty(currentNamespace) && currentNamespace != rootNamespace) { writer.WriteXmlnsAttribute(null, currentNamespace); } } public void WriteEndElement() { writer.WriteEndElement(); } } public abstract class XmlObjectSerializer { private IDataContractSurrogate surrogate; private SerializationBinder binder; private ISurrogateSelector selector; private int max_items = 65536; public virtual bool IsStartObject(XmlReader reader) { return IsStartObject(XmlDictionaryReader.CreateDictionaryReader(reader)); } public abstract bool IsStartObject(XmlDictionaryReader reader); public virtual object ReadObject(Stream stream) { return ReadObject(XmlReader.Create(stream)); } public virtual object ReadObject(XmlReader reader) { return ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader)); } public virtual object ReadObject(XmlDictionaryReader reader) { return ReadObject(reader, readContentOnly: true); } public virtual object ReadObject(XmlReader reader, bool readContentOnly) { return ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader), readContentOnly); } [MonoTODO] public abstract object ReadObject(XmlDictionaryReader reader, bool readContentOnly); public virtual void WriteObject(Stream stream, object graph) { using XmlWriter writer = XmlDictionaryWriter.CreateTextWriter(stream); WriteObject(writer, graph); } public virtual void WriteObject(XmlWriter writer, object graph) { WriteObject(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph); } public virtual void WriteStartObject(XmlWriter writer, object graph) { WriteStartObject(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph); } public virtual void WriteObject(XmlDictionaryWriter writer, object graph) { WriteStartObject(writer, graph); WriteObjectContent(writer, graph); WriteEndObject(writer); } public abstract void WriteStartObject(XmlDictionaryWriter writer, object graph); public virtual void WriteObjectContent(XmlWriter writer, object graph) { WriteObjectContent(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph); } public abstract void WriteObjectContent(XmlDictionaryWriter writer, object graph); public virtual void WriteEndObject(XmlWriter writer) { WriteEndObject(XmlDictionaryWriter.CreateDictionaryWriter(writer)); } public abstract void WriteEndObject(XmlDictionaryWriter writer); } } namespace System.Xml { public interface IStreamProvider { Stream GetStream(); void ReleaseStream(Stream stream); } public interface IXmlBinaryReaderInitializer { void SetInput(Stream stream, IXmlDictionary dictionary, XmlDictionaryReaderQuotas quota, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose); void SetInput(byte[] buffer, int offset, int count, IXmlDictionary dictionary, XmlDictionaryReaderQuotas quota, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose); } public interface IXmlBinaryWriterInitializer { void SetOutput(Stream stream, IXmlDictionary dictionary, XmlBinaryWriterSession session, bool ownsStream); } public interface IXmlDictionary { bool TryLookup(int key, out XmlDictionaryString result); bool TryLookup(string value, out XmlDictionaryString result); bool TryLookup(XmlDictionaryString value, out XmlDictionaryString result); } public interface IXmlMtomReaderInitializer { void SetInput(Stream stream, Encoding[] encodings, string contentType, XmlDictionaryReaderQuotas quotas, int maxBufferSize, OnXmlDictionaryReaderClose onClose); void SetInput(byte[] buffer, int offset, int count, Encoding[] encodings, string contentType, XmlDictionaryReaderQuotas quotas, int maxBufferSize, OnXmlDictionaryReaderClose onClose); } public interface IXmlMtomWriterInitializer { void SetOutput(Stream stream, Encoding encoding, int maxSizeInBytes, string startInfo, string boundary, string startUri, bool writeMessageHeaders, bool ownsStream); } public interface IXmlTextReaderInitializer { void SetInput(byte[] buffer, int offset, int count, Encoding encoding, XmlDictionaryReaderQuotas quota, OnXmlDictionaryReaderClose onClose); void SetInput(Stream stream, Encoding encoding, XmlDictionaryReaderQuotas quota, OnXmlDictionaryReaderClose onClose); } public interface IXmlTextWriterInitializer { void SetOutput(Stream stream, Encoding encoding, bool ownsStream); } public class UniqueId { private Guid guid; private string id; public int CharArrayLength => (id == null) ? 45 : id.Length; public bool IsGuid => guid != default(Guid); public UniqueId() : this(Guid.NewGuid()) { } public UniqueId(byte[] id) : this(id, 0) { } public UniqueId(Guid id) { guid = id; } public UniqueId(string value) { if (value == null) { throw new ArgumentNullException("value cannot be null", "value"); } if (value.Length == 0) { throw new FormatException("UniqueId cannot be zero length"); } id = value; } public UniqueId(byte[] id, int offset) { if (id == null) { throw new ArgumentNullException(); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset"); } if (offset >= id.Length) { throw new ArgumentException("id too small.", "offset"); } if (id.Length - offset != 16) { throw new ArgumentException("id and offset provide less than 16 bytes"); } if (offset == 0) { guid = new Guid(id); return; } List<byte> list = new List<byte>(id); list.RemoveRange(0, offset); guid = new Guid(list.ToArray()); } public UniqueId(char[] id, int offset, int count) { if (id == null) { throw new ArgumentNullException("id"); } if (offset < 0 || offset >= id.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || id.Length - offset < count) { throw new ArgumentOutOfRangeException("count"); } if (count == 0) { throw new FormatException(); } if (count > 8 && id[offset] == 'u' && id[offset + 1] == 'r' && id[offset + 2] == 'n' && id[offset + 3] == ':' && id[offset + 4] == 'u' && id[offset + 5] == 'u' && id[offset + 6] == 'i' && id[offset + 7] == 'd' && id[offset + 8] == ':') { if (count != 45) { throw new ArgumentOutOfRangeException("Invalid Guid"); } guid = new Guid(new string(id, offset + 9, count - 9)); } else { this.id = new string(id, offset, count); } } public override bool Equals(object obj) { UniqueId uniqueId = obj as UniqueId; if (uniqueId == null) { return false; } if (IsGuid && uniqueId.IsGuid) { return guid.Equals(uniqueId.guid); } return id == uniqueId.id; } [MonoTODO("Determine semantics when IsGuid==true")] public override int GetHashCode() { return (id == null) ? guid.GetHashCode() : id.GetHashCode(); } public int ToCharArray(char[] array, int offset) { if (array == null) { throw new ArgumentNullException("array"); } if (offset < 0 || offset >= array.Length) { throw new ArgumentOutOfRangeException("offset"); } string text = ToString(); text.CopyTo(0, array, offset, text.Length); return text.Length; } public override string ToString() { if (id == null) { return "urn:uuid:" + guid; } return id; } public bool TryGetGuid(out Guid guid) { if (IsGuid) { guid = this.guid; return true; } guid = default(Guid); return false; } public bool TryGetGuid(byte[] buffer, int offset) { if (!IsGuid) { return false; } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0 || offset >= buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (buffer.Length - offset < 16) { throw new ArgumentOutOfRangeException("offset"); } guid.ToByteArray().CopyTo(buffer, offset); return true; } public static bool operator ==(UniqueId id1, UniqueId id2) { return object.Equals(id1, id2); } public static bool operator !=(UniqueId id1, UniqueId id2) { return !(id1 == id2); } } internal class XmlBinaryDictionaryReader : XmlDictionaryReader, IXmlNamespaceResolver { internal interface ISource { int Position { get; } BinaryReader Reader { get; } int ReadByte(); int Read(byte[] data, int offset, int count); } internal class StreamSource : ISource { private BinaryReader reader; public int Position => (int)reader.BaseStream.Position; public BinaryReader Reader => reader; public StreamSource(Stream stream) { reader = new BinaryReader(stream); } public int ReadByte() { if (reader.PeekChar() < 0) { return -1; } return reader.ReadByte(); } public int Read(byte[] data, int offset, int count) { return reader.Read(data, offset, count); } } private class NodeInfo { public bool IsAttributeValue; public int Position; public string Prefix; public XmlDictionaryString DictLocalName; public XmlDictionaryString DictNS; public XmlDictionaryString DictValue; public XmlNodeType NodeType; public object TypedValue; public byte ValueType; public int NSSlot; private string name = string.Empty; private string local_name = string.Empty; private string ns = string.Empty; private string value; public string LocalName { get { return (DictLocalName == null) ? local_name : DictLocalName.Value; } set { DictLocalName = null; local_name = value; } } public string NS { get { return (DictNS == null) ? ns : DictNS.Value; } set { DictNS = null; ns = value; } } public string Name { get { if (name.Length == 0) { name = ((Prefix.Length <= 0) ? LocalName : (Prefix + ":" + LocalName)); } return name; } } public virtual string Value { get { switch (ValueType) { case 0: case 2: case 152: case 154: case 156: case 168: case 182: case 184: case 186: return value; case 170: return DictValue.Value; case 128: return "0"; case 130: return "1"; case 134: return "true"; case 132: return "false"; case 136: return XmlConvert.ToString((byte)TypedValue); case 138: return XmlConvert.ToString((short)TypedValue); case 140: return XmlConvert.ToString((int)TypedValue); case 142: return XmlConvert.ToString((long)TypedValue); case 144: return XmlConvert.ToString((float)TypedValue); case 146: return XmlConvert.ToString((double)TypedValue); case 150: return XmlConvert.ToString((DateTime)TypedValue, XmlDateTimeSerializationMode.RoundtripKind); case 174: return XmlConvert.ToString((TimeSpan)TypedValue); case 176: return XmlConvert.ToString((Guid)TypedValue); case 172: return TypedValue.ToString(); case 158: case 160: case 162: return Convert.ToBase64String((byte[])TypedValue); default: throw new NotImplementedException("ValueType " + ValueType + " on node " + NodeType); } } set { this.value = value; } } public NodeInfo() { } public NodeInfo(bool isAttr) { IsAttributeValue = isAttr; } public virtual void Reset() { Position = 0; DictLocalName = (DictNS = null); string prefix = (Value = string.Empty); prefix = (NS = (Prefix = prefix)); LocalName = prefix; NodeType = XmlNodeType.None; TypedValue = null; ValueType = 0; NSSlot = -1; } } private class AttrNodeInfo : NodeInfo { private XmlBinaryDictionaryReader owner; public int ValueIndex; public override string Value => owner.attr_values[ValueIndex].Value; public AttrNodeInfo(XmlBinaryDictionaryReader owner) { this.owner = owner; } public override void Reset() { base.Reset(); ValueIndex = -1; NodeType = XmlNodeType.Attribute; } } private ISource source; private IXmlDictionary dictionary; private XmlDictionaryReaderQuotas quota; private XmlBinaryReaderSession session; private OnXmlDictionaryReaderClose on_close; private XmlParserContext context; private ReadState state; private NodeInfo node; private NodeInfo current; private List<AttrNodeInfo> attributes = new List<AttrNodeInfo>(); private List<NodeInfo> attr_values = new List<NodeInfo>(); private List<NodeInfo> node_stack = new List<NodeInfo>(); private List<XmlQualifiedName> ns_store = new List<XmlQualifiedName>(); private Dictionary<int, XmlDictionaryString> ns_dict_store = new Dictionary<int, XmlDictionaryString>(); private int attr_count; private int attr_value_count; private int current_attr = -1; private int depth; private int ns_slot; private int next = -1; private bool is_next_end_element; private byte[] tmp_buffer = new byte[128]; private UTF8Encoding utf8enc = new UTF8Encoding(); private int array_item_remaining; private byte array_item_type; private XmlNodeType array_state; public override int AttributeCount => attr_count; public override string BaseURI => context.BaseURI; public override int Depth => (current == node) ? depth : ((NodeType != XmlNodeType.Attribute) ? (depth + 2) : (depth + 1)); public override bool EOF => state == ReadState.EndOfFile || state == ReadState.Error; public override bool HasValue => Value.Length > 0; public override bool IsEmptyElement => false; public override XmlNodeType NodeType => current.NodeType; public override string Prefix => (current_attr < 0) ? current.Prefix : attributes[current_attr].Prefix; public override string LocalName => (current_attr < 0) ? current.LocalName : attributes[current_attr].LocalName; public override string Name => (current_attr < 0) ? current.Name : attributes[current_attr].Name; public override string NamespaceURI => (current_attr < 0) ? current.NS : attributes[current_attr].NS; public override XmlNameTable NameTable => context.NameTable; public override XmlDictionaryReaderQuotas Quotas => quota; public override ReadState ReadState => state; public override string Value => current.Value; public XmlBinaryDictionaryReader(byte[] buffer, int offset, int count, IXmlDictionary dictionary, XmlDictionaryReaderQuotas quota, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose) { source = new StreamSource(new MemoryStream(buffer, offset, count)); Initialize(dictionary, quota, session, onClose); } public XmlBinaryDictionaryReader(Stream stream, IXmlDictionary dictionary, XmlDictionaryReaderQuotas quota, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose) { source = new StreamSource(stream); Initialize(dictionary, quota, session, onClose); } private void Initialize(IXmlDictionary dictionary, XmlDictionaryReaderQuotas quotas, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose) { if (quotas == null) { throw new ArgumentNullException("quotas"); } if (dictionary == null) { dictionary = new XmlDictionary(); } this.dictionary = dictionary; quota = quotas; if (session == null) { session = new XmlBinaryReaderSession(); } this.session = session; on_close = onClose; NameTable nameTable = new NameTable(); context = new XmlParserContext(nameTable, new XmlNamespaceManager(nameTable), null, XmlSpace.None); current = (node = new NodeInfo()); current.Reset(); node_stack.Add(node); } public override void Close() { if (on_close != null) { on_close(this); } } public override string GetAttribute(int i) { if (i >= attr_count) { throw new ArgumentOutOfRangeException($"Specified attribute index is {i} and should be less than {attr_count}"); } return attributes[i].Value; } public override string GetAttribute(string name) { for (int i = 0; i < attr_count; i++) { if (attributes[i].Name == name) { return attributes[i].Value; } } return null; } public override string GetAttribute(string localName, string ns) { for (int i = 0; i < attr_count; i++) { if (attributes[i].LocalName == localName && attributes[i].NS == ns) { return attributes[i].Value; } } return null; } public IDictionary<string, string> GetNamespacesInScope(XmlNamespaceScope scope) { return context.NamespaceManager.GetNamespacesInScope(scope); } public string LookupPrefix(string ns) { return context.NamespaceManager.LookupPrefix(NameTable.Get(ns)); } public override string LookupNamespace(string prefix) { return context.NamespaceManager.LookupNamespace(NameTable.Get(prefix)); } public override bool IsArray(out Type type) { if (array_state == XmlNodeType.Element) { type = GetArrayType(array_item_type); return true; } type = null; return false; } public override bool MoveToElement() { bool result = current_attr >= 0; current_attr = -1; current = node; return result; } public override bool MoveToFirstAttribute() { if (attr_count == 0) { return false; } current_attr = 0; current = attributes[current_attr]; return true; } public override bool MoveToNextAttribute() { if (++current_attr < attr_count) { current = attributes[current_attr]; return true; } current_attr--; return false; } public override void MoveToAttribute(int i) { if (i >= attr_count) { throw new ArgumentOutOfRangeException($"Specified attribute index is {i} and should be less than {attr_count}"); } current_attr = i; current = attributes[i]; } public override bool MoveToAttribute(string name) { for (int i = 0; i < attributes.Count; i++) { if (attributes[i].Name == name) { MoveToAttribute(i); return true; } } return false; } public override bool MoveToAttribute(string localName, string ns) { for (int i = 0; i < attributes.Count; i++) { if (attributes[i].LocalName == localName && attributes[i].NS == ns) { MoveToAttribute(i); return true; } } return false; } public override bool ReadAttributeValue() { if (current_attr < 0) { return false; } int valueIndex = attributes[current_attr].ValueIndex; int num = ((current_attr + 1 != attr_count) ? attributes[current_attr + 1].ValueIndex : attr_value_count); if (valueIndex == num) { return false; } if (!current.IsAttributeValue) { current = attr_values[valueIndex]; return true; } return false; } public override bool Read() { switch (state) { case ReadState.Error: case ReadState.EndOfFile: case ReadState.Closed: return false; default: { state = ReadState.Interactive; MoveToElement(); attr_count = 0; attr_value_count = 0; ns_slot = 0; if (node.NodeType == XmlNodeType.Element) { if (node_stack.Count <= ++depth) { if (depth == quota.MaxDepth) { throw new XmlException($"Binary XML stream quota exceeded. Depth must be less than {quota.MaxDepth}"); } node = new NodeInfo(); node_stack.Add(node); } else { node = node_stack[depth]; node.Reset(); } } current = node; if (is_next_end_element) { is_next_end_element = false; node.Reset(); ProcessEndElement(); return true; } switch (array_state) { case XmlNodeType.Element: ReadArrayItem(); return true; case XmlNodeType.Text: ShiftToArr