/// <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 sb = new StringBuilder(_node.InnerText); _object.Set(sb); return(true); }
/// <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); } }
/// <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); }
/// <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); }
/// <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> /// 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; } } } }
/// <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); }