コード例 #1
0
ファイル: CascadeSerializer.cs プロジェクト: Isuroku/Cascade
        object DeserializeDictionary(object inInstance, IKey inKey, Type declaredType, int inInheriteDeep, int inStructDeep, ILogPrinter inLogger)
        {
            Type[] gen_args = declaredType.GetGenericArguments();
            if (gen_args.Length < 2)
            {
                LogError(inLogger, string.Format("DeserializeDictionary: Generic Arguments are None. Type {0}", declaredType.Name));
                return(inInstance);
            }

            object instance = inInstance;

            // Instantiate if necessary
            if (instance == null)
            {
                instance = _reflectionProvider.Instantiate(declaredType, inLogger);
            }

            var dictionary = instance as IDictionary;

            Type keyDeclaredType   = gen_args[0];
            Type valueDeclaredType = gen_args[1];

            IKey tree_key = inKey.GetChild("BaseDictionary");

            if (tree_key == null)
            {
                tree_key = inKey;
            }

            for (int i = 0; i < tree_key.GetChildCount(); ++i)
            {
                IKey sub_key = tree_key.GetChild(i);

                object dic_key;
                if (!ReflectionHelper.StringToAtomicValue(sub_key.GetName(), keyDeclaredType, out dic_key, _reflectionProvider, inLogger))
                {
                    LogError(inLogger, string.Format("SubKey {0} [{3}] for dictionary with key type {1} can't convert value {2}",
                                                     tree_key, keyDeclaredType.Name, sub_key.GetName(), tree_key.GetPath()));
                }
                else
                {
                    object dic_value = DeserializeInternal(null, sub_key, valueDeclaredType, 0, inStructDeep + 1, inLogger);

                    if (dictionary.Contains(dic_key))
                    {
                        dictionary.Remove(dic_key);
                    }
                    dictionary.Add(dic_key, dic_value);
                }
            }
            return(instance);
        }
コード例 #2
0
        //public static bool IsDefault(object value, IReflectionProvider provider)
        //{
        //    if (value is string)
        //        return (string)value == string.Empty;
        //    if (value is char)
        //        return (char)value == '\0';
        //    if(IsINT(value))
        //        return Convert.ToInt64(value) == 0;
        //    if (IsUINT(value))
        //        return Convert.ToUInt64(value) == 0;
        //    if (IsFLOAT(value))
        //        return Convert.ToDecimal(value) == 0;
        //    if (value is bool)
        //        return (bool)value == false;
        //    if (value is ICollection)
        //        return (value as ICollection).Count == 0;
        //    if (value is Array)
        //        return (value as Array).Length == 0;

        //    Type type = value.GetType();
        //    if (type.IsEnum)
        //        return (int)value == 0;

        //    if (type.IsHashSet())
        //        return (int)provider.GetValue(type
        //            .GetProperty("Count", BindingFlags.ExactBinding | ReflectionHelper.PublicInstanceMembers, null, typeof(int), Type.EmptyTypes, null),
        //            value) == 0;


        //    return value.Equals(provider.Instantiate(type));
        //}

        public static object GetDefaultValue(Type inType, IReflectionProvider provider, ILogPrinter inLogger)
        {
            if (inType.IsValueType)
            {
                return(provider.Instantiate(inType, inLogger));
            }
            return(null);
        }
コード例 #3
0
        public static bool IsDefault(object value, IReflectionProvider provider, ILogPrinter inLogger)
        {
            Type type = value.GetType();

            if (type.IsValueType)
            {
                var t = provider.Instantiate(type, inLogger);
                return(t.Equals(value));
            }
            else
            {
                if (value == null)
                {
                    return(true);
                }

                if (value is string)
                {
                    return(string.IsNullOrEmpty((string)value));
                }

                if (value is ICollection)
                {
                    return((value as ICollection).Count == 0);
                }

                if (type.IsHashSet())
                {
                    return((int)provider.GetValue(type
                                                  .GetProperty("Count", BindingFlags.ExactBinding | ReflectionHelper.PublicInstanceMembers, null, typeof(int), Type.EmptyTypes, null),
                                                  value) == 0);
                }

                return(false);
            }
        }
コード例 #4
0
        public object DeserializeInternal(SerializedObject serialized, Type declaredType, object existingInstance)
        {
            var type     = declaredType;
            var instance = existingInstance;

            // Atomic or null values
            if (serialized is SerializedAtom)
            {
                // The current value is replaced; they're immutable
                instance = (serialized as SerializedAtom).Value;
            }

            else if (serialized is SerializedXml)
            {
                var it = (serialized as SerializedXml);

                if (IsXmlType(declaredType))
                {
                    using (var sr = new StringReader((serialized as SerializedXml).Value))
                        using (var xr = XmlReader.Create(sr, new XmlReaderSettings {
                            ConformanceLevel = ConformanceLevel.Fragment
                        }))
                        {
                            instance = _reflectionProvider.Instantiate(declaredType);

                            var readXml = instance as IXmlSerializable;

                            if (readXml == null)
                            {
                                throw new Exception("DeserializeInternal error. readXml is null");
                            }

                            readXml.ReadXml(xr);
                        }
                }
                else if (IsSerializable(declaredType))
                {
                    using (var ms = new MemoryStream(Encoding.Default.GetBytes(it.Value)))
                    {
                        return(serializer.Deserialize(ms));
                    }
                }
            }

            // Dictionaries
            else if (type.IsGenericDictionary())
            {
                // Instantiate if necessary
                if (instance == null)
                {
                    instance = _reflectionProvider.Instantiate(type);
                }

                var dictionary = instance as IDictionary;

                if (dictionary == null)
                {
                    throw new Exception("DeserializeInternal  error. dictionary is null");
                }

                var genericArguments  = dictionary.GetType().GetGenericArguments();
                var keyDeclaredType   = genericArguments[0];
                var valueDeclaredType = genericArguments[1];

                var serializedAggregation = serialized as SerializedAggregate;

                if (serializedAggregation == null)
                {
                    throw new Exception("DeserializeInternal  error. serializedAggregation is null");
                }

                foreach (var key in serializedAggregation.Children.Keys)
                {
                    // Dictionaries always contain atoms as keys
                    SafeAddToDictionary(dictionary,
                                        DeserializeInternal(key as SerializedObject, keyDeclaredType, null),
                                        DeserializeInternal(serializedAggregation.Children[key], valueDeclaredType, null));
                }
            }

            // Arrays, lists and sets (any collection excluding dictionaries)
            else if (type.IsGenericCollection())
            {
                var isArray              = type.IsArray;
                var isHashSet            = type.IsHashSet();
                var serializedCollection = serialized as SerializedCollection;

                if (serializedCollection == null)
                {
                    throw new Exception("DeserializeInternal  error. serializedCollection is null");
                }

                var declaredItemType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0];
                var genericListType  = typeof(System.Collections.Generic.List <>).MakeGenericType(declaredItemType);
                // Instantiate if necessary
                if (instance == null)
                {
                    if (isArray)
                    {
                        instance = Array.CreateInstance(declaredItemType, serializedCollection.Items.Count);
                    }
                    else if (type.IsAssignableFrom(genericListType))
                    {
                        instance = Activator.CreateInstance(genericListType);
                    }
                    else
                    {
                        if (declaredType.HasParameterlessConstructor())
                        {
                            instance = _reflectionProvider.Instantiate(declaredType) as IEnumerable;
                        }
                        else if (serializedCollection.Type.HasParameterlessConstructor())
                        {
                            instance = _reflectionProvider.Instantiate(serializedCollection.Type) as IEnumerable;
                        }
                    }
                }


                MethodHandler addToHashSet = null;
                if (isHashSet)
                {
                    addToHashSet = _reflectionProvider.GetDelegate(type.GetMethod("Add"));
                }

                var valueIndex = 0;
                foreach (var item in serializedCollection.Items)
                {
                    var value = DeserializeInternal(item, declaredItemType, null);

                    if (isArray)
                    {
                        var list = instance as IList;
                        if (list == null)
                        {
                            throw new Exception("DeserializeInternal collection error. list is null");
                        }
                        list[valueIndex++] = value;
                    }
                    else if (isHashSet)
                    {
                        // Potential problem if set already contains key...
                        addToHashSet(instance, value);
                    }
                    else if (instance is IList)
                    {
                        (instance as IList).Add(value);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }

            // Everything else (serialized with recursive property reflection)
            else
            {
                var mustInstantiate = instance == null;

                if (serialized.Type != null && declaredType != serialized.Type)
                {
                    type            = serialized.Type;
                    mustInstantiate = true;
                }

                if (mustInstantiate)
                {
                    instance = _reflectionProvider.Instantiate(type);
                }

                var serializedAggregation = serialized as SerializedAggregate;

                if (serializedAggregation == null)
                {
                    throw new Exception("DeserializeInternal collection error. serializedAggregation is null");
                }
                foreach (var memberInfo in _reflectionProvider.GetSerializableMembers(type))
                {
                    var memberAttr = _reflectionProvider.GetSingleAttributeOrDefault <SerializationAttribute>(memberInfo);
                    if (memberAttr.Ignore)
                    {
                        continue;
                    }

                    var memberType = memberInfo.GetMemberType();
                    var name       = memberAttr.Name ?? memberInfo.Name;

                    // Checking if it's a class before doing GetValue doesn't speed up the process
                    var valueFound = serializedAggregation.Children.ContainsKey(name);

                    if (!valueFound)
                    {
                        if (memberAttr.Required)
                        {
                            throw new InvalidOperationException(string.Format("MissingRequiredValue {0} {1}", name, type.Name));
                        }
                    }
                    else
                    {
                        try
                        {
                            var currentValue = _reflectionProvider.GetValue(memberInfo, instance);
                            var readValue    = DeserializeInternal(serializedAggregation[name], memberType, currentValue);
                            // This dirty check is naive and doesn't provide performance benefits
                            //if (memberType.IsClass && readValue != currentValue && (readValue == null || !readValue.Equals(currentValue)))
                            _reflectionProvider.SetValue(memberInfo, instance, readValue);
                        }
                        catch
                        {
                        }
                    }
                }
            }

            return(instance);
        }