示例#1
0
        private static void SerializeInternal(string name, object value, IniDictionary ini, string groupName, bool rootObject, IniCollectionSettings collectionSettings)
        {
            IniGroup group = ini[groupName];

            if (value == null || value == DBNull.Value)
            {
                return;
            }
            if (!value.GetType().IsComplexType())
            {
                group.Add(name, value.ConvertToString());
                return;
            }
            if (value is IList)
            {
                int i = collectionSettings.StartIndex;
                switch (collectionSettings.Mode)
                {
                case IniCollectionMode.Normal:
                    foreach (object item in (IList)value)
                    {
                        SerializeInternal(name + "[" + (i++).ToString() + "]", item, ini, groupName, false, defaultCollectionSettings);
                    }
                    return;

                case IniCollectionMode.IndexOnly:
                    foreach (object item in (IList)value)
                    {
                        SerializeInternal((i++).ToString(), item, ini, groupName, false, defaultCollectionSettings);
                    }
                    return;

                case IniCollectionMode.NoSquareBrackets:
                    foreach (object item in (IList)value)
                    {
                        SerializeInternal(name + (i++).ToString(), item, ini, groupName, false, defaultCollectionSettings);
                    }
                    return;

                case IniCollectionMode.SingleLine:
                    List <string> line = new List <string>();
                    foreach (object item in (IList)value)
                    {
                        line.Add(item.ConvertToString());
                    }
                    group.Add(name, string.Join(collectionSettings.Format, line.ToArray()));
                    return;
                }
            }
            if (value is IDictionary)
            {
                switch (collectionSettings.Mode)
                {
                case IniCollectionMode.Normal:
                    foreach (DictionaryEntry item in (IDictionary)value)
                    {
                        SerializeInternal(name + "[" + item.Key.ConvertToString() + "]", item.Value, ini, groupName, false, defaultCollectionSettings);
                    }
                    return;

                case IniCollectionMode.IndexOnly:
                    foreach (DictionaryEntry item in (IDictionary)value)
                    {
                        SerializeInternal(item.Key.ConvertToString(), item.Value, ini, groupName, false, defaultCollectionSettings);
                    }
                    return;

                case IniCollectionMode.NoSquareBrackets:
                    foreach (DictionaryEntry item in (IDictionary)value)
                    {
                        SerializeInternal(name + item.Key.ConvertToString(), item.Value, ini, groupName, false, defaultCollectionSettings);
                    }
                    return;

                case IniCollectionMode.SingleLine:
                    throw new InvalidOperationException("Cannot serialize IDictionary with IniCollectionMode.SingleLine!");
                }
            }
            string newgroup = groupName;

            if (!rootObject)
            {
                if (!string.IsNullOrEmpty(newgroup))
                {
                    newgroup += '.';
                }
                newgroup += name;
                ini.Add(newgroup, new Dictionary <string, string>());
            }
            foreach (MemberInfo member in value.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance))
            {
                if (Attribute.GetCustomAttribute(member, typeof(IniIgnoreAttribute), true) != null)
                {
                    continue;
                }
                string membername = member.Name;
                if (Attribute.GetCustomAttribute(member, typeof(IniNameAttribute), true) != null)
                {
                    membername = ((IniNameAttribute)Attribute.GetCustomAttribute(member, typeof(IniNameAttribute), true)).Name;
                }
                object item;
                object defval;
                switch (member.MemberType)
                {
                case MemberTypes.Field:
                    FieldInfo field = (FieldInfo)member;
                    item   = field.GetValue(value);
                    defval = field.FieldType.GetDefaultValue();
                    break;

                case MemberTypes.Property:
                    PropertyInfo property = (PropertyInfo)member;
                    defval = property.PropertyType.GetDefaultValue();
                    if (property.GetIndexParameters().Length > 0)
                    {
                        continue;
                    }
                    MethodInfo getmethod = property.GetGetMethod();
                    if (getmethod == null)
                    {
                        continue;
                    }
                    item = getmethod.Invoke(value, null);
                    break;

                default:
                    continue;
                }
                DefaultValueAttribute defattr = (DefaultValueAttribute)Attribute.GetCustomAttribute(member, typeof(DefaultValueAttribute), true);
                if (defattr != null)
                {
                    defval = defattr.Value;
                }
                if (Attribute.GetCustomAttribute(member, typeof(IniAlwaysIncludeAttribute), true) != null || !object.Equals(item, defval))
                {
                    IniCollectionSettings  settings = defaultCollectionSettings;
                    IniCollectionAttribute attr     = (IniCollectionAttribute)Attribute.GetCustomAttribute(member, typeof(IniCollectionAttribute));
                    if (attr != null)
                    {
                        settings = attr.Settings;
                    }
                    SerializeInternal(membername, item, ini, newgroup, false, settings);
                }
            }
        }
示例#2
0
        private static object DeserializeInternal(string name, Type type, object defaultvalue, IniDictionary ini, string groupName, bool rootObject, IniCollectionSettings collectionSettings)
        {
            string fullname = groupName;

            if (!rootObject)
            {
                if (!string.IsNullOrEmpty(fullname))
                {
                    fullname += '.';
                }
                fullname += name;
            }
            if (!ini.ContainsKey(groupName))
            {
                return(defaultvalue);
            }
            Dictionary <string, string> group = ini[groupName];

            if (!type.IsComplexType())
            {
                if (group.ContainsKey(name))
                {
                    object converted = type.ConvertFromString(group[name]);
                    group.Remove(name);
                    if (converted != null)
                    {
                        return(converted);
                    }
                }
                return(defaultvalue);
            }
            if (type.IsArray)
            {
                Type valuetype = type.GetElementType();
                int  maxind    = int.MinValue;
                if (!IsComplexType(valuetype))
                {
                    switch (collectionSettings.Mode)
                    {
                    case IniCollectionMode.Normal:
                        foreach (IniNameValue item in group)
                        {
                            if (item.Key.StartsWith(name + "["))
                            {
                                int key = int.Parse(item.Key.Substring(name.Length + 1, item.Key.Length - (name.Length + 2)));
                                maxind = Math.Max(key, maxind);
                            }
                        }
                        break;

                    case IniCollectionMode.IndexOnly:
                        foreach (IniNameValue item in group)
                        {
                            if (int.TryParse(item.Key, out int key))
                            {
                                maxind = Math.Max(key, maxind);
                            }
                        }
                        break;

                    case IniCollectionMode.NoSquareBrackets:
                        foreach (IniNameValue item in group)
                        {
                            if (item.Key.StartsWith(name))
                            {
                                if (int.TryParse(item.Key.Substring(name.Length), out int key))
                                {
                                    maxind = Math.Max(key, maxind);
                                }
                            }
                        }
                        break;

                    case IniCollectionMode.SingleLine:
                        string[] items = group[name].Split(new[] { collectionSettings.Format }, StringSplitOptions.None);
                        Array    _obj  = Array.CreateInstance(valuetype, items.Length);
                        for (int i = 0; i < items.Length; i++)
                        {
                            _obj.SetValue(valuetype.ConvertFromString(items[i]), i);
                        }
                        group.Remove(name);
                        break;
                    }
                }
                else
                {
                    switch (collectionSettings.Mode)
                    {
                    case IniCollectionMode.Normal:
                        foreach (IniNameGroup item in ini)
                        {
                            if (item.Key.StartsWith(fullname + "["))
                            {
                                int key = int.Parse(item.Key.Substring(fullname.Length + 1, item.Key.Length - (fullname.Length + 2)));
                                maxind = Math.Max(key, maxind);
                            }
                        }
                        break;

                    case IniCollectionMode.IndexOnly:
                        foreach (IniNameGroup item in ini)
                        {
                            if (int.TryParse(item.Key, out int key))
                            {
                                maxind = Math.Max(key, maxind);
                            }
                        }
                        break;

                    case IniCollectionMode.NoSquareBrackets:
                        foreach (IniNameGroup item in ini)
                        {
                            if (item.Key.StartsWith(fullname))
                            {
                                int key = int.Parse(item.Key.Substring(fullname.Length));
                                maxind = Math.Max(key, maxind);
                            }
                        }
                        break;

                    case IniCollectionMode.SingleLine:
                        throw new InvalidOperationException("Cannot deserialize type " + valuetype + " with IniCollectionMode.SingleLine!");
                    }
                }
                if (maxind == int.MinValue)
                {
                    return(Array.CreateInstance(valuetype, 0));
                }
                int   length = maxind + 1 - (collectionSettings.Mode == IniCollectionMode.SingleLine ? 0 : collectionSettings.StartIndex);
                Array obj    = Array.CreateInstance(valuetype, length);
                if (!IsComplexType(valuetype))
                {
                    switch (collectionSettings.Mode)
                    {
                    case IniCollectionMode.Normal:
                        for (int i = 0; i < length; i++)
                        {
                            if (group.ContainsKey(name + "[" + (i + collectionSettings.StartIndex).ToString() + "]"))
                            {
                                obj.SetValue(valuetype.ConvertFromString(group[name + "[" + (i + collectionSettings.StartIndex).ToString() + "]"]), i);
                                group.Remove(name + "[" + (i + collectionSettings.StartIndex).ToString() + "]");
                            }
                            else
                            {
                                obj.SetValue(valuetype.GetDefaultValue(), i);
                            }
                        }
                        break;

                    case IniCollectionMode.IndexOnly:
                        for (int i = 0; i < length; i++)
                        {
                            if (group.ContainsKey((i + collectionSettings.StartIndex).ToString()))
                            {
                                obj.SetValue(valuetype.ConvertFromString(group[(i + collectionSettings.StartIndex).ToString()]), i);
                                group.Remove((i + collectionSettings.StartIndex).ToString());
                            }
                            else
                            {
                                obj.SetValue(valuetype.GetDefaultValue(), i);
                            }
                        }
                        break;

                    case IniCollectionMode.NoSquareBrackets:
                        for (int i = 0; i < length; i++)
                        {
                            if (group.ContainsKey(name + (i + collectionSettings.StartIndex).ToString()))
                            {
                                obj.SetValue(valuetype.ConvertFromString(group[name + (i + collectionSettings.StartIndex).ToString()]), i);
                                group.Remove(name + (i + collectionSettings.StartIndex).ToString());
                            }
                            else
                            {
                                obj.SetValue(valuetype.GetDefaultValue(), i);
                            }
                        }
                        break;
                    }
                }
                else
                {
                    switch (collectionSettings.Mode)
                    {
                    case IniCollectionMode.Normal:
                        for (int i = 0; i < maxind; i++)
                        {
                            obj.SetValue(DeserializeInternal("value", valuetype, valuetype.GetDefaultValue(), ini, fullname + "[" + (i + collectionSettings.StartIndex).ToString() + "]", true, defaultCollectionSettings), i);
                        }
                        break;

                    case IniCollectionMode.IndexOnly:
                        for (int i = 0; i < maxind; i++)
                        {
                            obj.SetValue(DeserializeInternal("value", valuetype, valuetype.GetDefaultValue(), ini, (i + collectionSettings.StartIndex).ToString(), true, defaultCollectionSettings), i);
                        }
                        break;

                    case IniCollectionMode.NoSquareBrackets:
                        for (int i = 0; i < maxind; i++)
                        {
                            obj.SetValue(DeserializeInternal("value", valuetype, valuetype.GetDefaultValue(), ini, fullname + (i + collectionSettings.StartIndex).ToString(), true, defaultCollectionSettings), i);
                        }
                        break;
                    }
                }
                return(obj);
            }
            if (ImplementsGenericDefinition(type, typeof(IList <>), out Type generictype))
            {
                object obj       = Activator.CreateInstance(type);
                Type   valuetype = generictype.GetGenericArguments()[0];
                CollectionDeserializer deserializer = (CollectionDeserializer)Activator.CreateInstance(typeof(ListDeserializer <>).MakeGenericType(valuetype));
                deserializer.Deserialize(obj, group, groupName, collectionSettings, name, ini, fullname);
                return(obj);
            }
            if (type.ImplementsGenericDefinition(typeof(IDictionary <,>), out generictype))
            {
                object obj       = Activator.CreateInstance(type);
                Type   keytype   = generictype.GetGenericArguments()[0];
                Type   valuetype = generictype.GetGenericArguments()[1];
                if (keytype.IsComplexType())
                {
                    return(obj);
                }
                CollectionDeserializer deserializer = (CollectionDeserializer)Activator.CreateInstance(typeof(DictionaryDeserializer <,>).MakeGenericType(keytype, valuetype));
                deserializer.Deserialize(obj, group, groupName, collectionSettings, name, ini, fullname);
                return(obj);
            }
            object     result     = Activator.CreateInstance(type);
            MemberInfo collection = null;

            foreach (MemberInfo member in type.GetMembers(BindingFlags.Public | BindingFlags.Instance))
            {
                if (Attribute.GetCustomAttribute(member, typeof(IniIgnoreAttribute), true) != null)
                {
                    continue;
                }
                string membername = member.Name;
                if (Attribute.GetCustomAttribute(member, typeof(IniNameAttribute), true) != null)
                {
                    membername = ((IniNameAttribute)Attribute.GetCustomAttribute(member, typeof(IniNameAttribute), true)).Name;
                }
                IniCollectionSettings  colset  = defaultCollectionSettings;
                IniCollectionAttribute colattr = (IniCollectionAttribute)Attribute.GetCustomAttribute(member, typeof(IniCollectionAttribute), true);
                if (colattr != null)
                {
                    colset = colattr.Settings;
                }
                switch (member.MemberType)
                {
                case MemberTypes.Field:
                    FieldInfo field = (FieldInfo)member;
                    if (colset.Mode == IniCollectionMode.IndexOnly && typeof(ICollection).IsAssignableFrom(field.FieldType))
                    {
                        if (collection != null)
                        {
                            throw new Exception("IniCollectionMode.IndexOnly cannot be used on multiple members of a Type.");
                        }
                        collection = member;
                        continue;
                    }
                    object defval = field.FieldType.GetDefaultValue();
                    DefaultValueAttribute defattr = (DefaultValueAttribute)Attribute.GetCustomAttribute(member, typeof(DefaultValueAttribute), true);
                    if (defattr != null)
                    {
                        defval = defattr.Value;
                    }
                    field.SetValue(result, DeserializeInternal(membername, field.FieldType, defval, ini, fullname, false, colset));
                    break;

                case MemberTypes.Property:
                    PropertyInfo property = (PropertyInfo)member;
                    if (property.GetIndexParameters().Length > 0)
                    {
                        continue;
                    }
                    if (colset.Mode == IniCollectionMode.IndexOnly && typeof(ICollection).IsAssignableFrom(property.PropertyType))
                    {
                        if (collection != null)
                        {
                            throw new Exception("IniCollectionMode.IndexOnly cannot be used on multiple members of a Type.");
                        }
                        collection = member;
                        continue;
                    }
                    defval  = property.PropertyType.GetDefaultValue();
                    defattr = (DefaultValueAttribute)Attribute.GetCustomAttribute(member, typeof(DefaultValueAttribute), true);
                    if (defattr != null)
                    {
                        defval = defattr.Value;
                    }
                    object     propval   = DeserializeInternal(membername, property.PropertyType, defval, ini, fullname, false, colset);
                    MethodInfo setmethod = property.GetSetMethod();
                    if (setmethod == null)
                    {
                        continue;
                    }
                    setmethod.Invoke(result, new object[] { propval });
                    break;
                }
            }
            if (collection != null)
            {
                switch (collection.MemberType)
                {
                case MemberTypes.Field:
                    FieldInfo field = (FieldInfo)collection;
                    field.SetValue(result, DeserializeInternal(collection.Name, field.FieldType, field.FieldType.GetDefaultValue(), ini, fullname, false, ((IniCollectionAttribute)Attribute.GetCustomAttribute(collection, typeof(IniCollectionAttribute), true)).Settings));
                    break;

                case MemberTypes.Property:
                    PropertyInfo property  = (PropertyInfo)collection;
                    object       propval   = DeserializeInternal(collection.Name, property.PropertyType, property.PropertyType.GetDefaultValue(), ini, fullname, false, ((IniCollectionAttribute)Attribute.GetCustomAttribute(collection, typeof(IniCollectionAttribute), true)).Settings);
                    MethodInfo   setmethod = property.GetSetMethod();
                    if (setmethod == null)
                    {
                        break;
                    }
                    setmethod.Invoke(result, new object[] { propval });
                    break;
                }
            }
            ini.Remove(rootObject ? string.Empty : name);
            return(result);
        }