Ejemplo n.º 1
0
        private YamlMapping DictionaryToMap(object obj)
        {
            var accessor = ObjectMemberAccessor.FindFor(obj.GetType());
            var iter = ((IEnumerable)obj).GetEnumerator();
            var dictionary = map();
            Func <object, object> key = null, value = null;

            while (iter.MoveNext())
            {
                if (key == null)
                {
                    var keyvalue  = iter.Current.GetType();
                    var keyprop   = keyvalue.GetProperty("Key");
                    var valueprop = keyvalue.GetProperty("Value");
                    key   = o => keyprop.GetValue(o, new object[0]);
                    value = o => valueprop.GetValue(o, new object[0]);
                }
                dictionary.Add(
                    ObjectToNode(key(iter.Current), accessor.KeyType),
                    ObjectToNode(value(iter.Current), accessor.ValueType)
                    );
            }
            return(dictionary);
        }
Ejemplo n.º 2
0
        private YamlMapping CreateMapping(string tag, object obj /*, bool by_content */)
        {
            var type = obj.GetType();

            /*
             * if ( type.IsClass && !by_content && type.GetConstructor(Type.EmptyTypes) == null )
             *  throw new ArgumentException(string.Format("Type {0} has no default constructor.", type.FullName));
             */

            var mapping = map();

            mapping.Tag = tag;
            AppendToAppeared(obj, mapping);

            // iterate props / fields
            var accessor = ObjectMemberAccessor.FindFor(type);

            foreach (var entry in accessor)
            {
                var name   = entry.Key;
                var access = entry.Value;
                if (!access.ShouldSeriealize(obj))
                {
                    continue;
                }
                if (access.SerializeMethod == YamlSerializeMethod.Binary)
                {
                    var array = CreateBinaryArrayNode((Array)access.Get(obj));
                    AppendToAppeared(access.Get(obj), array);
                    array.Properties["expectedTag"] = TypeNameToYamlTag(access.Type);
                    mapping.Add(MapKey(entry.Key), array);
                }
                else
                {
                    try
                    {
                        var value = ObjectToNode(access.Get(obj), access.Type);
                        if ((access.SerializeMethod != YamlSerializeMethod.Content) ||
                            !(value is YamlMapping) || ((YamlMapping)value).Count > 0)
                        {
                            mapping.Add(MapKey(entry.Key), value);
                        }
                    }
                    catch
                    {
                    }
                }
            }
            // if the object is IDictionary or IDictionary<,>
            if (accessor.IsDictionary && !accessor.IsReadOnly(obj))
            {
                var dictionary = DictionaryToMap(obj);
                if (dictionary.Count > 0)
                {
                    mapping.Add(MapKey("IDictionary.Entries"), dictionary);
                }
            }
            else
            {
                // if the object is ICollection<> or IList
                if (accessor.CollectionAdd != null && !accessor.IsReadOnly(obj))
                {
                    var iter = ((IEnumerable)obj).GetEnumerator();
                    if (iter.MoveNext())
                    { // Count > 0
                        iter.Reset();
                        mapping.Add(MapKey("ICollection.Items"), CreateSequence("!!seq", iter, accessor.ValueType));
                    }
                }
            }
            return(mapping);
        }
Ejemplo n.º 3
0
        object MappingToObject(YamlMapping map, Type type, object obj, Dictionary <YamlNode, object> appeared)
        {
            // Naked !!map is constructed as Dictionary<object, object>.
            if (((map.ShorthandTag() == "!!map" && type == null) || type == typeof(Dictionary <object, object>)) && obj == null)
            {
                var dict = new Dictionary <object, object>();
                appeared.Add(map, dict);
                foreach (var entry in map)
                {
                    dict.Add(NodeToObjectInternal(entry.Key, null, appeared), NodeToObjectInternal(entry.Value, null, appeared));
                }
                return(dict);
            }

            if (obj == null)
            {
                obj = config.Activator.Activate(type);
                appeared.Add(map, obj);
            }
            else
            {
                if (appeared.ContainsKey(map))
                {
                    throw new InvalidOperationException($"This member is not writeable: {obj.ToString()}");
                }
            }

            var access = ObjectMemberAccessor.FindFor(type);

            foreach (var entry in map)
            {
                if (obj == null)
                {
                    throw new InvalidOperationException("Object is not initialized");
                }
                var name = (string)NodeToObjectInternal(entry.Key, typeof(string), appeared);
                switch (name)
                {
                case "ICollection.Items":
                    if (access.CollectionAdd == null)
                    {
                        throw new FormatException($"{type.FullName} is not a collection type.");
                    }
                    access.CollectionClear(obj);
                    foreach (var item in (YamlSequence)entry.Value)
                    {
                        access.CollectionAdd(obj, NodeToObjectInternal(item, access.ValueType, appeared));
                    }
                    break;

                case "IDictionary.Entries":
                    if (!access.IsDictionary)
                    {
                        throw new FormatException($"{type.FullName} is not a dictionary type.");
                    }
                    var dict = obj as IDictionary;
                    dict.Clear();
                    foreach (var child in (YamlMapping)entry.Value)
                    {
                        dict.Add(NodeToObjectInternal(child.Key, access.KeyType, appeared), NodeToObjectInternal(child.Value, access.ValueType, appeared));
                    }
                    break;

                default:
                    if (!access.ContainsKey(name))
                    {
                        throw new FormatException($"{type.FullName} does not have a member {name}.");
                    }
                    switch (access[name].SerializeMethod)
                    {
                    case YamlSerializeMethod.Assign:
                        access[obj, name] = NodeToObjectInternal(entry.Value, access[name].Type, appeared);
                        break;

                    case YamlSerializeMethod.Content:
                        MappingToObject((YamlMapping)entry.Value, access[name].Type, access[obj, name], appeared);
                        break;

                    case YamlSerializeMethod.Binary:
                        access[obj, name] = ScalarToObject((YamlScalar)entry.Value, access[name].Type);
                        break;

                    default:
                        throw new InvalidOperationException($"Member {name} of {type.FullName} is not serializable.");
                    }
                    break;
                }
            }
            return(obj);
        }