Exemple #1
0
        /// <summary>
        /// Turn the innerText of an XML node into a DateTime and return that DateTime
        /// </summary>
        /// <param name="_object">The object to deserialize into</param>
        /// <param name="_node">The node containing the DateTime string</param>
        /// <param name="_deserializer">The serializer- not used</param>
        /// <returns>a DateTime object</returns>
        public bool Deserialize(CWorkingObject _object, XmlElement _node, CDeserializer _deserializer)
        {
            var sb = new StringBuilder(_node.InnerText);

            _object.Set(sb);
            return(true);
        }
Exemple #2
0
        /// <summary>
        /// Create an Array from the data in the Xml and return that array.
        /// </summary>
        /// <param name="_xml">The XML containing the data for the array</param>
        /// <param name="_type">The Type of the array, as inferred from the framework</param>
        /// <param name="_workingObject">
        /// A working object (optional) that must be an Array (if its not null)
        /// </param>
        /// <returns></returns>
        private void DeserializeArray(XmlElement _xml, Type _type, CWorkingObject _workingObject)
        {
            var condensedArray = FindCondensedArray(_xml);
            var inferredLength = (condensedArray != null) ? condensedArray.Length : -1;

            var arrayHelper =
                CreateArrayDeserializationHelper(_xml, _type, _workingObject, inferredLength);

            // At this stage, we know its a Rank 1 array. Figure out the serialization of that
            // array Single child node that's a text node is an assumed indicator that the
            // "Condensed" format was used to serialize
            if (condensedArray != null)
            {
                DeserializeArrayFromCondensedArray(condensedArray, arrayHelper);
            }
            else
            {
                // There are individual child XmlElements for each array element. "Index"
                // attributes can be used to "skip" null array values.
                DeserializeArrayFromElements(_xml, arrayHelper);
            }

            if (!_workingObject.IsSet)
            {
                _workingObject.Set(arrayHelper.Array);
            }
        }
Exemple #3
0
        /// <summary>
        /// The Type uses EntitySemantics. See <see cref="CEntityTypeData"/> for more info on
        /// EntitySemantics
        /// </summary>
        /// <param name="_xml">The XML containing the data</param>
        /// <param name="_type">
        /// The Type that has already been determined to use Entity Semantics
        /// </param>
        /// <param name="_workingObject">Where to put the resulting object</param>
        private void DeserializeUsingEntitySemantics(XmlElement _xml, Type _type, CWorkingObject _workingObject)
        {
            var obj      = _workingObject.GetExistingOrCreateNew(_type);
            var typeData = CEntityTypeData.GetTypeData(_type);

            for (var i = 0; i < typeData.NonCollectionProperties.Length; i++)
            {
                var prop = typeData.NonCollectionProperties[i];
                var xml  = _xml[prop.Name];

                if (xml != null) // There was some XmlElement for the property
                {
                    // This isn't a Field, and we're using EntitySemantics, so use there's
                    // nothing to query
                    PushCurrentField(null);

                    var propVal = FrameworkDeserialize(xml, prop.PropertyType);
                    prop.SetValue(obj, propVal);

                    PopField(); // pop the null we pushed
                }
            }

            for (var i = 0; i < typeData.CollectionProperties.Length; i++)
            {
                var colProp = typeData.CollectionProperties[i];
            }
        }
Exemple #4
0
 /// <summary>
 /// The framework will deserialize the object. No more surrogates or other "exceptional"
 /// behaviour.
 /// </summary>
 /// <param name="_xml"></param>
 /// <param name="_type"></param>
 /// <param name="_workingObject"></param>
 private void HandleDeserialization(XmlElement _xml, Type _type, CWorkingObject _workingObject)
 {
     // Strings are really easy- just return the "InnerText"
     if (_type == TYPEOF_STRING)
     {
         _workingObject.Set(Environment.ExpandEnvironmentVariables(_xml.InnerText));
     }
     // Primitives are also pretty easy, only because of the "Convert" class
     else if (_type.IsPrimitive)
     {
         _workingObject.Set(Convert.ChangeType(_xml.InnerText, _type));
     }
     // Check for an Array
     else if (_type.IsArray || XmlExtensions.HasAttribute(_xml, m_context.ArrayAttributeName))
     {
         DeserializeArray(_xml, _type, _workingObject);
     }
     else if (_type.IsEnum)
     {
         _workingObject.Set(Enum.Parse(_type, _xml.InnerText, false));
     }
     else // Handle ref-type fields and base classes.
     {
         DeserializeReferenceType(_xml, _type, _workingObject);
     }
 }
        /// <summary>
        /// Turn the innerText of an XML node into a DateTime and return that DateTime
        /// </summary>
        /// <param name="_object">The object to deserialize into</param>
        /// <param name="_node">The node containing the DateTime string</param>
        /// <param name="_deserializer">The serializer- not used</param>
        /// <returns>a DateTime object</returns>
        public bool Deserialize(CWorkingObject _object, XmlElement _node, CDeserializer _deserializer)
        {
            var dateData = long.Parse(_node.InnerText, NumberStyles.AllowHexSpecifier);

            _object.Set(DateTime.FromBinary(dateData));
            return(true);
        }
Exemple #6
0
        /// <summary>
        /// Check the easiest forms of deserialization- Null and RefTo an object already
        /// deserialized.
        /// </summary>
        /// <param name="_xml">The XML that's being deserialized</param>
        /// <param name="_workObj">
        /// The Object that was deserialized (when the return value is TRUE)
        /// </param>
        /// <returns>
        /// TRUE means that the _workObj parameter contains valid data and nothing further
        /// should be done, FALSE means that no deserialization was performed.
        /// </returns>
        private bool CheckNullAndReference(XmlElement _xml, CWorkingObject _workObj)
        {
            // Check the XML to see if this is a NULL object reference. If it is, then return
            // TRUE.
            if (XmlExtensions.HasAttribute(_xml, m_context.NullAttributeName))
            {
                return(true);
            }

            // Check the XML to see if its referring to some other object.
            var referTo = XmlExtensions.GetAttributeValue(_xml, m_context.ReferToAttributeName);

            if (referTo != null) // There was a reference to another object, so handle it and return that other object.
            {
                // Check the table for the RefID to get the object. The reference must be in the
                // table already because forward-looking references are not supported.
                if (!m_references.TryGetValue(referTo, out var obj))
                {
                    throw new XUnknownReference("All object-references must be to backward-defined objects. The RefID " + referTo + " has not been defined yet.");
                }

                _workObj.Set(obj);
                return(true);
            }

            // Check to see if this element is associating the XML with a reference ID
            var refId = XmlExtensions.GetAttributeValue(_xml, m_context.ReferenceIdAttributeName);

            if (refId != null)
            {
                _workObj.SetRefInfo(this, refId);
            }

            return(false);
        }
Exemple #7
0
        /// <summary>
        /// This is the Deserializer to turn a UTC "Complete date plus hours, minutes and seconds" string
        /// back into a DateTime structure.
        /// </summary>
        /// <param name="_workingObject">The object that is to receive the new DateTime structure</param>
        /// <param name="_parentNode">The node whose InnerText contains the UTC string</param>
        /// <param name="_deserializer">The deserializer- not used.</param>
        /// <returns>"true", because this routine completely deserializes the DateTime</returns>
        public bool Deserialize(CWorkingObject _workingObject, XmlElement _parentNode, CDeserializer _deserializer)
        {
            var asString = _parentNode.InnerText;
            var dt       = FromString(asString);

            _workingObject.Set(dt);
            return(true);
        }
        /// <summary>
        /// Given an XmlElement and a "CWorkingObject" instance, try to deserialize the Xml into
        /// the working object. The surrogate may be responsible for object creation- the
        /// _workingObject should be checked to see if an object has already been created (by,
        /// for instance, a super-class). All of the information for the object should be
        /// wholely contained within the XmlElement supplied. The implementation should never
        /// need to "hunt around" the XML DOM for information about the object.
        /// </summary>
        /// <param name="_workingObject">
        /// The container for object that is being deserialized. If the "WorkingObject" property
        /// is a NULL value, then the deserializer is expected to create the object and use the
        /// <see cref="CWorkingObject.Set"/> method to assign the newly created object to the
        /// working object. If it is NOT a null value, then the deserializer is not allowed to
        /// modify this "Working Object" value.
        /// </param>
        /// <param name="_parentElement">
        /// The XmlElement containing the data to populate the object with
        /// </param>
        /// <param name="_deserializer">
        /// The CDeserializer instance making this call- This can be used to get the context
        /// information or any other relevent information.
        /// </param>
        /// <returns>
        /// TRUE if the surrogate was able to completely deserialize the object, FALSE if the
        /// framework should perform its "default" function.
        /// </returns>
        public bool Deserialize(CWorkingObject _workingObject, XmlElement _parentElement, CDeserializer _deserializer)
        {
            if (Surrogate1.Deserialize(_workingObject, _parentElement, _deserializer))
            {
                return(true);
            }

            return(Surrogate2.Deserialize(_workingObject, _parentElement, _deserializer));
        }
Exemple #9
0
        /// <summary>
        /// Given information about the current state, create an ArrayDeserializationHelper to
        /// help with the deserialization process
        /// </summary>
        /// <param name="_xml">The XML containing the Array information</param>
        /// <param name="_type">The Type of the array expected</param>
        /// <param name="_workingObject">
        /// A "Working Object", likely from a surrogate that didn't complete the deserialization
        /// </param>
        /// <param name="_inferredLength">
        /// The Inferred Length of the array, from a "Condensed Array" already found in the XML
        /// </param>
        /// <returns>
        /// A properly formed <see cref="CArrayDeserializationHelper"/> object.
        /// </returns>
        private CArrayDeserializationHelper CreateArrayDeserializationHelper(XmlElement _xml,
                                                                             Type _type,
                                                                             CWorkingObject _workingObject,
                                                                             int _inferredLength)
        {
            CArrayDeserializationHelper arrayHelper;

            if (_workingObject.IsSet)
            {
                arrayHelper = new CArrayDeserializationHelper(_workingObject.WorkingObject as Array);
            }
            else
            {
                // Make sure that the array type actually is an array and it has an ElementType
                var arrType = _type;
                if (!arrType.IsArray)
                {
                    throw new XDeserializationError(
                              "The Type specified is not an array or it does not have an ElementTypes associated with it- " +
                              arrType.ToString());
                }

                // Get info from the XML
                var sLengths = XmlExtensions.GetAttributeValue(_xml, m_context.ArrayAttributeName);
                var lengths  = sLengths?.Split(',').Select(s => int.Parse(s)).ToArray();

                var sLowerBounds = XmlExtensions.GetAttributeValue(_xml, m_context.ArrayLowerBoundAttribute);
                var lowerBounds  = sLowerBounds?.Split(',').Select(s => int.Parse(s)).ToArray();

                if (lengths == null)
                {
                    if (_inferredLength > -1)
                    {
                        lengths = new int[] { _inferredLength }
                    }
                    ;
                    else
                    {
                        lengths = new int[] { InferArrayLength(_xml) }
                    };                                                    // This assumes a 1-dim array at this point.
                }

                arrayHelper = new CArrayDeserializationHelper(arrType.GetElementType(), lengths, lowerBounds);
            }

            return(arrayHelper);
        }
Exemple #10
0
        /// <summary>
        /// Check to see if there are surrogates that handle the deserialization.
        /// </summary>
        /// <param name="_xml">The XML containing the object data</param>
        /// <param name="_type">The TYPE that we're trying to deserialize</param>
        /// <param name="_workingObject">
        /// A "Working Object" that deserializers use to determine if they need to create a new
        /// object or if they have an object that they can deserialize into.
        /// </param>
        /// <returns>
        /// TRUE if a surrogate was successful in completing the deserialization of the object,
        /// or FALSE if the surrogates were not able to complete all deserialization
        /// </returns>
        private bool ApplySurrogates(XmlElement _xml, Type _type, CWorkingObject _workingObject)
        {
            var isComplete = false;

            _workingObject.WorkingType = _type;

            // Check for EntitySemantics as a special and overriding Surrogate method The
            // UseEntitySemantics on the XML element is ignored, as the destination Type gets to
            // define how it gets deserialized (the attribute may be little more than a Hint to
            // what happened at serializatiion time) See for more information on EntitySemantics
            if (CEntityTypeData.UsesEntitySemantics(_type))
            {
                DeserializeUsingEntitySemantics(_xml, _type, _workingObject);
                return(true);
            }

            // Check for external surrogates
            var externalSurrogate = GetExternalSurrogate(_type);

            if (externalSurrogate != null)
            {
                isComplete = externalSurrogate.Deserialize(_workingObject, _xml, this);
            }
            if (isComplete)
            {
                return(true);
            }

            // Check the Implicit surrogates if the External surrogate(s) didn't finish the
            // deserialization
            var typeData          = CTypeData.GetTypeData(_type);
            var implicitSurrogate = typeData.ImplicitSurrogate;

            if (implicitSurrogate != null && implicitSurrogate.HasSurrogate)
            {
                isComplete = implicitSurrogate.Deserialize(_workingObject, _xml, this);
            }
            if (isComplete)
            {
                return(true);
            }

            return(false);
        }
Exemple #11
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // The rest of the file contains the code to actually serialize or deserialize using the data constructed above. //
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////


        /// <summary>
        /// Create the parameter array for an implicit surrogate using the data created by the rest of this class.
        /// </summary>
        /// <param name="_implicit">The implicit surrogate</param>
        /// <param name="_xmlToSerializeTo">The XML that the object will serialize itself to</param>
        /// <param name="_framework">The Context that the object will use (optionally) to serialize the data.</param>
        /// <param name="_object">The "Working Object" useful to a deserializer</param>
        /// <returns>an object[] containing the parameter data as dictated by the implicitSurrogate object</returns>
        private static object[] BuildParamArray(CImplicitSurrogate _implicit,
                                                XmlElement _xmlToSerializeTo,
                                                CFramework _framework,
                                                CWorkingObject _object)
        {
            var arr = new object[_implicit.m_parameterCount];

            arr[_implicit.m_indexXml] = _xmlToSerializeTo;

            if (_implicit.m_indexFramework != -1)
            {
                arr[_implicit.m_indexFramework] = _framework;
            }

            if (_implicit.m_indexObject != -1)
            {
                arr[_implicit.m_indexObject] = _object;
            }

            return(arr);
        }
Exemple #12
0
        /// <summary>
        /// This is the recursively-called routine that will actually direct the deserialization
        /// using the analysis of the xml node being deserialized.
        /// </summary>
        /// <param name="_xml">The XML containing the data for the object</param>
        /// <param name="_defaultType">
        /// The Type that is expected for this object- this may be overridden by the XML
        /// </param>
        /// <returns>The object that was created from the XML</returns>
        public object FrameworkDeserialize(XmlElement _xml, Type _defaultType)
        {
            if (_xml == null)
            {
                return(null);
            }

            var workingObject = new CWorkingObject();

            // Figure out if this process can be cut way short with "null" or "reference" nodes
            if (CheckNullAndReference(_xml, workingObject))
            {
                return(workingObject.WorkingObject);
            }

            // Figure out the Type that we should be working with
            var oType = GetTypeFromXmlOrDefault(_xml, _defaultType);

            if (oType == null)
            {
                throw new XDeserializationError(
                          "For the XmlElement named '" +
                          _xml.Name +
                          "', there was no Type information available (Type Attribute: '" +
                          m_context.TypeAttributeName + "')");
            }

            // Check for Surrogates first, and if not then handle deserialization with this
            // class.
            if (!ApplySurrogates(_xml, oType, workingObject))
            {
                // An invalid type cannot be deserialized
                if (IsValidType(oType))
                {
                    HandleDeserialization(_xml, oType, workingObject);   // Let the Framework do its thing
                }
            }

            return(workingObject.WorkingObject);
        }
Exemple #13
0
        /// <summary>
        /// The Type is a reference type with zero or more fields, and it is to be deserialized
        /// using the Framework's algorithm
        /// </summary>
        /// <param name="_xml">The XML containing the field data</param>
        /// <param name="_type">The Type that is to be deserialized</param>
        /// <param name="_workingObject">
        /// The working object to be used if it is set (create new object instance if not)
        /// </param>
        /// <returns>The newly deserialized object</returns>
        private void DeserializeReferenceType(XmlElement _xml, Type _type, CWorkingObject _workingObject)
        {
            var typeData = CTypeData.GetTypeData(_type);

            if (!_workingObject.IsSet)
            {
                // Check to see if we can do anything with an explicit constructor (likely to be
                // private)
                var o = typeData.TryExplicitConstructor();
                if (o == null)
                {
                    o = Activator.CreateInstance(_type);
                }
                if (o == null)
                {
                    throw new XDeserializationError("Could not create a new object of type " + _type.ToString());
                }

                _workingObject.Set(o);
            }

            var currentObject = _workingObject.WorkingObject;

            while (typeData != null)
            {
                DeserializeObjectFields(_xml, currentObject, typeData);
                ClearIgnoredFields();

                typeData = typeData.BaseType;
                if (typeData != null)
                {
                    if (ApplySurrogates(_xml, typeData.Type, _workingObject))
                    {
                        typeData = null;
                    }
                }
            }
        }
Exemple #14
0
        /// <summary>
        /// Deserialize an object of this type.
        /// </summary>
        /// <param name="_object">A reference to an object that is being deserialized. NULL --> The serializer needs to create the object!</param>
        /// <param name="_xml">The XML node that contains the data for the deserialization</param>
        /// <param name="_framework">The serialization context to help with deserialization</param>
        /// <returns>TRUE if the deserialization is complete, FALSE if the framework needs to complete the deserialization</returns>
        internal bool Deserialize(CWorkingObject _object, XmlElement _xml, CFramework _framework)
        {
            var surrogate = m_implicitDeserializer;

            if (surrogate == null)
            {
                return(false);
            }

            var paramArray = BuildParamArray(surrogate, _xml, _framework, _object);

            var isComplete = surrogate.m_method.Invoke(null, paramArray);   // deserializer is always a static method

            if (isComplete is bool)
            {
                return((bool)isComplete);
            }
            else
            {
                return(true);
            }
            // An implicit deserializer is assumed to completely serialize the Type and all base classes unless explicitly stated otherwise.
        }
 /// <summary>
 /// Turn the innerText of an XML node into a guid and return that guid
 /// </summary>
 /// <param name="_node">The node containing the GUID string</param>
 /// <param name="_object">The object to deserialize into</param>
 /// <param name="_deserializer">The Deserializer- not used</param>
 /// <returns>a GUID object</returns>
 public bool Deserialize(CWorkingObject _object, XmlElement _node, CDeserializer _deserializer)
 {
     _object.Set(new Guid(_node.InnerText));
     return(true);
 }