// Adds a new entry as a raw hexstring representation of the object's raw bytes public bool AddEntryAsBinary(string Name, object Value) { // Verify entry is valid if (Value == null) { return(false); } // Create an output array byte[] Output = new byte[0]; int Size = 0; if (Value.GetType().IsArray) { Type ArrayType = Value.GetType(); foreach (object Val in (Value as Array)) { Size += Encoding.GetSizeOfObject(Val); } } else { Size = Encoding.GetSizeOfObject(Value); } Output = Encoding.AppendToByteArray(SerializeVarInt(Size), Output); // Serialize object Output = Encoding.AppendToByteArray(SerializeObjectAsBinary(Value), Output); // Add as an entry AddEntry(Name, Encoding.ByteArrayToString(Output)); return(true); }
/* Add the magic identifier to the beginning of the input string */ protected static string AddMagicIdentifier(string input, byte[] magicIdentifier) { byte[] inputBytes = Encoding.StringToByteArray(input); inputBytes = AddMagicIdentifier(inputBytes, magicIdentifier); return(Encoding.ByteArrayToString(inputBytes)); }
// Decodes an object packed into a byte array private T DeserializeObjectFromBinary <T>(byte[] Data) { // Create an output object T Output = default(T); // Object is an integer if (typeof(T).GetInterfaces().Contains(typeof(IConvertible))) { // Create a generic method wrapper to access deserialization MethodInfo MethodInfo = typeof(Encoding).GetMethod("ByteArrayToInteger", new[] { typeof(byte[]), typeof(int) }); Type[] Args = new Type[] { typeof(T) }; MethodInfo Method = MethodInfo.MakeGenericMethod(Args); // Deserialize integer Output = (T)Method.Invoke(null, new object[] { Data, 0 }); } // Object is a string else if (typeof(T) == typeof(string)) { // Deserialize string length int Length = DeserializeVarInt <int>(Data, 0, out int Offset); // Deserialize string Output = (T)Convert.ChangeType(Encoding.ByteArrayToString(Encoding.SplitByteArray(Data, Offset, Length)), typeof(T)); } // Object is an array else if (typeof(T).IsArray) { // Create a generic method wrapper to access deserialization MethodInfo MethodInfo = typeof(PortableStorage).GetMethod("DeserializeArrayFromBinary"); Type[] Args = new Type[] { typeof(T) }; MethodInfo Method = MethodInfo.MakeGenericMethod(Args); // Deserialize integer Output = (T)Method.Invoke(null, new object[] { Data }); } // Property is an object else { // Get property list of type var Properties = typeof(T).GetProperties(); // Create a buffer byte[] Buffer = Encoding.AppendToByteArray(Data, new byte[0]); // Loop through object properties foreach (PropertyInfo Property in Properties) { // Create a generic method wrapper to access deserialization MethodInfo MethodInfo = typeof(PortableStorage).GetMethod("DeserializeObjectFromBinary"); Type[] Args = new Type[] { Property.PropertyType }; MethodInfo Method = MethodInfo.MakeGenericMethod(Args); // Set object parameter value var Param = Method.Invoke(null, new object[] { Buffer }); object Temp = Output; Property.SetValue(Temp, Convert.ChangeType(Param, Property.PropertyType)); Output = (T)Convert.ChangeType(Temp, typeof(T)); // Resize buffer Buffer = Encoding.SplitByteArray(Buffer, Encoding.GetSizeOfObject(Property.GetValue(Output)), Buffer.Length - Encoding.GetSizeOfObject(Property.GetValue(Output))); } } // Return output return(Output); }
// Deserializes an entry from a byte array and adds it to storage private byte[] DeserializeEntry(byte[] Buffer) { // Get entry name length int NameLength = Encoding.ByteArrayToInteger <byte>(Buffer, 0, 1);//DeserializeVarInt<int>(Buffer, 0, out int Offset); int Offset = 1; if (NameLength < 1 || NameLength > MAX_STRING_LENGTH) { throw new Exception("Name size exceeds allowed string bounds"); } // Get entry name string Name = Encoding.ByteArrayToString(Buffer, Offset, NameLength); Offset += NameLength; Buffer = Encoding.SplitByteArray(Buffer, Offset, Buffer.Length - Offset); // Get object type SerializationType Type = GetType(Buffer); if ((int)Type < 1 || (int)Type > 14) { throw new Exception("Invalid serialization type caught: " + Encoding.ByteArrayToHexString(Encoding.SplitByteArray(Buffer, 1, Buffer.Length - 1))); } Buffer = Encoding.SplitByteArray(Buffer, 1, Buffer.Length - 1); // Create an entry object var Output = new object(); // Object is a string if (Type == SerializationType.STRING) { // Deserialize string length int Length = DeserializeVarInt <int>(Buffer, 0, out Offset); // Deserialize string Output = Encoding.ByteArrayToString(Encoding.SplitByteArray(Buffer, Offset, Length)); // Resize buffer Offset += (Output as string).Length; if (Buffer.Length - Offset > 0) { Buffer = Encoding.SplitByteArray(Buffer, Offset, Buffer.Length - Offset); } } // Object is an integer else if ((int)Type >= 1 && (int)Type <= 9) { // Create a generic method wrapper to access deserialization MethodInfo MethodInfo = typeof(Encoding).GetMethod("ByteArrayToInteger", new[] { typeof(byte[]), typeof(int) }); Type[] Args = new Type[] { ConvertSerializationType(Type) }; MethodInfo Method = MethodInfo.MakeGenericMethod(Args); // Deserialize integer Output = Method.Invoke(null, new object[] { Buffer, 0 }); // Resize buffer Offset = Encoding.GetSizeOfObject(Output); if (Buffer.Length - Offset > 0) { Buffer = Encoding.SplitByteArray(Buffer, Offset, Buffer.Length - Offset); } } // Object is an object else if (Type == SerializationType.OBJECT) { // Create a new storage object PortableStorage Storage = new PortableStorage(); // Deserialize entry Buffer = Storage.Deserialize(Buffer, false); Output = Storage; } // Add to entries Entries.Add(Name, Output); // Return buffer output return(Buffer); }