Add the ability to write out trees vs full graphs.

This commit is contained in:
Marc Hernandez 2019-07-11 15:01:55 -07:00
parent 0e98d66d06
commit 4d9181e6ad

View File

@ -21,13 +21,29 @@ namespace lib
void OnDeserialize( object enclosing ); void OnDeserialize( object enclosing );
} }
public enum Datastructure
{
Invalid,
Tree,
Full,
}
public class XmlFormatter2Cfg : Config
{
public readonly Datastructure datastructure = Datastructure.Full;
}
public class XmlFormatter2 : IFormatter public class XmlFormatter2 : IFormatter
{ {
public StreamingContext Context { get; set; } public StreamingContext Context { get; set; }
static private Random s_rnd = new Random(); static Random s_rnd = new Random();
private int m_rndVal = s_rnd.Next(); int m_rndVal = s_rnd.Next();
XmlFormatter2Cfg m_cfg = new XmlFormatter2Cfg();
#region Unimplimented #region Unimplimented
public ISurrogateSelector SurrogateSelector public ISurrogateSelector SurrogateSelector
@ -44,6 +60,10 @@ public class XmlFormatter2 : IFormatter
#endregion #endregion
public XmlFormatter2() public XmlFormatter2()
{ {
Context = new StreamingContext( StreamingContextStates.All ); Context = new StreamingContext( StreamingContextStates.All );
@ -51,6 +71,16 @@ public class XmlFormatter2 : IFormatter
public XmlFormatter2( XmlFormatter2Cfg cfg )
{
Context = new StreamingContext( StreamingContextStates.All );
m_cfg = cfg;
}
#region Deserialize #region Deserialize
private static FormatterConverter s_conv = new FormatterConverter(); private static FormatterConverter s_conv = new FormatterConverter();
@ -416,19 +446,44 @@ public class XmlFormatter2 : IFormatter
{ {
TypeCode tc = Type.GetTypeCode( type ); TypeCode tc = Type.GetTypeCode( type );
if( refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) ) if( m_cfg.datastructure == Datastructure.Full && 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 ];
} }
else else
{ {
//lib.log.info( "Creating new object for {0}", refInt ); object obj = null;
object obj = Activator.CreateInstance( type );
if( refInt > 0 ) try
{ {
m_alreadySerialized[ refInt ] = obj; //Trying the nice way to creat objects first.
obj = Activator.CreateInstance( type );
}
catch( Exception ex )
{
try
{
obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
}
catch( Exception exInner )
{
lib.Log.error( $"Got exception {exInner.Message} trying to make an uninitialized object" );
}
}
if( obj == null )
{
lib.Log.warn( $"Could not create object of type {type.Name}" );
return obj;
}
if( m_cfg.datastructure == Datastructure.Full && refInt > 0 )
{
m_alreadySerialized[refInt] = obj;
} }
return obj; return obj;
@ -446,7 +501,7 @@ public class XmlFormatter2 : IFormatter
{ {
TypeCode elemTC = Type.GetTypeCode( elemType ); TypeCode elemTC = Type.GetTypeCode( elemType );
if( refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) ) if( m_cfg.datastructure == Datastructure.Full && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
{ {
return (Array)m_alreadySerialized[ refInt ]; return (Array)m_alreadySerialized[ refInt ];
} }
@ -454,8 +509,12 @@ public class XmlFormatter2 : IFormatter
{ {
Array arr = Array.CreateInstance( elemType, length ) ; Array arr = Array.CreateInstance( elemType, length ) ;
if( m_cfg.datastructure == Datastructure.Full )
{
m_alreadySerialized[ refInt ] = arr; m_alreadySerialized[ refInt ] = arr;
}
return arr; return arr;
} }
} }
@ -566,11 +625,18 @@ public class XmlFormatter2 : IFormatter
long refInt = m_objectID.GetId( root, out first ); long refInt = m_objectID.GetId( root, out first );
if( m_cfg.datastructure == Datastructure.Full )
{
writer.WriteAttributeString( "ref", refInt.ToString() ); writer.WriteAttributeString( "ref", refInt.ToString() );
}
if( first ) if( first )
{
if( m_cfg.datastructure == Datastructure.Full )
{ {
m_alreadySerialized[ refInt ] = root; m_alreadySerialized[ refInt ] = root;
}
Type type = root.GetType(); Type type = root.GetType();
@ -641,11 +707,17 @@ public class XmlFormatter2 : IFormatter
long refInt = m_objectID.GetId( root, out first ); long refInt = m_objectID.GetId( root, out first );
if( m_cfg.datastructure == Datastructure.Full )
{
writer.WriteAttributeString( "ref", refInt.ToString() ); writer.WriteAttributeString( "ref", refInt.ToString() );
}
if( first ) if( first )
{
if( m_cfg.datastructure == Datastructure.Full )
{ {
m_alreadySerialized[ refInt ] = root; m_alreadySerialized[ refInt ] = root;
}
for( int i = 0; i < arr.Length; ++i ) for( int i = 0; i < arr.Length; ++i )