using System; using System.Collections.Generic; namespace InABox.Core { public abstract class PackableDictionary : Dictionary, IPackable { public void Pack(FastBinaryWriter writer) { writer.Write(Count); foreach (var key in Keys) { writer.Write(key); PackItem(writer, this[key]); } } public void Unpack(FastBinaryReader reader) { Clear(); var iCount = reader.ReadInt32(); for (var i = 0; i < iCount; i++) { var key = reader.ReadString(); this[key] = UnpackItem(reader); } } public override bool Equals(object obj) { var other = obj as PackableDictionary; if (other == null) return false; if (Count != other.Count) // Require equal count. return false; foreach (var pair in this) if (other.TryGetValue(pair.Key, out var value)) { if (value == null) { if (pair.Value != null) return false; } else if (!value.Equals(pair.Value)) { return false; } } else { return false; } return true; } public abstract void PackItem(FastBinaryWriter writer, T value); public abstract T UnpackItem(FastBinaryReader reader); } public class PackableStringDictionary : PackableDictionary { public override void PackItem(FastBinaryWriter writer, string value) { writer.Write(value); } public override string UnpackItem(FastBinaryReader reader) { return reader.ReadString(); } } public class PackableBooleanDictionary : PackableDictionary { public override void PackItem(FastBinaryWriter writer, bool value) { writer.Write(value); } public override bool UnpackItem(FastBinaryReader reader) { return reader.ReadBoolean(); } } public class PackableObjectDictionary : PackableDictionary { private static readonly Dictionary Types = new Dictionary { { typeof(object), 0x0000 }, { typeof(string), 0x0001 }, { typeof(string[]), 0x002 }, { typeof(sbyte), 0x1000 }, { typeof(byte), 0x0011 }, { typeof(ushort), 0x0012 }, { typeof(uint), 0x0013 }, { typeof(ulong), 0x0014 }, { typeof(short), 0x0015 }, { typeof(int), 0x0016 }, { typeof(long), 0x0017 }, { typeof(float), 0x0100 }, { typeof(double), 0x0101 }, { typeof(decimal), 0x0102 }, { typeof(TimeSpan), 0x1000 }, { typeof(DateTime), 0x1001 }, { typeof(Guid), 0x1002 } }; private static readonly Dictionary Indexes = new Dictionary(); static PackableObjectDictionary() { foreach (var key in Types.Keys) Indexes[Types[key]] = key; } private static short GetIndex(Type type) { if (Types.ContainsKey(type)) return Types[type]; return 0x0000; } public static Type GetType(short index) { if (Indexes.ContainsKey(index)) return Indexes[index]; return typeof(object); } public override void PackItem(FastBinaryWriter writer, object value) { if (value == null) { writer.Write(default(short)); writer.Write(""); } else { var type = GetIndex(value.GetType()); writer.Write(type); writer.Write(CoreUtils.TypedValueToString(value)); } } public override object UnpackItem(FastBinaryReader reader) { var index = reader.ReadInt16(); var type = GetType(index); var value = reader.ReadString(); if (type == typeof(object) && string.IsNullOrEmpty(value)) return null; return CoreUtils.StringToTypedValue(value, type); } } }