TPS1100-Convert/MadMilkman.Ini-1.0.6/MadMilkman.Ini/IniUtilities/IniSerializer.cs
2024-06-02 05:35:03 +02:00

129 lines
4.6 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
namespace MadMilkman.Ini
{
internal static class IniSerializer
{
private static readonly Predicate<Type> PropertyTypeVerifier = IniKey.IsSupportedValueType;
public static void Serialize<T>(T source, IniSection section) where T : class, new()
{
foreach (var propertyPair in GetPropertyPairs(typeof(T)))
{
var key = section.Keys.Add(propertyPair.Key);
if (key.ParentCollectionCore != null)
SetKeyValue(propertyPair.Value, source, key);
}
}
public static T Deserialize<T>(IniSection section) where T : class, new()
{
T destination = new T();
foreach (var propertyPair in GetPropertyPairs(typeof(T)))
{
var key = section.Keys[propertyPair.Key];
if (key != null)
SetPropertyValue(propertyPair.Value, destination, key);
}
return destination;
}
private static IEnumerable<KeyValuePair<string, PropertyInfo>> GetPropertyPairs(Type type)
{
foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!IniSerializer.PropertyTypeVerifier(property.PropertyType))
continue;
string propertyName = null;
var attributes = property.GetCustomAttributes(typeof(IniSerializationAttribute), false);
if (attributes.Length > 0)
{
var attribute = (IniSerializationAttribute)attributes[0];
if (attribute.Ignore)
continue;
propertyName = attribute.Alias;
}
yield return new KeyValuePair<string, PropertyInfo>((propertyName) ?? property.Name, property);
}
}
private static void SetKeyValue(PropertyInfo property, object source, IniKey key)
{
object propertyValue = property.GetValue(source, null);
if (propertyValue == null)
return;
if (property.PropertyType.IsArray || property.PropertyType.GetInterface(typeof(IList).Name) != null)
{
var values = new List<string>();
/* MZ(2016-01-02): Fixed issue with null items in array and list. */
foreach (var item in (IEnumerable)propertyValue)
values.Add(item != null ? item.ToString() : null);
key.Values = values.ToArray();
}
else
key.Value = propertyValue.ToString();
}
private static void SetPropertyValue(PropertyInfo property, object destination, IniKey key)
{
var propertyType = property.PropertyType;
if (propertyType.IsArray)
{
/* MZ(2016-01-02): Fixed issue with null array and list. */
if (!key.IsValueArray)
return;
var values = key.Values;
var itemType = propertyType.GetElementType();
var array = Array.CreateInstance(itemType, values.Length);
for (int i = 0; i < values.Length; i++)
array.SetValue(
TypeDescriptor.GetConverter(itemType).ConvertFromInvariantString(values[i]),
i);
property.SetValue(destination, array, null);
}
else if (propertyType.GetInterface(typeof(IList).Name) != null)
{
/* MZ(2016-01-02): Fixed issue with null array and list. */
if (!key.IsValueArray)
return;
var itemType = propertyType.GetGenericArguments()[0];
var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(itemType));
var values = key.Values;
if (!(values.Length == 1 && string.IsNullOrEmpty(values[0])))
foreach (var value in values)
list.Add(
TypeDescriptor.GetConverter(itemType).ConvertFromInvariantString(value));
property.SetValue(destination, list, null);
}
else
property.SetValue(
destination,
TypeDescriptor.GetConverter(propertyType).ConvertFromInvariantString(key.Value),
null);
}
}
}