118 lines
3.5 KiB
C#
118 lines
3.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Xml;
|
|
|
|
using RobloxFiles.Tokens;
|
|
|
|
namespace RobloxFiles.XmlFormat
|
|
{
|
|
public static class XmlPropertyTokens
|
|
{
|
|
private static readonly Dictionary<string, IXmlPropertyToken> Handlers = new Dictionary<string, IXmlPropertyToken>();
|
|
|
|
static XmlPropertyTokens()
|
|
{
|
|
// Initialize the PropertyToken handler singletons.
|
|
Type IXmlPropertyToken = typeof(IXmlPropertyToken);
|
|
var assembly = Assembly.GetExecutingAssembly();
|
|
|
|
var handlerTypes = assembly.GetTypes()
|
|
.Where(type => IXmlPropertyToken.IsAssignableFrom(type))
|
|
.Where(type => type != IXmlPropertyToken);
|
|
|
|
var propTokens = handlerTypes
|
|
.Select(handlerType => Activator.CreateInstance(handlerType))
|
|
.Cast<IXmlPropertyToken>();
|
|
|
|
foreach (IXmlPropertyToken propToken in propTokens)
|
|
{
|
|
var tokens = propToken.XmlPropertyToken.Split(';')
|
|
.Select(token => token.Trim())
|
|
.ToList();
|
|
|
|
tokens.ForEach(token => Handlers.Add(token, propToken));
|
|
}
|
|
}
|
|
|
|
public static bool ReadPropertyGeneric<T>(XmlNode token, out T outValue) where T : struct
|
|
{
|
|
if (token == null)
|
|
{
|
|
var name = nameof(token);
|
|
throw new ArgumentNullException(name);
|
|
}
|
|
|
|
try
|
|
{
|
|
string value = token.InnerText;
|
|
Type type = typeof(T);
|
|
|
|
object result = null;
|
|
|
|
if (type == typeof(int))
|
|
result = Formatting.ParseInt(value);
|
|
else if (type == typeof(float))
|
|
result = Formatting.ParseFloat(value);
|
|
else if (type == typeof(double))
|
|
result = Formatting.ParseDouble(value);
|
|
|
|
if (result == null)
|
|
{
|
|
Type resultType = typeof(T);
|
|
var converter = TypeDescriptor.GetConverter(resultType);
|
|
result = converter.ConvertFromString(token.InnerText);
|
|
}
|
|
|
|
outValue = (T)result;
|
|
return true;
|
|
}
|
|
catch (NotSupportedException)
|
|
{
|
|
outValue = default;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static bool ReadPropertyGeneric<T>(Property prop, PropertyType propType, XmlNode token) where T : struct
|
|
{
|
|
if (prop == null)
|
|
{
|
|
var name = nameof(prop);
|
|
throw new ArgumentNullException(name);
|
|
}
|
|
|
|
if (ReadPropertyGeneric(token, out T result))
|
|
{
|
|
prop.Type = propType;
|
|
prop.Value = result;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static IXmlPropertyToken GetHandler(string tokenName)
|
|
{
|
|
IXmlPropertyToken result = null;
|
|
|
|
if (Handlers.ContainsKey(tokenName))
|
|
result = Handlers[tokenName];
|
|
|
|
return result;
|
|
}
|
|
|
|
public static T GetHandler<T>() where T : IXmlPropertyToken
|
|
{
|
|
IXmlPropertyToken result = Handlers.Values
|
|
.Where(token => token is T)
|
|
.First();
|
|
|
|
return (T)result;
|
|
}
|
|
}
|
|
}
|