예제 #1
0
 private void WriteTypeDataLayout(TypeDataLayout layout, string typeString)
 {
     this.typeDataLayout[typeString] = layout;
     this.writer.Write(-1L);
     this.typeDataLayoutMap[typeString] = this.writer.BaseStream.Position;
     layout.Write(this.writer);
 }
예제 #2
0
        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);
        }
예제 #3
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);
        }
예제 #4
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.SerializeType != null)
            {
                custom       = true;
                objSurrogate = header.SerializeType.Surrogate;
                if (objSurrogate == null)
                {
                    this.LocalLog.WriteError(
                        "Object type '{0}' was serialized using a surrogate, but no such surrogate was found for deserialization.",
                        LogFormat.Type(header.SerializeType.Type));
                }
            }

            // If the object was serialized as a surrogate, deserialize its header first
            CustomSerialIO surrogateHeader = null;

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

                surrogateHeader = new CustomSerialIO();
                surrogateHeader.Deserialize(this);
            }

            // Construct object
            object obj = null;

            if (header.ObjectType != null)
            {
                if (objSurrogate != null)
                {
                    try { obj = objSurrogate.ConstructObject(surrogateHeader, 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,
                        LogFormat.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
                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);
        }
예제 #5
0
		/// <summary>
		/// Initializes a TypeDataLayout by cloning an existing TypeDataLayout.
		/// </summary>
		/// <param name="t">The source layout</param>
		public TypeDataLayout(TypeDataLayout t)
		{
			this.fields = t.fields != null ? t.fields.Clone() as FieldDataInfo[] : null;
		}
예제 #6
0
 /// <summary>
 /// Initializes a TypeDataLayout by cloning an existing TypeDataLayout.
 /// </summary>
 /// <param name="t">The source layout</param>
 public TypeDataLayout(TypeDataLayout t)
 {
     this.fields = t.fields != null?t.fields.Clone() as FieldDataInfo[] : null;
 }