x) Fix EOL on file

This commit is contained in:
Marc Hernandez 2024-04-28 17:09:29 -07:00
parent 0bd6b086f6
commit dcd15a2663
3 changed files with 372 additions and 373 deletions

1
.gitattributes vendored
View File

@ -19,6 +19,7 @@
# Source code # Source code
# Source code # Source code
# Source code # Source code
*.cs text eol=lf
*.rs text *.rs text
*.bash text eol=lf *.bash text eol=lf
*.bat text eol=crlf *.bat text eol=crlf

View File

@ -1,188 +1,187 @@
using System; using System;
using System.IO; using System.IO;
using System.Xml; using System.Xml;
using System.Reflection; using System.Reflection;
/* /*
TODO: TODO:
x) x)
*/ */
namespace lib namespace lib
{ {
public class DescAttribute: Attribute public class DescAttribute : Attribute
{ {
public string Desc { get; private set; } public string Desc { get; private set; }
public DescAttribute( string desc ) public DescAttribute( string desc )
{ {
Desc = desc; Desc = desc;
} }
} }
[Serializable] [Serializable]
public class ConfigCfg: Config public class ConfigCfg : Config
{ {
public readonly bool writeOutTemplateFiles = true; public readonly bool writeOutTemplateFiles = true;
} }
public interface ConfigBase
{
[Serializable]
public class Config }
{
/* [Serializable]
static public Config Load( string filename ) public class Config : ConfigBase
{ {
return null;
} //private int _test = 0;
*/
private static ConfigCfg s_cfg = new();
static ConfigCfg s_cfg = new ConfigCfg();
static public void startup( string filename )
static public void startup( string filename ) {
{ res.Mgr.register( load );
res.Mgr.register<Config>( load ); res.Mgr.registerSub( typeof( Config ) );
res.Mgr.registerSub( typeof( Config ) );
s_cfg = load<ConfigCfg>( filename );
s_cfg = Config.load<ConfigCfg>( filename );
}
}
#region SaveLoad
#region SaveLoad /*
/* static public res.Ref<Config> res_load( string filename )
static public res.Ref<Config> res_load( string filename ) {
{ return new res.Ref<Config>( filename, load( filename ) );
return new res.Ref<Config>( filename, load( filename ) ); }
} */
*/
static public T res_load<T>( string filename ) where T : Config
static public T res_load<T>( string filename ) where T : Config {
{ return load<T>( filename );
return load<T>( filename ); }
}
/*
/* static public ResRefConfig res_load( string filename, Type t )
static public ResRefConfig res_load( string filename, Type t ) {
{ return new ResRefConfig( filename, load( filename, t ) );
return new ResRefConfig( filename, load( filename, t ) ); }
} */
*/
static public Config load( string filename )
static public Config load( string filename ) {
{ return load( filename, null );
return load( filename, null ); }
}
static public T load<T>( string filename ) where T : Config
static public T load<T>( string filename ) where T : Config {
{ return (T)load( filename, typeof( T ) );
return (T)load( filename, typeof( T ) ); }
}
static public Config load( string filename, Type t )
static public Config load( string filename, Type t ) {
{ Config cfg = null;
Config cfg = null;
try
try {
{ if( File.Exists( filename ) )
if( File.Exists( filename ) ) {
{ FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read );
FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
XmlFormatter2 formatter = new XmlFormatter2();
XmlFormatter2 formatter = new XmlFormatter2();
cfg = (Config)( t != null ? formatter.DeserializeKnownType( fs, t ) : formatter.Deserialize( fs ) );
cfg = (Config)( t != null ? formatter.DeserializeKnownType( fs, t ) : formatter.Deserialize( fs ) );
cfg.SetFilename( filename );
cfg.SetFilename( filename ); }
} else
else {
{ cfg = CreateTemplate( filename, t );
cfg = CreateTemplate( filename, t ); }
} }
} catch( IOException )
catch( IOException ) {
{ cfg = CreateTemplate( filename, t );
cfg = CreateTemplate( filename, t ); }
}
return cfg;
return cfg; }
}
private static Config CreateTemplate( string filename, Type t )
private static Config CreateTemplate( string filename, Type t ) {
{ Type[] types = new Type[0];
Type[] types = new Type[0]; object[] parms = new object[0];
object[] parms = new object[0];
//types[ 0 ] = typeof( string );
//types[ 0 ] = typeof( string ); //parms[ 0 ] = filename;
//parms[ 0 ] = filename; Config cfg = null;
Config cfg = null;
ConstructorInfo cons = t?.GetConstructor( types );
ConstructorInfo cons = t?.GetConstructor(types);
try
try {
{ cfg = (Config)cons?.Invoke( parms );
cfg = (Config)cons?.Invoke( parms ); }
} catch( Exception e )
catch( Exception e ) {
{ log.error( $"Exception while creating config {t.ToString()}, Msg {e.Message}" );
log.error( $"Exception while creating config {t.ToString()}, Msg {e.Message}" ); }
}
//cfg.SetFilename( filename );
//cfg.SetFilename( filename );
if( s_cfg.writeOutTemplateFiles )
if( s_cfg.writeOutTemplateFiles ) {
{ var templateFile = $"templates/{filename}";
var templateFile = $"templates/{filename}";
var dirName = Path.GetDirectoryName( templateFile );
var dirName = Path.GetDirectoryName(templateFile);
Util.checkAndAddDirectory( dirName );
lib.Util.checkAndAddDirectory( dirName );
log.info( $"Writing out template config of type {t?.Name} in {templateFile}" );
log.info( $"Writing out template config of type {t?.Name} in {templateFile}" );
save( cfg, templateFile );
Config.save( cfg, templateFile ); }
}
return cfg;
return cfg; }
}
static public void save( Config cfg )
static public void save( Config cfg ) {
{ save( cfg, cfg._filename );
Config.save( cfg, cfg.m_filename ); }
}
static public void save( Config cfg, String filename )
static public void save( Config cfg, String filename ) {
{ FileStream fs = new( filename, FileMode.Create, FileAccess.Write );
FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
XmlFormatter2 formatter = new();
XmlFormatter2 formatter = new XmlFormatter2();
formatter.Serialize( fs, cfg );
formatter.Serialize( fs, cfg );
fs.Close();
fs.Close(); }
} #endregion
#endregion
private string _filename = "{unknown}";
private string m_filename = "{unknown}";
public Config()
public Config() {
{ }
}
public Config( string filename )
public Config( string filename ) {
{ _filename = filename;
m_filename = filename; }
}
public String Filename { get { return _filename; } }
public String Filename { get { return m_filename; } }
protected void SetFilename( String filename ) { _filename = filename; }
protected void SetFilename( String filename ) { m_filename = filename; }
}
} }
}

View File

@ -10,8 +10,6 @@ using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices;
using static System.Net.WebRequestMethods;
using System.Linq; using System.Linq;
using System.Collections.Immutable; using System.Collections.Immutable;
@ -19,15 +17,15 @@ using System.Collections.Immutable;
/* /*
element and attribute names element and attribute names
- Element names are case-sensitive - Element names are case-sensitive
- Element names must start with a letter or underscore - Element names must start with a letter or underscore
- Element names cannot start with the letters xml(or XML, or Xml, etc) - Element names cannot start with the letters xml(or XML, or Xml, etc)
- Element names can contain letters, digits, hyphens, underscores, and periods - Element names can contain letters, digits, hyphens, underscores, and periods
- Element names cannot contain spaces - Element names cannot contain spaces
* TODO * TODO
* x) Add the ability for correctly named attributes to be able to fill in classes * x) Add the ability for correctly named attributes to be able to fill in classes
* x) * x)
*/ */
@ -46,15 +44,15 @@ namespace lib
[Flags] [Flags]
public enum Types public enum Types
{ {
Fields = 0b_0001, Fields = 0b_0001,
Props = 0b_0010, Props = 0b_0010,
Implied = 0b_0100, Implied = 0b_0100,
Explicit= 0b_1000, Explicit = 0b_1000,
None = 0b_0000,
None = 0b_0000,
Default = Fields, Default = Fields,
All = Fields | Props, All = Fields | Props,
} }
public class Ser : Attribute public class Ser : Attribute
@ -70,22 +68,22 @@ namespace lib
{ {
} }
public class ChildAttributes : Attribute public class ChildAttribute : Attribute
{ {
public string[] Values { get; private set; } public string[] Values { get; private set; }
public ChildAttributes( params string[] values ) public ChildAttribute( params string[] values )
{ {
this.Values = values; this.Values = values;
} }
} }
public class ChildFieldsAttribute : ChildAttributes public class ChildFieldsAttribute : ChildAttribute
{ {
public ChildFieldsAttribute( params string[] values ) : base( values ) { } public ChildFieldsAttribute( params string[] values ) : base( values ) { }
} }
public class ChildPropsAttribute : ChildAttributes public class ChildPropsAttribute : ChildAttribute
{ {
public ChildPropsAttribute( params string[] values ) : base( values ) { } public ChildPropsAttribute( params string[] values ) : base( values ) { }
} }
@ -103,7 +101,7 @@ namespace lib
} }
public record struct TypeProxy( Func<object, string> ser, Func<string, string, object> des ); public record struct TypeProxy( Func<object, string> ser, Func<string, string, object> des );
//public record struct CollectionCreator( Func<IEnumerable, object> FnCreate ); //public record struct CollectionCreator( Func<IEnumerable, object> FnCreate );
//These 2 enums are for serialization //These 2 enums are for serialization
@ -122,14 +120,14 @@ namespace lib
} }
public class XmlFormatter2Cfg: Config public class XmlFormatter2Cfg : Config
{ {
public Datastructure datastructure = Datastructure.Tree; public Datastructure datastructure = Datastructure.Tree;
public int Version = 2; public int Version = 2;
public Dictionary<string, List<string>> WLProps = new(); public Dictionary<string, List<string>> WLProps = new();
public Dictionary<string, List<string>> WLFields= new(); public Dictionary<string, List<string>> WLFields = new();
public Dictionary<Type, TypeProxy> TypeProxy = new(); public Dictionary<Type, TypeProxy> TypeProxy = new();
@ -141,14 +139,11 @@ namespace lib
public Types TypesDefault = Types.Fields; public Types TypesDefault = Types.Fields;
} }
public class XmlFormatter2: IFormatter public class XmlFormatter2 : IFormatter
{ {
public StreamingContext Context { get; set; } public StreamingContext Context { get; set; }
static Random s_rnd = new Random(); private XmlFormatter2Cfg _cfg = new();
int m_rndVal = s_rnd.Next();
XmlFormatter2Cfg m_cfg = new XmlFormatter2Cfg();
#region Unimplimented #region Unimplimented
public ISurrogateSelector SurrogateSelector public ISurrogateSelector SurrogateSelector
@ -174,7 +169,7 @@ namespace lib
{ {
//Context = new StreamingContext( StreamingContextStates.All ); //Context = new StreamingContext( StreamingContextStates.All );
m_cfg = cfg; _cfg = cfg;
log.warn( $"XML serialization is NOT fast" ); log.warn( $"XML serialization is NOT fast" );
} }
@ -189,16 +184,13 @@ namespace lib
} }
public T Deserialize<T>(Stream stream) public T Deserialize<T>( Stream stream ) => (T)DeserializeKnownType( stream, typeof( T ) );
{
return (T)DeserializeKnownType(stream, typeof(T));
}
public object DeserializeKnownType( Stream stream, Type t ) public object DeserializeKnownType( Stream stream, Type t )
{ {
XmlTextReader reader = new XmlTextReader(stream); XmlTextReader reader = new XmlTextReader( stream );
object obj = Deserialize(reader, t); object obj = Deserialize( reader, t );
return obj; return obj;
} }
@ -220,12 +212,12 @@ namespace lib
return Deserialize( doc.DocumentElement, null, t, null ); return Deserialize( doc.DocumentElement, null, t, null );
} }
public void DeserializeInto<T>(Stream stream, T obj) public void DeserializeInto<T>( Stream stream, T obj )
{ {
XmlTextReader reader = new XmlTextReader( stream ); XmlTextReader reader = new( stream );
reader.Read(); reader.Read();
XmlDocument doc = new XmlDocument(); XmlDocument doc = new();
doc.Load( reader ); doc.Load( reader );
@ -236,7 +228,7 @@ namespace lib
{ {
//lib.log.info( "object Deserialize( XmlElement elem ) {0} {1}", m_rndVal, m_alreadySerialized.Count ); //lib.log.info( "object Deserialize( XmlElement elem ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
string typename = elem.HasAttribute("_.t") ? elem.GetAttribute("_.t") : elem.Name; string typename = elem.HasAttribute( "_.t" ) ? elem.GetAttribute( "_.t" ) : elem.Name;
return Deserialize( elem, null, typename ); return Deserialize( elem, null, typename );
} }
@ -248,8 +240,8 @@ namespace lib
Type type = null; Type type = null;
// @@@@: This should go backwards, we tend to lookup our own stuff, then builtins. // @@@@: This should go backwards, we tend to lookup our own stuff, then builtins.
// Also, cache a typename into its assembly. // Also, cache a typename into its assembly.
foreach( Assembly a in assems ) foreach( Assembly a in assems )
{ {
type = a.GetType( typename ); type = a.GetType( typename );
@ -266,10 +258,7 @@ namespace lib
return Deserialize( elem, null, type, null ); return Deserialize( elem, null, type, null );
} }
private bool IsEnumerable( Type type ) static private bool IsEnumerable( Type type ) => type.IsAssignableTo( typeof( IEnumerable ) );
{
return type.IsAssignableTo( typeof(IEnumerable) );
}
private object Deserialize( XmlElement elem, MemberInfo mi, Type type, object existing /*, object enclosing = null*/ ) private object Deserialize( XmlElement elem, MemberInfo mi, Type type, object existing /*, object enclosing = null*/ )
{ {
@ -281,7 +270,7 @@ namespace lib
{ {
try try
{ {
TypeCode typeCode = Type.GetTypeCode(type); TypeCode typeCode = Type.GetTypeCode( type );
if( typeCode != TypeCode.Object ) if( typeCode != TypeCode.Object )
{ {
@ -291,13 +280,13 @@ namespace lib
{ {
if( !type.IsArray ) if( !type.IsArray )
{ {
if( IsEnumerable(type) ) if( IsEnumerable( type ) )
{ {
return DeserializeCollection( elem, mi, type ); return DeserializeCollection( elem, mi, type );
} }
else else
{ {
object obj = DeserializeObject(elem, mi, type, existing); object obj = DeserializeObject( elem, mi, type, existing );
if( obj is I_Serialize ) if( obj is I_Serialize )
{ {
@ -328,7 +317,7 @@ namespace lib
{ {
mm_types[0] = t; mm_types[0] = t;
var fn = GetType().GetMethod("GetDefaultGeneric").MakeGenericMethod(mm_types); var fn = GetType().GetMethod( "GetDefaultGeneric" ).MakeGenericMethod( mm_types );
return fn.Invoke( this, null ); return fn.Invoke( this, null );
} }
@ -342,11 +331,11 @@ namespace lib
{ {
string val = ""; string val = "";
if( elem.HasAttribute("v") ) if( elem.HasAttribute( "v" ) )
{ {
val = elem.GetAttribute("v"); val = elem.GetAttribute( "v" );
} }
else if( elem.HasAttribute(name) ) else if( elem.HasAttribute( name ) )
{ {
val = elem.GetAttribute( name ); val = elem.GetAttribute( name );
} }
@ -355,7 +344,7 @@ namespace lib
val = elem.InnerText; val = elem.InnerText;
} }
if ( !type.IsEnum ) if( !type.IsEnum )
{ {
try try
{ {
@ -392,7 +381,7 @@ namespace lib
foreach( Assembly a in ass ) foreach( Assembly a in ass )
{ {
Type t = a.GetType(shortname); Type t = a.GetType( shortname );
if( t != null ) if( t != null )
{ {
@ -502,25 +491,25 @@ namespace lib
} }
else else
{ {
HydrateObjectOfNarrowType(elem, mi, finalType, obj); HydrateObjectOfNarrowType( elem, mi, finalType, obj );
} }
return obj; return obj;
} }
private void HydrateObjectOfNarrowType(XmlElement elem, MemberInfo mi, Type narrowType, object obj) private void HydrateObjectOfNarrowType( XmlElement elem, MemberInfo mi, Type narrowType, object obj )
{ {
XmlNodeList allChildren = elem.ChildNodes; XmlNodeList allChildren = elem.ChildNodes;
bool filterFields, filterProps, doImpls, doFields, doProps; bool filterFields, filterProps, doImpls, doFields, doProps;
HashSet<string> whitelistFields, whitelistProps; HashSet<string> whitelistFields, whitelistProps;
GetFilters(m_cfg.TypesDefault, mi, narrowType, out filterFields, out filterProps, out doImpls, out doFields, out doProps, out whitelistFields, out whitelistProps); GetFilters( _cfg.TypesDefault, mi, narrowType, out filterFields, out filterProps, out doImpls, out doFields, out doProps, out whitelistFields, out whitelistProps );
if (doFields || doImpls) if( doFields || doImpls )
{ {
var fields = refl.GetAllFields(narrowType); var fields = refl.GetAllFields( narrowType );
foreach (FieldInfo childFi in fields) foreach( FieldInfo childFi in fields )
{ {
String name = childFi.Name; String name = childFi.Name;
@ -529,7 +518,7 @@ namespace lib
string propName = ""; string propName = "";
if( name.StartsWith( "<" ) && name.EndsWith( "BackingField" ) ) if( name.StartsWith( "<" ) && name.EndsWith( "BackingField" ) )
{ {
var gtIndex = name.IndexOf( '>' ); var gtIndex = name.IndexOf( '>' );
@ -548,34 +537,37 @@ namespace lib
//if( name.EndsWith( ) ) //if( name.EndsWith( ) )
//This is to convert c# names that would be bad as XML tags //This is to convert c# names that would be bad as XML tags
name = refl.TypeToIdentifier(name); name = refl.TypeToIdentifier( name );
// @@@ TODO This doesnt yet handle propNames! // @@@ TODO This doesnt yet handle propNames!
if (FilterField(filterFields, doImpls, whitelistFields, childFi as MemberInfo, name)) continue; if( FilterField( filterFields, doImpls, whitelistFields, childFi as MemberInfo, name ) )
continue;
string attValue = elem.GetAttribute( name ); string attValue = elem.GetAttribute( name );
if( !string.IsNullOrWhiteSpace( propName ) && string.IsNullOrWhiteSpace( attValue ) ) attValue = elem.GetAttribute( propName ); if( !string.IsNullOrWhiteSpace( propName ) && string.IsNullOrWhiteSpace( attValue ) )
attValue = elem.GetAttribute( propName );
if( !string.IsNullOrWhiteSpace( attValue ) ) if( !string.IsNullOrWhiteSpace( attValue ) )
{ {
object existingObj = childFi.GetValue(obj); object existingObj = childFi.GetValue( obj );
object childObj = DeserializeConcrete(elem, childFi, attValue, childFi.FieldType); object childObj = DeserializeConcrete( elem, childFi, attValue, childFi.FieldType );
childFi.SetValue(obj, childObj); childFi.SetValue( obj, childObj );
} }
else else
{ {
XmlElement childElem = getNamedChild(allChildren, name); XmlElement childElem = getNamedChild( allChildren, name );
if( childElem == null && !string.IsNullOrWhiteSpace( propName ) ) childElem = getNamedChild( allChildren, propName ); if( childElem == null && !string.IsNullOrWhiteSpace( propName ) )
childElem = getNamedChild( allChildren, propName );
if (childElem != null) if( childElem != null )
{ {
object existingObj = childFi.GetValue(obj); object existingObj = childFi.GetValue( obj );
object childObj = Deserialize(childElem, childFi, childFi.FieldType, existingObj); object childObj = Deserialize( childElem, childFi, childFi.FieldType, existingObj );
childFi.SetValue(obj, childObj); childFi.SetValue( obj, childObj );
} }
} }
@ -583,11 +575,11 @@ namespace lib
} }
if (doProps || doImpls) if( doProps || doImpls )
{ {
var props = refl.GetAllProperties(narrowType); var props = refl.GetAllProperties( narrowType );
foreach (var childPi in props) foreach( var childPi in props )
{ {
String name = childPi.Name; String name = childPi.Name;
var dontAtt = childPi.GetCustomAttributes<lib.Dont>(); var dontAtt = childPi.GetCustomAttributes<lib.Dont>();
@ -596,30 +588,31 @@ namespace lib
continue; continue;
} }
name = refl.TypeToIdentifier(name); name = refl.TypeToIdentifier( name );
if (FilterField(filterProps, doImpls, whitelistProps, childPi as PropertyInfo, name)) continue; if( FilterField( filterProps, doImpls, whitelistProps, childPi as PropertyInfo, name ) )
continue;
XmlElement childElem = getNamedChild(allChildren, name); XmlElement childElem = getNamedChild( allChildren, name );
if (childElem != null) if( childElem != null )
{ {
object existingObj = childPi.GetValue(obj); object existingObj = childPi.GetValue( obj );
object childObj = Deserialize(childElem, childPi, childPi.PropertyType, existingObj); object childObj = Deserialize( childElem, childPi, childPi.PropertyType, existingObj );
var setMethod = childPi.GetSetMethod(); var setMethod = childPi.GetSetMethod();
if (setMethod != null) if( setMethod != null )
{ {
//Object o = Activator.CreateInstance( setMethod.ReflectedType ); //Object o = Activator.CreateInstance( setMethod.ReflectedType );
setMethod.Invoke(obj, new object[] { childObj }); setMethod.Invoke( obj, new object[] { childObj } );
//setMethod.CreateDelegate() //setMethod.CreateDelegate()
} }
else else
{ {
childPi.SetValue(obj, childObj); childPi.SetValue( obj, childObj );
} }
} }
@ -631,10 +624,12 @@ namespace lib
{ {
if( doImpls ) if( doImpls )
{ {
if( mi.GetCustomAttribute<ChildAttributes>( true ) == null ) return true; if( mi.GetCustomAttribute<ChildAttribute>( true ) == null )
return true;
} }
if( filterFields && !whitelistFields.Contains( name ) ) return true; if( filterFields && !whitelistFields.Contains( name ) )
return true;
return false; return false;
} }
@ -674,7 +669,7 @@ namespace lib
{ {
if( arrNodeList.Item( i ) is XmlElement ) if( arrNodeList.Item( i ) is XmlElement )
{ {
XmlElement arrElem = (XmlElement)arrNodeList.Item(i); XmlElement arrElem = (XmlElement)arrNodeList.Item( i );
list.Add( Deserialize( arrElem, mi, genT[0], null ) ); list.Add( Deserialize( arrElem, mi, genT[0], null ) );
} }
@ -685,7 +680,7 @@ namespace lib
private object DeserializeCollection( XmlElement elem, MemberInfo mi, Type type ) private object DeserializeCollection( XmlElement elem, MemberInfo mi, Type type )
{ {
Type typeElem = typeof(object); Type typeElem = typeof( object );
if( type.GenericTypeArguments.Length == 1 ) if( type.GenericTypeArguments.Length == 1 )
{ {
@ -693,40 +688,40 @@ namespace lib
} }
else if( type.GenericTypeArguments.Length == 2 ) else if( type.GenericTypeArguments.Length == 2 )
{ {
typeElem = typeof(KeyValuePair<,>).MakeGenericType(type.GenericTypeArguments ); typeElem = typeof( KeyValuePair<,> ).MakeGenericType( type.GenericTypeArguments );
} }
string refString = elem.GetAttribute("ref"); string refString = elem.GetAttribute( "ref" );
int refInt = refString.Length > 0 ? Convert.ToInt32(refString) : -1; int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
XmlNodeList arrNodeList = elem.ChildNodes; XmlNodeList arrNodeList = elem.ChildNodes;
int length = arrNodeList.Count; int length = arrNodeList.Count;
Array arr = createArray(typeElem, refInt, length); Array arr = createArray( typeElem, refInt, length );
for( int i = 0; i < arr.Length; ++i ) for( int i = 0; i < arr.Length; ++i )
{ {
if( arrNodeList.Item( i ) is XmlElement ) if( arrNodeList.Item( i ) is XmlElement )
{ {
XmlElement arrElem = (XmlElement)arrNodeList.Item(i); XmlElement arrElem = (XmlElement)arrNodeList.Item( i );
var finalType = typeElem; var finalType = typeElem;
if (arrElem.HasAttribute("_.t")) if( arrElem.HasAttribute( "_.t" ) )
{ {
var typename = arrElem.GetAttribute("_.t"); var typename = arrElem.GetAttribute( "_.t" );
finalType = FindType(typename); finalType = FindType( typename );
if (finalType == null) if( finalType == null )
finalType = typeElem; finalType = typeElem;
} }
arr.SetValue( Deserialize( arrElem, mi, finalType, null), i ); arr.SetValue( Deserialize( arrElem, mi, finalType, null ), i );
} }
} }
var listType = (typeof(List<>)).MakeGenericType( typeElem ); var listType = ( typeof( List<> ) ).MakeGenericType( typeElem );
IList list = Activator.CreateInstance( listType ) as IList; IList list = Activator.CreateInstance( listType ) as IList;
foreach( var a in arr ) foreach( var a in arr )
@ -734,28 +729,28 @@ namespace lib
list.Add( a ); list.Add( a );
} }
MethodInfo ?toMeth = null; MethodInfo? toMeth = null;
var typeGen = Type.MakeGenericSignatureType( type ); var typeGen = Type.MakeGenericSignatureType( type );
if( type == typeof(ImmutableArray<>).MakeGenericType( typeElem ) ) if( type == typeof( ImmutableArray<> ).MakeGenericType( typeElem ) )
{ {
var genMeth = GetType().GetMethod("MakeImmutableArray", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); var genMeth = GetType().GetMethod( "MakeImmutableArray", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
toMeth = genMeth.MakeGenericMethod( typeElem ); toMeth = genMeth.MakeGenericMethod( typeElem );
} }
else if( type == typeof(ImmutableDictionary<,>).MakeGenericType( typeElem.GenericTypeArguments ) ) else if( type == typeof( ImmutableDictionary<,> ).MakeGenericType( typeElem.GenericTypeArguments ) )
{ {
var genMeth = GetType().GetMethod("MakeImmutableDictionary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); var genMeth = GetType().GetMethod( "MakeImmutableDictionary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
toMeth = genMeth.MakeGenericMethod( typeElem.GenericTypeArguments ); toMeth = genMeth.MakeGenericMethod( typeElem.GenericTypeArguments );
} }
else if( type == typeof(List<>).MakeGenericType( typeElem ) ) else if( type == typeof( List<> ).MakeGenericType( typeElem ) )
{ {
var genMeth = GetType().GetMethod("MakeList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); var genMeth = GetType().GetMethod( "MakeList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
toMeth = genMeth.MakeGenericMethod( typeElem ); toMeth = genMeth.MakeGenericMethod( typeElem );
} }
else if( type == typeof(Dictionary<,>).MakeGenericType( typeElem.GenericTypeArguments ) ) else if( type == typeof( Dictionary<,> ).MakeGenericType( typeElem.GenericTypeArguments ) )
{ {
var genMeth = GetType().GetMethod("MakeDictionary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); var genMeth = GetType().GetMethod( "MakeDictionary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
toMeth = genMeth.MakeGenericMethod( typeElem.GenericTypeArguments ); toMeth = genMeth.MakeGenericMethod( typeElem.GenericTypeArguments );
} }
@ -777,14 +772,14 @@ namespace lib
return arr; return arr;
} }
private object MakeImmutableDictionary<K,V>( List<KeyValuePair<K,V>> list ) private object MakeImmutableDictionary<K, V>( List<KeyValuePair<K, V>> list )
{ {
var dict = list.ToImmutableDictionary(); var dict = list.ToImmutableDictionary();
return dict; return dict;
} }
private object MakeDictionary<K,V>( List<KeyValuePair<K,V>> list ) private object MakeDictionary<K, V>( List<KeyValuePair<K, V>> list )
{ {
var dict = list.ToDictionary(); var dict = list.ToDictionary();
return dict; return dict;
@ -795,32 +790,32 @@ namespace lib
{ {
Type typeElem = type.GetElementType(); Type typeElem = type.GetElementType();
string refString = elem.GetAttribute("ref"); string refString = elem.GetAttribute( "ref" );
int refInt = refString.Length > 0 ? Convert.ToInt32(refString) : -1; int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
XmlNodeList arrNodeList = elem.ChildNodes; XmlNodeList arrNodeList = elem.ChildNodes;
int length = arrNodeList.Count; int length = arrNodeList.Count;
Array arr = createArray(typeElem, refInt, length); Array arr = createArray( typeElem, refInt, length );
for( int i = 0; i < arr.Length; ++i ) for( int i = 0; i < arr.Length; ++i )
{ {
if( arrNodeList.Item( i ) is XmlElement ) if( arrNodeList.Item( i ) is XmlElement )
{ {
XmlElement arrElem = (XmlElement)arrNodeList.Item(i); XmlElement arrElem = (XmlElement)arrNodeList.Item( i );
var finalType = typeElem; var finalType = typeElem;
if (arrElem.HasAttribute("_.t")) if( arrElem.HasAttribute( "_.t" ) )
{ {
var typename = arrElem.GetAttribute("_.t"); var typename = arrElem.GetAttribute( "_.t" );
finalType = FindType(typename); finalType = FindType( typename );
if (finalType == null) if( finalType == null )
finalType = typeElem; finalType = typeElem;
} }
arr.SetValue( Deserialize( arrElem, mi, finalType, null), i ); arr.SetValue( Deserialize( arrElem, mi, finalType, null ), i );
} }
} }
@ -829,16 +824,16 @@ namespace lib
private object createObject( XmlElement elem, string typename, int refInt, object obj ) private object createObject( XmlElement elem, string typename, int refInt, object obj )
{ {
Type type = Type.GetType(typename); Type type = Type.GetType( typename );
return createObject( elem, type, refInt, obj ); return createObject( elem, type, refInt, obj );
} }
private object createObject( XmlElement elem, Type type, int refInt, object existingObj ) private object createObject( XmlElement elem, Type type, int refInt, object existingObj )
{ {
TypeCode tc = Type.GetTypeCode(type); TypeCode tc = Type.GetTypeCode( type );
if( m_cfg.datastructure == Datastructure.Graph && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) ) if( _cfg.datastructure == Datastructure.Graph && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
{ {
//lib.log.info( "Reusing object for {0}", refInt ); //lib.log.info( "Reusing object for {0}", refInt );
return m_alreadySerialized[refInt]; return m_alreadySerialized[refInt];
@ -855,10 +850,10 @@ namespace lib
var tryType = type; var tryType = type;
TypeProxy? proxy = null; TypeProxy? proxy = null;
while( tryType != typeof(object) && obj == null ) while( tryType != typeof( object ) && obj == null )
{ {
//m_cfg.TypeProxy.TryGetValue( ) //m_cfg.TypeProxy.TryGetValue( )
if( m_cfg.TypeProxy.TryGetValue( tryType, out var newProxy ) ) if( _cfg.TypeProxy.TryGetValue( tryType, out var newProxy ) )
{ {
proxy = newProxy; proxy = newProxy;
break; break;
@ -890,7 +885,8 @@ namespace lib
// @@@ GROSS Fix the types so theyre known good. // @@@ GROSS Fix the types so theyre known good.
var isSubclass = type.IsSubclassOf( existingObjType ) || existingObjType.IsSubclassOf( type ); var isSubclass = type.IsSubclassOf( existingObjType ) || existingObjType.IsSubclassOf( type );
if( isSubclass ) return existingObj; if( isSubclass )
return existingObj;
// old // old
//if( type == existingObjType ) return existingObj; //if( type == existingObjType ) return existingObj;
@ -926,7 +922,7 @@ namespace lib
return obj; return obj;
} }
if( m_cfg.datastructure == Datastructure.Graph && refInt > 0 ) if( _cfg.datastructure == Datastructure.Graph && refInt > 0 )
{ {
m_alreadySerialized[refInt] = obj; m_alreadySerialized[refInt] = obj;
} }
@ -937,24 +933,24 @@ namespace lib
private Array createArray( string elemTypename, int refInt, int length ) private Array createArray( string elemTypename, int refInt, int length )
{ {
Type elemType = Type.GetType(elemTypename); Type elemType = Type.GetType( elemTypename );
return createArray( elemType, refInt, length ); return createArray( elemType, refInt, length );
} }
private Array createArray( Type elemType, int refInt, int length ) private Array createArray( Type elemType, int refInt, int length )
{ {
TypeCode elemTC = Type.GetTypeCode(elemType); TypeCode elemTC = Type.GetTypeCode( elemType );
if( m_cfg.datastructure == Datastructure.Graph && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) ) if( _cfg.datastructure == Datastructure.Graph && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
{ {
return (Array)m_alreadySerialized[refInt]; return (Array)m_alreadySerialized[refInt];
} }
else else
{ {
Array arr = Array.CreateInstance(elemType, length); Array arr = Array.CreateInstance( elemType, length );
if( m_cfg.datastructure == Datastructure.Graph ) if( _cfg.datastructure == Datastructure.Graph )
{ {
m_alreadySerialized[refInt] = arr; m_alreadySerialized[refInt] = arr;
@ -992,13 +988,13 @@ namespace lib
m_alreadySerialized.Clear(); m_alreadySerialized.Clear();
m_objectID = new ObjectIDGenerator(); m_objectID = new ObjectIDGenerator();
XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.ASCII); XmlTextWriter writer = new XmlTextWriter( stream, System.Text.Encoding.ASCII );
writer.Formatting = Formatting.Indented; writer.Formatting = Formatting.Indented;
Serialize( writer, mi, root ); Serialize( writer, mi, root );
//Rely on the parent closing the stream. //Rely on the parent closing the stream.
//writer.Close(); //writer.Close();
writer.Flush(); writer.Flush();
@ -1018,15 +1014,17 @@ namespace lib
{ {
Type type = root.GetType(); Type type = root.GetType();
TypeCode typeCode = Type.GetTypeCode(type); TypeCode typeCode = Type.GetTypeCode( type );
if( typeCode != TypeCode.Object ) if( typeCode != TypeCode.Object )
{ {
if( m_cfg.POD == POD.Elements || forceType ) writer.WriteStartElement( name ); if( _cfg.POD == POD.Elements || forceType )
writer.WriteStartElement( name );
SerializeConcrete( writer, mi, root, name, forceType ); SerializeConcrete( writer, mi, root, name, forceType );
if( m_cfg.POD == POD.Elements || forceType ) writer.WriteEndElement(); if( _cfg.POD == POD.Elements || forceType )
writer.WriteEndElement();
return; return;
} }
@ -1035,7 +1033,7 @@ namespace lib
writer.WriteStartElement( name ); writer.WriteStartElement( name );
if( !type.IsArray ) if( !type.IsArray )
{ {
if( IsEnumerable( type )) if( IsEnumerable( type ) )
{ {
SerializeCollection( writer, mi, root, depth ); SerializeCollection( writer, mi, root, depth );
} }
@ -1063,9 +1061,10 @@ namespace lib
private void SerializeConcrete( XmlWriter writer, MemberInfo mi, object root, string name, bool forceType ) private void SerializeConcrete( XmlWriter writer, MemberInfo mi, object root, string name, bool forceType )
{ {
//TODO: Only write this out if debugging. //TODO: Only write this out if debugging.
if( forceType || m_cfg.POD == POD.Elements ) if( forceType || _cfg.POD == POD.Elements )
{ {
if( forceType ) writer.WriteAttributeString( "_.t", getTypeName( root.GetType() ) ); if( forceType )
writer.WriteAttributeString( "_.t", getTypeName( root.GetType() ) );
writer.WriteAttributeString( "v", root.ToString() ); writer.WriteAttributeString( "v", root.ToString() );
} }
else else
@ -1088,16 +1087,16 @@ namespace lib
bool first; bool first;
long refInt = m_objectID.GetId(root, out first); long refInt = m_objectID.GetId( root, out first );
if( m_cfg.datastructure == Datastructure.Graph ) if( _cfg.datastructure == Datastructure.Graph )
{ {
writer.WriteAttributeString( "ref", refInt.ToString() ); writer.WriteAttributeString( "ref", refInt.ToString() );
} }
if( first ) if( first )
{ {
if( m_cfg.datastructure == Datastructure.Graph ) if( _cfg.datastructure == Datastructure.Graph )
{ {
m_alreadySerialized[refInt] = root; m_alreadySerialized[refInt] = root;
} }
@ -1116,24 +1115,22 @@ namespace lib
{ {
writer.WriteAttributeString( "_.t", getTypeName( root.GetType() ) ); writer.WriteAttributeString( "_.t", getTypeName( root.GetType() ) );
if(depth == 1) if( depth == 1 )
{ {
writer.WriteAttributeString( "_.version.", $"{m_cfg.Version}" ); writer.WriteAttributeString( "_.version.", $"{_cfg.Version}" );
} }
bool first; long refInt = m_objectID.GetId( root, out var first );
long refInt = m_objectID.GetId(root, out first); // @@@@ FIX for proxies.
if( _cfg.datastructure == Datastructure.Graph )
// @@@@ FIX for proxies.
if( m_cfg.datastructure == Datastructure.Graph )
{ {
writer.WriteAttributeString( "ref", refInt.ToString() ); writer.WriteAttributeString( "ref", refInt.ToString() );
} }
if( first ) if( first )
{ {
if (m_cfg.datastructure == Datastructure.Graph) if( _cfg.datastructure == Datastructure.Graph )
{ {
m_alreadySerialized[refInt] = root; m_alreadySerialized[refInt] = root;
} }
@ -1141,28 +1138,28 @@ namespace lib
Type type = root.GetType(); Type type = root.GetType();
//* //*
Type typeISerializable = typeof(ISerializable); Type typeISerializable = typeof( ISerializable );
if (root is ISerializable ser) if( root is ISerializable ser )
{ {
if ((root is Delegate)) if( root is Delegate )
{ {
return; return;
} }
var serInfo = new SerializationInfo(type, new FormatterConverter()); var serInfo = new SerializationInfo( type, new FormatterConverter() );
var context = new StreamingContext(StreamingContextStates.File, root); var context = new StreamingContext( StreamingContextStates.File, root );
ser.GetObjectData(serInfo, context); ser.GetObjectData( serInfo, context );
foreach (var serMember in serInfo) foreach( var serMember in serInfo )
{ {
String name = serMember.Name; String name = serMember.Name;
name = refl.TypeToIdentifier(name); name = refl.TypeToIdentifier( name );
Serialize(writer, mi, serMember.Value, name, depth, true); Serialize( writer, mi, serMember.Value, name, depth, true );
} }
return; return;
@ -1172,9 +1169,9 @@ namespace lib
var tryType = type; var tryType = type;
TypeProxy? proxy = null; TypeProxy? proxy = null;
while (tryType != typeof(object)) while( tryType != typeof( object ) )
{ {
if (m_cfg.TypeProxy.TryGetValue(tryType, out var newProxy)) if( _cfg.TypeProxy.TryGetValue( tryType, out var newProxy ) )
{ {
proxy = newProxy; proxy = newProxy;
break; break;
@ -1183,37 +1180,37 @@ namespace lib
tryType = tryType.BaseType; tryType = tryType.BaseType;
} }
if (proxy.HasValue) if( proxy.HasValue )
{ {
var proxyStr = proxy.Value.ser(root); var proxyStr = proxy.Value.ser( root );
writer.WriteAttributeString("proxy", proxyStr); writer.WriteAttributeString( "proxy", proxyStr );
return; return;
} }
} }
//*/ //*/
SerializeObjectOfNarrowType(writer, mi, root, depth, type); SerializeObjectOfNarrowType( writer, mi, root, depth, type );
} }
} }
private void SerializeObjectOfNarrowType(XmlWriter writer, MemberInfo mi, object root, int depth, Type narrowType) private void SerializeObjectOfNarrowType( XmlWriter writer, MemberInfo mi, object root, int depth, Type narrowType )
{ {
bool filterFields, filterProps, doImpls, doFields, doProps; bool filterFields, filterProps, doImpls, doFields, doProps;
HashSet<string> whitelistFields, whitelistProps; HashSet<string> whitelistFields, whitelistProps;
GetFilters(m_cfg.TypesDefault, mi, narrowType, out filterFields, out filterProps, out doImpls, out doFields, out doProps, out whitelistFields, out whitelistProps); GetFilters( _cfg.TypesDefault, mi, narrowType, out filterFields, out filterProps, out doImpls, out doFields, out doProps, out whitelistFields, out whitelistProps );
if (doFields || doImpls) if( doFields || doImpls )
{ {
var fields = refl.GetAllFields(narrowType); var fields = refl.GetAllFields( narrowType );
foreach (var childFi in fields) foreach( var childFi in fields )
{ {
String name = childFi.Name; String name = childFi.Name;
var dontAtt = childFi.GetCustomAttributes<lib.Dont>(); var dontAtt = childFi.GetCustomAttributes<lib.Dont>();
string propName = ""; string propName = "";
if( name.StartsWith( "<" ) && name.EndsWith( "BackingField" ) ) if( name.StartsWith( "<" ) && name.EndsWith( "BackingField" ) )
{ {
var gtIndex = name.IndexOf( '>' ); var gtIndex = name.IndexOf( '>' );
@ -1230,32 +1227,33 @@ namespace lib
continue; continue;
} }
if (FilterField(filterFields, doImpls, whitelistFields, childFi as MemberInfo, name)) continue; if( FilterField( filterFields, doImpls, whitelistFields, childFi as MemberInfo, name ) )
continue;
object[] objs = childFi.GetCustomAttributes(typeof(NonSerializedAttribute), true); object[] objs = childFi.GetCustomAttributes( typeof( NonSerializedAttribute ), true );
if (objs.Length > 0) if( objs.Length > 0 )
{ {
continue; continue;
} }
//if( childFi.GetCustomAttribute<WhitelistAttribute>() ) //if( childFi.GetCustomAttribute<WhitelistAttribute>() )
name = refl.TypeToIdentifier(name); name = refl.TypeToIdentifier( name );
var finalName = (m_cfg.Naming == BackingFieldNaming.Short && !string.IsNullOrEmpty( propName )) ? var finalName = ( _cfg.Naming == BackingFieldNaming.Short && !string.IsNullOrEmpty( propName ) ) ?
propName : propName :
name; name;
Serialize(writer, childFi, childFi.GetValue(root), finalName, depth + 1, false); Serialize( writer, childFi, childFi.GetValue( root ), finalName, depth + 1, false );
} }
} }
if (doProps || doImpls) if( doProps || doImpls )
{ {
var props = refl.GetAllProperties(narrowType); var props = refl.GetAllProperties( narrowType );
foreach (var childPi in props) foreach( var childPi in props )
{ {
String name = childPi.Name; String name = childPi.Name;
@ -1265,18 +1263,19 @@ namespace lib
continue; continue;
} }
if (FilterField(filterProps, doImpls, whitelistProps, childPi as MemberInfo, name)) continue; if( FilterField( filterProps, doImpls, whitelistProps, childPi as MemberInfo, name ) )
continue;
object[] objs = childPi.GetCustomAttributes(typeof(NonSerializedAttribute), true); object[] objs = childPi.GetCustomAttributes( typeof( NonSerializedAttribute ), true );
if (objs.Length > 0) if( objs.Length > 0 )
{ {
continue; continue;
} }
name = refl.TypeToIdentifier(name); name = refl.TypeToIdentifier( name );
Serialize(writer, childPi, childPi.GetValue(root), name, depth + 1, false); Serialize( writer, childPi, childPi.GetValue( root ), name, depth + 1, false );
} }
} }
@ -1311,16 +1310,16 @@ namespace lib
bool first; bool first;
long refInt = m_objectID.GetId(root, out first); long refInt = m_objectID.GetId( root, out first );
if( m_cfg.datastructure == Datastructure.Graph ) if( _cfg.datastructure == Datastructure.Graph )
{ {
writer.WriteAttributeString( "ref", refInt.ToString() ); writer.WriteAttributeString( "ref", refInt.ToString() );
} }
if( first ) if( first )
{ {
if( m_cfg.datastructure == Datastructure.Graph ) if( _cfg.datastructure == Datastructure.Graph )
{ {
m_alreadySerialized[refInt] = root; m_alreadySerialized[refInt] = root;
} }