示例#1
0
        private object ReadStruct(XElement element, ObjectHeader header)
        {
            // Read struct type
            string customString    = element.GetAttributeValue("custom");
            string surrogateString = element.GetAttributeValue("surrogate");
            bool   custom          = customString != null && XmlConvert.ToBoolean(customString);
            bool   surrogate       = surrogateString != null && XmlConvert.ToBoolean(surrogateString);

            // Retrieve surrogate if requested
            ISerializeSurrogate objSurrogate = null;

            if (surrogate && header.ObjectType != null)
            {
                objSurrogate = GetSurrogateFor(header.ObjectType);
            }

            // Construct object
            object obj = null;

            if (header.ObjectType != null)
            {
                if (objSurrogate != null)
                {
                    custom = true;

                    // Set fake object reference for surrogate constructor: No self-references allowed here.
                    this.idManager.Inject(null, header.ObjectId);

                    CustomSerialIO customIO            = new CustomSerialIO();
                    XElement       customHeaderElement = element.Element(CustomSerialIO.HeaderElement) ?? element.Elements().FirstOrDefault();
                    if (customHeaderElement != null)
                    {
                        customIO.Deserialize(this, customHeaderElement);
                    }
                    try { obj = objSurrogate.ConstructObject(customIO, header.ObjectType); }
                    catch (Exception e) { this.LogCustomDeserializationError(header.ObjectId, header.ObjectType, e); }
                }
                if (obj == null)
                {
                    obj = header.ObjectType.CreateInstanceOf();
                }
            }

            // Prepare object reference
            this.idManager.Inject(obj, header.ObjectId);

            // Read custom object data
            if (custom)
            {
                CustomSerialIO customIO          = new CustomSerialIO();
                XElement       customBodyElement = element.Element(CustomSerialIO.BodyElement) ?? element.Elements().ElementAtOrDefault(1);
                if (customBodyElement != null)
                {
                    customIO.Deserialize(this, customBodyElement);
                }

                ISerializeExplicit objAsCustom;
                if (objSurrogate != null)
                {
                    objSurrogate.RealObject = obj;
                    objAsCustom             = objSurrogate.SurrogateObject;
                }
                else
                {
                    objAsCustom = obj as ISerializeExplicit;
                }

                if (objAsCustom != null)
                {
                    try { objAsCustom.ReadData(customIO); }
                    catch (Exception e) { this.LogCustomDeserializationError(header.ObjectId, header.ObjectType, e); }
                }
                else if (obj != null && header.ObjectType != null)
                {
                    this.LocalLog.WriteWarning(
                        "Object data (Id {0}) is flagged for custom deserialization, yet the objects Type ('{1}') does not support it. Guessing associated fields...",
                        header.ObjectId,
                        Log.Type(header.ObjectType));
                    this.LocalLog.PushIndent();
                    foreach (var pair in customIO.Data)
                    {
                        this.AssignValueToField(header.SerializeType, obj, pair.Key, pair.Value);
                    }
                    this.LocalLog.PopIndent();
                }
            }
            // Red non-custom object data
            else if (!element.IsEmpty)
            {
                // Read fields
                object fieldValue;
                foreach (XElement fieldElement in element.Elements())
                {
                    fieldValue = this.ReadObjectData(fieldElement);
                    this.AssignValueToField(header.SerializeType, obj, GetCodeElementName(fieldElement.Name.LocalName), fieldValue);
                }
            }

            return(obj);
        }
示例#2
0
        private object ReadStruct(ObjectHeader header)
        {
            // Read struct type
            bool custom    = this.reader.ReadBoolean();
            bool surrogate = this.reader.ReadBoolean();

            // Retrieve surrogate if requested
            ISerializeSurrogate objSurrogate = null;

            if (surrogate && header.ObjectType != null)
            {
                objSurrogate = GetSurrogateFor(header.ObjectType);
            }

            // Construct object
            object obj = null;

            if (header.ObjectType != null)
            {
                if (objSurrogate != null)
                {
                    custom = true;

                    // Set fake object reference for surrogate constructor: No self-references allowed here.
                    this.idManager.Inject(null, header.ObjectId);

                    CustomSerialIO customIO = new CustomSerialIO();
                    customIO.Deserialize(this);
                    try { obj = objSurrogate.ConstructObject(customIO, header.ObjectType); }
                    catch (Exception e) { this.LogCustomDeserializationError(header.ObjectId, header.ObjectType, e); }
                }
                if (obj == null)
                {
                    obj = header.ObjectType.CreateInstanceOf();
                }
            }

            // Prepare object reference
            this.idManager.Inject(obj, header.ObjectId);

            // Read custom object data
            if (custom)
            {
                CustomSerialIO customIO = new CustomSerialIO();
                customIO.Deserialize(this);

                ISerializeExplicit objAsCustom;
                if (objSurrogate != null)
                {
                    objSurrogate.RealObject = obj;
                    objAsCustom             = objSurrogate.SurrogateObject;
                }
                else
                {
                    objAsCustom = obj as ISerializeExplicit;
                }

                if (objAsCustom != null)
                {
                    try { objAsCustom.ReadData(customIO); }
                    catch (Exception e) { this.LogCustomDeserializationError(header.ObjectId, header.ObjectType, e); }
                }
                else if (obj != null && header.ObjectType != null)
                {
                    this.LocalLog.WriteWarning(
                        "Object data (Id {0}) is flagged for custom deserialization, yet the objects Type ('{1}') does not support it. Guessing associated fields...",
                        header.ObjectId,
                        Log.Type(header.ObjectType));
                    this.LocalLog.PushIndent();
                    foreach (var pair in customIO.Data)
                    {
                        this.AssignValueToField(header.SerializeType, obj, pair.Key, pair.Value);
                    }
                    this.LocalLog.PopIndent();
                }
            }
            // Red non-custom object data
            else
            {
                // Determine data layout
                TypeDataLayout layout = this.ReadTypeDataLayout(header.TypeString);

                // Read fields
                if (this.dataVersion <= 2)
                {
                    for (int i = 0; i < layout.Fields.Length; i++)
                    {
                        object fieldValue = this.ReadObjectData();
                        this.AssignValueToField(header.SerializeType, 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(header.SerializeType, obj, layout.Fields[i].name, fieldValue);
                    }
                }
            }

            return(obj);
        }