public static NMSTemplate DeserializeEXml(EXmlBase xmlData) { NMSTemplate template = null; if (xmlData.GetType() == typeof(EXmlData)) { template = TemplateFromName(((EXmlData)xmlData).Template); } else if (xmlData.GetType() == typeof(EXmlProperty)) { template = TemplateFromName(((EXmlProperty)xmlData).Value.Replace(".xml", "")); } if (template == null) { return(null); } Type templateType = template.GetType(); var templateFields = templateType.GetFields().OrderBy(field => field.MetadataToken); // hack to get fields in order of declaration (todo: use something less hacky, this might break mono?) foreach (var templateField in templateFields) { NMSAttribute settings = templateField.GetCustomAttribute <NMSAttribute>(); if (settings?.DefaultValue != null) { templateField.SetValue(template, settings.DefaultValue); } } foreach (var xmlProperty in xmlData.Elements.OfType <EXmlProperty>()) { FieldInfo field = templateType.GetField(xmlProperty.Name); object fieldValue = null; if (field.FieldType == typeof(NMSTemplate) || field.FieldType.BaseType == typeof(NMSTemplate)) { fieldValue = DeserializeEXml(xmlProperty); } else { Type fieldType = field.FieldType; NMSAttribute settings = field.GetCustomAttribute <NMSAttribute>(); fieldValue = DeserializeEXmlValue(template, fieldType, field, xmlProperty, templateType, settings); } field.SetValue(template, fieldValue); } foreach (EXmlData innerXmlData in xmlData.Elements.OfType <EXmlData>()) { FieldInfo field = templateType.GetField(innerXmlData.Name); NMSTemplate innerTemplate = DeserializeEXml(innerXmlData); field.SetValue(template, innerTemplate); } return(template); }
public EXmlBase SerializeEXmlValue(Type fieldType, FieldInfo field, NMSAttribute settings, object value) { string t = fieldType.Name; int i = 0; switch (fieldType.Name) { case "String": case "Single": case "Boolean": case "Int16": case "UInt16": case "Int32": case "UInt32": case "Int64": case "UInt64": var valueStr = value.ToString(); if (fieldType.Name == "Int32") { var valuesMethod = GetType().GetMethod(field.Name + "Values"); // if we have an "xxxValues()" method in the struct, use that to get the value name if (valuesMethod != null) { if (((int)value) == -1) { valueStr = ""; } else { string[] values = (string[])valuesMethod.Invoke(this, null); valueStr = values[(int)value]; } } else if (settings?.EnumValue != null) { if (((int)value) == -1) { valueStr = ""; } else { valueStr = settings.EnumValue[(int)value]; } } } return(new EXmlProperty { Name = field.Name, Value = valueStr }); case "Byte[]": byte[] bytes = (byte[])value; string base64Value = bytes == null ? null : Convert.ToBase64String(bytes); return(new EXmlProperty { Name = field.Name, Value = base64Value }); case "List`1": var listType = field.FieldType.GetGenericArguments()[0]; EXmlProperty listProperty = new EXmlProperty { Name = field.Name }; IList templates = (IList)value; i = 0; foreach (var template in templates) { EXmlBase data = SerializeEXmlValue(listType, field, settings, template); if (settings?.EnumValue != null) { data.Name = settings.EnumValue[i]; i++; } else { data.Name = null; } listProperty.Elements.Add(data); } return(listProperty); case "NMSTemplate": if (value != null) { NMSTemplate template = (NMSTemplate)value; EXmlData templateXmlData = template.SerializeEXml(); templateXmlData.Name = field.Name; return(templateXmlData); } return(null); default: if (fieldType.BaseType.Name == "NMSTemplate") { NMSTemplate template = (NMSTemplate)value; EXmlData templateXmlData = template.SerializeEXml(); templateXmlData.Name = field.Name; return(templateXmlData); } else if (fieldType.IsArray) { var arrayType = field.FieldType.GetElementType(); EXmlProperty arrayProperty = new EXmlProperty { Name = field.Name }; Array array = (Array)value; i = 0; foreach (var template in array) { EXmlBase data = SerializeEXmlValue(arrayType, field, settings, template); if (settings?.EnumValue != null) { data.Name = settings.EnumValue[i]; i++; } else { data.Name = null; } arrayProperty.Elements.Add(data); } return(arrayProperty); } else { throw new Exception(string.Format("Unable to encode {0} to EXml!", field)); } } }