/// <summary> /// Serializes a KeyValue object into stream in plain text.. /// </summary> /// <param name="stream">The stream to serialize into.</param> /// <param name="data">The data to serialize.</param> /// <param name="options">Options to use that can influence the serialization process.</param> public static void Serialize(Stream stream, KVObject data, KVSerializerOptions options = null) { using (var writer = new KVTextWriter(stream, options ?? KVSerializerOptions.DefaultOptions)) { writer.WriteObject(data); } }
static bool IsArray(KVObject obj, out object[] values) { values = null; if (obj.Children.Any(i => !IsNumeric(i.Name))) { return(false); } var items = obj.Children .Select(i => new { Index = int.Parse(i.Name), i.Value }) .OrderBy(i => i.Index) .ToArray(); for (int i = 0; i < items.Length; i++) { if (i != items[i].Index) { return(false); } } values = items.Select(i => i.Value).ToArray(); return(true); }
static void CopyObject <TObject>(KVObject kv, TObject obj, IObjectReflector reflector) { Require.NotNull(kv, nameof(kv)); // Cannot use Require.NotNull here because TObject might be a struct. if (obj == null) { throw new ArgumentNullException(nameof(obj)); } Require.NotNull(reflector, nameof(reflector)); var members = reflector.GetMembers(obj).ToDictionary(m => m.Name, m => m, StringComparer.OrdinalIgnoreCase); foreach (var item in kv.Children) { IObjectMember member; if (!members.TryGetValue(item.Name, out member)) { continue; } member.Value = MakeObject(member.MemberType, item, reflector); } }
/// <summary> /// Serializes a KeyValue object into stream. /// </summary> /// <param name="stream">The stream to serialize into.</param> /// <param name="data">The data to serialize.</param> /// <param name="options">Options to use that can influence the serialization process.</param> public void Serialize(Stream stream, KVObject data, KVSerializerOptions options = null) { using (var serializer = MakeSerializer(stream, options ?? KVSerializerOptions.DefaultOptions)) { var visitor = new KVObjectVisitor(serializer); visitor.Visit(data); } }
static object MakeDictionary(Type type, KVObject kv, IObjectReflector reflector) { var dictionary = Activator.CreateInstance(type); var genericArguments = type.GetGenericArguments(); typeof(ObjectCopier) .GetMethod(nameof(FillDictionary), BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(genericArguments) .Invoke(null, new[] { dictionary, kv, reflector }); return(dictionary); }
static void Merge(KVObject from, KVObject into) { foreach (var child in from) { var matchingChild = into.Children.FirstOrDefault(c => c.Name == child.Name); if (matchingChild == null && into.Value.ValueType == KVValueType.Collection) { into.Add(child); } else { Merge(from: child, into: matchingChild); } } }
public void WriteObject(KVObject data) { if (data.Value.ValueType == KVValueType.Collection) { WriteStartObject(data.Name); var children = data.Children; foreach (var item in children) { WriteObject(item); } WriteEndObject(); } else { WriteKeyValuePair(data.Name, data.Value); } }
public static TObject MakeObject <TObject>(KVObject keyValueObject, IObjectReflector reflector) { Require.NotNull(keyValueObject, nameof(keyValueObject)); Require.NotNull(reflector, nameof(reflector)); if (keyValueObject.Value.ValueType == KVValueType.Collection) { object[] enumerableValues; Type lookupValueType; object enumerable; if (IsLookupWithStringKey(typeof(TObject), out lookupValueType)) { return((TObject)MakeLookup(lookupValueType, keyValueObject, reflector)); } else if (IsDictionary(typeof(TObject))) { return((TObject)MakeDictionary(typeof(TObject), keyValueObject, reflector)); } else if (IsArray(keyValueObject, out enumerableValues) && ConstructTypedEnumerable(typeof(TObject), enumerableValues, reflector, out enumerable)) { return((TObject)enumerable); } else if (IsConstructibleEnumerableType(typeof(TObject))) { throw new InvalidOperationException($"Cannot deserialize a non-array value to type \"{typeof(TObject).Namespace}.{typeof(TObject).Name}\"."); } var typedObject = (TObject)FormatterServices.GetUninitializedObject(typeof(TObject)); CopyObject(keyValueObject, typedObject, reflector); return(typedObject); } else if (TryConvertValueTo <TObject>(keyValueObject.Value, out var converted)) { return(converted); } else { throw new NotSupportedException(typeof(TObject).Name); } }
/// <summary> /// Adds a <see cref="KVObject" /> as a child of the current object. /// </summary> /// <param name="value">The child to add.</param> public void Add(KVObject value) { Require.NotNull(value, nameof(value)); GetCollectionValue().Add(value); }
static void FillDictionary <TKey, TValue>(Dictionary <TKey, TValue> dictionary, KVObject kv, IObjectReflector reflector) { foreach (var item in kv.Children) { var key = ConvertValue <TKey>(item.Name, reflector); var value = ConvertValue <TValue>(item.Value, reflector); dictionary[key] = value; } }
public static object MakeObject(Type objectType, KVObject keyValueObject, IObjectReflector reflector) => InvokeGeneric(nameof(MakeObject), objectType, new object[] { keyValueObject, reflector });
public static TObject MakeObject <TObject>(KVObject keyValueObject) => MakeObject <TObject>(keyValueObject, new DefaultObjectReflector());
static void FillDictionary <TKey, TValue>(Dictionary <TKey, TValue> dictionary, KVObject kv) { foreach (var item in kv.Children) { var key = (TKey)Convert.ChangeType(item.Name, typeof(TKey)); var value = (TValue)Convert.ChangeType(item.Value, typeof(TValue)); dictionary[key] = value; } }
public void AddItemForAppending(KVObject item) => includedObjectsToAppend.Add(item);
public void AddItemForMerging(KVObject item) => includedObjectsToMerge.Add(item);
public void AddItem(KVObject item) => CurrentObject.Items.Add(item);