Example #1
0
        /// <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);
        }
Example #2
0
        /// <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);
        }