object MappingToObject(YamlMapping map, Type type, object obj, Dictionary<YamlNode, object> appeared) { // 1) Give a chance to deserialize through a IYamlSerializable interface var serializable = config.Serializable.FindSerializable(context, obj, type); if (serializable != null) { return serializable.Deserialize(context, map, type); } // 2) Naked !!map is constructed as Dictionary<object, object>. if ( ( ( map.ShorthandTag() == "!!map" && type == null ) || type == typeof(Dictionary<object,object>) ) && obj == null ) { var objectDictionary = new Dictionary<object, object>(); appeared.Add(map, objectDictionary); foreach ( var entry in map ) objectDictionary.Add(NodeToObjectInternal(entry.Key, null, appeared), NodeToObjectInternal(entry.Value, null, appeared)); return objectDictionary; } if (type == null) { throw new FormatException("Unable to find type for {0}]".DoFormat(map.ToString())); } // 3) Give a chance to config.Activator 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 dictionary = obj as IDictionary; var access = ObjectMemberAccessor.FindFor(type); foreach (var entry in map) { if (obj == null) throw new InvalidOperationException("Object is not initialized"); // If this is a pure dictionary, we can directly add key,value to it if (dictionary != null && access.IsPureDictionary) { dictionary.Add(NodeToObjectInternal(entry.Key, access.KeyType, appeared), NodeToObjectInternal(entry.Value, access.ValueType, appeared)); continue; } // Else go the long way var name = (string)NodeToObjectInternal(entry.Key, typeof(string), appeared); if (name == "~Items") { if (entry.Value is YamlSequence) { SequenceToObject((YamlSequence)entry.Value, obj.GetType(), obj, appeared); } else if (entry.Value is YamlMapping) { if (!access.IsDictionary || dictionary == null) throw new FormatException("{0} is not a dictionary type.".DoFormat(type.FullName)); dictionary.Clear(); foreach (var child in (YamlMapping)entry.Value) dictionary.Add(NodeToObjectInternal(child.Key, access.KeyType, appeared), NodeToObjectInternal(child.Value, access.ValueType, appeared)); } else { throw new InvalidOperationException("Member {0} of {1} is not serializable.".DoFormat(name, type.FullName)); } } else { 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)); } } } return obj; }
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); }
object MappingToObject(YamlMapping map, Type type, object obj, Dictionary <YamlNode, object> appeared) { // 1) Give a chance to deserialize through a IYamlSerializable interface var serializable = config.Serializable.FindSerializable(context, obj, type); if (serializable != null) { return(serializable.Deserialize(context, map, type)); } // 2) Naked !!map is constructed as Dictionary<object, object>. if (((map.ShorthandTag() == "!!map" && type == null) || type == typeof(Dictionary <object, object>)) && obj == null) { var objectDictionary = new Dictionary <object, object>(); appeared.Add(map, objectDictionary); foreach (var entry in map) { objectDictionary.Add(NodeToObjectInternal(entry.Key, null, appeared), NodeToObjectInternal(entry.Value, null, appeared)); } return(objectDictionary); } if (type == null) { throw new FormatException("Unable to find type for {0}]".DoFormat(map.ToString())); } // 3) Give a chance to config.Activator 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 dictionary = obj as IDictionary; var access = ObjectMemberAccessor.FindFor(type); foreach (var entry in map) { if (obj == null) { throw new InvalidOperationException("Object is not initialized"); } // If this is a pure dictionary, we can directly add key,value to it if (dictionary != null && access.IsPureDictionary) { dictionary.Add(NodeToObjectInternal(entry.Key, access.KeyType, appeared), NodeToObjectInternal(entry.Value, access.ValueType, appeared)); continue; } // Else go the long way var name = (string)NodeToObjectInternal(entry.Key, typeof(string), appeared); if (name == "~Items") { if (entry.Value is YamlSequence) { SequenceToObject((YamlSequence)entry.Value, obj.GetType(), obj, appeared); } else if (entry.Value is YamlMapping) { if (!access.IsDictionary || dictionary == null) { throw new FormatException("{0} is not a dictionary type.".DoFormat(type.FullName)); } dictionary.Clear(); foreach (var child in (YamlMapping)entry.Value) { dictionary.Add(NodeToObjectInternal(child.Key, access.KeyType, appeared), NodeToObjectInternal(child.Value, access.ValueType, appeared)); } } else { throw new InvalidOperationException("Member {0} of {1} is not serializable.".DoFormat(name, type.FullName)); } } else { 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)); } } } return(obj); }