Пример #1
0
 /// <summary>
 ///     Sets the field to its default value if it has one (specified as DefaultValueAttribute or an empty collection if it is an embedded one)
 /// </summary>
 /// <param name="result"></param>
 /// <param name="field"></param>
 /// <returns>True if default value was set</returns>
 private static bool _CheckAndSetDefaultValue(object result, SFieldInfo field)
 {
     if (field.IsEmbeddedList)
     {
         _AddList(result, field, new List <object>());
         return(true);
     }
     if (!field.HasDefaultValue)
     {
         return(false);
     }
     field.SetValue(result, field.DefaultValue);
     return(true);
 }
Пример #2
0
        /// <summary>
        ///     Reads childnodes of the given node (either nodes or attributes)
        /// </summary>
        /// <param name="parent">Node to process</param>
        /// <param name="o">Object to put the values in</param>
        /// <param name="attributes">True for processing attributes, false for nodes</param>
        private void _ReadChildNodes(XmlNode parent, object o, bool attributes)
        {
            IEnumerable nodes;

            if (parent == null)
            {
                nodes = null;
            }
            else if (attributes)
            {
                nodes = parent.Attributes;
            }
            else
            {
                nodes = parent.ChildNodes;
            }

            List <SFieldInfo> fields = o.GetType().GetFields(attributes);

            if (nodes != null)
            {
                //Dictionary of all embedded lists to allow interleaved/mixed elements
                Dictionary <string, Tuple <SFieldInfo, List <object> > > embLists = new Dictionary <string, Tuple <SFieldInfo, List <object> > >();
                foreach (XmlNode node in nodes)
                {
                    if (node is XmlComment || node.LocalName == "xsd" || node.LocalName == "xsi")
                    {
                        continue;
                    }

                    SFieldInfo field = new SFieldInfo();
                    int        curField;
                    for (curField = 0; curField < fields.Count; curField++)
                    {
                        field = fields[curField];
                        if (field.Name == node.Name || field.AltName == node.Name || (field.IsEmbeddedList && node.Name.StartsWith(field.Name)))
                        {
                            break;
                        }
                    }
                    if (curField >= fields.Count)
                    {
                        string msg = "Unexpected element: %n";
                        if (fields.Count > 0)
                        {
                            msg += " Expected: " + string.Join(", ", fields.Select(f => f.Name));
                        }
                        _ErrorHandler.HandleError(new CXmlException(msg, node));
                        continue;
                    }

                    if (field.IsByteArray)
                    {
                        fields.RemoveAt(curField); //Do this also on error
                        byte[] value;
                        try
                        {
                            value = Convert.FromBase64String(node.InnerText);
                        }
                        catch (Exception)
                        {
                            _ErrorHandler.HandleError(new CXmlInvalidValueException("Invalid value in %n: %v", node, node.InnerText));
                            if (!_CheckAndSetDefaultValue(o, field))
                            {
                                _ErrorHandler.HandleError(new CXmlException("No default value for %n", node));
                            }
                            continue;
                        }
                        field.SetValue(o, value);
                    }
                    else if (field.IsEmbeddedList)
                    {
                        Tuple <SFieldInfo, List <object> > entry;
                        if (!embLists.TryGetValue(field.Name, out entry))
                        {
                            entry = new Tuple <SFieldInfo, List <object> >(field, new List <object>());
                            embLists.Add(field.Name, entry);
                        }
                        object subValue = _GetValue(node, field.SubType);
                        if (subValue != null)
                        {
                            entry.Item2.Add(subValue);
                        }
                    }
                    else
                    {
                        fields.RemoveAt(curField); //Do this also on error
                        object value = _GetValue(node, field.Type, field.ArrayItemName);
                        if (value == null)
                        {
                            if (_CheckAndSetDefaultValue(o, field))
                            {
                                continue;
                            }
                            if (!field.IsNullable)
                            {
                                _ErrorHandler.HandleError(new CXmlException("No default value for unset field at %n", node));
                                continue;
                            }
                        }
                        if (field.Ranged != null && value != null && !field.Ranged.IsValid(field.IsNullable ? field.SubType : field.Type, value))
                        {
                            _ErrorHandler.HandleError(new CXmlInvalidValueException("Value in %n is not in the range " + field.Ranged +
                                                                                    ". (Value=%v)", node, value.ToString()));
                        }

                        field.SetValue(o, value);
                    }
                }
                //Add embedded lists
                foreach (Tuple <SFieldInfo, List <object> > entry in embLists.Values)
                {
                    _AddList(o, entry.Item1, entry.Item2);
                    fields.Remove(entry.Item1);
                }
            }
            foreach (SFieldInfo field in fields)
            {
                if (!_CheckAndSetDefaultValue(o, field))
                {
                    if (parent != null)
                    {
                        _ErrorHandler.HandleError(new CXmlMissingElementException(parent, field));
                    }
                    object value = _GetValue(null, field.Type, field.ArrayItemName, field.GetValue(o));
                    if (value != null)
                    {
                        field.SetValue(o, value);
                    }
                }
            }
        }
Пример #3
0
 /// <summary>
 ///     Creates a collection (array or list) and puts it into the specified field
 /// </summary>
 /// <param name="o">Object which listField belongs to</param>
 /// <param name="listField">Field that will contain the list</param>
 /// <param name="values">Collection of values that are used to fill the list</param>
 private static void _AddList(object o, SFieldInfo listField, ICollection values)
 {
     listField.SetValue(o, _CreateList(listField.Type, values));
 }