Beispiel #1
0
        /// <summary>
        ///     Gets the writable plist value of the given object identified by the specified type.
        /// </summary>
        /// <param name="type">The of the object.</param>
        /// <param name="obj">The object to get the plist value of.</param>
        /// <returns>The plist value of the given object.</returns>
        private object GetWritablePlistObject(Type type, object obj)
        {
            object result = null;

            if (obj != null)
            {
                if (typeof(IPlistSerializable).IsAssignableFrom(type))
                {
                    result = ((IPlistSerializable)obj).ToPlistDictionary();
                }
                else if (typeof(IDictionary).IsAssignableFrom(type))
                {
                    var dict       = obj as IDictionary;
                    var resultDict = new Dictionary <object, object>();

                    foreach (object key in dict.Keys)
                    {
                        object value = dict[key];
                        resultDict[GetWritablePlistObject(key.GetType(), key)] = GetWritablePlistObject(value.GetType(), value);
                    }

                    result = resultDict;
                }
                else if (type.IsCollection())
                {
                    var coll       = obj as IEnumerable;
                    var resultColl = (from object value in coll select GetWritablePlistObject(value.GetType(), value)).ToList();

                    result = resultColl;
                }
                else if (type.IsPrimitiveOrEnum())
                {
                    result = obj;
                }
                else
                {
                    if (!typeCache.ContainsKey(type))
                    {
                        typeCache[type] = new TypeCacheItem(type);
                    }

                    TypeCacheItem cache      = typeCache[type];
                    var           resultDict = new Dictionary <string, object>();

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

                        if (member.EmitDefaultValue || !field.FieldType.IsDefaultValue(fieldValue))
                        {
                            resultDict[member.Name] = GetWritablePlistObject(field.FieldType, fieldValue);
                        }
                    }

                    for (int i = 0; i < cache.Properties.Count; i++)
                    {
                        PropertyInfo        property = cache.Properties[i];
                        DataMemberAttribute member   = cache.PropertyMembers[i];
                        object propertyValue         = property.GetValue(obj, null);

                        if (member.EmitDefaultValue || !property.PropertyType.IsDefaultValue(propertyValue))
                        {
                            resultDict[member.Name] = GetWritablePlistObject(property.PropertyType, propertyValue);
                        }
                    }

                    result = resultDict;
                }
            }

            return(result);
        }
Beispiel #2
0
        /// <summary>
        ///     Gets the readable plist value of the given object identified by the specified type.
        /// </summary>
        /// <param name="type">The type the object is expected to have after being de-serialized.</param>
        /// <param name="obj">The raw plist object value.</param>
        /// <returns>A readable plist object value.</returns>
        private object GetReadablePlistObject(Type type, object obj)
        {
            object result    = null;
            var    plistDict = obj as IDictionary;

            if (obj != null)
            {
                if (typeof(IPlistSerializable).IsAssignableFrom(type))
                {
                    if (plistDict != null)
                    {
                        var 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];
                        }

                        var 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[GetReadablePlistObject(keyType, key)] = GetReadablePlistObject(valueType, plistDict[key]);
                        }

                        result = dictResult;
                    }
                }
                else if (type.IsCollection())
                {
                    var 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(GetReadablePlistObject(valueType, value));
                        }

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

                    TypeCacheItem cache = 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, 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, GetReadablePlistObject(property.PropertyType, plistDict[member.Name]), null);
                        }
                    }
                }
            }

            return(result);
        }