/// <summary>
        /// Deserialises the specified value node into a .NET object
        /// </summary>
        /// <param name="t"></param>
        /// <param name="node"></param>
        /// <returns></returns>
        public object Deserialise(Type t, ValueNode node)
        {
            // Instantiate
            if (t.IsAbstract)
            {
                throw new Exception($"Can't instantiate type '{t}'");
            }
            object obj;

            try
            {
                // Special case for arrays
                if (t.IsArray)
                {
                    obj = Activator.CreateInstance(t, node.As <ArrayValue>().Count);
                }
                else
                {
                    obj = Activator.CreateInstance(t);
                }
            }
            catch (Exception ex)
            {
                // TODO: Handle this better
                throw ex;
            }

            // Populate
            Deserialise(obj, node);

            // Return
            return(obj);
        }
Exemple #2
0
        /// <summary>
        /// Tests the enum value
        /// </summary>
        /// <param name="valueNode"></param>
        /// <param name="expectedFullValue"></param>
        public static void TestEnumValue(ValueNode valueNode, string expectedFullValue)
        {
            Assert.IsInstanceOfType(valueNode, typeof(EnumValue));
            EnumValue enumValue = valueNode.As <EnumValue>();

            Assert.IsNotNull(enumValue);
            Assert.AreEqual(expectedFullValue, enumValue.Full);
        }
Exemple #3
0
        /// <summary>
        /// Tests the primitive value
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="valueNode"></param>
        /// <param name="expectedValue"></param>
        public static void TestPrimitiveValue <T>(ValueNode valueNode, T expectedValue)
        {
            Assert.IsInstanceOfType(valueNode, typeof(PrimitiveValue <T>));
            PrimitiveValue <T> testStringNodeStr = valueNode.As <PrimitiveValue <T> >();

            Assert.IsNotNull(testStringNodeStr);
            Assert.AreEqual(expectedValue, testStringNodeStr.Value);
        }
        /// <summary>
        /// Populates the a .NET object with the specified value node
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="node"></param>
        public void Deserialise(object obj, ValueNode node)
        {
            // Sanity check
            if (obj == null)
            {
                return;
            }

            Type t = obj.GetType();

            // Is it a map type?
            if (typeof(IDictionary).IsAssignableFrom(t) && node is MapValue)
            {
                IDictionary dict   = obj as IDictionary;
                MapValue    mapVal = node.As <MapValue>();

                // Is it a generic dict?
                if (TranslateOptions.IsGenericType(typeof(IDictionary <,>), t))
                {
                    Type[] genArgs = t.GetGenericArguments();
                    if (genArgs[0] != typeof(string))
                    {
                        return;                               // TODO: Throw error?
                    }
                    foreach (var pair in mapVal)
                    {
                        object val;
                        if (translateOpts.Deserialise(genArgs[1], pair.Value, out val))
                        {
                            dict[pair.Key] = val;
                        }
                    }
                }
                else
                {
                    foreach (var pair in mapVal)
                    {
                        object val;
                        if (translateOpts.Deserialise(null, pair.Value, out val))
                        {
                            dict.Add(pair.Key, val);
                        }
                    }
                }
            }

            // Is it an array type?
            else if (t.IsArray)
            {
                Array      arr         = obj as Array;
                ArrayValue arrVal      = node.As <ArrayValue>();
                Type       elementType = t.GetElementType();
                for (int i = 0; i < Math.Min(arrVal.Count, arr.Length); i++)
                {
                    object val;
                    translateOpts.Deserialise(elementType == typeof(object) ? null : elementType, arrVal[i], out val);
                    arr.SetValue(val, i);
                }
            }
            else if (typeof(IList).IsAssignableFrom(t))
            {
                var        list   = obj as IList;
                ArrayValue arrVal = node.As <ArrayValue>();
                list.Clear();

                // Is it a generic list?
                if (TranslateOptions.IsGenericType(typeof(IList <>), t))
                {
                    Type elementType = t.GetGenericArguments()[0];
                    for (int i = 0; i < arrVal.Count; i++)
                    {
                        object val;
                        translateOpts.Deserialise(elementType == typeof(object) ? null : elementType, arrVal[i], out val);
                        list.Add(val);
                    }
                }
                else
                {
                    for (int i = 0; i < arrVal.Count; i++)
                    {
                        object val;
                        translateOpts.Deserialise(null, arrVal[i], out val);
                        list.Add(val);
                    }
                }
            }
            else if (typeof(ICollection).IsAssignableFrom(t))
            {
                throw new NotImplementedException("Can't deserialise into an ICollection");
            }

            MapValue mapValue = node as MapValue;

            if (mapValue == null)
            {
                return;                   // Throw error?
            }
            foreach (var pair in mapValue)
            {
                MemberInfo member = t.GetMember(pair.Key, BindingFlags.Public | BindingFlags.Instance)
                                    .Where(m => m is FieldInfo || m is PropertyInfo)
                                    .SingleOrDefault();
                if (member != null)
                {
                    FieldInfo fieldInfo = member as FieldInfo;
                    if (fieldInfo != null)
                    {
                        object val;
                        translateOpts.Deserialise(fieldInfo.FieldType, pair.Value, out val);
                        if ((val == null && !fieldInfo.FieldType.IsValueType) || fieldInfo.FieldType.IsAssignableFrom(val.GetType()))
                        {
                            fieldInfo.SetValue(obj, val);
                        }
                    }
                    PropertyInfo propertyInfo = member as PropertyInfo;
                    if (propertyInfo != null)
                    {
                        object val;
                        translateOpts.Deserialise(propertyInfo.PropertyType, pair.Value, out val);
                        if ((val == null && !propertyInfo.PropertyType.IsValueType) || propertyInfo.PropertyType.IsAssignableFrom(val.GetType()))
                        {
                            propertyInfo.SetValue(obj, val, null);
                        }
                    }
                }
            }
        }