Various XML fixes
This commit is contained in:
parent
d237c438c7
commit
72a28b5f81
16
imm/Imm.cs
16
imm/Imm.cs
@ -1,15 +1,25 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using lib;
|
||||||
|
|
||||||
namespace imm;
|
namespace imm;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
T O D O :
|
||||||
|
T O D O :
|
||||||
|
T O D O :
|
||||||
|
x) Add unit tests for all this. This will definitely benefit from them
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
static public class Util
|
static public class Util
|
||||||
{
|
{
|
||||||
//This can handle both Timed and Recorded
|
//This can handle both Timed and Recorded
|
||||||
@ -38,7 +48,7 @@ static public class Util
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//[lib.Ser( Types = lib.Types.None )]
|
||||||
public record class Versioned<T>
|
public record class Versioned<T>
|
||||||
where T : Versioned<T>
|
where T : Versioned<T>
|
||||||
{
|
{
|
||||||
@ -61,6 +71,7 @@ public record class Versioned<T>
|
|||||||
|
|
||||||
public MetaData Meta => MetaStorage;
|
public MetaData Meta => MetaStorage;
|
||||||
|
|
||||||
|
[lib.Dont]
|
||||||
public ChangeDelegate OnChange = (x, y) => {};
|
public ChangeDelegate OnChange = (x, y) => {};
|
||||||
|
|
||||||
public T Process( Func<T, T> fn, string reason = "" )
|
public T Process( Func<T, T> fn, string reason = "" )
|
||||||
@ -78,11 +89,14 @@ public record class Versioned<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//[lib.Ser( Types = lib.Types.None )]
|
||||||
public record class Recorded<T> : Versioned<T>
|
public record class Recorded<T> : Versioned<T>
|
||||||
where T : Recorded<T>
|
where T : Recorded<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
new public record class MetaData : Versioned<T>.MetaData
|
new public record class MetaData : Versioned<T>.MetaData
|
||||||
{
|
{
|
||||||
|
[lib.Dont]
|
||||||
public T? ZZOld { get; internal set; }
|
public T? ZZOld { get; internal set; }
|
||||||
public T? Old => ZZOld;
|
public T? Old => ZZOld;
|
||||||
public string Expression { get; internal set; } = "";
|
public string Expression { get; internal set; } = "";
|
||||||
|
|||||||
@ -12,6 +12,7 @@ using System.Diagnostics;
|
|||||||
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using static System.Net.WebRequestMethods;
|
using static System.Net.WebRequestMethods;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -44,11 +45,13 @@ 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,
|
||||||
|
|
||||||
|
|
||||||
None = 0b_000,
|
None = 0b_0000,
|
||||||
Default = Fields,
|
Default = Fields,
|
||||||
All = Fields | Props,
|
All = Fields | Props,
|
||||||
}
|
}
|
||||||
@ -58,6 +61,14 @@ namespace lib
|
|||||||
public Types Types { get; set; } = Types.Default;
|
public Types Types { get; set; } = Types.Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Do : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Dont : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public class ChildAttributes : Attribute
|
public class ChildAttributes : Attribute
|
||||||
{
|
{
|
||||||
public string[] Values { get; private set; }
|
public string[] Values { get; private set; }
|
||||||
@ -82,10 +93,10 @@ namespace lib
|
|||||||
{
|
{
|
||||||
Invalid,
|
Invalid,
|
||||||
|
|
||||||
//
|
// Breaks on circular datastructures since it will go on forever
|
||||||
Tree,
|
Tree,
|
||||||
|
|
||||||
//
|
// Works for everything.
|
||||||
Graph,
|
Graph,
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -94,7 +105,7 @@ namespace lib
|
|||||||
|
|
||||||
public class XmlFormatter2Cfg: Config
|
public class XmlFormatter2Cfg: Config
|
||||||
{
|
{
|
||||||
public Datastructure datastructure = Datastructure.Graph;
|
public Datastructure datastructure = Datastructure.Tree;
|
||||||
|
|
||||||
public int Version = 2;
|
public int Version = 2;
|
||||||
|
|
||||||
@ -132,12 +143,12 @@ namespace lib
|
|||||||
|
|
||||||
public XmlFormatter2()
|
public XmlFormatter2()
|
||||||
{
|
{
|
||||||
Context = new StreamingContext( StreamingContextStates.All );
|
//Context = new StreamingContext( StreamingContextStates.All );
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlFormatter2( XmlFormatter2Cfg cfg )
|
public XmlFormatter2( XmlFormatter2Cfg cfg )
|
||||||
{
|
{
|
||||||
Context = new StreamingContext( StreamingContextStates.All );
|
//Context = new StreamingContext( StreamingContextStates.All );
|
||||||
|
|
||||||
m_cfg = cfg;
|
m_cfg = cfg;
|
||||||
|
|
||||||
@ -406,8 +417,10 @@ namespace lib
|
|||||||
mm_consType[1] = typeof( StreamingContext );
|
mm_consType[1] = typeof( StreamingContext );
|
||||||
ConstructorInfo serCons = finalType.GetConstructor( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, mm_consType, null );
|
ConstructorInfo serCons = finalType.GetConstructor( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, mm_consType, null );
|
||||||
|
|
||||||
|
var context = new StreamingContext( StreamingContextStates.File, obj );
|
||||||
|
|
||||||
mm_args[0] = serInfo;
|
mm_args[0] = serInfo;
|
||||||
mm_args[1] = Context;
|
mm_args[1] = context;
|
||||||
serCons.Invoke( obj, mm_args );
|
serCons.Invoke( obj, mm_args );
|
||||||
|
|
||||||
if( objUnOnDeser != null )
|
if( objUnOnDeser != null )
|
||||||
@ -434,103 +447,117 @@ namespace lib
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
XmlNodeList allChildren = elem.ChildNodes;
|
HydrateObjectOfNarrowType(elem, mi, finalType, obj);
|
||||||
|
|
||||||
bool filterFields, filterProps, doImpls, doFields, doProps;
|
|
||||||
HashSet<string> whitelistFields, whitelistProps;
|
|
||||||
GetFilters( m_cfg.TypesDefault, mi, finalType, out filterFields, out filterProps, out doImpls, out doFields, out doProps, out whitelistFields, out whitelistProps );
|
|
||||||
|
|
||||||
/*
|
|
||||||
List<MemberInfo> members = new();
|
|
||||||
|
|
||||||
if( doFields || doImpls )
|
|
||||||
{
|
|
||||||
members.AddRange( refl.GetAllFields( finalType ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( doProps || doImpls )
|
|
||||||
{
|
|
||||||
members.AddRange( refl.GetAllProperties( finalType ) );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( doFields || doImpls )
|
|
||||||
{
|
|
||||||
var fields = refl.GetAllFields( finalType );
|
|
||||||
|
|
||||||
foreach( FieldInfo childFi in fields )
|
|
||||||
{
|
|
||||||
|
|
||||||
String name = childFi.Name;
|
|
||||||
|
|
||||||
//This is to convert c# names that would be bad as XML tags
|
|
||||||
name = refl.TypeToIdentifier( name );
|
|
||||||
|
|
||||||
if( FilterField( filterFields, doImpls, whitelistFields, childFi as MemberInfo, name ) ) continue;
|
|
||||||
|
|
||||||
XmlElement childElem = getNamedChild( allChildren, name );
|
|
||||||
|
|
||||||
if( childElem != null )
|
|
||||||
{
|
|
||||||
object existingObj = childFi.GetValue( obj );
|
|
||||||
|
|
||||||
object childObj = Deserialize( childElem, childFi, childFi.FieldType, existingObj );
|
|
||||||
|
|
||||||
childFi.SetValue( obj, childObj );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( doProps || doImpls )
|
|
||||||
{
|
|
||||||
var props = refl.GetAllProperties( finalType );
|
|
||||||
|
|
||||||
foreach( var childPi in props )
|
|
||||||
{
|
|
||||||
String name = childPi.Name;
|
|
||||||
|
|
||||||
name = refl.TypeToIdentifier( name );
|
|
||||||
|
|
||||||
if( FilterField( filterProps, doImpls, whitelistProps, childPi as PropertyInfo, name ) ) continue;
|
|
||||||
|
|
||||||
XmlElement childElem = getNamedChild( allChildren, name );
|
|
||||||
|
|
||||||
if( childElem != null )
|
|
||||||
{
|
|
||||||
object existingObj = childPi.GetValue( obj );
|
|
||||||
|
|
||||||
object childObj = Deserialize( childElem, childPi, childPi.PropertyType, existingObj );
|
|
||||||
|
|
||||||
var setMethod = childPi.GetSetMethod();
|
|
||||||
|
|
||||||
if( setMethod != null )
|
|
||||||
{
|
|
||||||
//Object o = Activator.CreateInstance( setMethod.ReflectedType );
|
|
||||||
setMethod.Invoke( obj, new object[]{ childObj } );
|
|
||||||
|
|
||||||
//setMethod.CreateDelegate()
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
childPi.SetValue( obj, childObj );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HydrateObjectOfNarrowType(XmlElement elem, MemberInfo mi, Type narrowType, object obj)
|
||||||
|
{
|
||||||
|
XmlNodeList allChildren = elem.ChildNodes;
|
||||||
|
|
||||||
|
bool filterFields, filterProps, doImpls, doFields, doProps;
|
||||||
|
HashSet<string> whitelistFields, whitelistProps;
|
||||||
|
GetFilters(m_cfg.TypesDefault, mi, narrowType, out filterFields, out filterProps, out doImpls, out doFields, out doProps, out whitelistFields, out whitelistProps);
|
||||||
|
|
||||||
|
if (doFields || doImpls)
|
||||||
|
{
|
||||||
|
var fields = refl.GetAllFields(narrowType);
|
||||||
|
|
||||||
|
foreach (FieldInfo childFi in fields)
|
||||||
|
{
|
||||||
|
|
||||||
|
String name = childFi.Name;
|
||||||
|
|
||||||
|
var dontAtt = childFi.GetCustomAttributes<lib.Dont>();
|
||||||
|
|
||||||
|
if( name.StartsWith( "<" ) && name.EndsWith( "BackingField" ) )
|
||||||
|
{
|
||||||
|
var gtIndex = name.IndexOf( '>' );
|
||||||
|
|
||||||
|
var propName = name.Substring( 1, gtIndex - 1 );
|
||||||
|
|
||||||
|
var propInfo = narrowType.GetProperty( propName );
|
||||||
|
|
||||||
|
dontAtt = propInfo.GetCustomAttributes<lib.Dont>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( dontAtt.Any() )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if( name.EndsWith( ) )
|
||||||
|
|
||||||
|
//This is to convert c# names that would be bad as XML tags
|
||||||
|
name = refl.TypeToIdentifier(name);
|
||||||
|
|
||||||
|
if (FilterField(filterFields, doImpls, whitelistFields, childFi as MemberInfo, name)) continue;
|
||||||
|
|
||||||
|
XmlElement childElem = getNamedChild(allChildren, name);
|
||||||
|
|
||||||
|
if (childElem != null)
|
||||||
|
{
|
||||||
|
object existingObj = childFi.GetValue(obj);
|
||||||
|
|
||||||
|
object childObj = Deserialize(childElem, childFi, childFi.FieldType, existingObj);
|
||||||
|
|
||||||
|
childFi.SetValue(obj, childObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (doProps || doImpls)
|
||||||
|
{
|
||||||
|
var props = refl.GetAllProperties(narrowType);
|
||||||
|
|
||||||
|
foreach (var childPi in props)
|
||||||
|
{
|
||||||
|
String name = childPi.Name;
|
||||||
|
var dontAtt = childPi.GetCustomAttributes<lib.Dont>();
|
||||||
|
if( dontAtt.Any() )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = refl.TypeToIdentifier(name);
|
||||||
|
|
||||||
|
if (FilterField(filterProps, doImpls, whitelistProps, childPi as PropertyInfo, name)) continue;
|
||||||
|
|
||||||
|
XmlElement childElem = getNamedChild(allChildren, name);
|
||||||
|
|
||||||
|
if (childElem != null)
|
||||||
|
{
|
||||||
|
object existingObj = childPi.GetValue(obj);
|
||||||
|
|
||||||
|
object childObj = Deserialize(childElem, childPi, childPi.PropertyType, existingObj);
|
||||||
|
|
||||||
|
var setMethod = childPi.GetSetMethod();
|
||||||
|
|
||||||
|
if (setMethod != null)
|
||||||
|
{
|
||||||
|
//Object o = Activator.CreateInstance( setMethod.ReflectedType );
|
||||||
|
setMethod.Invoke(obj, new object[] { childObj });
|
||||||
|
|
||||||
|
//setMethod.CreateDelegate()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
childPi.SetValue(obj, childObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static bool FilterField( bool filterFields, bool doImpls, HashSet<string> whitelistFields, MemberInfo mi, string name )
|
private static bool FilterField( bool filterFields, bool doImpls, HashSet<string> whitelistFields, MemberInfo mi, string name )
|
||||||
{
|
{
|
||||||
if( doImpls )
|
if( doImpls )
|
||||||
{
|
{
|
||||||
if( mi.GetCustomAttribute<ChildAttributes>() == null ) return true;
|
if( mi.GetCustomAttribute<ChildAttributes>( true ) == null ) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( filterFields && !whitelistFields.Contains( name ) ) return true;
|
if( filterFields && !whitelistFields.Contains( name ) ) return true;
|
||||||
@ -868,7 +895,7 @@ namespace lib
|
|||||||
|
|
||||||
if( first )
|
if( first )
|
||||||
{
|
{
|
||||||
if( m_cfg.datastructure == Datastructure.Graph )
|
if (m_cfg.datastructure == Datastructure.Graph)
|
||||||
{
|
{
|
||||||
m_alreadySerialized[refInt] = root;
|
m_alreadySerialized[refInt] = root;
|
||||||
}
|
}
|
||||||
@ -878,19 +905,26 @@ namespace lib
|
|||||||
//*
|
//*
|
||||||
Type typeISerializable = typeof(ISerializable);
|
Type typeISerializable = typeof(ISerializable);
|
||||||
|
|
||||||
if( root is ISerializable ser )
|
if (root is ISerializable ser)
|
||||||
{
|
{
|
||||||
|
if ((root is Delegate))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var serInfo = new SerializationInfo(type, new FormatterConverter());
|
var serInfo = new SerializationInfo(type, new FormatterConverter());
|
||||||
|
|
||||||
ser.GetObjectData( serInfo, Context );
|
var context = new StreamingContext(StreamingContextStates.File, root);
|
||||||
|
|
||||||
foreach( var serMember in serInfo )
|
ser.GetObjectData(serInfo, context);
|
||||||
|
|
||||||
|
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;
|
||||||
@ -900,9 +934,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 (m_cfg.TypeProxy.TryGetValue(tryType, out var newProxy))
|
||||||
{
|
{
|
||||||
proxy = newProxy;
|
proxy = newProxy;
|
||||||
break;
|
break;
|
||||||
@ -911,82 +945,110 @@ 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SerializeObjectOfNarrowType(XmlWriter writer, MemberInfo mi, object root, int depth, Type narrowType)
|
||||||
|
{
|
||||||
|
bool filterFields, filterProps, doImpls, doFields, doProps;
|
||||||
|
HashSet<string> whitelistFields, whitelistProps;
|
||||||
|
GetFilters(m_cfg.TypesDefault, mi, narrowType, out filterFields, out filterProps, out doImpls, out doFields, out doProps, out whitelistFields, out whitelistProps);
|
||||||
|
|
||||||
|
if (doFields || doImpls)
|
||||||
|
{
|
||||||
|
var fields = refl.GetAllFields(narrowType);
|
||||||
|
|
||||||
|
foreach (var childFi in fields)
|
||||||
{
|
{
|
||||||
bool filterFields, filterProps, doImpls, doFields, doProps;
|
String name = childFi.Name;
|
||||||
HashSet<string> whitelistFields, whitelistProps;
|
var dontAtt = childFi.GetCustomAttributes<lib.Dont>();
|
||||||
GetFilters( m_cfg.TypesDefault, mi, type, out filterFields, out filterProps, out doImpls, out doFields, out doProps, out whitelistFields, out whitelistProps );
|
|
||||||
|
|
||||||
if( doFields || doImpls )
|
|
||||||
|
if( name.StartsWith( "<" ) && name.EndsWith( "BackingField" ) )
|
||||||
{
|
{
|
||||||
var fields = refl.GetAllFields( type );
|
var gtIndex = name.IndexOf( '>' );
|
||||||
|
|
||||||
foreach( var childFi in fields )
|
var propName = name.Substring( 1, gtIndex - 1 );
|
||||||
{
|
|
||||||
String name = childFi.Name;
|
|
||||||
|
|
||||||
if( FilterField( filterFields, doImpls, whitelistFields, childFi as MemberInfo, name ) ) continue;
|
var propInfo = narrowType.GetProperty( propName );
|
||||||
|
|
||||||
object[] objs = childFi.GetCustomAttributes( typeof( NonSerializedAttribute ), true );
|
dontAtt = propInfo.GetCustomAttributes<lib.Dont>();
|
||||||
|
|
||||||
if( objs.Length > 0 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if( childFi.GetCustomAttribute<WhitelistAttribute>() )
|
|
||||||
|
|
||||||
name = refl.TypeToIdentifier( name );
|
|
||||||
|
|
||||||
Serialize( writer, childFi, childFi.GetValue( root ), name, depth + 1, false );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( doProps || doImpls )
|
|
||||||
|
if( dontAtt.Any() )
|
||||||
{
|
{
|
||||||
var props = refl.GetAllProperties( type );
|
continue;
|
||||||
|
|
||||||
foreach( var childPi in props )
|
|
||||||
{
|
|
||||||
String name = childPi.Name;
|
|
||||||
|
|
||||||
if( FilterField( filterProps, doImpls, whitelistProps, childPi as MemberInfo, name ) ) continue;
|
|
||||||
|
|
||||||
object[] objs = childPi.GetCustomAttributes( typeof( NonSerializedAttribute ), true );
|
|
||||||
|
|
||||||
if( objs.Length > 0 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
name = refl.TypeToIdentifier( name );
|
|
||||||
|
|
||||||
Serialize( writer, childPi, childPi.GetValue( root ), name, depth + 1, false );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FilterField(filterFields, doImpls, whitelistFields, childFi as MemberInfo, name)) continue;
|
||||||
|
|
||||||
|
object[] objs = childFi.GetCustomAttributes(typeof(NonSerializedAttribute), true);
|
||||||
|
|
||||||
|
if (objs.Length > 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if( childFi.GetCustomAttribute<WhitelistAttribute>() )
|
||||||
|
|
||||||
|
name = refl.TypeToIdentifier(name);
|
||||||
|
|
||||||
|
Serialize(writer, childFi, childFi.GetValue(root), name, depth + 1, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (doProps || doImpls)
|
||||||
|
{
|
||||||
|
var props = refl.GetAllProperties(narrowType);
|
||||||
|
|
||||||
|
foreach (var childPi in props)
|
||||||
|
{
|
||||||
|
String name = childPi.Name;
|
||||||
|
|
||||||
|
var dontAtt = childPi.GetCustomAttributes<lib.Dont>();
|
||||||
|
if( dontAtt.Any() )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FilterField(filterProps, doImpls, whitelistProps, childPi as MemberInfo, name)) continue;
|
||||||
|
|
||||||
|
object[] objs = childPi.GetCustomAttributes(typeof(NonSerializedAttribute), true);
|
||||||
|
|
||||||
|
if (objs.Length > 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = refl.TypeToIdentifier(name);
|
||||||
|
|
||||||
|
Serialize(writer, childPi, childPi.GetValue(root), name, depth + 1, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GetFilters( Types TypesDefault, MemberInfo mi, Type type, out bool filterFields, out bool filterProps, out bool doImpls, out bool doFields, out bool doProps, out HashSet<string> whitelistFields, out HashSet<string> whitelistProps )
|
private static void GetFilters( Types TypesDefault, MemberInfo mi, Type type, out bool filterFields, out bool filterProps, out bool doImpls, out bool doFields, out bool doProps, out HashSet<string> whitelistFields, out HashSet<string> whitelistProps )
|
||||||
{
|
{
|
||||||
var custWLFields = mi?.GetCustomAttribute<ChildFieldsAttribute>();
|
var custWLFields = mi?.GetCustomAttribute<ChildFieldsAttribute>( true );
|
||||||
var custWLProps = mi?.GetCustomAttribute<ChildPropsAttribute>();
|
var custWLProps = mi?.GetCustomAttribute<ChildPropsAttribute>( true );
|
||||||
|
|
||||||
filterFields = custWLFields != null;
|
filterFields = custWLFields != null;
|
||||||
filterProps = custWLProps != null;
|
filterProps = custWLProps != null;
|
||||||
|
|
||||||
var typesTodo = type.GetCustomAttribute<Ser>()?.Types ?? TypesDefault;
|
var typesTodo = type.GetCustomAttribute<Ser>( true )?.Types ?? TypesDefault;
|
||||||
|
|
||||||
doImpls = typesTodo.HasFlag( Types.Implied );
|
doImpls = typesTodo.HasFlag( Types.Implied );
|
||||||
doFields = filterFields || typesTodo.HasFlag( Types.Fields );
|
doFields = filterFields || typesTodo.HasFlag( Types.Fields );
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user