Add nullable annotations and update class constructors. Improve XML deserialization handling.
This commit is contained in:
parent
05656d469a
commit
4e59ae0331
@ -18,7 +18,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<NoWarn>$(NoWarn);SYSLIB0050;CS8981</NoWarn>
|
<NoWarn>$(NoWarn);SYSLIB0050;CS8981; CS8632</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
27
imm/Imm.cs
27
imm/Imm.cs
@ -1,4 +1,9 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@ -13,7 +18,6 @@ using lib;
|
|||||||
|
|
||||||
namespace imm;
|
namespace imm;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
T O D O :
|
T O D O :
|
||||||
T O D O :
|
T O D O :
|
||||||
@ -21,7 +25,6 @@ T O D O :
|
|||||||
x) Add unit tests for all this. This will definitely benefit from them
|
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
|
||||||
@ -30,7 +33,7 @@ static public class Util
|
|||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
[CallerLineNumber] int dbgLine = 0,
|
[CallerLineNumber] int dbgLine = 0,
|
||||||
[CallerArgumentExpression("fn")]
|
[CallerArgumentExpression("fn")]
|
||||||
string dbgExp = default )
|
string dbgExp = "" )
|
||||||
where T : Recorded<T>
|
where T : Recorded<T>
|
||||||
{
|
{
|
||||||
obj = obj.Process( fn, reason, dbgName, dbgPath, dbgLine, dbgExp );
|
obj = obj.Process( fn, reason, dbgName, dbgPath, dbgLine, dbgExp );
|
||||||
@ -43,7 +46,7 @@ static public class Util
|
|||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
[CallerLineNumber] int dbgLine = 0,
|
[CallerLineNumber] int dbgLine = 0,
|
||||||
[CallerArgumentExpression("fn")]
|
[CallerArgumentExpression("fn")]
|
||||||
string dbgExp = default
|
string dbgExp = ""
|
||||||
)
|
)
|
||||||
where T : Versioned<T>
|
where T : Versioned<T>
|
||||||
{
|
{
|
||||||
@ -81,7 +84,7 @@ public interface Imm
|
|||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
[CallerLineNumber] int dbgLine = 0,
|
[CallerLineNumber] int dbgLine = 0,
|
||||||
[CallerArgumentExpression("next")]
|
[CallerArgumentExpression("next")]
|
||||||
string dbgExp = default
|
string dbgExp = ""
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return next;
|
return next;
|
||||||
@ -210,7 +213,7 @@ public record class Recorded<T> : Versioned<T>, imm.Imm
|
|||||||
}
|
}
|
||||||
|
|
||||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||||
new public MetaData Meta => MetaStorage as MetaData;
|
new public MetaData Meta => MetaStorage as MetaData ?? new MetaData();
|
||||||
|
|
||||||
|
|
||||||
override public T Record(
|
override public T Record(
|
||||||
@ -229,7 +232,7 @@ public record class Recorded<T> : Versioned<T>, imm.Imm
|
|||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
[CallerLineNumber] int dbgLine = 0,
|
[CallerLineNumber] int dbgLine = 0,
|
||||||
[CallerArgumentExpression("next")]
|
[CallerArgumentExpression("next")]
|
||||||
string dbgExp = default
|
string dbgExp = ""
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ProcessWork( ( old ) => next, reason, dbgName, dbgPath, dbgLine, dbgExp );
|
return ProcessWork( ( old ) => next, reason, dbgName, dbgPath, dbgLine, dbgExp );
|
||||||
@ -242,7 +245,7 @@ public record class Recorded<T> : Versioned<T>, imm.Imm
|
|||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
[CallerLineNumber] int dbgLine = 0,
|
[CallerLineNumber] int dbgLine = 0,
|
||||||
[CallerArgumentExpression("fn")]
|
[CallerArgumentExpression("fn")]
|
||||||
string dbgExp = default
|
string dbgExp = ""
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ProcessWork( fn, reason, dbgName, dbgPath, dbgLine, dbgExp );
|
return ProcessWork( fn, reason, dbgName, dbgPath, dbgLine, dbgExp );
|
||||||
@ -329,7 +332,7 @@ public record class Timed<T> : Recorded<T>, imm.Imm
|
|||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
[CallerLineNumber] int dbgLine = 0,
|
[CallerLineNumber] int dbgLine = 0,
|
||||||
[CallerArgumentExpression("next")]
|
[CallerArgumentExpression("next")]
|
||||||
string dbgExp = default
|
string dbgExp = ""
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ProcessWork( ( old ) => next, reason, dbgName, dbgPath, dbgLine, dbgExp );
|
return ProcessWork( ( old ) => next, reason, dbgName, dbgPath, dbgLine, dbgExp );
|
||||||
@ -341,7 +344,7 @@ public record class Timed<T> : Recorded<T>, imm.Imm
|
|||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
[CallerLineNumber] int dbgLine = 0,
|
[CallerLineNumber] int dbgLine = 0,
|
||||||
[CallerArgumentExpression("next")]
|
[CallerArgumentExpression("next")]
|
||||||
string dbgExp = default
|
string dbgExp = ""
|
||||||
)
|
)
|
||||||
where U : T
|
where U : T
|
||||||
{
|
{
|
||||||
@ -354,7 +357,7 @@ public record class Timed<T> : Recorded<T>, imm.Imm
|
|||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
[CallerLineNumber] int dbgLine = 0,
|
[CallerLineNumber] int dbgLine = 0,
|
||||||
[CallerArgumentExpression("fn")]
|
[CallerArgumentExpression("fn")]
|
||||||
string dbgExp = default
|
string dbgExp = ""
|
||||||
)
|
)
|
||||||
=> ProcessWork( fn, reason, dbgName, dbgPath, dbgLine, dbgExp );
|
=> ProcessWork( fn, reason, dbgName, dbgPath, dbgLine, dbgExp );
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
|||||||
@ -77,20 +77,11 @@ public class Ref : lib.I_Serialize
|
|||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
[DebuggerDisplay("Path = {path} / Res = {res}")]
|
[DebuggerDisplay("Path = {path} / Res = {res}")]
|
||||||
public class Ref<T> : Ref where T : class
|
public class Ref<T> : Ref where T : class, new()
|
||||||
{
|
{
|
||||||
public T? res => m_res != null ? m_res : lookup();
|
public T res => m_res != null ? m_res : lookup();
|
||||||
|
|
||||||
/*
|
override public T lookup(
|
||||||
override public T? lookup()
|
|
||||||
{
|
|
||||||
m_res = Mgr.load<T>( Filename );
|
|
||||||
if( s_verboseLogging ) log.info( $"Ref.lookup {GetType().Name} {GetType().GenericTypeArguments[0]} path {Filename}" );
|
|
||||||
return m_res;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
override public T? lookup(
|
|
||||||
string reason = "",
|
string reason = "",
|
||||||
[CallerMemberName] string dbgName = "",
|
[CallerMemberName] string dbgName = "",
|
||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
@ -170,39 +161,13 @@ public class Ref<T> : Ref where T : class
|
|||||||
|
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
protected T m_res;
|
protected T m_res;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
public class RefMemory<T> : Ref<T> where T : class
|
|
||||||
{
|
|
||||||
//For serialization
|
|
||||||
public RefMemory( T res )
|
|
||||||
:
|
|
||||||
base( "{memory}" )
|
|
||||||
{
|
|
||||||
m_res = res;
|
|
||||||
}
|
|
||||||
|
|
||||||
override internal void load()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Resource
|
public class Resource
|
||||||
{
|
{
|
||||||
static public Mgr mgr;
|
static public Mgr mgr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public delegate T Load<out T>( string filename );
|
public delegate T Load<out T>( string filename );
|
||||||
|
|
||||||
|
|
||||||
@ -237,9 +202,9 @@ where T : class
|
|||||||
}
|
}
|
||||||
|
|
||||||
//generic classes make a new static per generic type
|
//generic classes make a new static per generic type
|
||||||
class ResCache<T> where T : class
|
class ResCache<T> where T : class, new()
|
||||||
{
|
{
|
||||||
public static T s_default = default;
|
public static T s_default = new();
|
||||||
public static ImmutableDictionary<string, ResourceHolder<T>> s_cache = ImmutableDictionary<string, ResourceHolder<T>>.Empty;
|
public static ImmutableDictionary<string, ResourceHolder<T>> s_cache = ImmutableDictionary<string, ResourceHolder<T>>.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +279,7 @@ public class Mgr
|
|||||||
[CallerMemberName] string dbgName = "",
|
[CallerMemberName] string dbgName = "",
|
||||||
[CallerFilePath] string dbgPath = "",
|
[CallerFilePath] string dbgPath = "",
|
||||||
[CallerLineNumber] int dbgLine = 0
|
[CallerLineNumber] int dbgLine = 0
|
||||||
) where T : class
|
) where T : class, new()
|
||||||
{
|
{
|
||||||
return new Ref<T>( filename, reason, dbgName, dbgPath, dbgLine );
|
return new Ref<T>( filename, reason, dbgName, dbgPath, dbgLine );
|
||||||
}
|
}
|
||||||
@ -360,11 +325,10 @@ public class Mgr
|
|||||||
[CallerLineNumber] int dbgLine = 0,
|
[CallerLineNumber] int dbgLine = 0,
|
||||||
[CallerArgumentExpression("fn")]
|
[CallerArgumentExpression("fn")]
|
||||||
string dbgExp = default
|
string dbgExp = default
|
||||||
) where T : class
|
) where T : class, new()
|
||||||
{
|
{
|
||||||
if( ResCache<T>.s_cache.TryGetValue( filename, out var holder ) )
|
if( ResCache<T>.s_cache.TryGetValue( filename, out var holder ) )
|
||||||
{
|
{
|
||||||
|
|
||||||
if( holder.weak.TryGetTarget( out var v ) )
|
if( holder.weak.TryGetTarget( out var v ) )
|
||||||
{
|
{
|
||||||
return v;
|
return v;
|
||||||
@ -385,7 +349,7 @@ public class Mgr
|
|||||||
return newV;
|
return newV;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public T actualLoad<T>( string filename ) where T : class
|
static public T actualLoad<T>( string filename ) where T : class, new()
|
||||||
{
|
{
|
||||||
lock(s_loading)
|
lock(s_loading)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
@ -184,32 +187,41 @@ namespace lib
|
|||||||
|
|
||||||
void SetFromStr( Stream stream )
|
void SetFromStr( Stream stream )
|
||||||
{
|
{
|
||||||
fromStr = stream.ToString();
|
fromStr = stream.ToString() ?? "{null}";
|
||||||
fromStr = string.IsNullOrWhiteSpace(fromStr) ? (stream as FileStream).Name : fromStr;
|
|
||||||
fromStr = string.IsNullOrWhiteSpace(fromStr) ? (stream as NetworkStream).Socket.RemoteEndPoint.ToString() : fromStr;
|
if( stream is FileStream fs )
|
||||||
|
{
|
||||||
|
fromStr = fs.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stream is NetworkStream ns )
|
||||||
|
{
|
||||||
|
fromStr = ns?.Socket?.RemoteEndPoint?.ToString() ?? $"{ns}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Deserialize( Stream stream )
|
public object Deserialize( Stream stream )
|
||||||
{
|
{
|
||||||
SetFromStr( stream );
|
SetFromStr( stream );
|
||||||
return DeserializeKnownType( stream, null );
|
var obj = DeserializeKnownType( stream, null );
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public T Deserialize<T>( Stream stream ) => (T)DeserializeKnownType( stream, typeof( T ) );
|
public T? Deserialize<T>( Stream stream ) => (T)DeserializeKnownType( stream, typeof( T ) );
|
||||||
|
|
||||||
public object DeserializeKnownType( Stream stream, Type t )
|
public object? DeserializeKnownType( Stream stream, Type? t )
|
||||||
{
|
{
|
||||||
SetFromStr( stream );
|
SetFromStr( stream );
|
||||||
|
|
||||||
XmlTextReader reader = new( stream );
|
XmlTextReader reader = new( stream );
|
||||||
|
|
||||||
object obj = Deserialize( reader, t );
|
object? obj = Deserialize( reader, t );
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
private object Deserialize( XmlReader reader, Type t )
|
private object? Deserialize( XmlReader reader, Type? t )
|
||||||
{
|
{
|
||||||
m_alreadySerialized.Clear();
|
m_alreadySerialized.Clear();
|
||||||
m_objectID = new ObjectIDGenerator();
|
m_objectID = new ObjectIDGenerator();
|
||||||
@ -220,6 +232,8 @@ namespace lib
|
|||||||
|
|
||||||
doc.Load( reader );
|
doc.Load( reader );
|
||||||
|
|
||||||
|
if( doc.DocumentElement == null ) return null;
|
||||||
|
|
||||||
if( t == null )
|
if( t == null )
|
||||||
return Deserialize( doc.DocumentElement );
|
return Deserialize( doc.DocumentElement );
|
||||||
|
|
||||||
@ -276,13 +290,13 @@ namespace lib
|
|||||||
|
|
||||||
static private bool IsEnumerable( Type type ) => type.IsAssignableTo( typeof( IEnumerable ) );
|
static private bool IsEnumerable( Type type ) => 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*/ )
|
||||||
{
|
{
|
||||||
var name = mi?.Name ?? "{NOT_FOUND}";
|
var name = mi?.Name ?? "{NOT_FOUND}";
|
||||||
return Deserialize( elem, mi, type, name, existing );
|
return Deserialize( elem, mi, type, name, existing );
|
||||||
}
|
}
|
||||||
|
|
||||||
private object Deserialize( XmlElement elem, MemberInfo mi, Type type, string name, object existing /*, object enclosing = null*/ )
|
private object Deserialize( XmlElement elem, MemberInfo? mi, Type type, string name, object? existing /*, object enclosing = null*/ )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user