Example #1
0
        /// <summary>
        /// Creates a new SerializeType based on a <see cref="System.Type"/>, gathering all the information that is necessary for serialization.
        /// </summary>
        /// <param name="t"></param>
        public SerializeType(Type t)
        {
            this.type          = t.GetTypeInfo();
            this.typeString    = t.GetTypeId();
            this.dataType      = GetDataType(this.type);
            this.dontSerialize = this.type.HasAttributeCached <DontSerializeAttribute>();
            this.defaultValue  = this.type.GetDefaultOf();
            this.surrogate     = Serializer.GetSurrogateFor(this.type);

            if (this.dataType == DataType.Struct && this.surrogate == null)
            {
                // Retrieve all fields that are not flagged not to be serialized
                List <FieldInfo> filteredFields = this.type
                                                  .DeclaredFieldsDeep()
                                                  .Where(f => !f.IsStatic && !f.HasAttributeCached <DontSerializeAttribute>())
                                                  .ToList();

                // Hack: Remove some specific fields based on an internal blacklist
                this.RemoveBlacklistedFields(filteredFields);

                // Store the filtered fields in a fixed form
                this.fields = filteredFields.ToArray();
                this.fields.StableSort((a, b) => string.Compare(a.Name, b.Name));
            }
            else
            {
                this.fields = new FieldInfo[0];
            }
        }
Example #2
0
        private void WriteStruct(object obj, ObjectHeader header)
        {
            ISerializeExplicit  objAsCustom  = obj as ISerializeExplicit;
            ISerializeSurrogate objSurrogate = GetSurrogateFor(header.ObjectType);

            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(header.ObjectId, header.ObjectType, e); }
                customIO.Serialize(this);
            }

            if (objAsCustom != null)
            {
                CustomSerialIO customIO = new CustomSerialIO();
                try { objAsCustom.WriteData(customIO); }
                catch (Exception e) { this.LogCustomSerializationError(header.ObjectId, header.ObjectType, e); }
                customIO.Serialize(this);
            }
            else
            {
                // Assure the type data layout has been written (only once per file)
                this.WriteTypeDataLayout(header.SerializeType);

                // If we're serializing a value type, skip the entire object body if
                // it equals the zero-init struct. This will keep struct-heavy data a lot
                // smaller binary-wise.
                bool skipEntireBody =
                    header.ObjectType.IsValueType &&
                    object.Equals(obj, header.SerializeType.DefaultValue);

                // Write omitted field bitmask
                bool[] fieldOmitted = new bool[header.SerializeType.Fields.Length];
                for (int i = 0; i < fieldOmitted.Length; i++)
                {
                    fieldOmitted[i] = skipEntireBody || this.IsFieldBlocked(header.SerializeType.Fields[i], obj);
                }
                this.WriteArrayData(fieldOmitted);

                // Write the structs fields
                for (int i = 0; i < header.SerializeType.Fields.Length; i++)
                {
                    if (fieldOmitted[i])
                    {
                        continue;
                    }
                    this.WriteObjectData(header.SerializeType.Fields[i].GetValue(obj));
                }
            }
        }
Example #3
0
        private void WriteStruct(XElement element, object obj, ObjectHeader header)
        {
            ISerializeExplicit  objAsCustom  = obj as ISerializeExplicit;
            ISerializeSurrogate objSurrogate = GetSurrogateFor(header.ObjectType);

            // Write the structs data type
            if (objAsCustom != null)
            {
                element.SetAttributeValue("custom", XmlConvert.ToString(true));
            }
            if (objSurrogate != null)
            {
                element.SetAttributeValue("surrogate", XmlConvert.ToString(true));
            }

            if (objSurrogate != null)
            {
                objSurrogate.RealObject = obj;
                objAsCustom             = objSurrogate.SurrogateObject;

                CustomSerialIO customIO = new CustomSerialIO();
                try { objSurrogate.WriteConstructorData(customIO); }
                catch (Exception e) { this.LogCustomSerializationError(header.ObjectId, header.ObjectType, e); }

                XElement customHeaderElement = new XElement(CustomSerialIO.HeaderElement);
                element.Add(customHeaderElement);
                customIO.Serialize(this, customHeaderElement);
            }

            if (objAsCustom != null)
            {
                CustomSerialIO customIO = new CustomSerialIO();
                try { objAsCustom.WriteData(customIO); }
                catch (Exception e) { this.LogCustomSerializationError(header.ObjectId, header.ObjectType, e); }

                XElement customBodyElement = new XElement(CustomSerialIO.BodyElement);
                element.Add(customBodyElement);
                customIO.Serialize(this, customBodyElement);
            }
            else
            {
                // Write the structs fields
                foreach (FieldInfo field in header.SerializeType.Fields)
                {
                    if (this.IsFieldBlocked(field, obj))
                    {
                        continue;
                    }

                    XElement fieldElement = new XElement(GetXmlElementName(field.Name));
                    element.Add(fieldElement);

                    this.WriteObjectData(fieldElement, field.GetValue(obj));
                }
            }
        }
Example #4
0
        private void WriteStruct(object obj, ObjectHeader header)
        {
            ISerializeExplicit  objAsCustom  = obj as ISerializeExplicit;
            ISerializeSurrogate objSurrogate = GetSurrogateFor(header.ObjectType);

            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(header.ObjectId, header.ObjectType, e); }
                customIO.Serialize(this);
            }

            if (objAsCustom != null)
            {
                CustomSerialIO customIO = new CustomSerialIO();
                try { objAsCustom.WriteData(customIO); }
                catch (Exception e) { this.LogCustomSerializationError(header.ObjectId, header.ObjectType, e); }
                customIO.Serialize(this);
            }
            else
            {
                // Assure the type data layout has been written (only once per file)
                this.WriteTypeDataLayout(header.SerializeType);

                // Write omitted field bitmask
                bool[] fieldOmitted = new bool[header.SerializeType.Fields.Length];
                for (int i = 0; i < fieldOmitted.Length; i++)
                {
                    fieldOmitted[i] = this.IsFieldBlocked(header.SerializeType.Fields[i], obj);
                }
                this.WriteArrayData(fieldOmitted);

                // Write the structs fields
                for (int i = 0; i < header.SerializeType.Fields.Length; i++)
                {
                    if (fieldOmitted[i])
                    {
                        continue;
                    }
                    this.WriteObjectData(header.SerializeType.Fields[i].GetValue(obj));
                }
            }
        }
        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);
        }
        private void WriteStruct(XElement element, object obj, ObjectHeader header)
        {
            ISerializeExplicit  objAsCustom  = obj as ISerializeExplicit;
            ISerializeSurrogate objSurrogate = GetSurrogateFor(header.ObjectType);

            // If we're serializing a value type, skip the entire object body if
            // it equals the zero-init struct. This will keep struct-heavy data a lot
            // more concise.
            if (header.ObjectType.IsValueType &&
                object.Equals(obj, header.SerializeType.DefaultValue))
            {
                return;
            }

            // Write information about custom or surrogate serialization
            if (objAsCustom != null)
            {
                element.SetAttributeValue("custom", XmlConvert.ToString(true));
            }
            if (objSurrogate != null)
            {
                element.SetAttributeValue("surrogate", XmlConvert.ToString(true));
            }

            if (objSurrogate != null)
            {
                objSurrogate.RealObject = obj;
                objAsCustom             = objSurrogate.SurrogateObject;

                CustomSerialIO customIO = new CustomSerialIO();
                try { objSurrogate.WriteConstructorData(customIO); }
                catch (Exception e) { this.LogCustomSerializationError(header.ObjectId, header.ObjectType, e); }

                XElement customHeaderElement = new XElement(CustomSerialIO.HeaderElement);
                element.Add(customHeaderElement);
                customIO.Serialize(this, customHeaderElement);
            }

            if (objAsCustom != null)
            {
                CustomSerialIO customIO = new CustomSerialIO();
                try { objAsCustom.WriteData(customIO); }
                catch (Exception e) { this.LogCustomSerializationError(header.ObjectId, header.ObjectType, e); }

                XElement customBodyElement = new XElement(CustomSerialIO.BodyElement);
                element.Add(customBodyElement);
                customIO.Serialize(this, customBodyElement);
            }
            else
            {
                // Write the structs fields
                foreach (FieldInfo field in header.SerializeType.Fields)
                {
                    if (this.IsFieldBlocked(field, obj))
                    {
                        continue;
                    }

                    XElement fieldElement = new XElement(GetXmlElementName(field.Name));
                    element.Add(fieldElement);

                    this.WriteObjectData(fieldElement, field.GetValue(obj));
                }
            }
        }
Example #7
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
                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);
        }