예제 #1
0
 /// <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);
     }
 }
예제 #2
0
        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);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
 /// <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);
     }
 }
예제 #5
0
        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);
        }
예제 #6
0
 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);
         }
     }
 }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
 /// <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);
 }
예제 #10
0
        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;
            }
        }
예제 #11
0
 public static object MakeObject(Type objectType, KVObject keyValueObject, IObjectReflector reflector)
 => InvokeGeneric(nameof(MakeObject), objectType, new object[] { keyValueObject, reflector });
예제 #12
0
 public static TObject MakeObject <TObject>(KVObject keyValueObject)
 => MakeObject <TObject>(keyValueObject, new DefaultObjectReflector());
예제 #13
0
        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;
            }
        }
예제 #14
0
 public void AddItemForAppending(KVObject item) => includedObjectsToAppend.Add(item);
예제 #15
0
 public void AddItemForMerging(KVObject item) => includedObjectsToMerge.Add(item);
예제 #16
0
 public void AddItem(KVObject item) => CurrentObject.Items.Add(item);