x) Fix EOL on file
This commit is contained in:
parent
0bd6b086f6
commit
dcd15a2663
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -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
|
||||||
|
|||||||
375
cfg/Config.cs
375
cfg/Config.cs
@ -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; }
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user