Example #1
0
 /// <summary>
 ///
 /// 指定した型へのアクセス方法を表すインスタンスを返す
 /// キャッシュに存在すればそれを返す
 /// キャッシュに存在しなければ新しく作って返す
 /// 作った物はキャッシュされる
 /// </summary>
 /// <param name="type">クラスまたは構造体を表す型情報</param>
 /// <returns></returns>
 public static ObjectMemberAccessor FindFor(Type type)
 {
     if (!MemberAccessors.ContainsKey(type))
     {
         MemberAccessors[type] = new ObjectMemberAccessor(type);
     }
     return(MemberAccessors[type]);
 }
Example #2
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);
        }
Example #3
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("Type {0} has no default constructor.".DoFormat(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);
        }
Example #4
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: {0}".DoFormat(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("{0} is not a collection type.".DoFormat(type.FullName));
                    }
                    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("{0} is not a dictionary type.".DoFormat(type.FullName));
                    }
                    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("{0} does not have a member {1}.".DoFormat(type.FullName, 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 {0} of {1} is not serializable.".DoFormat(name, type.FullName));
                    }
                    break;
                }
            }
            return(obj);
        }