x) Add TODO
x) Add various attributes to control specific things x) Remove some unused logs x) Pass MethodInfo through almost everything x) Add DeserializeInto which keeps existing objects around x) Add Properties to things. Off by default x) Add various filtering code
This commit is contained in:
parent
d6a9cb42cf
commit
a27140700c
@ -10,8 +10,27 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
/*
|
||||
* TODO
|
||||
* HUGE FLAW IN DESERIALIZATION. If you deser into something it resets everything to default values
|
||||
* This didnt matter before when I did full things, but it matters now
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace lib
|
||||
{
|
||||
|
||||
@ -25,6 +44,41 @@ namespace lib
|
||||
void OnDeserialize( object enclosing );
|
||||
}
|
||||
|
||||
public class InstanceAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
public class PropertiesAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class WhitelistAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public class WhitelistFieldsAttribute : Attribute
|
||||
{
|
||||
public string[] Values { get; private set; }
|
||||
|
||||
public WhitelistFieldsAttribute( params string[] values )
|
||||
{
|
||||
this.Values = values;
|
||||
}
|
||||
}
|
||||
|
||||
public class WhitelistPropsAttribute : Attribute
|
||||
{
|
||||
public string[] Values { get; private set; }
|
||||
|
||||
public WhitelistPropsAttribute( params string[] values )
|
||||
{
|
||||
this.Values = values;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Datastructure
|
||||
{
|
||||
Invalid,
|
||||
@ -88,37 +142,29 @@ namespace lib
|
||||
#region Deserialize
|
||||
private static FormatterConverter s_conv = new FormatterConverter();
|
||||
|
||||
|
||||
public object Deserialize( Stream stream )
|
||||
{
|
||||
//lib.log.info( "Deserialize( Stream stream ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
return DeserializeKnownType( stream, null );
|
||||
//lib.log.info( "Deserialize END ( Stream stream ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
}
|
||||
|
||||
|
||||
public T Deserialize<T>(Stream stream)
|
||||
{
|
||||
//lib.log.info( "Deserialize( Stream stream ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
return (T)DeserializeKnownType(stream, typeof(T));
|
||||
//lib.log.info( "Deserialize END ( Stream stream ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
}
|
||||
|
||||
public object DeserializeKnownType( Stream stream, Type t )
|
||||
{
|
||||
//lib.log.info( "DeserializeKnownType( Stream stream, Type t ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
|
||||
XmlTextReader reader = new XmlTextReader(stream);
|
||||
//reader.Settings = System.Text.Encoding.ASCII;
|
||||
|
||||
object obj = Deserialize(reader, t);
|
||||
//lib.log.info( "DeserializeKnownType END( Stream stream, Type t ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private object Deserialize( XmlReader reader, Type t )
|
||||
{
|
||||
//lib.log.info( "Deserialize( XmlReader reader, Type t ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
|
||||
m_alreadySerialized.Clear();
|
||||
m_objectID = new ObjectIDGenerator();
|
||||
|
||||
@ -128,12 +174,22 @@ namespace lib
|
||||
|
||||
doc.Load( reader );
|
||||
|
||||
////lib.log.info( "What to deserialize {0}", doc.OuterXml.ToString() );
|
||||
|
||||
if( t == null )
|
||||
return Deserialize( doc.DocumentElement );
|
||||
|
||||
return Deserialize( doc.DocumentElement, t );
|
||||
return Deserialize( doc.DocumentElement, null, t );
|
||||
}
|
||||
|
||||
public void DeserializeInto<T>(Stream stream, T obj)
|
||||
{
|
||||
XmlTextReader reader = new XmlTextReader( stream );
|
||||
reader.Read();
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
doc.Load( reader );
|
||||
|
||||
HydrateObject<T>( doc.DocumentElement, null, obj );
|
||||
}
|
||||
|
||||
private object Deserialize( XmlElement elem )
|
||||
@ -142,10 +198,10 @@ namespace lib
|
||||
|
||||
string typename = elem.HasAttribute("t") ? elem.GetAttribute("t") : elem.Name;
|
||||
|
||||
return Deserialize( elem, typename );
|
||||
return Deserialize( elem, null, typename );
|
||||
}
|
||||
|
||||
private object Deserialize( XmlElement elem, string typename )
|
||||
private object Deserialize( XmlElement elem, MemberInfo mi, string typename )
|
||||
{
|
||||
AppDomain currentDomain = AppDomain.CurrentDomain;
|
||||
Assembly[] assems = currentDomain.GetAssemblies();
|
||||
@ -167,22 +223,22 @@ namespace lib
|
||||
return null;
|
||||
}
|
||||
|
||||
return Deserialize( elem, type );
|
||||
return Deserialize( elem, null, type );
|
||||
}
|
||||
|
||||
private object Deserialize( XmlElement elem, Type type, object enclosing = null )
|
||||
private object Deserialize( XmlElement elem, MemberInfo mi, Type type, object enclosing = null )
|
||||
{
|
||||
TypeCode typeCode = Type.GetTypeCode(type);
|
||||
|
||||
if( typeCode != TypeCode.Object )
|
||||
{
|
||||
return DeserializeConcrete( elem, type );
|
||||
return DeserializeConcrete( elem, mi, type );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !type.IsArray )
|
||||
{
|
||||
object obj = DeserializeObject(elem, type);
|
||||
object obj = DeserializeObject(elem, mi, type);
|
||||
|
||||
if( obj is I_Serialize )
|
||||
{
|
||||
@ -195,7 +251,7 @@ namespace lib
|
||||
}
|
||||
else
|
||||
{
|
||||
return DeserializeArray( elem, type );
|
||||
return DeserializeArray( elem, mi, type );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,7 +271,7 @@ namespace lib
|
||||
return default( T );
|
||||
}
|
||||
|
||||
private object DeserializeConcrete( XmlElement elem, Type type )
|
||||
private object DeserializeConcrete( XmlElement elem, MemberInfo mi, Type type )
|
||||
{
|
||||
string val = "";
|
||||
|
||||
@ -278,73 +334,72 @@ namespace lib
|
||||
|
||||
private Type[] mm_consType = new Type[2];
|
||||
private object[] mm_args = new object[2];
|
||||
private object DeserializeObject( XmlElement elem, Type type )
|
||||
|
||||
private object DeserializeObject( XmlElement elem, MemberInfo mi, Type type )
|
||||
{
|
||||
Type finalType;
|
||||
object obj;
|
||||
GetObjectForDeser( elem, type, out finalType, out obj );
|
||||
|
||||
return HydrateObject( elem, mi, finalType, obj );
|
||||
}
|
||||
|
||||
public object HydrateObject<T>( XmlElement elem, MemberInfo mi, T obj )
|
||||
{
|
||||
return HydrateObject( elem, mi, typeof( T ), obj );
|
||||
}
|
||||
|
||||
private object HydrateObject( XmlElement elem, MemberInfo mi, Type finalType, object obj )
|
||||
{
|
||||
string refString = elem.GetAttribute("ref");
|
||||
|
||||
int refInt = refString.Length > 0 ? Convert.ToInt32(refString) : -1;
|
||||
|
||||
var finalType = type;
|
||||
if( elem.HasAttribute( "t" ) )
|
||||
{
|
||||
var typename = elem.GetAttribute("t");
|
||||
finalType = FindType( typename );
|
||||
|
||||
if( finalType == null )
|
||||
finalType = type;
|
||||
}
|
||||
|
||||
object obj = createObject(finalType, refInt);
|
||||
|
||||
if( obj is IList )
|
||||
{
|
||||
var list = obj as IList;
|
||||
|
||||
return DeserializeList( elem, type, list );
|
||||
return DeserializeList( elem, mi, finalType, list );
|
||||
}
|
||||
|
||||
Type typeISerializable = typeof(ISerializable);
|
||||
Type typeISerializable = typeof( ISerializable );
|
||||
|
||||
if( obj is ISerializable ) // type.IsSubclassOf( typeISerializable ) )
|
||||
if( obj is ISerializable ) // type.IsSubclassOf( typeISerializable ) )
|
||||
{
|
||||
XmlNodeList allChildren = elem.ChildNodes;
|
||||
|
||||
//ISerializable ser = obj as ISerializable;
|
||||
|
||||
var serInfo = new SerializationInfo(finalType, new FormatterConverter());
|
||||
|
||||
//var serInfoForTypes = new SerializationInfo( type, new FormatterConverter() );
|
||||
|
||||
//ser.GetObjectData( serInfoForTypes, Context );
|
||||
|
||||
XmlNodeList allChildren = elem.ChildNodes;
|
||||
|
||||
//ISerializable ser = obj as ISerializable;
|
||||
|
||||
var serInfo = new SerializationInfo( finalType, new FormatterConverter() );
|
||||
|
||||
//var serInfoForTypes = new SerializationInfo( type, new FormatterConverter() );
|
||||
|
||||
//ser.GetObjectData( serInfoForTypes, Context );
|
||||
|
||||
foreach( var objNode in allChildren )
|
||||
{
|
||||
var node = objNode as XmlElement;
|
||||
|
||||
String name = node.Name;
|
||||
|
||||
String childType = node.GetAttribute("t");
|
||||
String childType = node.GetAttribute( "t" );
|
||||
|
||||
name = refl.TypeToIdentifier( name );
|
||||
|
||||
XmlElement childElem = getNamedChild(allChildren, name);
|
||||
XmlElement childElem = getNamedChild( allChildren, name );
|
||||
|
||||
var des = Deserialize(childElem, childType);
|
||||
var des = Deserialize( childElem, mi, childType );
|
||||
|
||||
serInfo.AddValue( name, des, des.GetType() );
|
||||
}
|
||||
|
||||
//ConstructorInfo[] allCons = obj.GetType().GetConstructors( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
|
||||
|
||||
//var serMem = FormatterServices.GetSerializableMembers( finalType );
|
||||
|
||||
//object objUn = FormatterServices.GetSafeUninitializedObject( finalType );
|
||||
|
||||
}
|
||||
|
||||
//ConstructorInfo[] allCons = obj.GetType().GetConstructors( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
|
||||
|
||||
//var serMem = FormatterServices.GetSerializableMembers( finalType );
|
||||
|
||||
//object objUn = FormatterServices.GetSafeUninitializedObject( finalType );
|
||||
|
||||
IDeserializationCallback objUnOnDeser = obj as IDeserializationCallback;
|
||||
|
||||
mm_consType[0] = typeof( SerializationInfo );
|
||||
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 );
|
||||
|
||||
mm_args[0] = serInfo;
|
||||
mm_args[1] = Context;
|
||||
@ -353,8 +408,8 @@ namespace lib
|
||||
if( objUnOnDeser != null )
|
||||
{
|
||||
objUnOnDeser.OnDeserialization( objUnOnDeser );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
ser.GetObjectData( serInfo, Context );
|
||||
|
||||
@ -370,47 +425,117 @@ namespace lib
|
||||
|
||||
var des = Deserialize( childElem, name );
|
||||
}
|
||||
*/
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlNodeList allChildren = elem.ChildNodes;
|
||||
XmlNodeList allChildren = elem.ChildNodes;
|
||||
|
||||
var doFields = true;
|
||||
var doProperties = false;
|
||||
|
||||
var filterFields = mi?.GetCustomAttribute<WhitelistFieldsAttribute>() != null;
|
||||
var filterProps = mi?.GetCustomAttribute<WhitelistPropsAttribute>() != null;
|
||||
|
||||
HashSet<string> whitelistFields = new( mi?.GetCustomAttribute<WhitelistFieldsAttribute>()?.Values ?? new string[0] );
|
||||
HashSet<string> whitelistProps = new( mi?.GetCustomAttribute<WhitelistPropsAttribute>()?.Values ?? new string[0] );
|
||||
|
||||
if( finalType.GetCustomAttribute<PropertiesAttribute>() != null )
|
||||
{
|
||||
doProperties = true;
|
||||
}
|
||||
|
||||
if( mi?.GetCustomAttribute<WhitelistPropsAttribute>() != null )
|
||||
{
|
||||
doProperties = true;
|
||||
|
||||
doFields = mi?.GetCustomAttribute<WhitelistFieldsAttribute>() != null;
|
||||
}
|
||||
|
||||
var fields = refl.GetAllFields(type);
|
||||
|
||||
//MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type, Context );
|
||||
|
||||
foreach( var childFi in fields )
|
||||
if( doFields )
|
||||
{
|
||||
|
||||
String name = childFi.Name;
|
||||
|
||||
name = refl.TypeToIdentifier( name );
|
||||
|
||||
XmlElement childElem = getNamedChild(allChildren, name);
|
||||
|
||||
|
||||
if( childElem != null )
|
||||
var fields = refl.GetAllFields( finalType );
|
||||
|
||||
foreach( var childFi in fields )
|
||||
{
|
||||
object childObj = Deserialize(childElem, childFi.FieldType, obj);
|
||||
String name = childFi.Name;
|
||||
|
||||
if( filterFields && !whitelistFields.Contains( name ) ) continue;
|
||||
|
||||
childFi.SetValue( obj, childObj );
|
||||
}
|
||||
else if( fields.Count == 1 )
|
||||
{
|
||||
object childObj = Deserialize(elem, childFi.FieldType, obj);
|
||||
name = refl.TypeToIdentifier( name );
|
||||
|
||||
childFi.SetValue( obj, childObj );
|
||||
}
|
||||
XmlElement childElem = getNamedChild( allChildren, name );
|
||||
|
||||
if( childElem != null )
|
||||
{
|
||||
object childObj = Deserialize( childElem, childFi, childFi.FieldType, obj );
|
||||
|
||||
childFi.SetValue( obj, childObj );
|
||||
}
|
||||
else if( fields.Count == 1 )
|
||||
{
|
||||
object childObj = Deserialize( elem, childFi, childFi.FieldType, obj );
|
||||
|
||||
childFi.SetValue( obj, childObj );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( doProperties )
|
||||
{
|
||||
var props = refl.GetAllProperties( finalType );
|
||||
|
||||
foreach( var childPi in props )
|
||||
{
|
||||
String name = childPi.Name;
|
||||
|
||||
if( filterProps && !whitelistProps.Contains( name ) ) continue;
|
||||
|
||||
name = refl.TypeToIdentifier( name );
|
||||
|
||||
XmlElement childElem = getNamedChild( allChildren, name );
|
||||
|
||||
if( childElem != null )
|
||||
{
|
||||
object childObj = Deserialize( childElem, childPi, childPi.PropertyType, obj );
|
||||
|
||||
childPi.SetValue( obj, childObj );
|
||||
}
|
||||
else if( props.Count == 1 )
|
||||
{
|
||||
object childObj = Deserialize( elem, childPi, childPi.PropertyType, obj );
|
||||
|
||||
childPi.SetValue( obj, childObj );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
private void GetObjectForDeser( XmlElement elem, Type type, out Type finalType, out object obj )
|
||||
{
|
||||
string refString = elem.GetAttribute( "ref" );
|
||||
|
||||
private object DeserializeList( XmlElement elem, Type type, IList list )
|
||||
int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
|
||||
|
||||
finalType = type;
|
||||
if( elem.HasAttribute( "t" ) )
|
||||
{
|
||||
var typename = elem.GetAttribute( "t" );
|
||||
finalType = FindType( typename );
|
||||
|
||||
if( finalType == null )
|
||||
finalType = type;
|
||||
}
|
||||
|
||||
obj = createObject( finalType, refInt );
|
||||
}
|
||||
|
||||
private object DeserializeList( XmlElement elem, MemberInfo mi, Type type, IList list )
|
||||
{
|
||||
XmlNodeList arrNodeList = elem.ChildNodes;
|
||||
|
||||
@ -426,14 +551,14 @@ namespace lib
|
||||
{
|
||||
XmlElement arrElem = (XmlElement)arrNodeList.Item(i);
|
||||
|
||||
list.Add( Deserialize( arrElem, genT[0] ) );
|
||||
list.Add( Deserialize( arrElem, mi, genT[0] ) );
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private object DeserializeArray( XmlElement elem, Type type )
|
||||
private object DeserializeArray( XmlElement elem, MemberInfo mi, Type type )
|
||||
{
|
||||
Type typeElem = type.GetElementType();
|
||||
|
||||
@ -462,7 +587,7 @@ namespace lib
|
||||
finalType = typeElem;
|
||||
}
|
||||
|
||||
arr.SetValue( Deserialize( arrElem, finalType), i );
|
||||
arr.SetValue( Deserialize( arrElem, mi, finalType), i );
|
||||
}
|
||||
}
|
||||
|
||||
@ -567,9 +692,16 @@ namespace lib
|
||||
//string assName = ass.GetName().Name;
|
||||
|
||||
return type.FullName; // + ", " + assName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Serialize( Stream stream, object root )
|
||||
{
|
||||
Serialize( stream, null, root );
|
||||
}
|
||||
|
||||
public void Serialize( Stream stream, object root )
|
||||
|
||||
public void Serialize( Stream stream, MemberInfo mi, object root )
|
||||
{
|
||||
//lib.log.info( "Serialize( Stream stream, object root ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
|
||||
@ -580,7 +712,7 @@ namespace lib
|
||||
|
||||
writer.Formatting = Formatting.Indented;
|
||||
|
||||
Serialize( writer, root );
|
||||
Serialize( writer, mi, root );
|
||||
|
||||
//Rely on the parent closing the stream.
|
||||
//writer.Close();
|
||||
@ -589,14 +721,14 @@ namespace lib
|
||||
//lib.log.info( "Serialize END ( Stream stream, object root ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
}
|
||||
|
||||
private void Serialize( XmlWriter writer, object root )
|
||||
private void Serialize( XmlWriter writer, MemberInfo mi, object root )
|
||||
{
|
||||
//writer.WriteStartDocument();
|
||||
Serialize( writer, root, "root", true );
|
||||
Serialize( writer, mi, root, "root", true );
|
||||
//writer.WriteEndDocument();
|
||||
}
|
||||
|
||||
private void Serialize( XmlWriter writer, object root, string name, bool forceType )
|
||||
private void Serialize( XmlWriter writer, MemberInfo mi, object root, string name, bool forceType )
|
||||
{
|
||||
writer.WriteStartElement( name );
|
||||
|
||||
@ -608,17 +740,17 @@ namespace lib
|
||||
|
||||
if( typeCode != TypeCode.Object )
|
||||
{
|
||||
SerializeConcrete( writer, root, forceType );
|
||||
SerializeConcrete( writer, mi, root, forceType );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !type.IsArray )
|
||||
{
|
||||
SerializeObject( writer, root );
|
||||
SerializeObject( writer, mi, root );
|
||||
}
|
||||
else
|
||||
{
|
||||
SerializeArray( writer, root );
|
||||
SerializeArray( writer, mi, root );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -630,7 +762,7 @@ namespace lib
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private void SerializeConcrete( XmlWriter writer, object root, bool forceType )
|
||||
private void SerializeConcrete( XmlWriter writer, MemberInfo mi, object root, bool forceType )
|
||||
{
|
||||
//TODO: Only write this out if debugging.
|
||||
if( forceType )
|
||||
@ -640,7 +772,7 @@ namespace lib
|
||||
writer.WriteAttributeString( "v", root.ToString() );
|
||||
}
|
||||
|
||||
private void SerializeObject( XmlWriter writer, object root )
|
||||
private void SerializeObject( XmlWriter writer, MemberInfo mi, object root )
|
||||
{
|
||||
writer.WriteAttributeString( "t", getTypeName( root.GetType() ) );
|
||||
|
||||
@ -674,7 +806,12 @@ namespace lib
|
||||
|
||||
Type type = root.GetType();
|
||||
|
||||
//*
|
||||
//var whitelistProp = type.GetCustomAttribute<WhitelistPropsAttribute>();
|
||||
|
||||
//var useWhitelist = whitelistProp != null;
|
||||
|
||||
|
||||
//*
|
||||
Type typeISerializable = typeof(ISerializable);
|
||||
|
||||
if( root is ISerializable ) // type.IsSubclassOf( typeISerializable ) )
|
||||
@ -693,7 +830,7 @@ namespace lib
|
||||
|
||||
name = refl.TypeToIdentifier( name );
|
||||
|
||||
Serialize( writer, serMember.Value, name, true );
|
||||
Serialize( writer, mi, serMember.Value, name, true );
|
||||
}
|
||||
|
||||
//var sc = new SerializationContext(
|
||||
@ -703,31 +840,83 @@ namespace lib
|
||||
else
|
||||
//*/
|
||||
{
|
||||
var fields = refl.GetAllFields(type);
|
||||
var doFields = true;
|
||||
var doProperties = false;
|
||||
|
||||
//MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type, Context );
|
||||
var filterFields = mi?.GetCustomAttribute<WhitelistFieldsAttribute>() != null;
|
||||
var filterProps = mi?.GetCustomAttribute<WhitelistPropsAttribute>() != null;
|
||||
|
||||
foreach( var childFi in fields )
|
||||
HashSet<string> whitelistFields = new( mi?.GetCustomAttribute<WhitelistFieldsAttribute>()?.Values ?? new string[0] );
|
||||
HashSet<string> whitelistProps = new( mi?.GetCustomAttribute<WhitelistPropsAttribute>()?.Values ?? new string[0] );
|
||||
|
||||
if( type.GetCustomAttribute<PropertiesAttribute>() != null )
|
||||
{
|
||||
|
||||
object[] objs = childFi.GetCustomAttributes(typeof(NonSerializedAttribute), true);
|
||||
|
||||
if( objs.Length > 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = childFi.Name;
|
||||
|
||||
name = refl.TypeToIdentifier( name );
|
||||
|
||||
Serialize( writer, childFi.GetValue( root ), name, false );
|
||||
doProperties = true;
|
||||
}
|
||||
|
||||
if( mi?.GetCustomAttribute<WhitelistPropsAttribute>() != null )
|
||||
{
|
||||
doProperties = true;
|
||||
|
||||
doFields = mi?.GetCustomAttribute<WhitelistFieldsAttribute>() != null;
|
||||
}
|
||||
|
||||
//MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type, Context );
|
||||
|
||||
if( doFields )
|
||||
{
|
||||
var fields = refl.GetAllFields( type );
|
||||
|
||||
foreach( var childFi in fields )
|
||||
{
|
||||
String name = childFi.Name;
|
||||
|
||||
if( filterFields && !whitelistFields.Contains( 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, false );
|
||||
}
|
||||
}
|
||||
|
||||
if( doProperties )
|
||||
{
|
||||
var props = refl.GetAllProperties( type );
|
||||
|
||||
foreach( var childPi in props )
|
||||
{
|
||||
String name = childPi.Name;
|
||||
|
||||
if( filterProps && !whitelistProps.Contains( 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, false );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SerializeArray( XmlWriter writer, object root )
|
||||
private void SerializeArray( XmlWriter writer, MemberInfo mi, object root )
|
||||
{
|
||||
Array arr = (Array)root;
|
||||
|
||||
@ -756,10 +945,10 @@ namespace lib
|
||||
|
||||
for( int i = 0; i < arr.Length; ++i )
|
||||
{
|
||||
Serialize( writer, arr.GetValue( i ), "i" + i.ToString(), false );
|
||||
Serialize( writer, mi, arr.GetValue( i ), "i" + i.ToString(), false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user