mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-04-05 22:01:33 +00:00
142 lines
4.9 KiB
C#
142 lines
4.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Xml.Serialization;
|
|
using SabreTools.Data.Models;
|
|
using SabreTools.Data.Models.Metadata;
|
|
|
|
namespace SabreTools.Metadata
|
|
{
|
|
// TODO: Investigate ways of either caching or speeding up these methods
|
|
public static class TypeHelper
|
|
{
|
|
/// <summary>
|
|
/// Get constant values for the given type, if possible
|
|
/// </summary>
|
|
/// <remarks>Does not return any values marked with the <see cref="NoFilterAttribute"/></remarks>
|
|
public static string[]? GetConstants(Type? type)
|
|
{
|
|
if (type is null)
|
|
return null;
|
|
|
|
var fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
|
|
if (fields is null)
|
|
return null;
|
|
|
|
FieldInfo[] noFilterFields = Array.FindAll(fields,
|
|
f => f.IsLiteral
|
|
&& !f.IsInitOnly
|
|
&& Attribute.GetCustomAttributes(f, typeof(NoFilterAttribute)).Length == 0);
|
|
|
|
string[] constantValues = Array.ConvertAll(noFilterFields,
|
|
f => (f.GetRawConstantValue() as string) ?? string.Empty);
|
|
|
|
return Array.FindAll(constantValues, s => s.Length > 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempt to get all DatItem types
|
|
/// </summary>
|
|
public static string[] GetDatItemTypeNames()
|
|
{
|
|
List<string> typeNames = [];
|
|
|
|
// Loop through all loaded assemblies
|
|
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
{
|
|
// If not all types can be loaded, use the ones that could be
|
|
Type?[] assemblyTypes = [];
|
|
try
|
|
{
|
|
assemblyTypes = assembly.GetTypes();
|
|
}
|
|
catch (ReflectionTypeLoadException rtle)
|
|
{
|
|
assemblyTypes = Array.FindAll(rtle.Types ?? [], t => t is not null);
|
|
}
|
|
|
|
// Loop through all types
|
|
foreach (Type? type in assemblyTypes)
|
|
{
|
|
// If the type is invalid
|
|
if (type is null)
|
|
continue;
|
|
|
|
// If the type isn't a class or doesn't implement the interface
|
|
if (!type.IsClass || !typeof(DatItem).IsAssignableFrom(type))
|
|
continue;
|
|
|
|
// Get the XML type name
|
|
string? elementName = GetXmlRootAttributeElementName(type);
|
|
if (elementName is not null)
|
|
typeNames.Add(elementName);
|
|
}
|
|
}
|
|
|
|
return [.. typeNames];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempt to get the DatItem type from the name
|
|
/// </summary>
|
|
public static Type? GetDatItemType(string? itemType)
|
|
{
|
|
if (string.IsNullOrEmpty(itemType))
|
|
return null;
|
|
|
|
// Loop through all loaded assemblies
|
|
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
{
|
|
// If not all types can be loaded, use the ones that could be
|
|
Type?[] assemblyTypes = [];
|
|
try
|
|
{
|
|
assemblyTypes = assembly.GetTypes();
|
|
}
|
|
catch (ReflectionTypeLoadException rtle)
|
|
{
|
|
assemblyTypes = Array.FindAll(rtle.Types ?? [], t => t is not null);
|
|
}
|
|
|
|
// Loop through all types
|
|
foreach (Type? type in assemblyTypes)
|
|
{
|
|
// If the type is invalid
|
|
if (type is null)
|
|
continue;
|
|
|
|
// If the type isn't a class or doesn't implement the interface
|
|
if (!type.IsClass || !typeof(DatItem).IsAssignableFrom(type))
|
|
continue;
|
|
|
|
// Get the XML type name
|
|
string? elementName = GetXmlRootAttributeElementName(type);
|
|
if (elementName is null)
|
|
continue;
|
|
|
|
// If the name matches
|
|
if (string.Equals(elementName, itemType, StringComparison.OrdinalIgnoreCase))
|
|
return type;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempt to get the XmlRootAttribute.ElementName value from a type
|
|
/// </summary>
|
|
public static string? GetXmlRootAttributeElementName(Type? type)
|
|
{
|
|
if (type is null)
|
|
return null;
|
|
|
|
#if NET20 || NET35 || NET40
|
|
return (Attribute.GetCustomAttribute(type, typeof(XmlRootAttribute)) as XmlRootAttribute)!.ElementName;
|
|
#else
|
|
return type.GetCustomAttribute<XmlRootAttribute>()?.ElementName;
|
|
#endif
|
|
}
|
|
}
|
|
}
|