/// <summary> /// Writes the specified <see cref="System.Delegate"/>, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteDelegate(object obj, SerializeType objSerializeType, uint id = 0) { bool multi = obj is MulticastDelegate; // Write the delegates type this.writer.WriteAttributeString("type", objSerializeType.TypeString); if (id != 0) { this.writer.WriteAttributeString("id", XmlConvert.ToString(id)); } if (multi) { this.writer.WriteAttributeString("multi", XmlConvert.ToString(multi)); } if (!multi) { Delegate objAsDelegate = obj as Delegate; this.WriteObjectData(objAsDelegate.Method); this.WriteObjectData(objAsDelegate.Target); } else { MulticastDelegate objAsDelegate = obj as MulticastDelegate; Delegate[] invokeList = objAsDelegate.GetInvocationList(); this.WriteObjectData(objAsDelegate.Method); this.WriteObjectData(objAsDelegate.Target); this.WriteObjectData(invokeList); } }
/// <summary> /// Determines internal data for writing a given object. /// </summary> /// <param name="obj">The object to write</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> that describes the specified object.</param> /// <param name="dataType">The <see cref="Duality.Serialization.DataType"/> that is used for writing the specified object.</param> /// <param name="objId">An object id that is assigned to the specified object.</param> protected virtual void GetWriteObjectData(object obj, out SerializeType objSerializeType, out DataType dataType, out uint objId) { Type objType = obj.GetType(); objSerializeType = objType.GetSerializeType(); objId = 0; dataType = objSerializeType.DataType; // Check whether it's going to be an ObjectRef or not if (dataType == DataType.Array || dataType == DataType.Class || dataType == DataType.Delegate || dataType.IsMemberInfoType()) { bool newId; objId = this.idManager.Request(obj, out newId); // If its not a new id, write a reference if (!newId) { dataType = DataType.ObjectRef; } } if (dataType != DataType.ObjectRef && !objSerializeType.Type.IsSerializable && !typeof(ISerializable).IsAssignableFrom(objSerializeType.Type) && this.GetSurrogateFor(objSerializeType.Type) == null) { this.SerializationLog.WriteWarning("Serializing object of Type '{0}' which isn't [Serializable]", Log.Type(objSerializeType.Type)); } }
public AssignFieldError(SerializeType targetObjType, object targetObj, string fieldName, object fieldValue) { this.targetObjType = targetObjType; this.targetObj = targetObj; this.fieldName = fieldName; this.fieldValue = fieldValue; }
public ObjectHeader(uint id, DataType dataType, SerializeType serializeType) { this.objectId = id; this.dataType = dataType; this.serializeType = serializeType; this.typeString = serializeType != null ? serializeType.TypeString : null; }
/// <summary> /// Writes the specified <see cref="System.Array"/>, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteArray(object obj, SerializeType objSerializeType, uint id = 0) { Array objAsArray = obj as Array; if (objAsArray.Rank != 1) throw new ArgumentException("Non single-Rank arrays are not supported"); if (objAsArray.GetLowerBound(0) != 0) throw new ArgumentException("Non zero-based arrays are not supported"); this.writer.WriteAttributeString("type", objSerializeType.TypeString); if (id != 0) this.writer.WriteAttributeString("id", XmlConvert.ToString(id)); if (objAsArray.Rank != 1) this.writer.WriteAttributeString("rank", XmlConvert.ToString(objAsArray.Rank)); this.writer.WriteAttributeString("length", XmlConvert.ToString(objAsArray.Length)); if (objAsArray is byte[]) { byte[] byteArr = objAsArray as byte[]; this.writer.WriteString(this.ByteArrayToString(byteArr)); //for (int l = 0; l < byteArr.Length; l++) // this.writer.WriteString(byteArr[l].ToString("X2")); } else { for (long l = 0; l < objAsArray.Length; l++) this.WriteObject(objAsArray.GetValue(l)); } }
public ObjectHeader(uint id, DataType dataType, string unresolvedTypeString) { this.objectId = id; this.dataType = dataType; this.serializeType = null; this.typeString = unresolvedTypeString; }
/// <summary> /// Prepares an object for serialization and generates its header information. /// </summary> /// <param name="obj">The object to write</param> protected ObjectHeader PrepareWriteObject(object obj) { Type objType = obj.GetType(); SerializeType objSerializeType = GetSerializeType(objType); DataType dataType = objSerializeType.DataType; uint objId = 0; // Check whether it's going to be an ObjectRef or not if (objSerializeType.CanBeReferenced) { bool newId; objId = this.idManager.Request(obj, out newId); // If its not a new id, write a reference if (!newId) { dataType = DataType.ObjectRef; } } // Check whether the object is expected to be serialized if (dataType != DataType.ObjectRef && !objSerializeType.Type.IsSerializable && !typeof(ISerializeExplicit).IsAssignableFrom(objSerializeType.Type) && GetSurrogateFor(objSerializeType.Type) == null) { this.LocalLog.WriteWarning("Ignoring object of Type '{0}' which isn't [Serializable]", Log.Type(objSerializeType.Type)); return(null); } // Generate object header information return(new ObjectHeader(objId, dataType, objSerializeType)); }
/// <summary> /// Writes the specified <see cref="System.Reflection.MemberInfo"/>, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="id">The objects id.</param> protected void WriteMemberInfo(object obj, uint id = 0) { this.writer.Write(id); if (obj is Type) { Type type = obj as Type; SerializeType cachedType = type.GetSerializeType(); this.writer.Write(cachedType.TypeString); } else if (obj is MemberInfo) { MemberInfo member = obj as MemberInfo; this.writer.Write(member.GetMemberId()); } else if (obj == null) { throw new ArgumentNullException("obj"); } else { throw new ArgumentException(string.Format("Type '{0}' is not a supported MemberInfo.", obj.GetType())); } }
/// <summary> /// Writes the specified <see cref="System.Array"/>, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteArray(object obj, SerializeType objSerializeType, uint id = 0) { Array objAsArray = obj as Array; if (objAsArray.Rank != 1) throw new ArgumentException("Non single-Rank arrays are not supported"); if (objAsArray.GetLowerBound(0) != 0) throw new ArgumentException("Non zero-based arrays are not supported"); this.writer.Write(objSerializeType.TypeString); this.writer.Write(id); this.writer.Write(objAsArray.Rank); this.writer.Write(objAsArray.Length); if (objAsArray is bool[]) this.WriteArrayData(objAsArray as bool[]); else if (objAsArray is byte[]) this.WriteArrayData(objAsArray as byte[]); else if (objAsArray is sbyte[]) this.WriteArrayData(objAsArray as sbyte[]); else if (objAsArray is short[]) this.WriteArrayData(objAsArray as short[]); else if (objAsArray is ushort[]) this.WriteArrayData(objAsArray as ushort[]); else if (objAsArray is int[]) this.WriteArrayData(objAsArray as int[]); else if (objAsArray is uint[]) this.WriteArrayData(objAsArray as uint[]); else if (objAsArray is long[]) this.WriteArrayData(objAsArray as long[]); else if (objAsArray is ulong[]) this.WriteArrayData(objAsArray as ulong[]); else if (objAsArray is float[]) this.WriteArrayData(objAsArray as float[]); else if (objAsArray is double[]) this.WriteArrayData(objAsArray as double[]); else if (objAsArray is decimal[]) this.WriteArrayData(objAsArray as decimal[]); else if (objAsArray is char[]) this.WriteArrayData(objAsArray as char[]); else if (objAsArray is string[]) this.WriteArrayData(objAsArray as string[]); else { for (long l = 0; l < objAsArray.Length; l++) this.WriteObject(objAsArray.GetValue(l)); } }
/// <summary> /// Initializes a TypeDataLayout by extracting necessary information from the specified <see cref="Duality.Serialization.SerializeType"/>. /// </summary> /// <param name="t">The source SerializeType.</param> public TypeDataLayout(SerializeType t) { this.fields = new FieldDataInfo[t.Fields.Length]; for (int i = 0; i < t.Fields.Length; i++) { this.fields[i].name = t.Fields[i].Name; this.fields[i].typeString = t.Fields[i].FieldType.GetTypeId(); } }
private void WriteTypeDataLayout(SerializeType objSerializeType) { if (this.typeDataLayout.ContainsKey(objSerializeType.TypeString)) { long backRef = this.typeDataLayoutMap[objSerializeType.TypeString]; this.writer.Write(backRef); return; } this.WriteTypeDataLayout(new TypeDataLayout(objSerializeType), objSerializeType.TypeString); }
protected override void GetWriteObjectData(object obj, out SerializeType objSerializeType, out DataType dataType, out uint objId) { DataNode node = obj as DataNode; if (node == null) throw new InvalidOperationException("The XmlMetaFormatter can't serialize objects that do not derive from DataNode"); objSerializeType = null; objId = 0; dataType = node.NodeType; if (node is ObjectNode) objId = (node as ObjectNode).ObjId; else if (node is ObjectRefNode) objId = (node as ObjectRefNode).ObjRefId; }
/// <summary> /// Writes the specified structural object, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteStruct(object obj, SerializeType objSerializeType, uint id = 0) { ISerializable objAsCustom = obj as ISerializable; ISurrogate objSurrogate = this.GetSurrogateFor(objSerializeType.Type); // Write the structs data type this.writer.Write(objSerializeType.TypeString); this.writer.Write(id); this.writer.Write(objAsCustom != null); this.writer.Write(objSurrogate != null); if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; CustomSerialIO customIO = new CustomSerialIO(); try { objSurrogate.WriteConstructorData(customIO); } catch (Exception e) { this.LogCustomSerializationError(id, objSerializeType.Type, e); } customIO.Serialize(this); } if (objAsCustom != null) { CustomSerialIO customIO = new CustomSerialIO(); try { objAsCustom.WriteData(customIO); } catch (Exception e) { this.LogCustomSerializationError(id, objSerializeType.Type, e); } customIO.Serialize(this); } else { // Assure the type data layout has bee written (only once per file) this.WriteTypeDataLayout(objSerializeType); // Write omitted field bitmask bool[] fieldOmitted = new bool[objSerializeType.Fields.Length]; for (int i = 0; i < fieldOmitted.Length; i++) { fieldOmitted[i] = this.IsFieldBlocked(objSerializeType.Fields[i], obj); } this.WriteArrayData(fieldOmitted); // Write the structs fields for (int i = 0; i < objSerializeType.Fields.Length; i++) { if (fieldOmitted[i]) { continue; } this.WriteObjectData(objSerializeType.Fields[i].GetValue(obj)); } } }
protected override void WriteObjectBody(DataType dataType, object obj, SerializeType objSerializeType, uint objId) { if (dataType.IsPrimitiveType()) this.WritePrimitive(obj); else if (dataType == DataType.Enum) this.WriteEnum(obj as Enum, objSerializeType); else if (dataType == DataType.String) this.WriteString(obj as string); else if (dataType == DataType.Struct) this.WriteStruct(obj, objSerializeType); else if (dataType == DataType.ObjectRef) this.writer.Write(objId); else if (dataType == DataType.Array) this.WriteArray(obj, objSerializeType, objId); else if (dataType == DataType.Class) this.WriteStruct(obj, objSerializeType, objId); else if (dataType == DataType.Delegate) this.WriteDelegate(obj, objSerializeType, objId); else if (dataType.IsMemberInfoType()) this.WriteMemberInfo(obj, objId); }
protected override void WriteObjectBody(DataType dataType, object obj, SerializeType objSerializeType, uint objId) { if (dataType.IsPrimitiveType()) this.WritePrimitive((obj as PrimitiveNode).PrimitiveValue); else if (dataType == DataType.String) this.writer.WriteString((obj as StringNode).StringValue); else if (dataType == DataType.Enum) this.WriteEnum(obj as EnumNode); else if (dataType == DataType.Struct) this.WriteStruct(obj as StructNode); else if (dataType == DataType.ObjectRef) this.writer.WriteValue((obj as ObjectRefNode).ObjRefId); else if (dataType == DataType.Array) this.WriteArray(obj as ArrayNode); else if (dataType == DataType.Class) this.WriteStruct(obj as StructNode); else if (dataType == DataType.Delegate) this.WriteDelegate(obj as DelegateNode); else if (dataType.IsMemberInfoType()) this.WriteMemberInfo(obj as MemberInfoNode); }
/// <summary> /// Writes the specified structural object, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteStruct(object obj, SerializeType objSerializeType, uint id = 0) { ISerializable objAsCustom = obj as ISerializable; ISurrogate objSurrogate = this.GetSurrogateFor(objSerializeType.Type); // Write the structs data type this.writer.WriteAttributeString("type", objSerializeType.TypeString); if (id != 0) { this.writer.WriteAttributeString("id", XmlConvert.ToString(id)); } if (objAsCustom != null) { this.writer.WriteAttributeString("custom", XmlConvert.ToString(true)); } if (objSurrogate != null) { this.writer.WriteAttributeString("surrogate", XmlConvert.ToString(true)); } if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; CustomSerialIO customIO = new CustomSerialIO(CustomSerialIO.HeaderElement); try { objSurrogate.WriteConstructorData(customIO); } catch (Exception e) { this.LogCustomSerializationError(id, objSerializeType.Type, e); } customIO.Serialize(this); } if (objAsCustom != null) { CustomSerialIO customIO = new CustomSerialIO(CustomSerialIO.BodyElement); try { objAsCustom.WriteData(customIO); } catch (Exception e) { this.LogCustomSerializationError(id, objSerializeType.Type, e); } customIO.Serialize(this); } else { // Write the structs fields foreach (FieldInfo field in objSerializeType.Fields) { if (this.IsFieldBlocked(field, obj)) { continue; } this.WriteObjectData(field.GetValue(obj), field.Name); } } }
private void WriteTypeDataLayout(string typeString) { if (this.typeDataLayout.ContainsKey(typeString)) { long backRef = this.typeDataLayoutMap[typeString]; this.writer.Write(backRef); return; } Type resolved = this.ResolveType(typeString); SerializeType cached = GetSerializeType(resolved); TypeDataLayout layout = cached != null ? new TypeDataLayout(cached) : null; this.WriteTypeDataLayout(layout, typeString); }
/// <summary> /// Assigns the specified value to a specific array index. /// </summary> /// <param name="objSerializeType"></param> /// <param name="obj"></param> /// <param name="fieldName"></param> /// <param name="fieldValue"></param> protected void AssignValueToArray(SerializeType elementSerializeType, Array array, int index, object value) { if (array == null) { return; } if (value != null && !elementSerializeType.Type.IsInstanceOfType(value)) { this.LocalLog.WriteWarning( "Actual Type '{0}' of array element value at index {1} does not match reflected array element type '{2}'. Skipping item.", value != null ? Log.Type(value.GetType()) : "unknown", index, Log.Type(elementSerializeType.Type)); return; } array.SetValue(value, index); }
/// <summary> /// Returns the <see cref="SerializeType"/> of a Type. /// </summary> /// <param name="type"></param> /// <returns></returns> protected static SerializeType GetSerializeType(Type type) { if (type == null) { return(null); } SerializeType result; if (serializeTypeCache.TryGetValue(type, out result)) { return(result); } result = new SerializeType(type); serializeTypeCache[type] = result; return(result); }
protected override void WriteObjectBody(DataType dataType, object obj, SerializeType objSerializeType, uint objId) { if (dataType.IsPrimitiveType()) { this.WritePrimitive(obj); } else if (dataType == DataType.Enum) { this.WriteEnum(obj as Enum, objSerializeType); } else if (dataType == DataType.String) { this.WriteString(obj as string); } else if (dataType == DataType.Struct) { this.WriteStruct(obj, objSerializeType); } else if (dataType == DataType.ObjectRef) { this.writer.Write(objId); } else if (dataType == DataType.Array) { this.WriteArray(obj, objSerializeType, objId); } else if (dataType == DataType.Class) { this.WriteStruct(obj, objSerializeType, objId); } else if (dataType == DataType.Delegate) { this.WriteDelegate(obj, objSerializeType, objId); } else if (dataType.IsMemberInfoType()) { this.WriteMemberInfo(obj, objId); } }
private void WriteMemberInfo(XElement element, object obj, ObjectHeader header) { if (obj is Type) { Type type = obj as Type; SerializeType cachedType = GetSerializeType(type); element.SetAttributeValue("value", cachedType.TypeString); } else if (obj is MemberInfo) { MemberInfo member = obj as MemberInfo; element.SetAttributeValue("value", member.GetMemberId()); } else if (obj == null) { throw new ArgumentNullException("obj"); } else { throw new ArgumentException(string.Format("Type '{0}' is not a supported MemberInfo.", obj.GetType())); } }
/// <summary> /// Writes the specified <see cref="System.Array"/>, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteArray(object obj, SerializeType objSerializeType, uint id = 0) { Array objAsArray = obj as Array; if (objAsArray.Rank != 1) { throw new ArgumentException("Non single-Rank arrays are not supported"); } if (objAsArray.GetLowerBound(0) != 0) { throw new ArgumentException("Non zero-based arrays are not supported"); } this.writer.WriteAttributeString("type", objSerializeType.TypeString); if (id != 0) { this.writer.WriteAttributeString("id", XmlConvert.ToString(id)); } if (objAsArray.Rank != 1) { this.writer.WriteAttributeString("rank", XmlConvert.ToString(objAsArray.Rank)); } this.writer.WriteAttributeString("length", XmlConvert.ToString(objAsArray.Length)); if (objAsArray is byte[]) { byte[] byteArr = objAsArray as byte[]; this.writer.WriteString(this.ByteArrayToString(byteArr)); //for (int l = 0; l < byteArr.Length; l++) // this.writer.WriteString(byteArr[l].ToString("X2")); } else { for (long l = 0; l < objAsArray.Length; l++) { this.WriteObjectData(objAsArray.GetValue(l)); } } }
/// <summary> /// Writes the specified <see cref="System.Delegate"/>, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteDelegate(object obj, SerializeType objSerializeType, uint id = 0) { bool multi = obj is MulticastDelegate; // Write the delegates type this.writer.Write(objSerializeType.TypeString); this.writer.Write(id); this.writer.Write(multi); if (!multi) { Delegate objAsDelegate = obj as Delegate; this.WriteObjectData(objAsDelegate.Method); this.WriteObjectData(objAsDelegate.Target); } else { MulticastDelegate objAsDelegate = obj as MulticastDelegate; Delegate[] invokeList = objAsDelegate.GetInvocationList(); this.WriteObjectData(objAsDelegate.Method); this.WriteObjectData(objAsDelegate.Target); this.WriteObjectData(invokeList); } }
/// <summary> /// Writes the specified <see cref="System.Enum"/>. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> protected void WriteEnum(Enum obj, SerializeType objSerializeType) { this.writer.Write(objSerializeType.TypeString); this.writer.Write(obj.ToString()); this.writer.Write(Convert.ToInt64(obj)); }
/// <summary> /// Writes the specified <see cref="System.Delegate"/>, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteDelegate(object obj, SerializeType objSerializeType, uint id = 0) { bool multi = obj is MulticastDelegate; // Write the delegates type this.writer.Write(objSerializeType.TypeString); this.writer.Write(id); this.writer.Write(multi); if (!multi) { Delegate objAsDelegate = obj as Delegate; this.WriteObject(objAsDelegate.Method); this.WriteObject(objAsDelegate.Target); } else { MulticastDelegate objAsDelegate = obj as MulticastDelegate; Delegate[] invokeList = objAsDelegate.GetInvocationList(); this.WriteObject(objAsDelegate.Method); this.WriteObject(objAsDelegate.Target); this.WriteObject(invokeList); } }
/// <summary> /// Writes the specified <see cref="System.Delegate"/>, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteDelegate(object obj, SerializeType objSerializeType, uint id = 0) { bool multi = obj is MulticastDelegate; // Write the delegates type this.writer.WriteAttributeString("type", objSerializeType.TypeString); if (id != 0) this.writer.WriteAttributeString("id", XmlConvert.ToString(id)); if (multi) this.writer.WriteAttributeString("multi", XmlConvert.ToString(multi)); if (!multi) { Delegate objAsDelegate = obj as Delegate; this.WriteObjectData(objAsDelegate.Method); this.WriteObjectData(objAsDelegate.Target); } else { MulticastDelegate objAsDelegate = obj as MulticastDelegate; Delegate[] invokeList = objAsDelegate.GetInvocationList(); this.WriteObjectData(objAsDelegate.Method); this.WriteObjectData(objAsDelegate.Target); this.WriteObjectData(invokeList); } }
/// <summary> /// Writes the specified <see cref="System.Array"/>, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteArray(object obj, SerializeType objSerializeType, uint id = 0) { Array objAsArray = obj as Array; if (objAsArray.Rank != 1) { throw new ArgumentException("Non single-Rank arrays are not supported"); } if (objAsArray.GetLowerBound(0) != 0) { throw new ArgumentException("Non zero-based arrays are not supported"); } this.writer.Write(objSerializeType.TypeString); this.writer.Write(id); this.writer.Write(objAsArray.Rank); this.writer.Write(objAsArray.Length); if (objAsArray is bool[]) { this.WriteArrayData(objAsArray as bool[]); } else if (objAsArray is byte[]) { this.WriteArrayData(objAsArray as byte[]); } else if (objAsArray is sbyte[]) { this.WriteArrayData(objAsArray as sbyte[]); } else if (objAsArray is short[]) { this.WriteArrayData(objAsArray as short[]); } else if (objAsArray is ushort[]) { this.WriteArrayData(objAsArray as ushort[]); } else if (objAsArray is int[]) { this.WriteArrayData(objAsArray as int[]); } else if (objAsArray is uint[]) { this.WriteArrayData(objAsArray as uint[]); } else if (objAsArray is long[]) { this.WriteArrayData(objAsArray as long[]); } else if (objAsArray is ulong[]) { this.WriteArrayData(objAsArray as ulong[]); } else if (objAsArray is float[]) { this.WriteArrayData(objAsArray as float[]); } else if (objAsArray is double[]) { this.WriteArrayData(objAsArray as double[]); } else if (objAsArray is decimal[]) { this.WriteArrayData(objAsArray as decimal[]); } else if (objAsArray is char[]) { this.WriteArrayData(objAsArray as char[]); } else if (objAsArray is string[]) { this.WriteArrayData(objAsArray as string[]); } else { for (long l = 0; l < objAsArray.Length; l++) { this.WriteObjectData(objAsArray.GetValue(l)); } } }
/// <summary> /// Reads a structural object, including referenced objects. /// </summary> /// <returns>The object that has been read.</returns> protected object ReadStruct() { // Read struct type string objTypeString = this.reader.GetAttribute("type"); string objIdString = this.reader.GetAttribute("id"); string customString = this.reader.GetAttribute("custom"); string surrogateString = this.reader.GetAttribute("surrogate"); uint objId = objIdString == null ? 0 : XmlConvert.ToUInt32(objIdString); bool custom = customString != null && XmlConvert.ToBoolean(customString); bool surrogate = surrogateString != null && XmlConvert.ToBoolean(surrogateString); Type objType = this.ResolveType(objTypeString, objId); SerializeType objSerializeType = null; if (objType != null) { objSerializeType = objType.GetSerializeType(); } // Retrieve surrogate if requested ISurrogate objSurrogate = null; if (surrogate && objType != null) { objSurrogate = this.GetSurrogateFor(objType); } // Construct object object obj = null; if (objType != null) { if (objSurrogate != null) { custom = true; // Set fake object reference for surrogate constructor: No self-references allowed here. this.idManager.Inject(null, objId); CustomSerialIO customIO = new CustomSerialIO(CustomSerialIO.HeaderElement); customIO.Deserialize(this); try { obj = objSurrogate.ConstructObject(customIO, objType); } catch (Exception e) { this.LogCustomDeserializationError(objId, objType, e); } } if (obj == null) { obj = objType.CreateInstanceOf(); } if (obj == null) { obj = objType.CreateInstanceOf(true); } } // Prepare object reference this.idManager.Inject(obj, objId); // Read custom object data if (custom) { CustomSerialIO customIO = new CustomSerialIO(CustomSerialIO.BodyElement); customIO.Deserialize(this); ISerializable objAsCustom; if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; } else { objAsCustom = obj as ISerializable; } if (objAsCustom != null) { try { objAsCustom.ReadData(customIO); } catch (Exception e) { this.LogCustomDeserializationError(objId, objType, e); } } else if (obj != null && objType != null) { this.SerializationLog.WriteWarning( "Object data (Id {0}) is flagged for custom deserialization, yet the objects Type ('{1}') does not support it. Guessing associated fields...", objId, Log.Type(objType)); this.SerializationLog.PushIndent(); foreach (var pair in customIO.Data) { this.AssignValueToField(objSerializeType, obj, pair.Key, pair.Value); } this.SerializationLog.PopIndent(); } } // Red non-custom object data else if (!this.reader.IsEmptyElement) { // Read fields bool scopeChanged; string fieldName; object fieldValue; while (true) { fieldValue = this.ReadObjectData(out fieldName, out scopeChanged); if (scopeChanged) { break; } this.AssignValueToField(objSerializeType, obj, fieldName, fieldValue); } } return(obj); }
/// <summary> /// Reads a structural object, including referenced objects. /// </summary> /// <returns>The object that has been read.</returns> protected object ReadStruct() { // Read struct type string objTypeString = this.reader.ReadString(); uint objId = this.reader.ReadUInt32(); bool custom = this.reader.ReadBoolean(); bool surrogate = this.reader.ReadBoolean(); Type objType = this.ResolveType(objTypeString, objId); SerializeType objSerializeType = null; if (objType != null) { objSerializeType = objType.GetSerializeType(); } // Retrieve surrogate if requested ISurrogate objSurrogate = null; if (surrogate && objType != null) { objSurrogate = this.GetSurrogateFor(objType); } // Construct object object obj = null; if (objType != null) { if (objSurrogate != null) { custom = true; // Set fake object reference for surrogate constructor: No self-references allowed here. this.idManager.Inject(null, objId); CustomSerialIO customIO = new CustomSerialIO(); customIO.Deserialize(this); try { obj = objSurrogate.ConstructObject(customIO, objType); } catch (Exception e) { this.LogCustomDeserializationError(objId, objType, e); } } if (obj == null) { obj = objType.CreateInstanceOf(); } if (obj == null) { obj = objType.CreateInstanceOf(true); } } // Prepare object reference this.idManager.Inject(obj, objId); // Read custom object data if (custom) { CustomSerialIO customIO = new CustomSerialIO(); customIO.Deserialize(this); ISerializable objAsCustom; if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; } else { objAsCustom = obj as ISerializable; } if (objAsCustom != null) { try { objAsCustom.ReadData(customIO); } catch (Exception e) { this.LogCustomDeserializationError(objId, objType, e); } } else if (obj != null && objType != null) { this.SerializationLog.WriteWarning( "Object data (Id {0}) is flagged for custom deserialization, yet the objects Type ('{1}') does not support it. Guessing associated fields...", objId, Log.Type(objType)); this.SerializationLog.PushIndent(); foreach (var pair in customIO.Data) { this.AssignValueToField(objSerializeType, obj, pair.Key, pair.Value); } this.SerializationLog.PopIndent(); } } // Red non-custom object data else { // Determine data layout TypeDataLayout layout = this.ReadTypeDataLayout(objTypeString); // Read fields if (this.dataVersion <= 2) { for (int i = 0; i < layout.Fields.Length; i++) { object fieldValue = this.ReadObjectData(); this.AssignValueToField(objSerializeType, obj, layout.Fields[i].name, fieldValue); } } else if (this.dataVersion >= 3) { bool[] fieldOmitted = new bool[layout.Fields.Length]; this.ReadArrayData(fieldOmitted); for (int i = 0; i < layout.Fields.Length; i++) { if (fieldOmitted[i]) { continue; } object fieldValue = this.ReadObjectData(); this.AssignValueToField(objSerializeType, obj, layout.Fields[i].name, fieldValue); } } } return(obj); }
/// <summary> /// Writes the specified <see cref="System.Enum"/>. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> protected void WriteEnum(Enum obj, SerializeType objSerializeType) { this.writer.WriteAttributeString("type", objSerializeType.TypeString); this.writer.WriteAttributeString("name", obj.ToString()); this.writer.WriteAttributeString("value", XmlConvert.ToString(Convert.ToInt64(obj))); }
/// <summary> /// Assigns the specified value to an objects field. /// </summary> /// <param name="objSerializeType"></param> /// <param name="obj"></param> /// <param name="fieldName"></param> /// <param name="fieldValue"></param> protected void AssignValueToField(SerializeType objSerializeType, object obj, string fieldName, object fieldValue) { if (obj == null) { return; } // Retrieve field FieldInfo field = null; if (objSerializeType != null) { field = objSerializeType.Fields.FirstOrDefault(f => f.Name == fieldName); if (field == null) { field = ReflectionHelper.ResolveMember("F:" + objSerializeType.TypeString + ":" + fieldName, false) as FieldInfo; } } if (field == null) { this.HandleAssignValueToField(objSerializeType, obj, fieldName, fieldValue); return; } if (field.IsNotSerialized) { this.HandleAssignValueToField(objSerializeType, obj, fieldName, fieldValue); return; } if (fieldValue != null && !field.FieldType.IsInstanceOfType(fieldValue)) { if (!this.HandleAssignValueToField(objSerializeType, obj, fieldName, fieldValue)) { this.SerializationLog.WriteWarning("Actual Type '{0}' of object value in field '{1}' does not match reflected FieldType '{2}'. Trying to convert...'", fieldValue != null ? Log.Type(fieldValue.GetType()) : "unknown", fieldName, Log.Type(field.FieldType)); this.SerializationLog.PushIndent(); object castVal; try { castVal = Convert.ChangeType(fieldValue, field.FieldType, System.Globalization.CultureInfo.InvariantCulture); this.SerializationLog.Write("...succeeded! Assigning value '{0}'", castVal); field.SetValue(obj, castVal); } catch (Exception) { this.SerializationLog.WriteWarning("...failed! Discarding value '{0}'", fieldValue); } this.SerializationLog.PopIndent(); } return; } if (fieldValue == null && field.FieldType.IsValueType) { fieldValue = field.FieldType.CreateInstanceOf(); } field.SetValue(obj, fieldValue); }
/// <summary> /// Writes the specified structural object, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteStruct(object obj, SerializeType objSerializeType, uint id = 0) { ISerializable objAsCustom = obj as ISerializable; ISurrogate objSurrogate = this.GetSurrogateFor(objSerializeType.Type); // Write the structs data type this.writer.Write(objSerializeType.TypeString); this.writer.Write(id); this.writer.Write(objAsCustom != null); this.writer.Write(objSurrogate != null); if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; CustomSerialIO customIO = new CustomSerialIO(); try { objSurrogate.WriteConstructorData(customIO); } catch (Exception e) { this.LogCustomSerializationError(id, objSerializeType.Type, e); } customIO.Serialize(this); } if (objAsCustom != null) { CustomSerialIO customIO = new CustomSerialIO(); try { objAsCustom.WriteData(customIO); } catch (Exception e) { this.LogCustomSerializationError(id, objSerializeType.Type, e); } customIO.Serialize(this); } else { // Assure the type data layout has bee written (only once per file) this.WriteTypeDataLayout(objSerializeType); // Write omitted field bitmask bool[] fieldOmitted = new bool[objSerializeType.Fields.Length]; for (int i = 0; i < fieldOmitted.Length; i++) { fieldOmitted[i] = this.IsFieldBlocked(objSerializeType.Fields[i], obj); } this.WriteArrayData(fieldOmitted); // Write the structs fields for (int i = 0; i < objSerializeType.Fields.Length; i++) { if (fieldOmitted[i]) continue; this.WriteObject(objSerializeType.Fields[i].GetValue(obj)); } } }
/// <summary> /// Writes the specified structural object, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteStruct(object obj, SerializeType objSerializeType, uint id = 0) { ISerializable objAsCustom = obj as ISerializable; ISurrogate objSurrogate = this.GetSurrogateFor(objSerializeType.Type); // Write the structs data type this.writer.WriteAttributeString("type", objSerializeType.TypeString); if (id != 0) this.writer.WriteAttributeString("id", XmlConvert.ToString(id)); if (objAsCustom != null) this.writer.WriteAttributeString("custom", XmlConvert.ToString(true)); if (objSurrogate != null) this.writer.WriteAttributeString("surrogate", XmlConvert.ToString(true)); if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; CustomSerialIO customIO = new CustomSerialIO(CustomSerialIO.HeaderElement); try { objSurrogate.WriteConstructorData(customIO); } catch (Exception e) { this.LogCustomSerializationError(id, objSerializeType.Type, e); } customIO.Serialize(this); } if (objAsCustom != null) { CustomSerialIO customIO = new CustomSerialIO(CustomSerialIO.BodyElement); try { objAsCustom.WriteData(customIO); } catch (Exception e) { this.LogCustomSerializationError(id, objSerializeType.Type, e); } customIO.Serialize(this); } else { // Write the structs fields foreach (FieldInfo field in objSerializeType.Fields) { if (this.IsFieldBlocked(field, obj)) continue; this.WriteObjectData(field.GetValue(obj), field.Name); } } }
/// <summary> /// Writes the body of a given object. /// </summary> /// <param name="dataType">The <see cref="Duality.Serialization.DataType"/> as which the object will be written.</param> /// <param name="obj">The object to be written.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> that describes the specified object.</param> /// <param name="objId">An object id that is assigned to the specified object.</param> protected abstract void WriteObjectBody(DataType dataType, object obj, SerializeType objSerializeType, uint objId);
private Array ReadArray(XElement element, ObjectHeader header) { Array arrObj; Type elementType = (header.ObjectType != null) ? header.ObjectType.GetElementType() : null; // Determine the array length based on child elements or explicit value string explicitLengthString = element.GetAttributeValue("length"); int explicitLength = explicitLengthString == null ? -1 : XmlConvert.ToInt32(explicitLengthString); // Expect the "complex" array format, if there are child elements or an explicit length (children may be omitted) bool isComplex = element.Elements().Any() || explicitLength != -1; bool isEmpty = explicitLength == 0 || (!isComplex && string.IsNullOrEmpty(element.Value)); // Early-out: Create an empty array if (isEmpty) { arrObj = elementType != null?Array.CreateInstance(elementType, 0) : null; this.idManager.Inject(arrObj, header.ObjectId); } // Read a primitive value array else if (!isComplex) { if (elementType == typeof(bool)) { bool[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(byte)) { byte[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(sbyte)) { sbyte[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(short)) { short[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(ushort)) { ushort[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(int)) { int[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(uint)) { uint[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(long)) { long[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(ulong)) { ulong[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(float)) { float[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(double)) { double[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(decimal)) { decimal[] array; this.ReadArrayData(element, out array); arrObj = array; } else { this.LocalLog.WriteWarning("Can't read primitive value array. Unknown element type '{0}'. Discarding data.", Log.Type(elementType)); arrObj = elementType != null?Array.CreateInstance(elementType, 0) : null; } // Set object reference this.idManager.Inject(arrObj, header.ObjectId); } // Read a complex value array, where each item is an XML element else { SerializeType elementSerializeType = GetSerializeType(elementType); int arrLength = explicitLength != -1 ? explicitLength : element.Elements().Count(); // Prepare object reference arrObj = elementType != null?Array.CreateInstance(elementType, arrLength) : null; this.idManager.Inject(arrObj, header.ObjectId); int itemIndex = 0; foreach (XElement itemElement in element.Elements()) { object item = this.ReadObjectData(itemElement); this.AssignValueToArray(elementSerializeType, arrObj, itemIndex, item); itemIndex++; if (itemIndex >= arrLength) { break; } } } return(arrObj); }
/// <summary> /// Writes the specified structural object, including references objects. /// </summary> /// <param name="obj">The object to write.</param> /// <param name="objSerializeType">The <see cref="Duality.Serialization.SerializeType"/> describing the object.</param> /// <param name="id">The objects id.</param> protected void WriteStruct(object obj, SerializeType objSerializeType, uint id = 0) { ISerializable objAsCustom = obj as ISerializable; ISurrogate objSurrogate = this.GetSurrogateFor(objSerializeType.Type); // Write the structs data type this.writer.Write(objSerializeType.TypeString); this.writer.Write(id); this.writer.Write(objAsCustom != null); this.writer.Write(objSurrogate != null); if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; CustomSerialIO customIO = new CustomSerialIO(); try { objSurrogate.WriteConstructorData(customIO); } catch (Exception e) { this.LogCustomSerializationError(id, objSerializeType.Type, e); } customIO.Serialize(this); } if (objAsCustom != null) { CustomSerialIO customIO = new CustomSerialIO(); try { objAsCustom.WriteData(customIO); } catch (Exception e) { this.LogCustomSerializationError(id, objSerializeType.Type, e); } customIO.Serialize(this); } else { // Assure the type data layout has bee written (only once per file) this.WriteTypeDataLayout(objSerializeType); // Write the structs fields foreach (FieldInfo field in objSerializeType.Fields) { object val = field.GetValue(obj); if (val != null && this.IsFieldBlocked(field)) val = field.FieldType.GetDefaultInstanceOf(); this.WriteObject(val); } } }
private bool HandleAssignValueToField(SerializeType objSerializeType, object obj, string fieldName, object fieldValue) { AssignFieldError error = new AssignFieldError(objSerializeType, obj, fieldName, fieldValue); return(ReflectionHelper.HandleSerializeError(error)); }
private Array ReadArray(ObjectHeader header) { int arrRank = this.reader.ReadInt32(); int arrLength = this.reader.ReadInt32(); Type elementType = header.ObjectType.GetElementType(); // Prepare object reference Array arrObj = header.ObjectType != null?Array.CreateInstance(elementType, arrLength) : null; this.idManager.Inject(arrObj, header.ObjectId); if (elementType == typeof(bool)) { this.ReadArrayData(arrObj as bool[]); } else if (elementType == typeof(byte)) { this.ReadArrayData(arrObj as byte[]); } else if (elementType == typeof(sbyte)) { this.ReadArrayData(arrObj as sbyte[]); } else if (elementType == typeof(short)) { this.ReadArrayData(arrObj as short[]); } else if (elementType == typeof(ushort)) { this.ReadArrayData(arrObj as ushort[]); } else if (elementType == typeof(int)) { this.ReadArrayData(arrObj as int[]); } else if (elementType == typeof(uint)) { this.ReadArrayData(arrObj as uint[]); } else if (elementType == typeof(long)) { this.ReadArrayData(arrObj as long[]); } else if (elementType == typeof(ulong)) { this.ReadArrayData(arrObj as ulong[]); } else if (elementType == typeof(float)) { this.ReadArrayData(arrObj as float[]); } else if (elementType == typeof(double)) { this.ReadArrayData(arrObj as double[]); } else if (elementType == typeof(decimal)) { this.ReadArrayData(arrObj as decimal[]); } else if (elementType == typeof(char)) { this.ReadArrayData(arrObj as char[]); } else if (elementType == typeof(string)) { this.ReadArrayData(arrObj as string[]); } else { SerializeType elementSerializeType = GetSerializeType(elementType); // If it's serialized as a value type array and the format version supports it, we can take the fast path bool valueTypeArray = false; if (this.dataVersion >= 5) { valueTypeArray = this.reader.ReadBoolean(); } if (valueTypeArray) { object defaultValue = elementSerializeType.Type.GetDefaultOf(); // In a value type array all elements are the exact same type ObjectHeader sharedHeader = null; sharedHeader = new ObjectHeader(0, elementSerializeType.DataType, elementSerializeType); for (int l = 0; l < arrLength; l++) { object element = null; // Read the current element or assume the default value bool isNonDefault = this.reader.ReadBoolean(); if (isNonDefault) { element = this.ReadObjectBody(sharedHeader); } else { element = defaultValue; } if (arrObj != null) { arrObj.SetValue(element, l); } } } // Otherwise, each element requires a full object entry else { for (int l = 0; l < arrLength; l++) { object elem = this.ReadObjectData(); if (arrObj != null) { arrObj.SetValue(elem, l); } } } } return(arrObj); }