示例#1
0
        /// <summary>
        /// Returns the serializable type cache if known for the specified type.
        /// Will be cached just in time.
        /// </summary>
        public static SerializableTypeCache GetSerializableTypeCacheFor(Type type)
        {
            SerializableTypeCache cache;

            if (!typeCache.TryGetValue(type, out cache))
            {
                cache = SerializableTypeCache.TryBuild(type);
                typeCache.Add(type, cache);
            }
            return(cache);
        }
示例#2
0
        /// <summary>
        /// </summary>
        /// <param name="targetType">The target type to be parsed.</param>
        /// <param name="element">The xml element to parse the data from.</param>
        /// <param name="filename">The filename to be reported in case of errors.</param>
        public SerializedData(SerializableTypeCache targetType, XElement element)
        {
            this.targetType = targetType;
            this.xElement   = element;

            var inheritsAttrib = element.Attribute(XMLSerializer.AttributeInherits);

            if (!ReferenceEquals(inheritsAttrib, null))
            {
                this.inherits = inheritsAttrib.Value;
            }
        }
        /// <summary>
        /// Tries buildding the cache for the specified type.
        /// In case of an issue while building, null will be returned.
        ///
        /// If you want to know more as to why building failed, <see cref="GetBuildError(Type)"/>
        /// </summary>
        public static SerializableTypeCache TryBuild(Type type)
        {
            SerializableTypeCache stc = new SerializableTypeCache();

            try
            {
                stc.Build(type);
            }
            catch (Exception ex)
            {
                buildErrors.Set(type, ex.ToString());
                return(null);
            }

            return(stc);
        }
 public static bool FieldKnown(XMLSerializerParams parameters, IXmlLineInfo debug, SerializableTypeCache type, string field, string filename, List <SerializerError> errors)
 {
     if (!type.HasField(field))
     {
         // TODO: Line number
         string msg = string.Format("Unknown field {0}!", field);
         errors.Add(new SerializerError(SerializerErrorSeverity.ERROR, filename, ReferenceEquals(debug, null) ? -1 : debug.LineNumber, msg));
         return(false);
     }
     return(true);
 }
 public static bool TypeFound(XMLSerializerParams parameters, XElement xElement, XAttribute typeAttribute, SerializableTypeCache type, string filename, List <SerializerError> errors)
 {
     if (ReferenceEquals(type, null))
     {
         errors.Add(new SerializerError(SerializerErrorSeverity.ERROR, filename, (xElement as IXmlLineInfo).LineNumber, "Element type " + typeAttribute.Value + " unknown!"));
         return(false);
     }
     return(true);
 }
 public static bool DataFieldSerializerValid(XMLSerializerParams parameters, XElement xElement, SerializableTypeCache typeCache, string typeName, string fieldName, string filename, List <SerializerError> errors)
 {
     if (ReferenceEquals(typeCache, null))
     {
         // TODO: Explanation - why unserializable!?
         string msg = string.Format("Field '{0}' with unserializeable type {1}!", fieldName, typeName);
         errors.Add(new SerializerError(SerializerErrorSeverity.ERROR, filename, (xElement as IXmlLineInfo).LineNumber, msg));
         return(false);
     }
     return(true);
 }
示例#7
0
        /// <summary>
        /// It will for every field with string data deserialize this data using <see cref="IXMLDataSerializer"/>.
        ///
        /// For every sub-data field a <see cref="SerializedData"/> object is being written to <see cref="fields"/>.
        /// </summary>
        /// <param name="filename">Only used for error reporting</param>
        public void LoadFieldsFromXML(string filename, List <SerializerError> errors, XMLSerializerParams parameters)
        {
            foreach (var xNode in xElement.Nodes())
            {
                if (!SerializerValidation.NodeIsElement(parameters, xNode, filename, errors))                 // Malformed XML
                {
                    continue;
                }

                var xElement    = xNode as XElement;
                var elementName = xElement.Name.LocalName;

                // Field unknown?
                if (!SerializerValidation.FieldKnown(parameters, xElement, targetType, elementName, filename, errors))
                {
                    continue;
                }

                debug.Add(elementName, xElement);
                var _fieldData = targetType.GetFieldData(elementName);
                var fieldData  = _fieldData.Value;
                var fieldType  = fieldData.serializableTypeCache;

                if (xElement.Value == XMLSerializer.TokenNull)                 // Null special case
                {
                    fields.Add(elementName, null);
                    continue;
                }

                bool isCollection             = SerializedCollectionData.IsCollection(fieldData.fieldInfo.FieldType);
                IXMLDataSerializer serializer = SerializerCache.GetBestSerializerFor(fieldData.fieldInfo.FieldType);

                if (!ReferenceEquals(serializer, null))
                {
                    try
                    {
                        if (!SerializerValidation.SerializerWasFound(parameters, xElement, serializer, elementName, targetType == null ? null : targetType.type, fieldType == null ? null : fieldType.type, filename, errors))
                        {
                            continue;
                        }

                        fields.Add(elementName, serializer.Deserialize(fieldData.fieldInfo.FieldType, xElement, parameters));
                    }
                    catch (Exception ex)
                    {
                        errors.Add(new SerializerError(SerializerErrorSeverity.ERROR, filename, -1, "Serializer threw exception on field " + elementName + " on type " + targetType.type + ":\n\n" + ex.ToString() + "\n\nSkipping field!"));
                    }
                }
                else if (isCollection)
                {
                    var col = new SerializedCollectionData(fieldData.fieldInfo.FieldType, xElement);
                    col.ParseAndLoadData(filename, errors, parameters);
                    fields.Add(elementName, col);

                    // Collection override action?
                    var collectionOverrideAttrib = xElement.Attribute(XMLSerializer.AttributeCollectionOverrideAction);
                    if (!ReferenceEquals(collectionOverrideAttrib, null))
                    {
                        collectionOverrideActions.Set(elementName, (CollectionOverrideAction)Enum.Parse(typeof(CollectionOverrideAction), collectionOverrideAttrib.Value));
                    }
                }
                else
                {
                    // root reference?
                    if (fieldData.isSerializableRoot)
                    {
                        fields.Add(elementName, new SerializedRootObjectReference()
                        {
                            identifier = xElement.Value as string
                        });
                    }
                    else
                    {
                        // Determine which type to serialize
                        var    targetType = fieldData.serializableTypeCache;
                        string typeName   = fieldData.fieldInfo.Name;

                        // Check if element explicitly overwrites the type to support polymorphism
                        // The field type might be some base class type and the xml overwrites this type with a class extending from the base
                        var classAttrib = xElement.Attribute(XMLSerializer.AttributeType);
                        if (!ReferenceEquals(classAttrib, null))
                        {
                            targetType = SerializerCache.GetSerializableTypeCacheFor(classAttrib.Value, parameters.standardNamespace);
                            typeName   = classAttrib.Value;
                        }

                        // Field not serializable?
                        if (!SerializerValidation.DataFieldSerializerValid(parameters, xElement, targetType, typeName, elementName, filename, errors))
                        {
                            continue;
                        }

                        // Resolve field name type
                        var d = new SerializedData(targetType, xElement as XElement);
                        d.LoadFieldsFromXML(filename, errors, parameters);
                        fields.Add(elementName, d);
                    }
                }
            }
        }