System.Runtime.Serialization.Plists.DataContractBinaryPlistSerializer.GetReadablePlistObject C# (CSharp) Method

GetReadablePlistObject() private method

Gets the readable plist value of the given object identified by the specified type.
private GetReadablePlistObject ( Type type, object obj ) : object
type System.Type The type the object is expected to have after being de-serialized.
obj object The raw plist object value.
return object
        private object GetReadablePlistObject(Type type, object obj)
        {
            object result = null;
            IDictionary plistDict = obj as IDictionary;

            if (obj != null)
            {
                if (typeof(IPlistSerializable).IsAssignableFrom(type))
                {
                    if (plistDict != null)
                    {
                        IPlistSerializable serResult = (IPlistSerializable)Activator.CreateInstance(type);
                        serResult.FromPlistDictionary(plistDict);
                    }
                }
                else if (typeof(IDictionary).IsAssignableFrom(type))
                {
                    if (plistDict != null)
                    {
                        Type keyType = typeof(object), valueType = typeof(object);

                        if (type.IsGenericType)
                        {
                            Type[] args = type.GetGenericArguments();
                            keyType = args[0];
                            valueType = args[1];
                        }

                        IDictionary dictResult = (IDictionary)(type.IsInterface ?
                                Activator.CreateInstance(typeof(Dictionary<,>).MakeGenericType(keyType, valueType)) :
                                Activator.CreateInstance(type));

                        foreach (object key in plistDict.Keys)
                        {
                            if (!type.IsGenericType)
                            {
                                keyType = key.GetType();
                                valueType = plistDict[key] != null ? plistDict[key].GetType() : typeof(object);
                            }

                            dictResult[this.GetReadablePlistObject(keyType, key)] = this.GetReadablePlistObject(valueType, plistDict[key]);
                        }

                        result = dictResult;
                    }
                }
                else if (type.IsCollection())
                {
                    IEnumerable plistColl = obj as IEnumerable;

                    if (plistColl != null)
                    {
                        Type valueType = typeof(object);
                        bool isArray = false;
                        IList listResult;

                        if (type.IsGenericType)
                        {
                            valueType = type.GetGenericArguments()[0];
                        }
                        else if (typeof(Array).IsAssignableFrom(type))
                        {
                            valueType = type.GetElementType();
                            isArray = true;
                        }

                        if (isArray)
                        {
                            listResult = new ArrayList();
                        }
                        else
                        {
                            // TODO: The default DataContractSerializer uses an informal protocal requiring a method named "Add()"
                            // rather than requiring concrete collection types to implement IList.
                            listResult = (IList)(type.IsInterface ?
                                Activator.CreateInstance(typeof(List<>).MakeGenericType(valueType)) :
                                Activator.CreateInstance(type));
                        }

                        foreach (object value in plistColl)
                        {
                            listResult.Add(this.GetReadablePlistObject(valueType, value));
                        }

                        result = isArray ? ((ArrayList)listResult).ToArray() : listResult;
                    }
                }
                else if (type.IsPrimitiveOrEnum())
                {
                    result = obj;
                }
                else
                {
                    if (plistDict != null)
                    {
                        if (!this.typeCache.ContainsKey(type))
                        {
                            this.typeCache[type] = new TypeCacheItem(type);
                        }

                        TypeCacheItem cache = this.typeCache[type];
                        result = Activator.CreateInstance(type);

                        for (int i = 0; i < cache.Fields.Count; i++)
                        {
                            FieldInfo field = cache.Fields[i];
                            DataMemberAttribute member = cache.FieldMembers[i];

                            if (plistDict.Contains(member.Name))
                            {
                                field.SetValue(result, this.GetReadablePlistObject(field.FieldType, plistDict[member.Name]));
                            }
                        }

                        for (int i = 0; i < cache.Properties.Count; i++)
                        {
                            PropertyInfo property = cache.Properties[i];
                            DataMemberAttribute member = cache.PropertyMembers[i];

                            if (plistDict.Contains(member.Name))
                            {
                                property.SetValue(result, this.GetReadablePlistObject(property.PropertyType, plistDict[member.Name]), null);
                            }
                        }
                    }
                }
            }

            return result;
        }