From 4e59ae03318cb66779e21483005559159329ee2b Mon Sep 17 00:00:00 2001 From: Marc Hernandez Date: Sun, 26 May 2024 18:47:11 -0700 Subject: [PATCH] Add nullable annotations and update class constructors. Improve XML deserialization handling. --- SharpLib.csproj | 2 +- imm/Imm.cs | 27 ++++++++++++--------- net/Conn.cs | 3 +++ res/Resource.cs | 58 +++++++++----------------------------------- scr/Script.cs | 1 + ser/XmlFormatter2.cs | 36 ++++++++++++++++++--------- 6 files changed, 56 insertions(+), 71 deletions(-) diff --git a/SharpLib.csproj b/SharpLib.csproj index ba0cd54..c726707 100644 --- a/SharpLib.csproj +++ b/SharpLib.csproj @@ -18,7 +18,7 @@ - $(NoWarn);SYSLIB0050;CS8981 + $(NoWarn);SYSLIB0050;CS8981; CS8632 diff --git a/imm/Imm.cs b/imm/Imm.cs index 0ea20db..23ca6d4 100644 --- a/imm/Imm.cs +++ b/imm/Imm.cs @@ -1,4 +1,9 @@ -using System; + + +#nullable enable + + +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; @@ -13,7 +18,6 @@ using lib; namespace imm; - /* 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 */ - static public class Util { //This can handle both Timed and Recorded @@ -30,7 +33,7 @@ static public class Util [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = 0, [CallerArgumentExpression("fn")] - string dbgExp = default ) + string dbgExp = "" ) where T : Recorded { obj = obj.Process( fn, reason, dbgName, dbgPath, dbgLine, dbgExp ); @@ -43,7 +46,7 @@ static public class Util [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = 0, [CallerArgumentExpression("fn")] - string dbgExp = default + string dbgExp = "" ) where T : Versioned { @@ -81,7 +84,7 @@ public interface Imm [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = 0, [CallerArgumentExpression("next")] - string dbgExp = default + string dbgExp = "" ) { return next; @@ -210,7 +213,7 @@ public record class Recorded : Versioned, imm.Imm } [DebuggerBrowsable(DebuggerBrowsableState.Never)] - new public MetaData Meta => MetaStorage as MetaData; + new public MetaData Meta => MetaStorage as MetaData ?? new MetaData(); override public T Record( @@ -229,7 +232,7 @@ public record class Recorded : Versioned, imm.Imm [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = 0, [CallerArgumentExpression("next")] - string dbgExp = default + string dbgExp = "" ) { return ProcessWork( ( old ) => next, reason, dbgName, dbgPath, dbgLine, dbgExp ); @@ -242,7 +245,7 @@ public record class Recorded : Versioned, imm.Imm [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = 0, [CallerArgumentExpression("fn")] - string dbgExp = default + string dbgExp = "" ) { return ProcessWork( fn, reason, dbgName, dbgPath, dbgLine, dbgExp ); @@ -329,7 +332,7 @@ public record class Timed : Recorded, imm.Imm [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = 0, [CallerArgumentExpression("next")] - string dbgExp = default + string dbgExp = "" ) { return ProcessWork( ( old ) => next, reason, dbgName, dbgPath, dbgLine, dbgExp ); @@ -341,7 +344,7 @@ public record class Timed : Recorded, imm.Imm [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = 0, [CallerArgumentExpression("next")] - string dbgExp = default + string dbgExp = "" ) where U : T { @@ -354,7 +357,7 @@ public record class Timed : Recorded, imm.Imm [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = 0, [CallerArgumentExpression("fn")] - string dbgExp = default + string dbgExp = "" ) => ProcessWork( fn, reason, dbgName, dbgPath, dbgLine, dbgExp ); diff --git a/net/Conn.cs b/net/Conn.cs index e47b54c..b648253 100644 --- a/net/Conn.cs +++ b/net/Conn.cs @@ -1,3 +1,6 @@ + +#nullable enable + using System; using System.Runtime.Serialization; using System.Net.Sockets; diff --git a/res/Resource.cs b/res/Resource.cs index 55c9885..626ad8d 100644 --- a/res/Resource.cs +++ b/res/Resource.cs @@ -77,20 +77,11 @@ public class Ref : lib.I_Serialize [Serializable] [DebuggerDisplay("Path = {path} / Res = {res}")] -public class Ref : Ref where T : class +public class Ref : 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() - { - m_res = Mgr.load( Filename ); - if( s_verboseLogging ) log.info( $"Ref.lookup {GetType().Name} {GetType().GenericTypeArguments[0]} path {Filename}" ); - return m_res; - } - */ - - override public T? lookup( + override public T lookup( string reason = "", [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", @@ -138,7 +129,7 @@ public class Ref : Ref where T : class return enclosing; } - static public Ref createAsset( T v, string path, + static public Ref createAsset( T v, string path, string reason = "", [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", @@ -170,39 +161,13 @@ public class Ref : Ref where T : class [NonSerialized] protected T m_res; - - - - - } -/* -public class RefMemory : Ref where T : class -{ - //For serialization - public RefMemory( T res ) - : - base( "{memory}" ) - { - m_res = res; - } - - override internal void load() - { - } -} -*/ - - - public class Resource { static public Mgr mgr; - } - public delegate T Load( string filename ); @@ -237,9 +202,9 @@ where T : class } //generic classes make a new static per generic type -class ResCache where T : class +class ResCache where T : class, new() { - public static T s_default = default; + public static T s_default = new(); public static ImmutableDictionary> s_cache = ImmutableDictionary>.Empty; } @@ -309,19 +274,19 @@ public class Mgr } - static public Ref lookup( string filename, + static public Ref lookup( string filename, string reason = "", [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = 0 - ) where T : class + ) where T : class, new() { return new Ref( filename, reason, dbgName, dbgPath, dbgLine ); } /* - static public Ref lookup( string filename, Type t, + static public Ref lookup( string filename, Type t, string reason = "", [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", @@ -360,11 +325,10 @@ public class Mgr [CallerLineNumber] int dbgLine = 0, [CallerArgumentExpression("fn")] string dbgExp = default - ) where T : class + ) where T : class, new() { if( ResCache.s_cache.TryGetValue( filename, out var holder ) ) { - if( holder.weak.TryGetTarget( out var v ) ) { return v; @@ -385,7 +349,7 @@ public class Mgr return newV; } - static public T actualLoad( string filename ) where T : class + static public T actualLoad( string filename ) where T : class, new() { lock(s_loading) { diff --git a/scr/Script.cs b/scr/Script.cs index fadb3dd..fe24105 100644 --- a/scr/Script.cs +++ b/scr/Script.cs @@ -1,5 +1,6 @@  +#nullable enable diff --git a/ser/XmlFormatter2.cs b/ser/XmlFormatter2.cs index 44f0455..8c10c92 100644 --- a/ser/XmlFormatter2.cs +++ b/ser/XmlFormatter2.cs @@ -1,4 +1,7 @@ -using System; + + + +using System; using System.IO; using System.Xml; using System.Runtime.Serialization; @@ -184,32 +187,41 @@ namespace lib void SetFromStr( Stream stream ) { - fromStr = stream.ToString(); - fromStr = string.IsNullOrWhiteSpace(fromStr) ? (stream as FileStream).Name : fromStr; - fromStr = string.IsNullOrWhiteSpace(fromStr) ? (stream as NetworkStream).Socket.RemoteEndPoint.ToString() : fromStr; + fromStr = stream.ToString() ?? "{null}"; + + if( stream is FileStream fs ) + { + fromStr = fs.Name; + } + + if( stream is NetworkStream ns ) + { + fromStr = ns?.Socket?.RemoteEndPoint?.ToString() ?? $"{ns}"; + } } public object Deserialize( Stream stream ) { SetFromStr( stream ); - return DeserializeKnownType( stream, null ); + var obj = DeserializeKnownType( stream, null ); + return obj; } - public T Deserialize( Stream stream ) => (T)DeserializeKnownType( stream, typeof( T ) ); + public T? Deserialize( Stream stream ) => (T)DeserializeKnownType( stream, typeof( T ) ); - public object DeserializeKnownType( Stream stream, Type t ) + public object? DeserializeKnownType( Stream stream, Type? t ) { SetFromStr( stream ); XmlTextReader reader = new( stream ); - object obj = Deserialize( reader, t ); + object? obj = Deserialize( reader, t ); return obj; } - private object Deserialize( XmlReader reader, Type t ) + private object? Deserialize( XmlReader reader, Type? t ) { m_alreadySerialized.Clear(); m_objectID = new ObjectIDGenerator(); @@ -220,6 +232,8 @@ namespace lib doc.Load( reader ); + if( doc.DocumentElement == null ) return null; + if( t == null ) return Deserialize( doc.DocumentElement ); @@ -276,13 +290,13 @@ namespace lib 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}"; 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 {