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); }
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)) { // ignoring non existing properties //throw new FormatException("{0} does not have a member {1}.".DoFormat(type.FullName, name)); continue; } 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); }
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); }