From 46b76f68edcaf6fcbc0f538aecce671459137c52 Mon Sep 17 00:00:00 2001 From: Marc Date: Wed, 3 Apr 2013 19:30:41 -0700 Subject: [PATCH] Initial stuff --- .gitignore | 31 + Clock.cs | 52 ++ Config.cs | 158 ++++++ Conn.cs | 106 ++++ Helpers.cs | 179 ++++++ Log.cs | 239 ++++++++ NetMsg.cs | 103 ++++ Pos.cs | 52 ++ Properties/AssemblyInfo.cs | 36 ++ SerializableDictionary.cs | 157 ++++++ SharpLib.sln | 20 + Timer.cs | 95 ++++ Token.cs | 46 ++ UpgradeLog.XML | Bin 0 -> 2482 bytes UpgradeLog.htm | Bin 0 -> 16270 bytes VersionFormatter.cs | 670 ++++++++++++++++++++++ XmlFormatter.cs | 1096 ++++++++++++++++++++++++++++++++++++ XmlFormatter2.cs | 605 ++++++++++++++++++++ import.txt | 0 res/Resource.cs | 167 ++++++ 20 files changed, 3812 insertions(+) create mode 100644 .gitignore create mode 100644 Clock.cs create mode 100644 Config.cs create mode 100644 Conn.cs create mode 100644 Helpers.cs create mode 100644 Log.cs create mode 100644 NetMsg.cs create mode 100644 Pos.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 SerializableDictionary.cs create mode 100644 SharpLib.sln create mode 100644 Timer.cs create mode 100644 Token.cs create mode 100644 UpgradeLog.XML create mode 100644 UpgradeLog.htm create mode 100644 VersionFormatter.cs create mode 100644 XmlFormatter.cs create mode 100644 XmlFormatter2.cs delete mode 100644 import.txt create mode 100644 res/Resource.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..866703f --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +################################### +# Git ignore file for Molyjam2012 # +################################### + +#Folders +Library/ +Temp/ +Builds/ +Libraries/ +Debug/ +Release/ +run/ +bin/ +obj/ + +#Project/User Preference Files +*.csproj +*.pidb +*.userprefs +*.user +*.suo + +#OS Junk +Thumbs.db +.DS_Store* +ehthumbs.db +Icon7 + + + +#*.sln diff --git a/Clock.cs b/Clock.cs new file mode 100644 index 0000000..483c567 --- /dev/null +++ b/Clock.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace lib +{ + public class Clock + { + public Clock( long timeOffset ) + { + m_timer = new Timer(); + + m_lastTime = m_timer.Current; + + m_totalMillis = timeOffset; + m_totalSeconds= (double)m_totalMillis / 1000.0; + } + + public void tick() + { + long current = m_timer.Current; + + m_dtMillis = (int)(current - m_lastTime); + + m_dtSeconds = (double)m_dtMillis / 1000.0; + + m_totalMillis += m_dtMillis; + m_totalSeconds = (double)m_totalMillis / 1000.0; + + m_lastTime = current; + } + + public int dtMs { get { return m_dtMillis; } } + public double dtSec { get { return m_dtSeconds; } } + + public long ms { get { return m_totalMillis; } } + public double sec{ get { return m_totalSeconds; } } + + + Timer m_timer; + + long m_lastTime = 0; + + int m_dtMillis = 0; + double m_dtSeconds = 0; + + long m_totalMillis = 0; + double m_totalSeconds = 0; + + } +} diff --git a/Config.cs b/Config.cs new file mode 100644 index 0000000..38d7181 --- /dev/null +++ b/Config.cs @@ -0,0 +1,158 @@ +using System; +using System.IO; +using System.Xml; +using System.Reflection; + +namespace lib +{ + +[Serializable] +public class ResRefConfig : res.Ref where T: Config +{ + public ResRefConfig() + { + } + + public ResRefConfig( string filename, T cfg ) + : base( filename, cfg ) + { + } + + override public void OnDeserialize( object enclosing ) + { + base.OnDeserialize( enclosing ); + + var cfg = Config.load( filename ); + + res = cfg; + } +} + +[Serializable] +public class Config +{ + /* + static public Config Load( string filename ) + { + return null; + } + */ + + static public void startup() + { + res.Mgr.register( res_load ); + res.Mgr.registerSub( res_load ); + } + + + #region SaveLoad + static public ResRefConfig res_load( string filename ) + { + return new ResRefConfig( filename, load( filename ) ); + } + + static public ResRefConfig res_load( string filename ) where T : Config + { + return new ResRefConfig( filename, load( filename ) ); + } + + /* + static public ResRefConfig res_load( string filename, Type t ) + { + return new ResRefConfig( filename, load( filename, t ) ); + } + */ + + + static public Config load( string filename ) + { + FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read ); + + XmlFormatter2 formatter = new XmlFormatter2(); + + Config cfg = (Config)formatter.Deserialize( fs ); + + return cfg; + } + + static public T load( string filename ) where T : Config + { + return (T)load( filename, typeof( T ) ); + } + + static public Config load( string filename, Type t ) + { + Config cfg = null; + + try + { + FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read ); + + XmlFormatter2 formatter = new XmlFormatter2(); + + cfg = (Config)( t != null ? formatter.DeserializeKnownType( fs,t ) : formatter.Deserialize( fs ) ); + + cfg.SetFilename( filename ); + } + catch( FileNotFoundException ) + { + Type[] types = new Type[ 0 ]; + object[] parms = new object[ 0 ]; + + //types[ 0 ] = typeof( string ); + //parms[ 0 ] = filename; + + ConstructorInfo cons = t.GetConstructor( types ); + + try + { + cfg = (Config)cons.Invoke( parms ); + } + catch( Exception e ) + { + Log.error( "Caught exception {0}", e ); + } + + cfg.SetFilename( filename ); + + Config.save( cfg, filename ); + } + + return cfg; + } + + static public void save( Config cfg ) + { + Config.save( cfg, cfg.m_filename ); + } + + static public void save( Config cfg, String filename ) + { + FileStream fs = new FileStream( filename, FileMode.Create, FileAccess.Write ); + + XmlFormatter2 formatter = new XmlFormatter2(); + + formatter.Serialize( fs, cfg ); + + fs.Close(); + } + #endregion + + private string m_filename = ""; + + public Config() + { + } + + public Config( string filename ) + { + m_filename = filename; + } + + public String Filename { get { return m_filename; } } + + protected void SetFilename( String filename ) { m_filename = filename; } + +} +} + diff --git a/Conn.cs b/Conn.cs new file mode 100644 index 0000000..4b460b5 --- /dev/null +++ b/Conn.cs @@ -0,0 +1,106 @@ +using System; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using System.Net.Sockets; +using System.IO; + +//using Util; + +namespace lib +{ + + + +public class Conn +{ + public Socket Sock { get { return m_socket; } } + public Stream Stream { get { return m_streamNet; } } + public IFormatter Formatter { get { return m_formatter; } } + + + public Conn( Socket sock, IFormatter formatter ) + { + m_socket = sock; + + //sock.DontFragment = true; + sock.NoDelay = true; + + m_streamNet = new NetworkStream( m_socket ); + //m_streamBufIn = new BufferedStream( m_streamNet ); + + m_formatter = formatter; + //m_formatter = new VersionFormatter(); + + //mm_memStream = new MemoryStream( mm_buffer ); + + + } + + public object recieveObject() + { + return recieveObject( Stream ); + } + + public object recieveObject( Stream stream ) + { + object obj = null; + lock( this ) + { + try + { + obj = m_formatter.Deserialize( stream ); + } + catch( System.Xml.XmlException e ) + { + lib.Log.error( "Outer Exception {0}", e.ToString() ); + //lib.Log.error( "Inner Exception {0}", e.InnerException.ToString() ); + } + } + + return obj; + } + + public void send( object obj ) + { + lock( this ) + { + try + { + var ms = new MemoryStream( 1024 ); + m_formatter.Serialize( ms, obj ); + + //var str = System.Text.Encoding.Default.GetString( mm_buffer, 0, (int)ms.Position ); + //lib.Log.info( "Sent data {0} of length {1}", str, ms.Position ); + + byte[] byteSize = BitConverter.GetBytes( (uint)ms.Position ); + m_streamNet.Write( byteSize, 0, 4 ); + m_streamNet.Write( ms.GetBuffer(), 0, (int)ms.Position ); + + m_streamNet.Flush(); + } + catch( Exception e ) + { + //m_streamNet.Close(); + //m_socket.Close(); + } + } + } + + public virtual void recieve( object obj ) + { + //Log.log.msg( "Recieved " + obj.ToString() ); + } + + private Socket m_socket; + + private NetworkStream m_streamNet; + //private BufferedStream m_streamBufIn; + //private BufferedStream m_streamBufOut; + + private IFormatter m_formatter; + +} + + + +} diff --git a/Helpers.cs b/Helpers.cs new file mode 100644 index 0000000..56e08f1 --- /dev/null +++ b/Helpers.cs @@ -0,0 +1,179 @@ + +/* + * TODO: Need to verify types are correct when deserializing. +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Reflection; + +using System.Xml; +using System.Xml.Serialization; + +using System.IO; + +namespace lib +{ + public class Helpers + { + public void XmlSave( String filename, Object obj ) + { + FileStream fs = new FileStream( filename, FileMode.Create, FileAccess.Write ); + + XmlSerializer xs = new XmlSerializer( obj.GetType() ); + //MemoryStream memoryStream = new MemoryStream( StringToUTF8ByteArray( pXmlizedString ) ); + //XmlTextReader reader = new XmlTextReader( fs, Encoding.UTF8 ); + + xs.Serialize( fs, obj ); + } + + public Object XmlLoad( String filename ) + { + FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read ); + + XmlSerializer xs = new XmlSerializer( typeof( TType ) ); + //MemoryStream memoryStream = new MemoryStream( StringToUTF8ByteArray( pXmlizedString ) ); + //XmlTextReader reader = new XmlTextReader( fs, Encoding.UTF8 ); + + return xs.Deserialize( fs ); + } + + + static public MethodInfo FindConvertFunction( string typeName ) + { + Type t = typeof( Convert ); + + + MethodInfo[] allMethods = t.GetMethods(); + + foreach( MethodInfo mi in allMethods ) + { + if( mi.GetParameters().Length == 1 ) + { + string paramName = mi.GetParameters()[ 0 ].ParameterType.Name; + + if( paramName == "String" ) + { + if( mi.ReturnType.FullName == typeName ) + { + return mi; + } + } + } + } + + return null; + + } + + static public void SerializeDict( string filename, Dictionary dict ) + { + XmlTextWriter xmlWriter = new XmlTextWriter( filename, null ); + + xmlWriter.Formatting = Formatting.Indented; + + //xmlWriter.WriteStartDocument(); + + xmlWriter.WriteStartElement( "dictionary" ); + + Type[] types = dict.GetType().GetGenericArguments(); + + xmlWriter.WriteAttributeString( "keyType", types[ 0 ].FullName ); + xmlWriter.WriteAttributeString( "valType", types[ 1 ].FullName ); + + foreach( KeyValuePair kvp in dict ) + { + xmlWriter.WriteStartElement( "kvp" ); + + xmlWriter.WriteAttributeString( "key", kvp.Key.ToString() ); + xmlWriter.WriteAttributeString( "value", kvp.Value.ToString() ); + + xmlWriter.WriteEndElement(); + } + + xmlWriter.WriteEndElement(); + + //xmlWriter.WriteEndDocument(); + + xmlWriter.Close(); + } + + static public void DeserializeDict( string filename, Dictionary dict ) + { + FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read ); + + XmlDocument doc = new XmlDocument(); + + doc.Load( fs ); + + //CreateTypeFor() + + XmlElement docElem = doc.DocumentElement; + + if( docElem.Name == "dictionary" ) + { + string keyType = docElem.GetAttribute( "keyType" ); + string valType = docElem.GetAttribute( "valType" ); + + MethodInfo keyMI = FindConvertFunction( keyType ); + MethodInfo valMI = FindConvertFunction( valType ); + + + if( keyMI != null && valMI != null ) + { + XmlNodeList nodeList = docElem.ChildNodes; + + object[] args = new object[ 1 ]; + + //fi.SetValue( newObj, obj ); + + foreach( XmlElement node in nodeList ) + { + if( node.Name == "kvp" ) + { + if( node.Attributes != null ) + { + args[ 0 ] = node.GetAttribute( "key" ); + + TKey key = (TKey)keyMI.Invoke( null, args ); + + args[ 0 ] = node.GetAttribute( "value" ); + + TVal val = (TVal)valMI.Invoke( null, args ); + + dict[ key ] = val; + } + else + { + Log.error( String.Format( "No attributes in node while loading file {0}", filename ) ); + } + } + else + { + Log.error( String.Format( "Incorrect key {0} found while loading file {1}", node.Name, filename ) ); + } + } + } + else + { + if( keyMI == null ) + Log.error( String.Format( "Key type conversion not found for type {0}", keyType ) ); + + if( valMI == null ) + Log.error( String.Format( "Val type conversion not found for type {0}", valType ) ); + } + + } + else + { + Log.error( String.Format( "No dictionary element found while loading file {0}", filename ) ); + } + } + + } + + + +} diff --git a/Log.cs b/Log.cs new file mode 100644 index 0000000..aa05147 --- /dev/null +++ b/Log.cs @@ -0,0 +1,239 @@ +using System; +using System.IO; +using System.Diagnostics; +using System.Collections; +//using System.Threading.Tasks; + +namespace lib +{ + + public delegate void Log_delegate( String type, String cat, String msg ); + + public class Log : TraceListener + { + static public void create( String filename ) + { + s_log = new Log( filename ); + } + + static public void destroy() + { + string msg = "==============================================================================\nLogfile shutdown at " + DateTime.Now.ToString(); + + s_log.writeToAll( "info", "log", msg ); + + s_log.stop(); + + s_log = null; + } + + static private Log s_log; + + static public Log log + { + get + { + return s_log; + } + } + + // Forwards. + static public void error( String msg, params object[] args ) { lock( s_log ) { log.error_i( msg, args ); } } + static public void warn( String msg, params object[] args ) { lock( s_log ) { log.warn_i( msg, args ); } } + static public void info( String msg, params object[] args ) { lock( s_log ) { log.info_i( msg, args ); } } + + + private Log( String filename ) + { + //TODO: Fix this so itll work without a directory. + Directory.CreateDirectory( Path.GetDirectoryName( filename ) ); + + m_stream = new FileStream( filename, FileMode.Append, FileAccess.Write ); + m_writer = new StreamWriter( m_stream ); + + m_errorStream = new FileStream( filename + ".error", FileMode.Append, FileAccess.Write ); + m_errorWriter = new StreamWriter( m_errorStream ); + + Debug.Listeners.Add( this ); + + string msg = "\n==============================================================================\nLogfile " + filename + " startup at " + DateTime.Now.ToString(); + + writeToAll( "info", "log", msg ); + } + + public override void Write( string msg ) + { + WriteLine( msg ); + } + + public override void WriteLine( string msg ) + { + error( msg ); + //base.WriteLine( msg ); + } + + void stop() + { + m_writer.Close(); + m_stream.Close(); + + m_errorWriter.Close(); + m_errorStream.Close(); + } + + public void addDelegate( Log_delegate cb ) + { + m_delegates.Add( cb ); + } + + private void writeFileAndLine( StackTrace st ) + { + StackFrame frame = st.GetFrame( 1 ); + + String srcFile = frame.GetFileName(); + String srcLine = frame.GetFileLineNumber().ToString(); + + Console.WriteLine( "{0} ({1}):", srcFile, srcLine ); + } + + private void writeStack( StackTrace st ) + { + for( int i=0; i { + StackTrace st = new StackTrace( true ); + + writeStack( st ); + + String msgPrint = msg; + + if( args.Length > 0 ) + { + msgPrint = String.Format( msg, args ); + } + + writeToAll( "error", "log", msgPrint ); + //} ); + } + + private void warn_i( String msg, params object[] args ) + { + //var t = Task.Run( () => { + StackTrace st = new StackTrace( true ); + + writeStack( st ); + + String msgPrint = msg; + + if( args.Length > 0 ) + { + msgPrint = String.Format( msg, args ); + } + + writeToAll( "warn", "log", msgPrint ); + //}); + } + + private void info_i( String msg, params object[] args ) + { + //var t = Task.Run( () => { + StackTrace st = new StackTrace( true ); + + String msgPrint = msg; + + if( args.Length > 0 ) + { + msgPrint = String.Format( msg, args ); + } + + writeToAll( "info", "log", msgPrint ); + //} ); + } + + + private Stream m_stream; + private StreamWriter m_writer; + + private Stream m_errorStream; + private StreamWriter m_errorWriter; + + private ArrayList m_delegates = new ArrayList(); + } + + + + + + + + + +} diff --git a/NetMsg.cs b/NetMsg.cs new file mode 100644 index 0000000..582e36e --- /dev/null +++ b/NetMsg.cs @@ -0,0 +1,103 @@ +using System; + +namespace lib.Net +{ + [Serializable] + public class Msg + { + public Msg() + { + } + } + + [Serializable] + public class Login + { + public Login( String name, String pass ) + { + m_username = name; + m_password = pass; + } + + public readonly String m_username; + public readonly String m_password; + } + + [Serializable] + public class LoginResp + { + public LoginResp( bool resp ) + { + m_resp = resp; + } + + public readonly bool m_resp; + } + + #region Admin Messages + //Subclasses of this need to be on an admin client. + [Serializable] + public class Admin + { + + }; + + [Serializable] + public class CreateEntity : Admin + { + + } + + + [Serializable] + public class MoveEntity : Admin + { + + } + #endregion + + [Serializable] + public class EntityBase + { + public EntityBase( int id ) + { + m_id = id; + } + + public readonly int m_id; + }; + + + [Serializable] + public class EntityPos : EntityBase + { + public EntityPos( int id, float x, float y, float z ) : + base( id ) + { + m_x = x; + m_y = y; + m_z = z; + } + + public readonly float m_x; + public readonly float m_y; + public readonly float m_z; + } + + [Serializable] + public class EntityDesc : EntityBase + { + public EntityDesc( int id ) : + base( id ) + { + } + + //Should an entity have a mesh? Be made up of multiple meshes? + public readonly String m_mesh; + } + + + + + +} diff --git a/Pos.cs b/Pos.cs new file mode 100644 index 0000000..5303b84 --- /dev/null +++ b/Pos.cs @@ -0,0 +1,52 @@ +using System; + +namespace lib +{ + +[Serializable] +public struct Pos +{ + public float x { get; private set; } + public float y { get; private set; } + public float z { get; private set; } + + + public Pos( float _x, float _y, float _z ) : this() + { + x = _x; + y = _y; + z = _z; + } + + // overload operator + + public static Pos operator +( Pos a, Pos b ) + { + return new Pos( a.x + b.x, a.y + b.y, a.z + b.z ); + } + + public static Pos operator -( Pos a, Pos b ) + { + return new Pos( a.x - b.x, a.y - b.y, a.z - b.z ); + } + + public static Pos operator /( Pos a, float val ) + { + return new Pos( a.x / val, a.y / val, a.z / val ); + } + + public static Pos operator *( Pos a, float val ) + { + return new Pos( a.x * val, a.y * val, a.z * val ); + } + + public float distSqr( Pos other ) + { + float dx = x - other.x; + float dy = y - other.y; + float dz = z - other.z; + + return dx * dx + dy * dy + dz * dz; + } +} + +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6c7d80d --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle( "Common" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "Allusion Studio, Inc" )] +[assembly: AssemblyProduct( "Common" )] +[assembly: AssemblyCopyright( "Copyright © Allusion Studio, Inc 2008" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible( false )] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid( "fbc724c2-ea86-47cf-ae0b-f15e11ba6701" )] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/SerializableDictionary.cs b/SerializableDictionary.cs new file mode 100644 index 0000000..1724390 --- /dev/null +++ b/SerializableDictionary.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml.Serialization; +using System.Xml; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using System.IO; +using System.Security.Permissions; + +namespace lib +{ + [Serializable] + public class SerializableDictionary : Dictionary, IXmlSerializable, ISerializable + { + #region Constants + private const string DictionaryNodeName = "Dictionary"; + private const string ItemNodeName = "Item"; + private const string KeyNodeName = "Key"; + private const string ValueNodeName = "Value"; + #endregion + #region Constructors + public SerializableDictionary() + { + } + + public SerializableDictionary(IDictionary dictionary) + : base(dictionary) + { + } + + public SerializableDictionary(IEqualityComparer comparer) + : base(comparer) + { + } + + public SerializableDictionary(int capacity) + : base(capacity) + { + } + + public SerializableDictionary(IDictionary dictionary, IEqualityComparer comparer) + : base(dictionary, comparer) + { + } + + public SerializableDictionary(int capacity, IEqualityComparer comparer) + : base(capacity, comparer) + { + } + + #endregion + #region ISerializable Members + + protected SerializableDictionary(SerializationInfo info, StreamingContext context) + { + int itemCount = info.GetInt32("ItemCount"); + for (int i = 0; i < itemCount; i++) { + KeyValuePair kvp = (KeyValuePair)info.GetValue(String.Format("Item{0}", i), typeof(KeyValuePair)); + this.Add(kvp.Key, kvp.Value); + } + } + + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("ItemCount", this.Count); + int itemIdx = 0; + foreach (KeyValuePair kvp in this) { + info.AddValue(String.Format("Item{0}", itemIdx), kvp, typeof(KeyValuePair)); + itemIdx++; + } + } + + #endregion + #region IXmlSerializable Members + + void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) + { + //writer.WriteStartElement(DictionaryNodeName); + foreach (KeyValuePair kvp in this) { + writer.WriteStartElement(ItemNodeName); + writer.WriteStartElement(KeyNodeName); + KeySerializer.Serialize(writer, kvp.Key); + writer.WriteEndElement(); + writer.WriteStartElement(ValueNodeName); + ValueSerializer.Serialize(writer, kvp.Value); + writer.WriteEndElement(); + writer.WriteEndElement(); + } + //writer.WriteEndElement(); + } + + void IXmlSerializable.ReadXml(System.Xml.XmlReader reader) + { + if (reader.IsEmptyElement) { + return; + } + + // Move past container + if (!reader.Read()){ + throw new XmlException("Error in Deserialization of Dictionary"); + } + + //reader.ReadStartElement(DictionaryNodeName); + while (reader.NodeType != XmlNodeType.EndElement) { + reader.ReadStartElement(ItemNodeName); + reader.ReadStartElement(KeyNodeName); + TKey key = (TKey)KeySerializer.Deserialize(reader); + reader.ReadEndElement(); + reader.ReadStartElement(ValueNodeName); + TVal value = (TVal)ValueSerializer.Deserialize(reader); + reader.ReadEndElement(); + reader.ReadEndElement(); + this.Add(key, value); + reader.MoveToContent(); + } + //reader.ReadEndElement(); + + reader.ReadEndElement(); // Read End Element to close Read of containing node + } + + System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() + { + return null; + } + + #endregion + #region Private Properties + protected XmlSerializer ValueSerializer + { + get + { + if (valueSerializer == null) { + valueSerializer = new XmlSerializer(typeof(TVal)); + } + return valueSerializer; + } + } + + private XmlSerializer KeySerializer + { + get + { + if (keySerializer == null) { + keySerializer = new XmlSerializer(typeof(TKey)); + } + return keySerializer; + } + } + #endregion + #region Private Members + private XmlSerializer keySerializer = null; + private XmlSerializer valueSerializer = null; + #endregion + } +} diff --git a/SharpLib.sln b/SharpLib.sln new file mode 100644 index 0000000..49408e4 --- /dev/null +++ b/SharpLib.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpLib", "SharpLib.csproj", "{DED134FC-C282-49C9-BA02-3CE6257E91FC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DED134FC-C282-49C9-BA02-3CE6257E91FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DED134FC-C282-49C9-BA02-3CE6257E91FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DED134FC-C282-49C9-BA02-3CE6257E91FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DED134FC-C282-49C9-BA02-3CE6257E91FC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Timer.cs b/Timer.cs new file mode 100644 index 0000000..b60287f --- /dev/null +++ b/Timer.cs @@ -0,0 +1,95 @@ +using System; +using System.Runtime.InteropServices; +using System.ComponentModel; +using System.Threading; + +namespace lib +{ + public class Timer + { + [DllImport("Kernel32.dll")] + private static extern bool QueryPerformanceCounter( + out long lpPerformanceCount); + + [DllImport("Kernel32.dll")] + private static extern bool QueryPerformanceFrequency( + out long lpFrequency); + + private long startTime; + private long stopTime; + private long freq; + private long freq_millis; + + // Constructor + + public Timer() + { + startTime = 0; + stopTime = 0; + + if (QueryPerformanceFrequency(out freq) == false) + { + // high-performance counter not supported + throw new Win32Exception(); + } + + freq_millis = freq / 1000; + + } + + // Start the timer + + public void Start() + { + // lets do the waiting threads there work + + //Thread.Sleep(0); + + QueryPerformanceCounter(out startTime); + } + + // Stop the timer + + public void Stop() + { + QueryPerformanceCounter(out stopTime); + } + + public double Seconds + { + get + { + long current; + + QueryPerformanceCounter( out current ); + + return (double)( current - startTime ) / freq; + } + } + + public long Current + { + get + { + long current; + + QueryPerformanceCounter( out current ); + + return ( current - startTime ) / freq_millis; + } + } + + public double Duration + { + get + { + return (double)( stopTime - startTime ) / (double)freq; + } + } + + public long DurationMS + { + get { return (stopTime - startTime) / freq_millis; } + } + } +} diff --git a/Token.cs b/Token.cs new file mode 100644 index 0000000..4bbe8a5 --- /dev/null +++ b/Token.cs @@ -0,0 +1,46 @@ +using System; +using System.Diagnostics; + +namespace lib +{ +[Serializable] +public struct Token +{ + public string str { get{ return m_str; } } + + public Token( String str ) + { + m_str = str; + m_hash = m_str.GetHashCode(); + } + + public override bool Equals( object obj ) + { + if( !( obj is Token ) ) + return false; + + //This doesnt use as because Token is a struct + var otherId = (Token)obj; + + if( m_hash != otherId.m_hash ) + return false; + + return m_str == otherId.m_str; + } + + + public bool Equals_fast( Token other ) + { + return m_hash == other.m_hash && m_str == other.m_str; + } + + public override int GetHashCode() + { + return m_hash; + } + + int m_hash; + String m_str; +} + +} diff --git a/UpgradeLog.XML b/UpgradeLog.XML new file mode 100644 index 0000000000000000000000000000000000000000..70a8c8b4082e5df2969a6e760d9303aeb1111d7a GIT binary patch literal 2482 zcmcJR-%lDr5Xa}aN&kmUUwkRx*`yDqVp_FHo3?3+`qaem;}k3$$WA@I=My!u)k9CaivDNs^(A?v^3xe3L{rQz$ z*a%;#HSrtU5B^4ANV#)`=U#5Twnnd-+a6;*AY5&;ZZGWxF?`3v5Kqd+7%z%Iu`SD| zp#2820q4q9gFAhj_#4WfvUbV2WHXH}`xMJxu-Zan=CM|?{d|9Jo{_TW6Fan@-p38! z23cOjQI=GFJru(>2v6~%8kg}j{Kz3vs@Et ziBZZ?8@05n$6Iw z=R=>Y#x15?gLAoSw?iGRsKM?~Uy|RLB1z`at_%gL=&^iSdXckgO^SFg-mCf z92Fv-@D(@0EY=ip?8OmHUsZW_dyG`x+?)x4RSs!_R2MgX8+EA|8e&(hWn?YzDie2TE4u2I zEDkSRnC^=`xjR10-YVx=(Iz@oF!OcpQ(MiumXBIIP!=a-K{-`jpPJqu@|(J|*(@)5 yd(%$;|2ca2eyT5e`RlJ&L|IW!J(j)g=E16&yu13J_`VJu6JlA7c-?<9b^8Y=HLXqn literal 0 HcmV?d00001 diff --git a/UpgradeLog.htm b/UpgradeLog.htm new file mode 100644 index 0000000000000000000000000000000000000000..0cbd10f24ff9f7dcfdfd8f8f9e7510141fbf8deb GIT binary patch literal 16270 zcmeI3eREUC6~_1P&h$H6AjKv`vZ0;M)QQbdLI!3+U}CqOHf9)O%P&EGsU)1xkbd;G z&u@>{dv|rU_X-Sg1EZ02b??5M*JsZ;yZY~czHnFEm+rB<=QiBm-4l1;Rc_x++@Tw~ zHTPTh8%K+tUX>fWEqCe$Zb#R2snUjAmn38a>QbxgY(kN1A6vS7ZGi`;o8uIgWI9?6%c@pr>29?&vUs zcxrCDrq)gLK;NwUJX_MMa_gcETbjs3l4}$Vzjfj>(fq};Z zdFgB8k;qr$8&BtJosmQmZ&Q|Lkf$Dr1~0v z;`spk?w?EiMsbdxichhSx;AFbvFH}0t)p|TFL=F`rHTwn9R6H<3hsb>m272KpVP9~ zkp)F5e64oSgH}KTbXS^vez}zALqfqPx=07R-<3v<%ZrlL+i{$GD%SAJa$VM8iCe?H z4O#7;UbgN;Ogi<}a-ishH3>8aaflpfL)1c#N_GTBjdg{WfPHa{v5<5i6u~|ZbOjC` zsV`_yraMO(#*B1soX`L5+3bH7b>Ezgym&sx+xmUwS0vC8D;#R&3%r7c)3!i7Gm*#D z(QoXa4T|?_6fUUUNdC}f)wZ^V^J9%`7ctvF*tKx3wXRYzYHSs_qR4v| zHP_vB(bN32FB({9i7p?@O6#@*A8@kVNqY0jFqb9R{8v#!j23)rwj9B6i#7YAo?a)? z{Fe7oqk2ISMgQ%350nIXPSbH`rasGbR9>sBiUVC$$~0!#Mf*5#)0LOi)fFfpP_Kz*hl%q;*(6@hAycEmS*bWuOYhoh+lOp4^nByg!hYIftFv||KA6W zRzhO1c$(KP>yv4)i`Cb4omzfahw480Q20c20s0OU#VqRANbAzTug>!#D61hkBsCnO z78_|EBrao57xc0=CG4;kDXlTqE+cK3zS67~agv7|DQ^x@A+ck~nVTZUP<6?(TJi%p zu$6CHSB$i+Rge|^KyR`^%fxNQG)j%tw2-~>yhQ&rwuheZ^2%F|)v3z%+|`DIPeuv6 zcCSU_vfixn#0TM78u^vykN(k>lF%cym@s#D>o(gd$vDgu>N3>C&}XbLqIYyhwGoY( zzR4B26KfImXQ`b8d!r^BvzC2nkbH%BKj^j1A|kZ`$F0U2Y~0q8C0RzG`1SeKSh_Tt zZ@5jxMw_bp@cvF5_1wP{CHLGvr0bshlkWHQ?kk4Asj*fX+dOrj3bF3^G47~UX`E+j zMa$28>rH)bYUJzgcl!RsUDM~P`?n&lO;vX`Ri$~Vkv|n}d(uW39il|KX}Q^=`k7}h zdPE(ndTgGI4J;`Cp)$Si+gg3~6Y)SjlW*#fTe>Ens9LCg-=9crWd+n5=kvb}M(O_9Wj9AhU&*!OcU6oDN^=6sl zJ^2XxC$=wjQ)4zutV_*l9%>dEsd*p@ZTDlOy_J1mIim(}ndo}p5z=ZCWxC4xD{H@` z`DyQ5mzUvhZPkL*0zP`_`|(oCV2DYrf`i|V{MsEdn1yp|ucmgruzz&>Ln|5tbgbv8 z;C7rjVl^wHAplj>)GqA)oA_cG-$ATyNE#%zC7D4fkv!-^ydENZqPSE2s@FbEPPDSU z(z0BM2ZJWa2gnLotvF>c)UU$?FM}4!UJZ}DE=C6to!e2covt$Cl%5h58%MSu&;C58 zD&m>Dka2c5Z@R`BRh2?Z!Eevyp7pxG#q6ut)pe_urg~uq(c&rTWBU zLx{8D9#`FanI~-rm2Klv2if;~P`0x$J)*T}AM3to#4|y^*%a1WwU7BX`6$&g&|t4P zZr-we>=X@4H0LerVWN#;?!u_#E+xE75 z5$A!Pxl}HF#eGPU(=(u-&7HR4nVlViH{&IIvonE?83X&xbL?yKPT~`G?(9sESwFQq z!`>V(a?i^9ub=f~octMj2qQy{<@9zpr8DOw$B@3p8Hy{@Y~-1mVThd3UZ`r_6DCp_ zrXs|;Wn5BGSWf5&a^rj6vC`_rv}ALwt;x3PGPuaOu?e(}G&n2x!dvK@#-ps)sg>Bi zZkk)wPk4OpC49S)zsv4{>+*(ey(}wh_Q15w+j?NSKAPvG_v&_%`*gdnaKVK#cI=DI(F3MuPsu^SK3*+#llkbn-v$VG-l=KH0{rL7U`^=o!|&r=DMu!rT0Se zTPn!J4eTLV#>-j!7rMtYR@$Dj+w`2RWviTCC6eN_RP2pq<7;_c4{sskB`W766V_() z5x)ei;@-ZWJ4KMt_Enpoh|t)kLtS5P{bt zj;6SN9&Z6*ay$$Yx+@D~l?n4=uc>sc`dr_WyXFzLu8&;K=?GxfbR0_cE1XkJ+s8^+ zeb?emu+8}|-ukm*3Hq(#K=kvZJ)jpF7M@5X1l#h_VkADn!&INLCq sSaCY8?KeiYVZXHg-5f3CR=wn-)YG%5*s54)Zb`9C+>4C={a$nb13-3;R{#J2 literal 0 HcmV?d00001 diff --git a/VersionFormatter.cs b/VersionFormatter.cs new file mode 100644 index 0000000..72159df --- /dev/null +++ b/VersionFormatter.cs @@ -0,0 +1,670 @@ +using System; +using System.IO; +using System.Reflection; +using System.Collections; +using System.Diagnostics; +//using System.Globalization; +//using System.ComponentModel; +using System.Runtime.Serialization; + +namespace lib +{ + /// + /// + /// + public class VersionFormatter : IFormatter + { + public enum ETypes + { + Array, + Int32, + Ref, + Object, + EndObject, + Single, + Double, + Char, + String, + Boolean, + EndStream, + } + + + public VersionFormatter() + { + // + // TODO: Add constructor logic here + // + } + + + #region Useless + public ISurrogateSelector SurrogateSelector + { + get + { + return null; + } + + set + { + } + } + + public SerializationBinder Binder + { + get + { + return null; + } + + set + { + } + } + + public StreamingContext Context + { + get + { + return new StreamingContext(); + } + + set + { + } + } + #endregion Useless + + Queue m_objectsToBeDeserialized = new Queue(); + Hashtable m_alreadyDeserialzied = new Hashtable(); + //int m_GUID = 0; + + #region Serialize + public void Serialize( Stream stream, object obj ) + { + //Default is 4k + //BufferedStream bufStream = new BufferedStream( stream ); + + BinaryWriter writer = new BinaryWriter( stream ); + + writeObject( writer, obj ); + + while( m_objectsToBeDeserialized.Count != 0 ) + { + object objToDes = m_objectsToBeDeserialized.Dequeue(); + + writeObject( writer, objToDes ); + } + + writer.Write( (char)ETypes.EndStream ); + } + + void writeRefAndSched( BinaryWriter writer, object obj ) + { + //if( m_alreadyDeserialzied[ obj.GetType().GetArrayRank( + + if( obj == null ) + { + writer.Write( 0 ); + return; + } + + + //Now write the address. + //Bad bad. Need to do this correctly. + int objRef = obj.GetHashCode(); + writer.Write( objRef ); + + if( m_alreadyDeserialzied[ obj ] == null ) + { + m_alreadyDeserialzied[ obj ] = obj; + m_objectsToBeDeserialized.Enqueue( obj ); + } + } + + void dispatchWrite( BinaryWriter writer, object parentObj, FieldInfo fi ) + { + string typeName = fi.FieldType.Name; + + string name = fi.Name; + + if( fi.IsNotSerialized ) + { + return; + } + + if( fi.FieldType.IsArray ) + { + writer.Write( (char)ETypes.Array ); + writer.Write( name.GetHashCode() ); + + writeArray( writer, (Array)fi.GetValue( parentObj ) ); + } + else if( ( fi.FieldType.IsClass || fi.FieldType.IsInterface ) && typeName != "String" ) + { + writer.Write( (char)ETypes.Ref ); + writer.Write( name.GetHashCode() ); + + writeRefAndSched( writer, fi.GetValue( parentObj ) ); + } + else if( fi.FieldType.IsEnum ) + { + writer.Write( (char)ETypes.Int32 ); + writer.Write( name.GetHashCode() ); + + write( writer, Convert.ToInt32( fi.GetValue( parentObj ) ) ); + } + else + { + switch( typeName ) + { + case "Int32": + writer.Write( (char)ETypes.Int32 ); + writer.Write( name.GetHashCode() ); + + write( writer, Convert.ToInt32( fi.GetValue( parentObj ) ) ); + break; + case "Single": + writer.Write( (char)ETypes.Single ); + writer.Write( name.GetHashCode() ); + + write( writer, Convert.ToSingle( fi.GetValue( parentObj ) ) ); + break; + case "Double": + writer.Write( (char)ETypes.Double ); + writer.Write( name.GetHashCode() ); + + write( writer, Convert.ToDouble( fi.GetValue( parentObj ) ) ); + break; + case "Char": + writer.Write( (char)ETypes.Char ); + writer.Write( name.GetHashCode() ); + + write( writer, Convert.ToChar( fi.GetValue( parentObj ) ) ); + break; + case "String": + writer.Write( (char)ETypes.String ); + writer.Write( name.GetHashCode() ); + + write( writer, Convert.ToString( fi.GetValue( parentObj ) ) ); + break; + case "Boolean": + writer.Write( (char)ETypes.Boolean ); + writer.Write( name.GetHashCode() ); + + writer.Write( Convert.ToBoolean( fi.GetValue( parentObj ) ) ); + break; + default: + Console.WriteLine( "VersionFormatter does not understand type " + typeName ); + break; + } + } + } + + void writeArray( BinaryWriter writer, Array array ) + { + if( array == null ) + { + writer.Write( (int)-1 ); + return; + } + + writer.Write( array.Length ); + + foreach( object obj in array ) + { + writeRefAndSched( writer, obj ); + } + } + + void getAllFields( object obj, ArrayList list ) + { + Type t = obj.GetType(); + + while( t != null ) + { + FieldInfo[] fiArr = t.GetFields( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly ); + list.AddRange( fiArr ); + + t = t.BaseType; + } + } + + + void writeObject( BinaryWriter writer, object obj ) + { + Type objType = obj.GetType(); + + writer.Write( (char)ETypes.Object ); + writer.Write( objType.FullName ); + + int objRef = obj.GetHashCode(); + writer.Write( objRef ); + + ArrayList list = new ArrayList(); + + getAllFields( obj, list ); + + foreach( FieldInfo fi in list ) + { + dispatchWrite( writer, obj, fi ); + } + + writer.Write( (char)ETypes.EndObject ); + } + + void write( BinaryWriter wr, TType val ) + { + //wr.Write( val ); + } + + /* + void writeInt( BinaryWriter writer, int val ) + { + writer.Write( val ); + } + + void writeSingle( BinaryWriter writer, float val ) + { + writer.Write( val ); + } + + void writeDouble( BinaryWriter writer, double val ) + { + writer.Write( val ); + } + + void writeChar( BinaryWriter writer, char val ) + { + writer.Write( val ); + } + + void writeString( BinaryWriter writer, string val ) + { + writer.Write( val ); + } + + void writeBool( BinaryWriter writer, bool val ) + { + writer.Write( val ); + } + */ + #endregion Serialize + + + #region Deserialize + + class Fixup + { + public Fixup( int guid, object obj, FieldInfo fi ) + { + m_guid= guid; + m_obj = obj; + m_fi = fi; + } + + public Fixup( int guid, object obj, int index ) + { + m_guid = guid; + m_obj = obj; + m_index= index; + } + + public readonly int m_guid = 0; + public readonly object m_obj = null; + + public readonly FieldInfo m_fi = null; + public readonly int m_index= -1; + + } + + Hashtable m_mapGUIDToObject = new Hashtable(); + ArrayList m_fixupList = new ArrayList(); + + ArrayList m_desObjects = new ArrayList(); + + public object Deserialize( Stream stream ) + { + BinaryReader reader = new BinaryReader( stream ); + + object objRoot = null; + + //Read in the first object. + { + ETypes type = (ETypes)reader.ReadChar(); + + Debug.Assert( type == ETypes.Object ); + + objRoot = readObject( reader ); + + m_desObjects.Add( objRoot ); + } + + bool readObjects = true; + + while( readObjects ) + { + ETypes type = (ETypes)reader.ReadChar(); + + Debug.Assert( type == ETypes.Object || type == ETypes.EndStream ); + + if( type == ETypes.Object ) + { + object obj = readObject( reader ); + + m_desObjects.Add( obj ); + } + else + { + Debug.Assert( type == ETypes.EndStream ); + + readObjects = false; + } + } + + foreach( Fixup fu in m_fixupList ) + { + //Fixup fix = m_fixups[ + + object obj = m_mapGUIDToObject[ fu.m_guid ]; + + if( obj != null ) + { + if( fu.m_fi != null ) + { + fu.m_fi.SetValue( fu.m_obj, obj ); + } + else + { + Debug.Assert( fu.m_index >= 0 ); + + object []array = (object [])fu.m_obj; + + array[ fu.m_index ] = obj; + } + } + else + { + Console.WriteLine( "Obj to ref is null." ); + } + } + + foreach( object obj in m_desObjects ) + { + if( typeof( IDeserializationCallback ).IsAssignableFrom( obj.GetType() ) ) + { + IDeserializationCallback desCB = (IDeserializationCallback)obj; + + if( desCB != null ) + { + desCB.OnDeserialization( this ); + } + } + } + + return objRoot; + } + + + + bool dispatchRead( BinaryReader reader, object obj, Hashtable ht ) + { + + //Read the type + ETypes type = (ETypes)reader.ReadChar(); + + if( type == ETypes.EndObject ) + { + return false; + } + + int nameHash = reader.ReadInt32(); + + FieldInfo fi = (FieldInfo)ht[ nameHash ]; + + if( fi == null ) + { + Console.WriteLine( "Field no longer exists" ); + } + + try + { + switch( type ) + { + case ETypes.Array: + readArray( reader, obj, fi ); + break; + case ETypes.Int32: + readInt( reader, obj, fi ); + break; + case ETypes.Single: + readSingle( reader, obj, fi ); + break; + case ETypes.Double: + readDouble( reader, obj, fi ); + break; + case ETypes.Char: + readChar( reader, obj, fi ); + break; + case ETypes.Boolean: + readBool( reader, obj, fi ); + break; + case ETypes.String: + readString( reader, obj, fi ); + break; + case ETypes.Ref: + readRef( reader, obj, fi ); + break; + case ETypes.Object: + readObject( reader ); + break; + default: + Debug.Fail( "Unknown type on read." ); + break; + } + } + catch( Exception ex ) + { + Console.WriteLine( "Exception: " + ex.Message ); + Console.WriteLine( "Stack: " + ex.StackTrace ); + } + + + return true; + } + + object createObject( string objTypeName ) + { + Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies(); + + foreach( Assembly a in ass ) + { + Type t = a.GetType( objTypeName ); + + if( t != null ) + { + object obj = FormatterServices.GetUninitializedObject( t ); + + if( obj != null ) + { + return obj; + } + } + } + + return null; + } + + + object readObject( BinaryReader reader ) + { + //ETypes type = (ETypes)reader.ReadChar(); + + //Debug.Assert( type == ETypes.Object, "Expecting type Object" ); + + string objTypeName = reader.ReadString(); + int objGUID = reader.ReadInt32(); + + try + { + object obj = createObject( objTypeName ); + + m_mapGUIDToObject[ objGUID ] = obj; + + ArrayList list = new ArrayList(); + Hashtable ht = new Hashtable(); + + if( obj != null ) + { + getAllFields( obj, list ); + + foreach( FieldInfo fi in list ) + { + ht[ fi.Name.GetHashCode() ] = fi; + } + } + + while( dispatchRead( reader, obj, ht ) ) + { + } + + return obj; + } + catch( Exception ex ) + { + Console.WriteLine( "Exception: " + ex.Message ); + } + + return null; + } + + void readArray( BinaryReader reader, object obj, FieldInfo fi ) + { + int length = reader.ReadInt32(); + + if( length < 0 ) + { + if( fi == null ) return; + + fi.SetValue( obj, null ); + + return; + } + + object[] array = new object[length]; + + if( fi != null ) + { + fi.SetValue( obj, array ); + } + + for( int i=0; i m_alreadySerialized = new Dictionary(); + + public object Deserialize( XmlElement elem ) + { + string strType = elem.GetAttribute( "t" ); + + return Deserialize( elem, strType ); + } + + public object Deserialize( XmlElement elem, string strType ) + { + Type type = Type.GetType( strType ); + + MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type ); + + object obj = Activator.CreateInstance( type ); + + + /* + object obj = FormatterServices.GetUninitializedObject( type ); + + + ConstructorInfo[] ciArr = obj.GetType().GetConstructors(); + + ConstructorInfo ci = getNoParamCons( ciArr ); + + if( ci == null ) + return null; + + obj = ci.Invoke( null ); + */ + + for( int i = 0; i < miArr.Length; ++i ) + { + FieldInfo fi = (FieldInfo)miArr[ i ]; + + XmlNodeList nodeList = elem.GetElementsByTagName( fi.Name ); + + if( nodeList.Count == 1 ) + { + Type t = fi.FieldType; + + TypeCode tc = Type.GetTypeCode( t ); + + XmlElement child = (XmlElement)nodeList[ 0 ]; + + object childObj = null; + + if( tc != TypeCode.Object || fi.FieldType.FullName == "System.String" ) + { + childObj = s_conv.Convert( child.GetAttribute( "v" ), fi.FieldType ); + } + else + { + if( !t.IsArray ) + { + string refStr = child.GetAttribute( "ref" ); + int refInt = Convert.ToInt32( refStr ); + + if( child.HasAttribute( "t" ) ) + { + childObj = Deserialize( child ); + + m_alreadySerialized[ refInt ] = childObj; + } + else + { + childObj = m_alreadySerialized[ refInt ]; + } + } + else + { + //FormatterServices.GetUninitializedObject() + + int length = s_conv.ToInt32( child.GetAttribute( "c" ) ); + + string elemType = child.GetAttribute( "t" ); + + Array arr = Array.CreateInstance( t.GetElementType(), length ); + + XmlNodeList arrNodeList = child.ChildNodes; + + for( int iElems = 0; iElems < arr.Length; ++iElems ) + { + XmlElement arrElem = (XmlElement)arrNodeList.Item( iElems ); + + arr.SetValue( Deserialize( arrElem, elemType ), iElems ); + } + } + } + + fi.SetValue( obj, childObj ); + } + else + { + if( nodeList.Count == 0 ) + { + // Should be + + //object obj2 = fi.GetRawConstantValue(); + } + else //More than 1. + { + //Log.error( "Too many fields named the same thing" ); + } + } + } + + //FieldInfo fi = (FieldInfo)miArr[0]; + + //ConstructorInfo ci = fi.FieldType.TypeInitializer; + + //ci.Invoke( null ); + + return obj; + } + + + /* + public T Deserialize (Stream stream) + { + return (T) Deserialize (XmlReader.Create (stream), typeof (T)); + } + + public T Deserialize (XmlReader reader) + { + return (T) Deserialize (reader, typeof (T), false); + } + + public T Deserialize (XmlReader reader, bool readContentOnly) + { + return (T) Deserialize (reader, typeof (T), readContentOnly); + } + */ + + public void Serialize( Stream stream, object graph ) + { + /* + XmlWriterSettings settings = new XmlWriterSettings(); + + settings.Indent = true; + + Serialize( XmlWriter.Create( stream, settings ), graph ); + */ + + XmlTextWriter writer = new XmlTextWriter( stream, null ); + + writer.Formatting = Formatting.Indented; + + Serialize( writer, graph ); + + writer.Close(); + } + + public void Serialize (XmlWriter writer, object graph) + { + Serialize (writer, graph, null, true, false, true); + } + + public void Serialize (XmlWriter writer, object graph, + Type rootType, bool preserveObjectReferences, + bool writeContentOnly, + bool ignoreUnknownSerializationData) + { + Type t = graph.GetType(); + + //writer.WriteStartDocument(); + + if( Type.GetTypeCode( t ) == TypeCode.Object ) + { + writer.WriteStartElement( "root" ); + + Assembly assem = t.Assembly; + + string assemName = assem.GetName().Name; + + writer.WriteAttributeString( "t", graph.GetType().FullName + ", " + assemName ); + + FieldInfo[] fiArr = t.GetFields( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly ); + + foreach( FieldInfo fi in fiArr ) + { + Serialize( writer, fi.Name, fi.GetValue( graph ) ); + + /* + if( fi.FieldType.IsClass ) + { + Serialize( writer, fi.GetValue( graph ), rootType, preserveObjectReferences, writeContentOnly, ignoreUnknownSerializationData ); + } + else + { + SerializePod( writer, fi.GetValue( graph ) ); + } + */ + } + + writer.WriteEndElement(); + } + + //writer.WriteEndDocument(); + } + + private ObjectIDGenerator m_idGenerator = new ObjectIDGenerator(); + private Dictionary m_alreadyDeserialzied = new Dictionary(); + + public void Serialize( XmlWriter writer, string name, object obj ) + { + writer.WriteStartElement( name ); + + if( obj != null ) + { + Type t = obj.GetType(); + + if( Type.GetTypeCode( t ) == TypeCode.Object ) + { + bool first = false; + if( !m_alreadyDeserialzied.ContainsKey( m_idGenerator.GetId( obj, out first ) ) ) + { + m_alreadyDeserialzied[ m_idGenerator.GetId( obj, out first ) ] = obj; + + Assembly assem = t.Assembly; + + string assemName = assem.GetName().Name; + + if( !t.IsArray ) + { + writer.WriteAttributeString( "t", t.FullName + ", " + assemName ); + + writer.WriteAttributeString( "ref", m_idGenerator.GetId( obj, out first ).ToString() ); + + FieldInfo[] fiArr = t.GetFields( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public ); + + foreach( FieldInfo fi in fiArr ) + { + Serialize( writer, fi.Name, fi.GetValue( obj ) ); + } + } + else + { + Array arr = (Array)obj; + + Type aType = t.GetElementType(); + + string aTypeString = aType.FullName; + + writer.WriteAttributeString( "t", aTypeString + ", " + assemName ); + + writer.WriteAttributeString( "c", arr.Length.ToString() ); + + for( int i = 0; i < arr.Length; ++i ) + { + Serialize( writer, "val", arr.GetValue(i) ); + } + + //writer.WriteStartElement( "values" ); + + + + //writer.WriteEndElement(); + + } + } + else + { + writer.WriteAttributeString( "ref", m_idGenerator.GetId( obj, out first ).ToString() ); + } + } + else + { + writer.WriteAttributeString( "t", t.FullName ); + + writer.WriteAttributeString( "v", obj.ToString() ); + } + } + else + { + writer.WriteAttributeString( "null", "" ); + } + + writer.WriteEndElement(); + } + + } +} + + + + + + + + + + + + + + + + + + + /* + /// + /// + /// + public class XmlFormatter : IFormatter + { + public enum ETypes + { + Array, + Int32, + Ref, + Object, + EndObject, + Single, + Double, + Char, + String, + Boolean, + EndStream, + } + + + public XmlFormatter() + { + // + // TODO: Add constructor logic here + // + } + + + #region Useless + public ISurrogateSelector SurrogateSelector + { + get + { + return null; + } + + set + { + } + } + + public SerializationBinder Binder + { + get + { + return null; + } + + set + { + } + } + + public StreamingContext Context + { + get + { + return new StreamingContext(); + } + + set + { + } + } + #endregion Useless + + Queue m_objectsToBeDeserialized = new Queue(); + Hashtable m_alreadyDeserialzied = new Hashtable(); + //int m_GUID = 0; + + #region Serialize + public void Serialize( System.IO.Stream stream, object obj ) + { + //Default is 4k + //BufferedStream bufStream = new BufferedStream( stream ); + + TextWriter writer = new StreamWriter( stream ); + + writeObject( writer, obj ); + + while( m_objectsToBeDeserialized.Count != 0 ) + { + object objToDes = m_objectsToBeDeserialized.Dequeue(); + + writeObject( writer, objToDes ); + } + + writer.Write( (char)ETypes.EndStream ); + } + + void writeRefAndSched( TextWriter writer, object obj ) + { + //if( m_alreadyDeserialzied[ obj.GetType().GetArrayRank( + + if( obj == null ) + { + writer.Write( 0 ); + return; + } + + + //Now write the address. + //Bad bad. Need to do this correctly. + int objRef = obj.GetHashCode(); + writer.Write( objRef ); + + if( m_alreadyDeserialzied[ obj ] == null ) + { + m_alreadyDeserialzied[ obj ] = obj; + m_objectsToBeDeserialized.Enqueue( obj ); + } + } + + void dispatchWrite( TextWriter writer, object parentObj, FieldInfo fi ) + { + string typeName = fi.FieldType.Name; + + string name = fi.Name; + + if( fi.IsNotSerialized ) + { + return; + } + + if( fi.FieldType.IsArray ) + { + writer.Write( (char)ETypes.Array ); + writer.Write( name.GetHashCode() ); + + writeArray( writer, (Array)fi.GetValue( parentObj ) ); + } + else if( ( fi.FieldType.IsClass || fi.FieldType.IsInterface ) && typeName != "String" ) + { + writer.Write( (char)ETypes.Ref ); + writer.Write( name.GetHashCode() ); + + writeRefAndSched( writer, fi.GetValue( parentObj ) ); + } + else if( fi.FieldType.IsEnum ) + { + writer.Write( (char)ETypes.Int32 ); + writer.Write( name.GetHashCode() ); + + writer.Write( Convert.ToInt32( fi.GetValue( parentObj ) ) ); + } + else + { + switch( typeName ) + { + case "Int32": + writer.Write( (char)ETypes.Int32 ); + writer.Write( name.GetHashCode() ); + + writer.Write( Convert.ToInt32( fi.GetValue( parentObj ) ) ); + break; + case "Single": + writer.Write( (char)ETypes.Single ); + writer.Write( name.GetHashCode() ); + + writer.Write( Convert.ToSingle( fi.GetValue( parentObj ) ) ); + break; + case "Double": + writer.Write( (char)ETypes.Double ); + writer.Write( name.GetHashCode() ); + + writer.Write( Convert.ToDouble( fi.GetValue( parentObj ) ) ); + break; + case "Char": + writer.Write( (char)ETypes.Char ); + writer.Write( name.GetHashCode() ); + + writer.Write( Convert.ToChar( fi.GetValue( parentObj ) ) ); + break; + case "String": + writer.Write( (char)ETypes.String ); + writer.Write( name.GetHashCode() ); + + writer.Write( Convert.ToString( fi.GetValue( parentObj ) ) ); + break; + case "Boolean": + writer.Write( (char)ETypes.Boolean ); + writer.Write( name.GetHashCode() ); + + writer.Write( Convert.ToBoolean( fi.GetValue( parentObj ) ) ); + break; + default: + Console.WriteLine( "VersionFormatter does not understand type " + typeName ); + break; + } + } + } + + void writeArray( TextWriter writer, Array array ) + { + if( array == null ) + { + writer.Write( (int)-1 ); + return; + } + + writer.Write( array.Length ); + + foreach( object obj in array ) + { + writeRefAndSched( writer, obj ); + } + } + + void getAllFields( object obj, ArrayList list ) + { + Type t = obj.GetType(); + + while( t != null ) + { + FieldInfo[] fiArr = t.GetFields( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly ); + list.AddRange( fiArr ); + + t = t.BaseType; + } + } + + + void writeObject( TextWriter writer, object obj ) + { + Type objType = obj.GetType(); + + writer.Write( (char)ETypes.Object ); + writer.Write( objType.FullName ); + + int objRef = obj.GetHashCode(); + writer.Write( objRef ); + + ArrayList list = new ArrayList(); + + getAllFields( obj, list ); + + foreach( FieldInfo fi in list ) + { + dispatchWrite( writer, obj, fi ); + } + + writer.Write( (char)ETypes.EndObject ); + } + + void write( TextWriter wr, TType val ) + { + //wr.Write( val ); + } + + /* + void writeInt( TextWriter writer, int val ) + { + writer.Write( val ); + } + + void writeSingle( TextWriter writer, float val ) + { + writer.Write( val ); + } + + void writeDouble( TextWriter writer, double val ) + { + writer.Write( val ); + } + + void writeChar( TextWriter writer, char val ) + { + writer.Write( val ); + } + + void writeString( TextWriter writer, string val ) + { + writer.Write( val ); + } + + void writeBool( TextWriter writer, bool val ) + { + writer.Write( val ); + } + * / + #endregion Serialize + + + #region Deserialize + + class Fixup + { + public Fixup( int guid, object obj, FieldInfo fi ) + { + m_guid= guid; + m_obj = obj; + m_fi = fi; + } + + XmlFormatter + + public Fixup( int guid, object obj, int index ) + { + m_guid = guid; + m_obj = obj; + m_index= index; + } + + public readonly int m_guid = 0; + public readonly object m_obj = null; + + public readonly FieldInfo m_fi = null; + public readonly int m_index= -1; + + } + + Hashtable m_mapGUIDToObject = new Hashtable(); + ArrayList m_fixupList = new ArrayList(); + + ArrayList m_desObjects = new ArrayList(); + + public object Deserialize( System.IO.Stream stream ) + { + StreamReader reader = new StreamReader( stream ); + + object objRoot = null; + + //Read in the first object. + { + ETypes type = (ETypes)reader.ReadChar(); + + Debug.Assert( type == ETypes.Object ); + + objRoot = readObject( reader ); + + m_desObjects.Add( objRoot ); + } + + bool readObjects = true; + + while( readObjects ) + { + ETypes type = (ETypes)reader.ReadChar(); + + Debug.Assert( type == ETypes.Object || type == ETypes.EndStream ); + + if( type == ETypes.Object ) + { + object obj = readObject( reader ); + + m_desObjects.Add( obj ); + } + else + { + Debug.Assert( type == ETypes.EndStream ); + + readObjects = false; + } + } + + foreach( Fixup fu in m_fixupList ) + { + //Fixup fix = m_fixups[ + + object obj = m_mapGUIDToObject[ fu.m_guid ]; + + if( obj != null ) + { + if( fu.m_fi != null ) + { + fu.m_fi.SetValue( fu.m_obj, obj ); + } + else + { + Debug.Assert( fu.m_index >= 0 ); + + object []array = (object [])fu.m_obj; + + array[ fu.m_index ] = obj; + } + } + else + { + Console.WriteLine( "Obj to ref is null." ); + } + } + + foreach( object obj in m_desObjects ) + { + if( typeof( IDeserializationCallback ).IsAssignableFrom( obj.GetType() ) ) + { + IDeserializationCallback desCB = (IDeserializationCallback)obj; + + if( desCB != null ) + { + desCB.OnDeserialization( this ); + } + } + } + + return objRoot; + } + + + + bool dispatchRead( StreamReader reader, object obj, Hashtable ht ) + { + + //Read the type + ETypes type = (ETypes)reader.ReadChar(); + + if( type == ETypes.EndObject ) + { + return false; + } + + int nameHash = reader.ReadInt32(); + + FieldInfo fi = (FieldInfo)ht[ nameHash ]; + + if( fi == null ) + { + Console.WriteLine( "Field no longer exists" ); + } + + try + { + switch( type ) + { + case ETypes.Array: + readArray( reader, obj, fi ); + break; + case ETypes.Int32: + readInt( reader, obj, fi ); + break; + case ETypes.Single: + readSingle( reader, obj, fi ); + break; + case ETypes.Double: + readDouble( reader, obj, fi ); + break; + case ETypes.Char: + readChar( reader, obj, fi ); + break; + case ETypes.Boolean: + readBool( reader, obj, fi ); + break; + case ETypes.String: + readString( reader, obj, fi ); + break; + case ETypes.Ref: + readRef( reader, obj, fi ); + break; + case ETypes.Object: + readObject( reader ); + break; + default: + Debug.Fail( "Unknown type on read." ); + break; + } + } + catch( Exception ex ) + { + Console.WriteLine( "Exception: " + ex.Message ); + Console.WriteLine( "Stack: " + ex.StackTrace ); + } + + + return true; + } + + object createObject( string objTypeName ) + { + Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies(); + + foreach( Assembly a in ass ) + { + Type t = a.GetType( objTypeName ); + + if( t != null ) + { + object obj = FormatterServices.GetUninitializedObject( t ); + + if( obj != null ) + { + return obj; + } + } + } + + return null; + } + + + object readObject( StreamReader reader ) + { + //ETypes type = (ETypes)reader.ReadChar(); + + //Debug.Assert( type == ETypes.Object, "Expecting type Object" ); + + string objTypeName = reader.ReadString(); + int objGUID = reader.ReadInt32(); + + try + { + object obj = createObject( objTypeName ); + + m_mapGUIDToObject[ objGUID ] = obj; + + ArrayList list = new ArrayList(); + Hashtable ht = new Hashtable(); + + if( obj != null ) + { + getAllFields( obj, list ); + + foreach( FieldInfo fi in list ) + { + ht[ fi.Name.GetHashCode() ] = fi; + } + } + + while( dispatchRead( reader, obj, ht ) ) + { + } + + return obj; + } + catch( Exception ex ) + { + Console.WriteLine( "Exception: " + ex.Message ); + } + + return null; + } + + void readArray( StreamReader reader, object obj, FieldInfo fi ) + { + int length = reader.ReadInt32(); + + if( length < 0 ) + { + if( fi == null ) return; + + fi.SetValue( obj, null ); + + return; + } + + object[] array = new object[length]; + + if( fi != null ) + { + fi.SetValue( obj, array ); + } + + for( int i=0; i() + { + return default( T ); + } + + private object DeserializeConcrete( XmlElement elem, Type type ) + { + string val = elem.GetAttribute( "v" ); + + if( !type.IsEnum ) + { + try + { + return s_conv.Convert( val, type ); + } + catch( Exception e ) + { + return GetDefault( type ); + } + } + else + { + return Enum.Parse( type, val ); + } + + } + + private XmlElement getNamedChild( XmlNodeList list, string name ) + { + foreach( XmlNode node in list ) + { + if( node.Name == name ) + { + return (XmlElement)node; + } + } + + return null; + } + + private Type FindType( string shortname ) + { + Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies(); + + foreach( Assembly a in ass ) + { + Type t = a.GetType( shortname ); + + if( t != null ) + { + return t; + } + } + + return null; + } + + private object DeserializeObject( XmlElement elem, Type type ) + { + 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 ); + } + + Type typeISerializable = typeof( ISerializable ); + + //* + /* + if( obj is ISerializable ) // type.IsSubclassOf( typeISerializable ) ) + { + XmlNodeList allChildren = elem.ChildNodes; + + ISerializable ser = obj as ISerializable; + + var serInfo = new SerializationInfo( type, new FormatterConverter() ); + + ser.GetObjectData( serInfo, Context ); + + //var serEnum = ; + + foreach( var serMember in serInfo ) + { + String name = serMember.Name; + + name = name.Replace( '+', '-' ); + name = name.Replace( '`', '_' ); + + XmlElement childElem = getNamedChild( allChildren, name ); + + var des = Deserialize( childElem, name ); + } + } + else + */ + { + MemberInfo[] miArr = FormatterServices.GetSerializableMembers( finalType ); + + XmlNodeList allChildren = elem.ChildNodes; + + for( int i = 0; i < miArr.Length; ++i ) + { + FieldInfo childFi = (FieldInfo)miArr[ i ]; + + String name = childFi.Name; + + name = name.Replace( '+', '-' ); + name = name.Replace( '`', '_' ); + + XmlElement childElem = getNamedChild( allChildren, name ); + + if( childElem != null ) + { + object childObj = Deserialize( childElem, childFi.FieldType, obj ); + + childFi.SetValue( obj, childObj ); + } + } + } + + return obj; + } + + private object DeserializeList( XmlElement elem, Type type, IList list ) + { + XmlNodeList arrNodeList = elem.ChildNodes; + + Type t = list.GetType(); + + Type[] genT = t.GetGenericArguments(); + + Debug.Assert( genT.Length == 1 ); + + for( int i = 0; i < arrNodeList.Count; ++i ) + { + if( arrNodeList.Item( i ) is XmlElement ) + { + XmlElement arrElem = (XmlElement)arrNodeList.Item( i ); + + list.Add( Deserialize( arrElem, genT[0] ) ); + } + } + + return list; + } + + private object DeserializeArray( XmlElement elem, Type type ) + { + Type typeElem = type.GetElementType(); + + string refString = elem.GetAttribute( "ref" ); + int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1; + + XmlNodeList arrNodeList = elem.ChildNodes; + + int length = arrNodeList.Count; + + Array arr = createArray( typeElem, refInt, length ); + + for( int i = 0; i < arr.Length; ++i ) + { + if( arrNodeList.Item( i ) is XmlElement ) + { + XmlElement arrElem = (XmlElement)arrNodeList.Item( i ); + + arr.SetValue( Deserialize( arrElem, typeElem ), i ); + } + } + + return arr; + } + + private object createObject( string typename, int refInt ) + { + Type type = Type.GetType( typename ); + + return createObject( type, refInt ); + } + + private object createObject( Type type, int refInt ) + { + TypeCode tc = Type.GetTypeCode( type ); + + if( refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) ) + { + //lib.log.info( "Reusing object for {0}", refInt ); + return m_alreadySerialized[ refInt ]; + } + else + { + //lib.log.info( "Creating new object for {0}", refInt ); + object obj = Activator.CreateInstance( type ); + + if( refInt > 0 ) + { + m_alreadySerialized[ refInt ] = obj; + } + + return obj; + } + } + + private Array createArray( string elemTypename, int refInt, int length ) + { + Type elemType = Type.GetType( elemTypename ); + + return createArray( elemType, refInt, length ); + } + + private Array createArray( Type elemType, int refInt, int length ) + { + TypeCode elemTC = Type.GetTypeCode( elemType ); + + if( refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) ) + { + return (Array)m_alreadySerialized[ refInt ]; + } + else + { + Array arr = Array.CreateInstance( elemType, length ) ; + + m_alreadySerialized[ refInt ] = arr; + + return arr; + } + } + + private ObjectIDGenerator m_objectID = new ObjectIDGenerator(); + private Dictionary m_alreadySerialized = new Dictionary(); + + #endregion + + #region Serialize + + private string getTypeName( Type type ) + { + //Assembly ass = type.Assembly; + + //string assName = ass.GetName().Name; + + return type.FullName; // + ", " + assName; + } + + public void Serialize( Stream stream, object root ) + { + //lib.log.info( "Serialize( Stream stream, object root ) {0} {1}", m_rndVal, m_alreadySerialized.Count ); + + m_alreadySerialized.Clear(); + m_objectID = new ObjectIDGenerator(); + + XmlTextWriter writer = new XmlTextWriter( stream, System.Text.Encoding.ASCII ); + + writer.Formatting = Formatting.Indented; + + Serialize( writer, root ); + + //Rely on the parent closing the stream. + //writer.Close(); + writer.Flush(); + + //lib.log.info( "Serialize END ( Stream stream, object root ) {0} {1}", m_rndVal, m_alreadySerialized.Count ); + } + + private void Serialize( XmlWriter writer, object root ) + { + //writer.WriteStartDocument(); + Serialize( writer, root, "root" ); + //writer.WriteEndDocument(); + } + + private void Serialize( XmlWriter writer, object root, string name ) + { + writer.WriteStartElement( name ); + + if( root != null ) + { + Type type = root.GetType(); + + TypeCode typeCode = Type.GetTypeCode( type ); + + if( typeCode != TypeCode.Object ) + { + SerializeConcrete( writer, root ); + } + else + { + if( !type.IsArray ) + { + SerializeObject( writer, root ); + } + else + { + SerializeArray( writer, root ); + } + } + } + else + { + writer.WriteAttributeString( "v", "null" ); + } + + writer.WriteEndElement(); + } + + private void SerializeConcrete( XmlWriter writer, object root ) + { + //TODO: Only write this out if debugging. + //writer.WriteAttributeString( "t", getTypeName( root.GetType() ) ); + writer.WriteAttributeString( "v", root.ToString() ); + } + + private void SerializeObject( XmlWriter writer, object root ) + { + writer.WriteAttributeString( "t", getTypeName( root.GetType() ) ); + + /* + if( root is IList ) + { + var list = root as IList; + + Type t = root.GetType(); + + Type[] genT = t.GetGenericArguments(); + } + */ + + bool first; + + long refInt = m_objectID.GetId( root, out first ); + + writer.WriteAttributeString( "ref", refInt.ToString() ); + + if( first ) + { + m_alreadySerialized[ refInt ] = root; + + Type type = root.GetType(); + + //* + Type typeISerializable = typeof( ISerializable ); + + if( root is ISerializable ) // type.IsSubclassOf( typeISerializable ) ) + { + ISerializable ser = root as ISerializable; + + var serInfo = new SerializationInfo( type, new FormatterConverter() ); + + ser.GetObjectData( serInfo, Context ); + + //var serEnum = ; + + foreach( var serMember in serInfo ) + { + String name = serMember.Name; + + name = name.Replace( '+', '-' ); + name = name.Replace( '`', '_' ); + + Serialize( writer, serMember.Value, name ); + } + + //var sc = new SerializationContext( + + //ser.GetObjectData( + } + else + //*/ + { + MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type, Context ); + + for( int i = 0; i < miArr.Length; ++i ) + { + FieldInfo childFi = (FieldInfo)miArr[ i ]; + + object[] objs = childFi.GetCustomAttributes( typeof( NonSerializedAttribute ), true ); + + if( objs.Length > 0 ) + { + continue; + } + + String name = childFi.Name; + + name = name.Replace( '+', '-' ); + name = name.Replace( '`', '_' ); + + Serialize( writer, childFi.GetValue( root ), name ); + } + } + } + } + + private void SerializeArray( XmlWriter writer, object root ) + { + Array arr = (Array)root; + + Type typeElem = arr.GetType().GetElementType(); + + writer.WriteAttributeString( "t", getTypeName( typeElem ) ); + + bool first; + + long refInt = m_objectID.GetId( root, out first ); + + writer.WriteAttributeString( "ref", refInt.ToString() ); + + if( first ) + { + m_alreadySerialized[ refInt ] = root; + + + for( int i = 0; i < arr.Length; ++i ) + { + Serialize( writer, arr.GetValue( i ), "i" + i.ToString() ); + } + } + } + #endregion +} + +} diff --git a/import.txt b/import.txt deleted file mode 100644 index e69de29..0000000 diff --git a/res/Resource.cs b/res/Resource.cs new file mode 100644 index 0000000..e3b9e1d --- /dev/null +++ b/res/Resource.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Threading.Tasks; +using System.Diagnostics; +using System.Reflection; + +namespace res +{ + +[Serializable] +public class Ref : lib.I_Serialize +{ + public string filename { get { return m_filename; } } + + //For construction + public Ref() + { + } + + public Ref( string filename ) + { + m_filename = filename; + } + + virtual public void OnSerialize() + { + } + + virtual public void OnDeserialize( object enclosing ) + { + } + + virtual public void OnChange() + { + } + + private string m_filename; +} + +[Serializable] +public class Ref : Ref +{ + public T res{ get{ return m_res; } set{ m_res = value; } } + + //For construction + public Ref() + { + } + + public Ref( string filename ) + : base( filename ) + { + } + + public Ref( string filename, T res ) : base( filename ) + { + m_res = res; + } + + [NonSerialized] + private T m_res; +} + + + + +public class Resource +{ + static public Mgr mgr; + +} + + +/* +public class Loader +{ + static public T load( string filename ) + { + Debug.Assert( false, "Specialize Loader for your type for file" ); + return default(T); + } +} +*/ +public delegate Ref Load( string filename ); +public delegate Ref LoadType( string filename, Type t ); + + +public class Mgr +{ + + + static public void startup() + { + Resource.mgr = new Mgr(); + } + + static public void register( Load loader ) + { + Debug.Assert( !Resource.mgr.m_loaders.ContainsKey( typeof( T ) ) ); + Resource.mgr.m_loaders[ typeof( T ) ] = loader; + } + + static public void registerSub( Load loaderOfType ) + { + + Type[] typeParams = new Type[1]; + foreach( var mi in typeof( T ).GetMethods() ) + { + if( mi.Name == "res_load" && mi.IsGenericMethod ) + { + foreach( var ass in AppDomain.CurrentDomain.GetAssemblies() ) + { + foreach( var t in ass.GetTypes() ) + { + if( t.IsSubclassOf( typeof( T ) ) ) + { + typeParams[0] = t; + var mi_ng = mi.MakeGenericMethod( typeParams ); + Resource.mgr.m_loaders[ t ] = (Load)Delegate.CreateDelegate( typeof(Load), mi_ng ); + } + } + } + return; + } + } + } + + static public Ref load( string filename ) where T : class + { + Load loader; + Resource.mgr.m_loaders.TryGetValue( typeof( T ), out loader ); + + if( loader != null ) + { + var rf_raw = loader( filename ); + Ref rf = rf_raw as Ref; + return rf; + } + + return new Ref( filename ); + } + + static public Ref load( string filename, Type t ) + { + Load loader; + Resource.mgr.m_loaders.TryGetValue( t, out loader ); + + if( loader != null ) + { + var rf_raw = loader( filename ); + return rf_raw; + } + + return new Ref( filename ); + } + + private Dictionary m_loaders = new Dictionary(); + //private Dictionary m_loadersOfType = new Dictionary(); +} + + + + + +}