/// <summary> /// Serialize a single value or array element /// </summary> /// <param name="ElementType">Type of the element</param> /// <param name="ElementValue">Value to serialize</param> /// <param name="Types">List of known types</param> /// <param name="Instances">List of known object instances</param> /// <param name="Writer">Writer for the output data</param> static void SerializeElement(Type ElementType, object ElementValue, HashList <Type> Types, HashList <object> Instances, BinaryWriter Writer) { if (ElementType == typeof(Boolean)) { Writer.Write((Boolean)ElementValue); } else if (ElementType == typeof(Int32)) { Writer.Write((Int32)ElementValue); } else if (ElementType.IsEnum) { Type UnderlyingType = ElementType.GetEnumUnderlyingType(); SerializeElement(UnderlyingType, Convert.ChangeType(ElementValue, UnderlyingType), Types, Instances, Writer); } else if (ElementType.IsClass || ElementType.IsArray || ElementType.IsInterface) { if (ElementValue == null) { Writer.Write(-1); } else { int Index = Instances.IndexOf(ElementValue); if (Index == -1) { Writer.Write(Instances.Count); SerializeInstance(ElementValue, Types, Instances, Writer); } else { Writer.Write(Index); } } } else { FieldInfo[] Fields = FindAllFields(ElementType); if (Fields.Length > 0) { SerializeObjectFields(ElementValue, Fields, Types, Instances, Writer); } else { throw new NotImplementedException(); } } }
/// <summary> /// Serialize an object instance to a BinaryWriter /// </summary> /// <param name="ThisObject">The object to serialize</param> /// <param name="Types">List of types which have been serialized before. If the type of this object is new, it will be added to the list.</param> /// <param name="Instances">List of object instances which have already been serialized. The given object must NOT be in this list.</param> /// <param name="Writer">The writer for output data</param> static void SerializeInstance(object ThisObject, HashList <Type> Types, HashList <object> Instances, BinaryWriter Writer) { Type ThisType = ThisObject.GetType(); // Write the type int TypeIdx = Types.IndexOf(ThisType); if (TypeIdx == -1) { Types.Add(ThisType); Writer.Write((int)(Types.Count - 1)); Writer.Write(ThisType.FullName); } else { Writer.Write(TypeIdx); } // Now write the instance data Instances.Add(ThisObject); if (ThisType.IsArray) { Array ThisArrayObject = (Array)ThisObject; for (int DimensionIdx = 0; DimensionIdx < ThisArrayObject.Rank; DimensionIdx++) { Writer.Write(ThisArrayObject.GetLength(DimensionIdx)); } Type ElementType = ThisArrayObject.GetType().GetElementType(); foreach (int[] Indices in EnumerateArrayIndices(ThisArrayObject)) { SerializeElement(ElementType, ThisArrayObject.GetValue(Indices), Types, Instances, Writer); } } else if (ThisType == typeof(string)) { Writer.Write((string)ThisObject); } else { SerializeObjectFields(ThisObject, FindAllFields(ThisType), Types, Instances, Writer); } }