diff --git a/Utilities.cs b/Utilities.cs
index 18a70ff..8604dba 100644
--- a/Utilities.cs
+++ b/Utilities.cs
@@ -1,845 +1,849 @@
-// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
-// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-//
-// Copyright (c) 2010-2012 SharpDX - Alexandre Mutel
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-#pragma warning disable SA1405 // Debug.Assert must provide message text
-using att;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Text;
-using System.Threading;
-
-namespace lib
-{
- ///
- /// Utility class.
- ///
- public static class Util
- {
-
- /*
- #if XENKO_PLATFORM_UWP
- public static unsafe void CopyMemory(IntPtr dest, IntPtr src, int sizeInBytesToCopy)
- {
- Interop.memcpy((void*)dest, (void*)src, sizeInBytesToCopy);
- }
- #else
- #if XENKO_PLATFORM_WINDOWS_DESKTOP
- private const string MemcpyDll = "msvcrt.dll";
- #elif XENKO_PLATFORM_ANDROID
- private const string MemcpyDll = "libc.so";
- #elif XENKO_PLATFORM_UNIX
- // We do not specifiy the .so extension as libc.so on Linux
- // is actually not a .so files but a script. Using just libc
- // will automatically find the corresponding .so.
- private const string MemcpyDll = "libc";
- #elif XENKO_PLATFORM_IOS
- private const string MemcpyDll = ObjCRuntime.Constants.SystemLibrary;
- #else
- # error Unsupported platform
- #endif
- [DllImport(MemcpyDll, EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
- #if !XENKO_RUNTIME_CORECLR
- [SuppressUnmanagedCodeSecurity]
- #endif
- private static extern IntPtr CopyMemory(IntPtr dest, IntPtr src, ulong sizeInBytesToCopy);
-
- ///
- /// Copy memory.
- ///
- /// The destination memory location
- /// The source memory location.
- /// The count.
- public static void CopyMemory(IntPtr dest, IntPtr src, int sizeInBytesToCopy)
- {
- CopyMemory(dest, src, (ulong)sizeInBytesToCopy);
- }
- #endif
- */
-
-
-
- public static void checkAndAddDirectory( string path )
- {
- if( !Directory.Exists( path ) )
- {
- lib.Log.info( $"Creating directory {path}" );
- Directory.CreateDirectory( path );
- }
-
- }
-
-
- ///
- /// Compares two block of memory.
- ///
- /// The pointer to compare from.
- /// The pointer to compare against.
- /// The size in bytes to compare.
- /// True if the buffers are equivalent, false otherwise.
- public static unsafe bool CompareMemory( IntPtr from, IntPtr against, int sizeToCompare )
- {
- var pSrc = (byte*)from;
- var pDst = (byte*)against;
-
- // Compare 8 bytes.
- var numberOf = sizeToCompare >> 3;
- while( numberOf > 0 )
- {
- if( *(long*)pSrc != *(long*)pDst )
- return false;
- pSrc += 8;
- pDst += 8;
- numberOf--;
- }
-
- // Compare remaining bytes.
- numberOf = sizeToCompare & 7;
- while( numberOf > 0 )
- {
- if( *pSrc != *pDst )
- return false;
- pSrc++;
- pDst++;
- numberOf--;
- }
-
- return true;
- }
-
- ///
- /// Clears the memory.
- ///
- /// The dest.
- /// The value.
- /// The size in bytes to clear.
- public static void ClearMemory( IntPtr dest, byte value, int sizeInBytesToClear )
- {
- unsafe
- {
- Interop.memset( (void*)dest, value, sizeInBytesToClear );
- }
- }
-
- ///
- /// Return the sizeof a struct from a CLR. Equivalent to sizeof operator but works on generics too.
- ///
- /// a struct to evaluate
- /// sizeof this struct
- public static int SizeOf() where T : struct
- {
- return Interop.SizeOf();
- }
-
- ///
- /// Return the sizeof an array of struct. Equivalent to sizeof operator but works on generics too.
- ///
- /// a struct
- /// The array of struct to evaluate.
- /// sizeof in bytes of this array of struct
- public static int SizeOf( T[] array ) where T : struct
- {
- return array == null ? 0 : array.Length * Interop.SizeOf();
- }
-
- ///
- /// Pins the specified source and call an action with the pinned pointer.
- ///
- /// The type of the structure to pin
- /// The source.
- /// The pin action to perform on the pinned pointer.
- public static void Pin( ref T source, Action pinAction ) where T : struct
- {
- unsafe
- {
- pinAction( (IntPtr)Interop.Fixed( ref source ) );
- }
- }
-
- ///
- /// Pins the specified source and call an action with the pinned pointer.
- ///
- /// The type of the structure to pin
- /// The source array.
- /// The pin action to perform on the pinned pointer.
- public static void Pin( T[] source, [NotNull] Action pinAction ) where T : struct
- {
- unsafe
- {
- pinAction( source == null ? IntPtr.Zero : (IntPtr)Interop.Fixed( source ) );
- }
- }
-
- ///
- /// Covnerts a structured array to an equivalent byte array.
- ///
- /// The source.
- /// The byte array.
- public static byte[] ToByteArray( T[] source ) where T : struct
- {
- if( source == null )
- return null;
-
- var buffer = new byte[SizeOf() * source.Length];
-
- if( source.Length == 0 )
- return buffer;
-
- unsafe
- {
- fixed ( void* pBuffer = buffer )
- Interop.Write( pBuffer, source, 0, source.Length );
- }
- return buffer;
- }
-
- ///
- /// Reads the specified T data from a memory location.
- ///
- /// Type of a data to read
- /// Memory location to read from.
- /// The data read from the memory location
- public static T Read( IntPtr source ) where T : struct
- {
- unsafe
- {
- return Interop.ReadInline( (void*)source );
- }
- }
-
- ///
- /// Reads the specified T data from a memory location.
- ///
- /// Type of a data to read
- /// Memory location to read from.
- /// The data write to.
- [MethodImpl( MethodImplOptions.AggressiveInlining )]
- public static void Read( IntPtr source, ref T data ) where T : struct
- {
- unsafe
- {
- Interop.CopyInline( ref data, (void*)source );
- }
- }
-
- ///
- /// Reads the specified T data from a memory location.
- ///
- /// Type of a data to read
- /// Memory location to read from.
- /// The data write to.
- public static void ReadOut( IntPtr source, out T data ) where T : struct
- {
- unsafe
- {
- Interop.CopyInlineOut( out data, (void*)source );
- }
- }
-
- ///
- /// Reads the specified T data from a memory location.
- ///
- /// Type of a data to read
- /// Memory location to read from.
- /// The data write to.
- /// source pointer + sizeof(T)
- public static IntPtr ReadAndPosition( IntPtr source, ref T data ) where T : struct
- {
- unsafe
- {
- return (IntPtr)Interop.Read( (void*)source, ref data );
- }
- }
-
- ///
- /// Reads the specified array T[] data from a memory location.
- ///
- /// Type of a data to read
- /// Memory location to read from.
- /// The data write to.
- /// The offset in the array to write to.
- /// The number of T element to read from the memory location
- /// source pointer + sizeof(T) * count
- public static IntPtr Read( IntPtr source, T[] data, int offset, int count ) where T : struct
- {
- unsafe
- {
- return (IntPtr)Interop.Read( (void*)source, data, offset, count );
- }
- }
-
- ///
- /// Writes the specified T data to a memory location.
- ///
- /// Type of a data to write
- /// Memory location to write to.
- /// The data to write.
- [MethodImpl( MethodImplOptions.AggressiveInlining )]
- public static void Write( IntPtr destination, ref T data ) where T : struct
- {
- unsafe
- {
- Interop.CopyInline( (void*)destination, ref data );
- }
- }
-
- ///
- /// Writes the specified T data to a memory location.
- ///
- /// Type of a data to write
- /// Memory location to write to.
- /// The data to write.
- /// destination pointer + sizeof(T)
- public static IntPtr WriteAndPosition( IntPtr destination, ref T data ) where T : struct
- {
- unsafe
- {
- return (IntPtr)Interop.Write( (void*)destination, ref data );
- }
- }
-
- ///
- /// Writes the specified array T[] data to a memory location.
- ///
- /// Type of a data to write
- /// Memory location to write to.
- /// The array of T data to write.
- /// The offset in the array to read from.
- /// The number of T element to write to the memory location
- public static void Write( byte[] destination, T[] data, int offset, int count ) where T : struct
- {
- unsafe
- {
- fixed ( void* pDest = destination )
- {
- Write( (IntPtr)pDest, data, offset, count );
- }
- }
- }
-
- ///
- /// Writes the specified array T[] data to a memory location.
- ///
- /// Type of a data to write
- /// Memory location to write to.
- /// The array of T data to write.
- /// The offset in the array to read from.
- /// The number of T element to write to the memory location
- /// destination pointer + sizeof(T) * count
- public static IntPtr Write( IntPtr destination, T[] data, int offset, int count ) where T : struct
- {
- unsafe
- {
- return (IntPtr)Interop.Write( (void*)destination, data, offset, count );
- }
- }
-
- ///
- /// Allocate an aligned memory buffer.
- ///
- /// Size of the buffer to allocate.
- /// Alignment, a positive value which is a power of 2. 16 bytes by default.
- /// A pointer to a buffer aligned.
- ///
- /// To free this buffer, call
- ///
- public static unsafe IntPtr AllocateMemory( int sizeInBytes, int align = 16 )
- {
- var mask = align - 1;
- if( ( align & mask ) != 0 )
- {
- throw new ArgumentException( "Alignment is not power of 2", nameof( align ) );
- }
- var memPtr = Marshal.AllocHGlobal(sizeInBytes + mask + sizeof(void*));
- var ptr = (byte*)((ulong)(memPtr.ToInt32() + sizeof(void*) + mask) & ~(ulong)mask);
- ( (IntPtr*)ptr )[-1] = memPtr;
- return new IntPtr( ptr );
- }
-
- ///
- /// Allocate an aligned memory buffer and clear it with a specified value (0 by defaault).
- ///
- /// Size of the buffer to allocate.
- /// Default value used to clear the buffer.
- /// Alignment, 16 bytes by default.
- /// A pointer to a buffer aligned.
- ///
- /// To free this buffer, call
- ///
- public static IntPtr AllocateClearedMemory( int sizeInBytes, byte clearValue = 0, int align = 16 )
- {
- var ptr = AllocateMemory(sizeInBytes, align);
- ClearMemory( ptr, clearValue, sizeInBytes );
- return ptr;
- }
-
- ///
- /// Determines whether the specified memory pointer is aligned in memory.
- ///
- /// The memory pointer.
- /// The align.
- /// true if the specified memory pointer is aligned in memory; otherwise, false.
- public static bool IsMemoryAligned( IntPtr memoryPtr, int align = 16 )
- {
- return ( memoryPtr.ToInt64() & ( align - 1 ) ) == 0;
- }
-
- ///
- /// Allocate an aligned memory buffer.
- ///
- ///
- /// The buffer must have been allocated with
- ///
- public static unsafe void FreeMemory( IntPtr alignedBuffer )
- {
- Marshal.FreeHGlobal( ( (IntPtr*)alignedBuffer )[-1] );
- }
-
- ///
- /// If non-null, disposes the specified object and set it to null, otherwise do nothing.
- ///
- /// The disposable.
- public static void Dispose( ref T disposable ) where T : class, IDisposable
- {
- if( disposable != null )
- {
- disposable.Dispose();
- disposable = null;
- }
- }
-
- ///
- /// String helper join method to display an array of object as a single string.
- ///
- /// The separator.
- /// The array.
- /// a string with array elements serparated by the seperator
- [NotNull]
- public static string Join( string separator, T[] array )
- {
- var text = new StringBuilder();
- if( array != null )
- {
- for( var i = 0; i < array.Length; i++ )
- {
- if( i > 0 )
- text.Append( separator );
- text.Append( array[i] );
- }
- }
- return text.ToString();
- }
-
- ///
- /// String helper join method to display an enumrable of object as a single string.
- ///
- /// The separator.
- /// The enumerable.
- /// a string with array elements serparated by the seperator
- [NotNull]
- public static string Join( string separator, [NotNull] IEnumerable elements )
- {
- var elementList = new List();
- foreach( var element in elements )
- elementList.Add( element.ToString() );
-
- var text = new StringBuilder();
- for( var i = 0; i < elementList.Count; i++ )
- {
- var element = elementList[i];
- if( i > 0 )
- text.Append( separator );
- text.Append( element );
- }
- return text.ToString();
- }
-
- ///
- /// String helper join method to display an enumrable of object as a single string.
- ///
- /// The separator.
- /// The enumerable.
- /// a string with array elements serparated by the seperator
- [NotNull]
- public static string Join( string separator, [NotNull] IEnumerator elements )
- {
- var elementList = new List();
- while( elements.MoveNext() )
- elementList.Add( elements.Current.ToString() );
-
- var text = new StringBuilder();
- for( var i = 0; i < elementList.Count; i++ )
- {
- var element = elementList[i];
- if( i > 0 )
- text.Append( separator );
- text.Append( element );
- }
- return text.ToString();
- }
-
- ///
- /// Read stream to a byte[] buffer
- ///
- /// input stream
- /// a byte[] buffer
- [NotNull]
- public static byte[] ReadStream( [NotNull] Stream stream )
- {
- var readLength = 0;
- return ReadStream( stream, ref readLength );
- }
-
- ///
- /// Read stream to a byte[] buffer
- ///
- /// input stream
- /// length to read
- /// a byte[] buffer
- [NotNull]
- public static byte[] ReadStream( [NotNull] Stream stream, ref int readLength )
- {
- System.Diagnostics.Debug.Assert( stream != null );
- System.Diagnostics.Debug.Assert( stream.CanRead );
- var num = readLength;
- System.Diagnostics.Debug.Assert( num <= ( stream.Length - stream.Position ) );
- if( num == 0 )
- readLength = (int)( stream.Length - stream.Position );
- num = readLength;
-
- System.Diagnostics.Debug.Assert( num >= 0 );
- if( num == 0 )
- return new byte[0];
-
- var buffer = new byte[num];
- var bytesRead = 0;
- if( num > 0 )
- {
- do
- {
- bytesRead += stream.Read( buffer, bytesRead, readLength - bytesRead );
- } while( bytesRead < readLength );
- }
- return buffer;
- }
-
- ///
- /// Computes a hashcode for a dictionary.
- ///
- /// Hashcode for the list.
- public static int GetHashCode( IDictionary dict )
- {
- if( dict == null )
- return 0;
-
- var hashCode = 0;
- foreach( DictionaryEntry keyValue in dict )
- {
- hashCode = ( hashCode * 397 ) ^ keyValue.Key.GetHashCode();
- hashCode = ( hashCode * 397 ) ^ ( keyValue.Value?.GetHashCode() ?? 0 );
- }
- return hashCode;
- }
-
- ///
- /// Computes a hashcode for an enumeration
- ///
- /// An enumerator.
- /// Hashcode for the list.
- public static int GetHashCode( IEnumerable it )
- {
- if( it == null )
- return 0;
-
- var hashCode = 0;
- foreach( var current in it )
- {
- hashCode = ( hashCode * 397 ) ^ ( current?.GetHashCode() ?? 0 );
- }
- return hashCode;
- }
-
- ///
- /// Computes a hashcode for an enumeration
- ///
- /// An enumerator.
- /// Hashcode for the list.
- public static int GetHashCode( IEnumerator it )
- {
- if( it == null )
- return 0;
-
- var hashCode = 0;
- while( it.MoveNext() )
- {
- var current = it.Current;
- hashCode = ( hashCode * 397 ) ^ ( current?.GetHashCode() ?? 0 );
- }
- return hashCode;
- }
-
- ///
- /// Compares two collection, element by elements.
- ///
- /// A "from" enumerator.
- /// A "to" enumerator.
- /// True if lists are identical. False otherwise.
- public static bool Compare( IEnumerable left, IEnumerable right )
- {
- if( ReferenceEquals( left, right ) )
- return true;
- if( ReferenceEquals( left, null ) || ReferenceEquals( right, null ) )
- return false;
-
- return Compare( left.GetEnumerator(), right.GetEnumerator() );
- }
-
- ///
- /// Compares two collection, element by elements.
- ///
- /// A "from" enumerator.
- /// A "to" enumerator.
- /// True if lists are identical. False otherwise.
- public static bool Compare( IEnumerator leftIt, IEnumerator rightIt )
- {
- if( ReferenceEquals( leftIt, rightIt ) )
- return true;
- if( ReferenceEquals( leftIt, null ) || ReferenceEquals( rightIt, null ) )
- return false;
-
- bool hasLeftNext;
- bool hasRightNext;
- while( true )
- {
- hasLeftNext = leftIt.MoveNext();
- hasRightNext = rightIt.MoveNext();
- if( !hasLeftNext || !hasRightNext )
- break;
-
- if( !Equals( leftIt.Current, rightIt.Current ) )
- return false;
- }
-
- // If there is any left element
- if( hasLeftNext != hasRightNext )
- return false;
-
- return true;
- }
-
- ///
- /// Compares two collection, element by elements.
- ///
- /// The collection to compare from.
- /// The colllection to compare to.
- /// True if lists are identical (but no necessarely of the same time). False otherwise.
- public static bool Compare( IDictionary first, IDictionary second )
- {
- if( ReferenceEquals( first, second ) )
- return true;
- if( ReferenceEquals( first, null ) || ReferenceEquals( second, null ) )
- return false;
- if( first.Count != second.Count )
- return false;
-
- var comparer = EqualityComparer.Default;
-
- foreach( var keyValue in first )
- {
- TValue secondValue;
- if( !second.TryGetValue( keyValue.Key, out secondValue ) )
- return false;
- if( !comparer.Equals( keyValue.Value, secondValue ) )
- return false;
- }
-
- // Check that all keys in second are in first
- return second.Keys.All( first.ContainsKey );
- }
-
- public static bool Compare( T[] left, T[] right )
- {
- if( ReferenceEquals( left, right ) )
- return true;
- if( ReferenceEquals( left, null ) || ReferenceEquals( right, null ) )
- return false;
-
- if( left.Length != right.Length )
- return false;
-
- var comparer = EqualityComparer.Default;
- for( var i = 0; i < left.Length; ++i )
- {
- if( !comparer.Equals( left[i], right[i] ) )
- return false;
- }
-
- return true;
- }
-
- ///
- /// Compares two collection, element by elements.
- ///
- /// The collection to compare from.
- /// The colllection to compare to.
- /// True if lists are identical (but no necessarely of the same time). False otherwise.
- public static bool Compare( ICollection left, ICollection right )
- {
- if( ReferenceEquals( left, right ) )
- return true;
- if( ReferenceEquals( left, null ) || ReferenceEquals( right, null ) )
- return false;
-
- if( left.Count != right.Count )
- return false;
-
- var count = 0;
- var leftIt = left.GetEnumerator();
- var rightIt = right.GetEnumerator();
- var comparer = EqualityComparer.Default;
- while( leftIt.MoveNext() && rightIt.MoveNext() )
- {
- if( !comparer.Equals( leftIt.Current, rightIt.Current ) )
- return false;
- count++;
- }
-
- // Just double check to make sure that the iterator actually returns
- // the exact number of elements
- if( count != left.Count )
- return false;
-
- return true;
- }
-
- ///
- /// Swaps the value between two references.
- ///
- /// Type of a data to swap.
- /// The left value.
- /// The right value.
- public static void Swap( ref T left, ref T right )
- {
- var temp = left;
- left = right;
- right = temp;
- }
-
- ///
- /// Suspends current thread for a .
- ///
- /// The duration of sleep.
- public static void Sleep( TimeSpan sleepTime )
- {
- var ms = (long)sleepTime.TotalMilliseconds;
- if( ms < 0 || ms > int.MaxValue )
- {
- throw new ArgumentOutOfRangeException( nameof( sleepTime ), "Sleep time must be a duration less than '2^31 - 1' milliseconds." );
- }
- // MH PORTED NativeInvoke.Sleep((int)ms);
- Thread.Sleep( (int)ms );
- }
-
- ///
- /// Suspends current thread for a .
- ///
- /// The duration of sleep in milliseconds.
- public static void Sleep( int sleepTimeInMillis )
- {
- // MH PORTED NativeInvoke.Sleep(sleepTimeInMillis);
- Thread.Sleep( sleepTimeInMillis );
- }
-
- ///
- /// Writes the specified T data to a memory location.
- ///
- /// Type of a data to write
- /// Memory location to write to.
- /// The data to write.
- internal static void UnsafeWrite( IntPtr destination, ref T data )
- {
- unsafe
- {
- Interop.CopyInline( (void*)destination, ref data );
- }
- }
-
- ///
- /// Reads the specified T data from a memory location.
- ///
- /// Type of a data to read
- /// Memory location to read from.
- /// The data write to.
- internal static void UnsafeReadOut( IntPtr source, out T data )
- {
- unsafe
- {
- Interop.CopyInlineOut( out data, (void*)source );
- }
- }
-
- ///
- /// Return the sizeof a struct from a CLR. Equivalent to sizeof operator but works on generics too.
- ///
- /// a struct to evaluate
- /// sizeof this struct
- internal static int UnsafeSizeOf()
- {
- return Interop.SizeOf();
- }
-
- ///
- /// Linq assisted full tree iteration and collection in a single line.
- /// Warning, could be slow.
- ///
- /// The type to iterate.
- /// The root item
- /// The function to retrieve a child
- public static IEnumerable IterateTree( T root, Func> childrenF )
- {
- var q = new List { root };
- while( q.Any() )
- {
- var c = q[0];
- q.RemoveAt( 0 );
- q.AddRange( childrenF( c ) ?? Enumerable.Empty() );
- yield return c;
- }
- }
-
- ///
- /// Converts a raw time to a .
- ///
- /// The delta.
- /// The .
- public static TimeSpan ConvertRawToTimestamp( long delta )
- {
- return new TimeSpan( delta == 0 ? 0 : ( delta * TimeSpan.TicksPerSecond ) / Stopwatch.Frequency );
- }
- }
-}
+// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+//
+// Copyright (c) 2010-2012 SharpDX - Alexandre Mutel
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+#pragma warning disable SA1405 // Debug.Assert must provide message text
+using att;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Text;
+using System.Threading;
+
+namespace lib
+{
+ ///
+ /// Utility class.
+ ///
+ public static class Util
+ {
+
+ /*
+ #if XENKO_PLATFORM_UWP
+ public static unsafe void CopyMemory(IntPtr dest, IntPtr src, int sizeInBytesToCopy)
+ {
+ Interop.memcpy((void*)dest, (void*)src, sizeInBytesToCopy);
+ }
+ #else
+ #if XENKO_PLATFORM_WINDOWS_DESKTOP
+ private const string MemcpyDll = "msvcrt.dll";
+ #elif XENKO_PLATFORM_ANDROID
+ private const string MemcpyDll = "libc.so";
+ #elif XENKO_PLATFORM_UNIX
+ // We do not specifiy the .so extension as libc.so on Linux
+ // is actually not a .so files but a script. Using just libc
+ // will automatically find the corresponding .so.
+ private const string MemcpyDll = "libc";
+ #elif XENKO_PLATFORM_IOS
+ private const string MemcpyDll = ObjCRuntime.Constants.SystemLibrary;
+ #else
+ # error Unsupported platform
+ #endif
+ [DllImport(MemcpyDll, EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
+ #if !XENKO_RUNTIME_CORECLR
+ [SuppressUnmanagedCodeSecurity]
+ #endif
+ private static extern IntPtr CopyMemory(IntPtr dest, IntPtr src, ulong sizeInBytesToCopy);
+
+ ///
+ /// Copy memory.
+ ///
+ /// The destination memory location
+ /// The source memory location.
+ /// The count.
+ public static void CopyMemory(IntPtr dest, IntPtr src, int sizeInBytesToCopy)
+ {
+ CopyMemory(dest, src, (ulong)sizeInBytesToCopy);
+ }
+ #endif
+ */
+
+
+
+ public static void checkAndAddDirectory( string path )
+ {
+ if( !Directory.Exists( path ) )
+ {
+ lib.Log.info( $"Creating directory {path}" );
+ Directory.CreateDirectory( path );
+ }
+ else
+ {
+ lib.Log.debug( $"{path} already exists." );
+ }
+
+ }
+
+
+ ///
+ /// Compares two block of memory.
+ ///
+ /// The pointer to compare from.
+ /// The pointer to compare against.
+ /// The size in bytes to compare.
+ /// True if the buffers are equivalent, false otherwise.
+ public static unsafe bool CompareMemory( IntPtr from, IntPtr against, int sizeToCompare )
+ {
+ var pSrc = (byte*)from;
+ var pDst = (byte*)against;
+
+ // Compare 8 bytes.
+ var numberOf = sizeToCompare >> 3;
+ while( numberOf > 0 )
+ {
+ if( *(long*)pSrc != *(long*)pDst )
+ return false;
+ pSrc += 8;
+ pDst += 8;
+ numberOf--;
+ }
+
+ // Compare remaining bytes.
+ numberOf = sizeToCompare & 7;
+ while( numberOf > 0 )
+ {
+ if( *pSrc != *pDst )
+ return false;
+ pSrc++;
+ pDst++;
+ numberOf--;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Clears the memory.
+ ///
+ /// The dest.
+ /// The value.
+ /// The size in bytes to clear.
+ public static void ClearMemory( IntPtr dest, byte value, int sizeInBytesToClear )
+ {
+ unsafe
+ {
+ Interop.memset( (void*)dest, value, sizeInBytesToClear );
+ }
+ }
+
+ ///
+ /// Return the sizeof a struct from a CLR. Equivalent to sizeof operator but works on generics too.
+ ///
+ /// a struct to evaluate
+ /// sizeof this struct
+ public static int SizeOf() where T : struct
+ {
+ return Interop.SizeOf();
+ }
+
+ ///
+ /// Return the sizeof an array of struct. Equivalent to sizeof operator but works on generics too.
+ ///
+ /// a struct
+ /// The array of struct to evaluate.
+ /// sizeof in bytes of this array of struct
+ public static int SizeOf( T[] array ) where T : struct
+ {
+ return array == null ? 0 : array.Length * Interop.SizeOf();
+ }
+
+ ///
+ /// Pins the specified source and call an action with the pinned pointer.
+ ///
+ /// The type of the structure to pin
+ /// The source.
+ /// The pin action to perform on the pinned pointer.
+ public static void Pin( ref T source, Action pinAction ) where T : struct
+ {
+ unsafe
+ {
+ pinAction( (IntPtr)Interop.Fixed( ref source ) );
+ }
+ }
+
+ ///
+ /// Pins the specified source and call an action with the pinned pointer.
+ ///
+ /// The type of the structure to pin
+ /// The source array.
+ /// The pin action to perform on the pinned pointer.
+ public static void Pin( T[] source, [NotNull] Action pinAction ) where T : struct
+ {
+ unsafe
+ {
+ pinAction( source == null ? IntPtr.Zero : (IntPtr)Interop.Fixed( source ) );
+ }
+ }
+
+ ///
+ /// Covnerts a structured array to an equivalent byte array.
+ ///
+ /// The source.
+ /// The byte array.
+ public static byte[] ToByteArray( T[] source ) where T : struct
+ {
+ if( source == null )
+ return null;
+
+ var buffer = new byte[SizeOf() * source.Length];
+
+ if( source.Length == 0 )
+ return buffer;
+
+ unsafe
+ {
+ fixed ( void* pBuffer = buffer )
+ Interop.Write( pBuffer, source, 0, source.Length );
+ }
+ return buffer;
+ }
+
+ ///
+ /// Reads the specified T data from a memory location.
+ ///
+ /// Type of a data to read
+ /// Memory location to read from.
+ /// The data read from the memory location
+ public static T Read( IntPtr source ) where T : struct
+ {
+ unsafe
+ {
+ return Interop.ReadInline( (void*)source );
+ }
+ }
+
+ ///
+ /// Reads the specified T data from a memory location.
+ ///
+ /// Type of a data to read
+ /// Memory location to read from.
+ /// The data write to.
+ [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ public static void Read( IntPtr source, ref T data ) where T : struct
+ {
+ unsafe
+ {
+ Interop.CopyInline( ref data, (void*)source );
+ }
+ }
+
+ ///
+ /// Reads the specified T data from a memory location.
+ ///
+ /// Type of a data to read
+ /// Memory location to read from.
+ /// The data write to.
+ public static void ReadOut( IntPtr source, out T data ) where T : struct
+ {
+ unsafe
+ {
+ Interop.CopyInlineOut( out data, (void*)source );
+ }
+ }
+
+ ///
+ /// Reads the specified T data from a memory location.
+ ///
+ /// Type of a data to read
+ /// Memory location to read from.
+ /// The data write to.
+ /// source pointer + sizeof(T)
+ public static IntPtr ReadAndPosition( IntPtr source, ref T data ) where T : struct
+ {
+ unsafe
+ {
+ return (IntPtr)Interop.Read( (void*)source, ref data );
+ }
+ }
+
+ ///
+ /// Reads the specified array T[] data from a memory location.
+ ///
+ /// Type of a data to read
+ /// Memory location to read from.
+ /// The data write to.
+ /// The offset in the array to write to.
+ /// The number of T element to read from the memory location
+ /// source pointer + sizeof(T) * count
+ public static IntPtr Read( IntPtr source, T[] data, int offset, int count ) where T : struct
+ {
+ unsafe
+ {
+ return (IntPtr)Interop.Read( (void*)source, data, offset, count );
+ }
+ }
+
+ ///
+ /// Writes the specified T data to a memory location.
+ ///
+ /// Type of a data to write
+ /// Memory location to write to.
+ /// The data to write.
+ [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ public static void Write( IntPtr destination, ref T data ) where T : struct
+ {
+ unsafe
+ {
+ Interop.CopyInline( (void*)destination, ref data );
+ }
+ }
+
+ ///
+ /// Writes the specified T data to a memory location.
+ ///
+ /// Type of a data to write
+ /// Memory location to write to.
+ /// The data to write.
+ /// destination pointer + sizeof(T)
+ public static IntPtr WriteAndPosition( IntPtr destination, ref T data ) where T : struct
+ {
+ unsafe
+ {
+ return (IntPtr)Interop.Write( (void*)destination, ref data );
+ }
+ }
+
+ ///
+ /// Writes the specified array T[] data to a memory location.
+ ///
+ /// Type of a data to write
+ /// Memory location to write to.
+ /// The array of T data to write.
+ /// The offset in the array to read from.
+ /// The number of T element to write to the memory location
+ public static void Write( byte[] destination, T[] data, int offset, int count ) where T : struct
+ {
+ unsafe
+ {
+ fixed ( void* pDest = destination )
+ {
+ Write( (IntPtr)pDest, data, offset, count );
+ }
+ }
+ }
+
+ ///
+ /// Writes the specified array T[] data to a memory location.
+ ///
+ /// Type of a data to write
+ /// Memory location to write to.
+ /// The array of T data to write.
+ /// The offset in the array to read from.
+ /// The number of T element to write to the memory location
+ /// destination pointer + sizeof(T) * count
+ public static IntPtr Write( IntPtr destination, T[] data, int offset, int count ) where T : struct
+ {
+ unsafe
+ {
+ return (IntPtr)Interop.Write( (void*)destination, data, offset, count );
+ }
+ }
+
+ ///
+ /// Allocate an aligned memory buffer.
+ ///
+ /// Size of the buffer to allocate.
+ /// Alignment, a positive value which is a power of 2. 16 bytes by default.
+ /// A pointer to a buffer aligned.
+ ///
+ /// To free this buffer, call
+ ///
+ public static unsafe IntPtr AllocateMemory( int sizeInBytes, int align = 16 )
+ {
+ var mask = align - 1;
+ if( ( align & mask ) != 0 )
+ {
+ throw new ArgumentException( "Alignment is not power of 2", nameof( align ) );
+ }
+ var memPtr = Marshal.AllocHGlobal(sizeInBytes + mask + sizeof(void*));
+ var ptr = (byte*)((ulong)(memPtr.ToInt32() + sizeof(void*) + mask) & ~(ulong)mask);
+ ( (IntPtr*)ptr )[-1] = memPtr;
+ return new IntPtr( ptr );
+ }
+
+ ///
+ /// Allocate an aligned memory buffer and clear it with a specified value (0 by defaault).
+ ///
+ /// Size of the buffer to allocate.
+ /// Default value used to clear the buffer.
+ /// Alignment, 16 bytes by default.
+ /// A pointer to a buffer aligned.
+ ///
+ /// To free this buffer, call
+ ///
+ public static IntPtr AllocateClearedMemory( int sizeInBytes, byte clearValue = 0, int align = 16 )
+ {
+ var ptr = AllocateMemory(sizeInBytes, align);
+ ClearMemory( ptr, clearValue, sizeInBytes );
+ return ptr;
+ }
+
+ ///
+ /// Determines whether the specified memory pointer is aligned in memory.
+ ///
+ /// The memory pointer.
+ /// The align.
+ /// true if the specified memory pointer is aligned in memory; otherwise, false.
+ public static bool IsMemoryAligned( IntPtr memoryPtr, int align = 16 )
+ {
+ return ( memoryPtr.ToInt64() & ( align - 1 ) ) == 0;
+ }
+
+ ///
+ /// Allocate an aligned memory buffer.
+ ///
+ ///
+ /// The buffer must have been allocated with
+ ///
+ public static unsafe void FreeMemory( IntPtr alignedBuffer )
+ {
+ Marshal.FreeHGlobal( ( (IntPtr*)alignedBuffer )[-1] );
+ }
+
+ ///
+ /// If non-null, disposes the specified object and set it to null, otherwise do nothing.
+ ///
+ /// The disposable.
+ public static void Dispose( ref T disposable ) where T : class, IDisposable
+ {
+ if( disposable != null )
+ {
+ disposable.Dispose();
+ disposable = null;
+ }
+ }
+
+ ///
+ /// String helper join method to display an array of object as a single string.
+ ///
+ /// The separator.
+ /// The array.
+ /// a string with array elements serparated by the seperator
+ [NotNull]
+ public static string Join( string separator, T[] array )
+ {
+ var text = new StringBuilder();
+ if( array != null )
+ {
+ for( var i = 0; i < array.Length; i++ )
+ {
+ if( i > 0 )
+ text.Append( separator );
+ text.Append( array[i] );
+ }
+ }
+ return text.ToString();
+ }
+
+ ///
+ /// String helper join method to display an enumrable of object as a single string.
+ ///
+ /// The separator.
+ /// The enumerable.
+ /// a string with array elements serparated by the seperator
+ [NotNull]
+ public static string Join( string separator, [NotNull] IEnumerable elements )
+ {
+ var elementList = new List();
+ foreach( var element in elements )
+ elementList.Add( element.ToString() );
+
+ var text = new StringBuilder();
+ for( var i = 0; i < elementList.Count; i++ )
+ {
+ var element = elementList[i];
+ if( i > 0 )
+ text.Append( separator );
+ text.Append( element );
+ }
+ return text.ToString();
+ }
+
+ ///
+ /// String helper join method to display an enumrable of object as a single string.
+ ///
+ /// The separator.
+ /// The enumerable.
+ /// a string with array elements serparated by the seperator
+ [NotNull]
+ public static string Join( string separator, [NotNull] IEnumerator elements )
+ {
+ var elementList = new List();
+ while( elements.MoveNext() )
+ elementList.Add( elements.Current.ToString() );
+
+ var text = new StringBuilder();
+ for( var i = 0; i < elementList.Count; i++ )
+ {
+ var element = elementList[i];
+ if( i > 0 )
+ text.Append( separator );
+ text.Append( element );
+ }
+ return text.ToString();
+ }
+
+ ///
+ /// Read stream to a byte[] buffer
+ ///
+ /// input stream
+ /// a byte[] buffer
+ [NotNull]
+ public static byte[] ReadStream( [NotNull] Stream stream )
+ {
+ var readLength = 0;
+ return ReadStream( stream, ref readLength );
+ }
+
+ ///
+ /// Read stream to a byte[] buffer
+ ///
+ /// input stream
+ /// length to read
+ /// a byte[] buffer
+ [NotNull]
+ public static byte[] ReadStream( [NotNull] Stream stream, ref int readLength )
+ {
+ System.Diagnostics.Debug.Assert( stream != null );
+ System.Diagnostics.Debug.Assert( stream.CanRead );
+ var num = readLength;
+ System.Diagnostics.Debug.Assert( num <= ( stream.Length - stream.Position ) );
+ if( num == 0 )
+ readLength = (int)( stream.Length - stream.Position );
+ num = readLength;
+
+ System.Diagnostics.Debug.Assert( num >= 0 );
+ if( num == 0 )
+ return new byte[0];
+
+ var buffer = new byte[num];
+ var bytesRead = 0;
+ if( num > 0 )
+ {
+ do
+ {
+ bytesRead += stream.Read( buffer, bytesRead, readLength - bytesRead );
+ } while( bytesRead < readLength );
+ }
+ return buffer;
+ }
+
+ ///
+ /// Computes a hashcode for a dictionary.
+ ///
+ /// Hashcode for the list.
+ public static int GetHashCode( IDictionary dict )
+ {
+ if( dict == null )
+ return 0;
+
+ var hashCode = 0;
+ foreach( DictionaryEntry keyValue in dict )
+ {
+ hashCode = ( hashCode * 397 ) ^ keyValue.Key.GetHashCode();
+ hashCode = ( hashCode * 397 ) ^ ( keyValue.Value?.GetHashCode() ?? 0 );
+ }
+ return hashCode;
+ }
+
+ ///
+ /// Computes a hashcode for an enumeration
+ ///
+ /// An enumerator.
+ /// Hashcode for the list.
+ public static int GetHashCode( IEnumerable it )
+ {
+ if( it == null )
+ return 0;
+
+ var hashCode = 0;
+ foreach( var current in it )
+ {
+ hashCode = ( hashCode * 397 ) ^ ( current?.GetHashCode() ?? 0 );
+ }
+ return hashCode;
+ }
+
+ ///
+ /// Computes a hashcode for an enumeration
+ ///
+ /// An enumerator.
+ /// Hashcode for the list.
+ public static int GetHashCode( IEnumerator it )
+ {
+ if( it == null )
+ return 0;
+
+ var hashCode = 0;
+ while( it.MoveNext() )
+ {
+ var current = it.Current;
+ hashCode = ( hashCode * 397 ) ^ ( current?.GetHashCode() ?? 0 );
+ }
+ return hashCode;
+ }
+
+ ///
+ /// Compares two collection, element by elements.
+ ///
+ /// A "from" enumerator.
+ /// A "to" enumerator.
+ /// True if lists are identical. False otherwise.
+ public static bool Compare( IEnumerable left, IEnumerable right )
+ {
+ if( ReferenceEquals( left, right ) )
+ return true;
+ if( ReferenceEquals( left, null ) || ReferenceEquals( right, null ) )
+ return false;
+
+ return Compare( left.GetEnumerator(), right.GetEnumerator() );
+ }
+
+ ///
+ /// Compares two collection, element by elements.
+ ///
+ /// A "from" enumerator.
+ /// A "to" enumerator.
+ /// True if lists are identical. False otherwise.
+ public static bool Compare( IEnumerator leftIt, IEnumerator rightIt )
+ {
+ if( ReferenceEquals( leftIt, rightIt ) )
+ return true;
+ if( ReferenceEquals( leftIt, null ) || ReferenceEquals( rightIt, null ) )
+ return false;
+
+ bool hasLeftNext;
+ bool hasRightNext;
+ while( true )
+ {
+ hasLeftNext = leftIt.MoveNext();
+ hasRightNext = rightIt.MoveNext();
+ if( !hasLeftNext || !hasRightNext )
+ break;
+
+ if( !Equals( leftIt.Current, rightIt.Current ) )
+ return false;
+ }
+
+ // If there is any left element
+ if( hasLeftNext != hasRightNext )
+ return false;
+
+ return true;
+ }
+
+ ///
+ /// Compares two collection, element by elements.
+ ///
+ /// The collection to compare from.
+ /// The colllection to compare to.
+ /// True if lists are identical (but no necessarely of the same time). False otherwise.
+ public static bool Compare( IDictionary first, IDictionary second )
+ {
+ if( ReferenceEquals( first, second ) )
+ return true;
+ if( ReferenceEquals( first, null ) || ReferenceEquals( second, null ) )
+ return false;
+ if( first.Count != second.Count )
+ return false;
+
+ var comparer = EqualityComparer.Default;
+
+ foreach( var keyValue in first )
+ {
+ TValue secondValue;
+ if( !second.TryGetValue( keyValue.Key, out secondValue ) )
+ return false;
+ if( !comparer.Equals( keyValue.Value, secondValue ) )
+ return false;
+ }
+
+ // Check that all keys in second are in first
+ return second.Keys.All( first.ContainsKey );
+ }
+
+ public static bool Compare( T[] left, T[] right )
+ {
+ if( ReferenceEquals( left, right ) )
+ return true;
+ if( ReferenceEquals( left, null ) || ReferenceEquals( right, null ) )
+ return false;
+
+ if( left.Length != right.Length )
+ return false;
+
+ var comparer = EqualityComparer.Default;
+ for( var i = 0; i < left.Length; ++i )
+ {
+ if( !comparer.Equals( left[i], right[i] ) )
+ return false;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Compares two collection, element by elements.
+ ///
+ /// The collection to compare from.
+ /// The colllection to compare to.
+ /// True if lists are identical (but no necessarely of the same time). False otherwise.
+ public static bool Compare( ICollection left, ICollection right )
+ {
+ if( ReferenceEquals( left, right ) )
+ return true;
+ if( ReferenceEquals( left, null ) || ReferenceEquals( right, null ) )
+ return false;
+
+ if( left.Count != right.Count )
+ return false;
+
+ var count = 0;
+ var leftIt = left.GetEnumerator();
+ var rightIt = right.GetEnumerator();
+ var comparer = EqualityComparer.Default;
+ while( leftIt.MoveNext() && rightIt.MoveNext() )
+ {
+ if( !comparer.Equals( leftIt.Current, rightIt.Current ) )
+ return false;
+ count++;
+ }
+
+ // Just double check to make sure that the iterator actually returns
+ // the exact number of elements
+ if( count != left.Count )
+ return false;
+
+ return true;
+ }
+
+ ///
+ /// Swaps the value between two references.
+ ///
+ /// Type of a data to swap.
+ /// The left value.
+ /// The right value.
+ public static void Swap( ref T left, ref T right )
+ {
+ var temp = left;
+ left = right;
+ right = temp;
+ }
+
+ ///
+ /// Suspends current thread for a .
+ ///
+ /// The duration of sleep.
+ public static void Sleep( TimeSpan sleepTime )
+ {
+ var ms = (long)sleepTime.TotalMilliseconds;
+ if( ms < 0 || ms > int.MaxValue )
+ {
+ throw new ArgumentOutOfRangeException( nameof( sleepTime ), "Sleep time must be a duration less than '2^31 - 1' milliseconds." );
+ }
+ // MH PORTED NativeInvoke.Sleep((int)ms);
+ Thread.Sleep( (int)ms );
+ }
+
+ ///
+ /// Suspends current thread for a .
+ ///
+ /// The duration of sleep in milliseconds.
+ public static void Sleep( int sleepTimeInMillis )
+ {
+ // MH PORTED NativeInvoke.Sleep(sleepTimeInMillis);
+ Thread.Sleep( sleepTimeInMillis );
+ }
+
+ ///
+ /// Writes the specified T data to a memory location.
+ ///
+ /// Type of a data to write
+ /// Memory location to write to.
+ /// The data to write.
+ internal static void UnsafeWrite( IntPtr destination, ref T data )
+ {
+ unsafe
+ {
+ Interop.CopyInline( (void*)destination, ref data );
+ }
+ }
+
+ ///
+ /// Reads the specified T data from a memory location.
+ ///
+ /// Type of a data to read
+ /// Memory location to read from.
+ /// The data write to.
+ internal static void UnsafeReadOut( IntPtr source, out T data )
+ {
+ unsafe
+ {
+ Interop.CopyInlineOut( out data, (void*)source );
+ }
+ }
+
+ ///
+ /// Return the sizeof a struct from a CLR. Equivalent to sizeof operator but works on generics too.
+ ///
+ /// a struct to evaluate
+ /// sizeof this struct
+ internal static int UnsafeSizeOf()
+ {
+ return Interop.SizeOf();
+ }
+
+ ///
+ /// Linq assisted full tree iteration and collection in a single line.
+ /// Warning, could be slow.
+ ///
+ /// The type to iterate.
+ /// The root item
+ /// The function to retrieve a child
+ public static IEnumerable IterateTree( T root, Func> childrenF )
+ {
+ var q = new List { root };
+ while( q.Any() )
+ {
+ var c = q[0];
+ q.RemoveAt( 0 );
+ q.AddRange( childrenF( c ) ?? Enumerable.Empty() );
+ yield return c;
+ }
+ }
+
+ ///
+ /// Converts a raw time to a .
+ ///
+ /// The delta.
+ /// The .
+ public static TimeSpan ConvertRawToTimestamp( long delta )
+ {
+ return new TimeSpan( delta == 0 ? 0 : ( delta * TimeSpan.TicksPerSecond ) / Stopwatch.Frequency );
+ }
+ }
+}
diff --git a/Config.cs b/cfg/Config.cs
similarity index 95%
rename from Config.cs
rename to cfg/Config.cs
index 6af70b3..5dfc0f0 100644
--- a/Config.cs
+++ b/cfg/Config.cs
@@ -1,172 +1,172 @@
-using System;
-using System.IO;
-using System.Xml;
-using System.Reflection;
-
-namespace lib
-{
-
- public class DescAttribute : Attribute
- {
- public string Desc { get; private set; }
-
- public DescAttribute( string desc )
- {
- Desc = desc;
- }
- }
-
- [Serializable]
- public class ConfigCfg : Config
- {
- public readonly bool writeOutTemplateFiles = true;
- }
-
-
-
- [Serializable]
- public class Config
- {
- /*
- static public Config Load( string filename )
- {
- return null;
- }
- */
-
- static ConfigCfg s_cfg = new ConfigCfg();
-
- static public void startup( string filename )
- {
- res.Mgr.register( load );
- res.Mgr.registerSub( typeof( Config ) );
-
- s_cfg = Config.load( filename );
-
- }
-
-
- #region SaveLoad
- /*
- static public res.Ref res_load( string filename )
- {
- return new res.Ref( filename, load( filename ) );
- }
- */
-
- static public T res_load( string filename ) where T : Config
- {
- return 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( $"Exception while creating config {t.ToString()}, Msg {e.Message}" );
- }
-
- //cfg.SetFilename( filename );
-
- if( s_cfg.writeOutTemplateFiles )
- {
- var templateFile = $"templates/{filename}";
-
- var dirName = Path.GetDirectoryName( templateFile );
-
- lib.Util.checkAndAddDirectory( dirName );
-
- lib.Log.info( $"Writing out template config of type {t.Name} in {templateFile}" );
-
- Config.save( cfg, templateFile );
- }
- }
-
- 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; }
-
- }
-}
-
+using System;
+using System.IO;
+using System.Xml;
+using System.Reflection;
+
+namespace lib
+{
+
+ public class DescAttribute : Attribute
+ {
+ public string Desc { get; private set; }
+
+ public DescAttribute( string desc )
+ {
+ Desc = desc;
+ }
+ }
+
+ [Serializable]
+ public class ConfigCfg : Config
+ {
+ public readonly bool writeOutTemplateFiles = true;
+ }
+
+
+
+ [Serializable]
+ public class Config
+ {
+ /*
+ static public Config Load( string filename )
+ {
+ return null;
+ }
+ */
+
+ static ConfigCfg s_cfg = new ConfigCfg();
+
+ static public void startup( string filename )
+ {
+ res.Mgr.register( load );
+ res.Mgr.registerSub( typeof( Config ) );
+
+ s_cfg = Config.load( filename );
+
+ }
+
+
+ #region SaveLoad
+ /*
+ static public res.Ref res_load( string filename )
+ {
+ return new res.Ref( filename, load( filename ) );
+ }
+ */
+
+ static public T res_load( string filename ) where T : Config
+ {
+ return 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( $"Exception while creating config {t.ToString()}, Msg {e.Message}" );
+ }
+
+ //cfg.SetFilename( filename );
+
+ if( s_cfg.writeOutTemplateFiles )
+ {
+ var templateFile = $"templates/{filename}";
+
+ var dirName = Path.GetDirectoryName( templateFile );
+
+ lib.Util.checkAndAddDirectory( dirName );
+
+ lib.Log.info( $"Writing out template config of type {t.Name} in {templateFile}" );
+
+ Config.save( cfg, templateFile );
+ }
+ }
+
+ 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/Imm.cs b/imm/Imm.cs
similarity index 94%
rename from Imm.cs
rename to imm/Imm.cs
index fe30cef..42522bb 100644
--- a/Imm.cs
+++ b/imm/Imm.cs
@@ -1,15 +1,15 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-// A spot for immutable helpers
-
-public static class imm
-{
-
-
-}
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+// A spot for immutable helpers
+
+public static class imm
+{
+
+
+}
diff --git a/Log.cs b/logging/Log.cs
similarity index 100%
rename from Log.cs
rename to logging/Log.cs
diff --git a/Pos.cs b/math/Pos.cs
similarity index 95%
rename from Pos.cs
rename to math/Pos.cs
index a97c97d..a90e61c 100644
--- a/Pos.cs
+++ b/math/Pos.cs
@@ -1,52 +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;
- }
+{
+
+ [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/Conn.cs b/net/Conn.cs
similarity index 94%
rename from Conn.cs
rename to net/Conn.cs
index 442dac0..2ce1f84 100644
--- a/Conn.cs
+++ b/net/Conn.cs
@@ -1,110 +1,110 @@
-using System;
-using System.Runtime.Serialization;
-using System.Runtime.Serialization.Formatters.Binary;
-using System.Net.Sockets;
-using System.IO;
-
-//using Util;
-
-namespace lib
-{
-
-
-
-
- public interface IProcess
- {
- void process( object obj );
- }
-
-
-
-
- public class Conn
- {
- public Socket Sock { get { return m_socket; } }
- public Stream Stream { get { return m_streamNet; } }
-
-
- public Conn( Socket sock, IProcess proc )
- {
- m_socket = sock;
-
- sock.NoDelay = true;
-
- m_streamNet = new NetworkStream( m_socket );
-
- m_proc = proc;
- }
-
- public object recieveObject()
- {
- return recieveObject( Stream );
- }
-
- public object recieveObject( Stream stream )
- {
- object obj = null;
-
- var formatter = new XmlFormatter2();
-
- try
- {
- obj = formatter.Deserialize( stream );
- }
- catch( System.Xml.XmlException ex )
- {
- lib.Log.error( $"Outer Exception {ex.Message}" );
- }
-
- return obj;
- }
-
- public void send( object obj )
- {
-
- var formatter = new XmlFormatter2();
-
- try
- {
- var ms = new MemoryStream( 1024 );
- formatter.Serialize( ms, obj );
-
- //var str = System.Text.Encoding.Default.GetString( mm_buffer, 0, (int)ms.Position );
- //lib.Log.info( $"Sent data {str} of length {ms.Position}" );
- //lib.Log.info( $"Sent {obj}" );
-
- 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 )
- {
- lib.Log.warn( $"Exception sending obj {obj} of {e}" );
- throw;
- }
- }
-
- public virtual void recieve( object obj )
- {
- if( m_proc != null )
- m_proc.process( obj );
- }
-
- Socket m_socket;
-
- NetworkStream m_streamNet;
-
- IProcess m_proc;
-
-
-
- //private BufferedStream m_streamBufIn;
- //private BufferedStream m_streamBufOut;
- }
-
-
-
-}
+using System;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Net.Sockets;
+using System.IO;
+
+//using Util;
+
+namespace lib
+{
+
+
+
+
+ public interface IProcess
+ {
+ void process( object obj );
+ }
+
+
+
+
+ public class Conn
+ {
+ public Socket Sock { get { return m_socket; } }
+ public Stream Stream { get { return m_streamNet; } }
+
+
+ public Conn( Socket sock, IProcess proc )
+ {
+ m_socket = sock;
+
+ sock.NoDelay = true;
+
+ m_streamNet = new NetworkStream( m_socket );
+
+ m_proc = proc;
+ }
+
+ public object recieveObject()
+ {
+ return recieveObject( Stream );
+ }
+
+ public object recieveObject( Stream stream )
+ {
+ object obj = null;
+
+ var formatter = new XmlFormatter2();
+
+ try
+ {
+ obj = formatter.Deserialize( stream );
+ }
+ catch( System.Xml.XmlException ex )
+ {
+ lib.Log.error( $"Outer Exception {ex.Message}" );
+ }
+
+ return obj;
+ }
+
+ public void send( object obj )
+ {
+
+ var formatter = new XmlFormatter2();
+
+ try
+ {
+ var ms = new MemoryStream( 1024 );
+ formatter.Serialize( ms, obj );
+
+ //var str = System.Text.Encoding.Default.GetString( mm_buffer, 0, (int)ms.Position );
+ //lib.Log.info( $"Sent data {str} of length {ms.Position}" );
+ //lib.Log.info( $"Sent {obj}" );
+
+ 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 )
+ {
+ lib.Log.warn( $"Exception sending obj {obj} of {e}" );
+ throw;
+ }
+ }
+
+ public virtual void recieve( object obj )
+ {
+ if( m_proc != null )
+ m_proc.process( obj );
+ }
+
+ Socket m_socket;
+
+ NetworkStream m_streamNet;
+
+ IProcess m_proc;
+
+
+
+ //private BufferedStream m_streamBufIn;
+ //private BufferedStream m_streamBufOut;
+ }
+
+
+
+}
diff --git a/NetMsg.cs b/net/NetMsg.cs
similarity index 97%
rename from NetMsg.cs
rename to net/NetMsg.cs
index 5e77ecb..cb67582 100644
--- a/NetMsg.cs
+++ b/net/NetMsg.cs
@@ -17,8 +17,8 @@ namespace lib.Net
{
m_username = name;
m_password = pass;
- }
-
+ }
+
public readonly String m_username;
public readonly String m_password;
}
@@ -29,23 +29,23 @@ namespace lib.Net
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.
+ //Subclasses of this need to be on an admin client.
[Serializable]
public class Admin
- {
-
+ {
+
};
[Serializable]
public class CreateEntity : Admin
- {
-
+ {
+
}
@@ -53,17 +53,17 @@ namespace lib.Net
public class MoveEntity : Admin
{
- }
+ }
#endregion
-
+
[Serializable]
public class EntityBase
{
public EntityBase( int id )
{
m_id = id;
- }
-
+ }
+
public readonly int m_id;
};
@@ -77,8 +77,8 @@ namespace lib.Net
m_x = x;
m_y = y;
m_z = z;
- }
-
+ }
+
public readonly float m_x;
public readonly float m_y;
public readonly float m_z;
@@ -90,14 +90,14 @@ namespace lib.Net
public EntityDesc( int id ) :
base( id )
{
- }
-
- //Should an entity have a mesh? Be made up of multiple meshes?
- public readonly String m_mesh;
- }
-
-
-
-
-
+ }
+
+ //Should an entity have a mesh? Be made up of multiple meshes?
+ public readonly String m_mesh;
+ }
+
+
+
+
+
}
diff --git a/Scr.cs b/reflect/Scr.cs
similarity index 95%
rename from Scr.cs
rename to reflect/Scr.cs
index c526320..3adcab3 100644
--- a/Scr.cs
+++ b/reflect/Scr.cs
@@ -1,220 +1,220 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-
-
-
-
-
-
-
-
-static public class scr
-{
-
- public class PredEnumerator
- {
- public static PredEnumerator Create( IEnumerator en, Predicate pred )
- {
- return new PredEnumerator( en, pred );
- }
-
- public static PredEnumerator Create( IEnumerable en, Predicate pred )
- {
- return new PredEnumerator( en.GetEnumerator(), pred );
- }
- }
-
- public class PredEnumerator : PredEnumerator, IEnumerator
- {
-
- public T Current => m_en.Current;
-
- object IEnumerator.Current => m_en.Current;
-
- public PredEnumerator( IEnumerator en, Predicate pred )
- {
- m_en = en;
- m_pred = pred;
- }
-
-
- public bool MoveNext()
- {
- var success = m_en.MoveNext();
-
- if( !success )
- return false;
-
- while( !m_pred( m_en.Current ) && ( success = m_en.MoveNext() ) )
- {
-
- }
-
- return success;
- }
-
- public void Reset()
- {
- m_en.Reset();
- }
-
- #region IDisposable Support
- private bool disposedValue = false; // To detect redundant calls
-
- protected virtual void Dispose( bool disposing )
- {
- if( !disposedValue )
- {
- if( disposing )
- {
- // TODO: dispose managed state (managed objects).
- }
-
- // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
- // TODO: set large fields to null.
-
- disposedValue = true;
- }
- }
-
- // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
- // ~MyEnumerator()
- // {
- // // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
- // Dispose(false);
- // }
-
- // This code added to correctly implement the disposable pattern.
- public void Dispose()
- {
- // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
- Dispose( true );
- // TODO: uncomment the following line if the finalizer is overridden above.
- // GC.SuppressFinalize(this);
- }
- #endregion
-
- IEnumerator m_en;
- Predicate m_pred;
- }
-
-
- public class PredEnumerable : IEnumerable
- {
- public PredEnumerable( PredEnumerator en )
- {
- m_en = en;
- }
-
- public IEnumerator GetEnumerator()
- {
- return m_en;
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return m_en;
- }
-
- PredEnumerator m_en;
- }
-
-
- public static void GetAllFields( Type t, List list )
- {
- var fieldArr = t.GetFields(
- BindingFlags.DeclaredOnly |
- BindingFlags.NonPublic |
- BindingFlags.Public |
- BindingFlags.Instance);
-
- var en = PredEnumerator.Create( fieldArr.AsEnumerable(), fa => fa.GetCustomAttribute( typeof( NonSerializedAttribute ) ) == null );
-
- list.AddRange( new PredEnumerable( en ) );
-
- if( t.BaseType != null && t.BaseType != typeof( object ) )
- {
- GetAllFields( t.BaseType, list );
- }
- }
-
-
- public static ImmutableList GetAllFields( Type t )
- {
- if( s_fieldCache.TryGetValue( t, out var info ) )
- return info;
-
- var list = new List();
-
- GetAllFields( t, list );
-
- var immList = list.ToImmutableList();
-
- s_fieldCache = s_fieldCache.Add( t, immList );
-
- return immList;
- }
-
-
- public static void GetAllProperties( Type t, List list )
- {
- var propArr = t.GetProperties(
- BindingFlags.DeclaredOnly |
- BindingFlags.NonPublic |
- BindingFlags.Public |
- BindingFlags.Instance
- );
-
-
-
- var en = PredEnumerator.Create( propArr.AsEnumerable(),
- fa => fa.GetCustomAttribute( typeof( NonSerializedAttribute ) ) == null && !list.Exists( f => f.Name == fa.Name ) );
-
- list.AddRange( new PredEnumerable( en ) );
-
- if( t.BaseType != null && t.BaseType != typeof( object ) )
- {
- GetAllProperties( t.BaseType, list );
- }
- }
-
- public static ImmutableList GetAllProperties( Type t )
- {
- if( s_propCache.TryGetValue( t, out var info ) )
- return info;
-
- var list = new List();
-
- GetAllProperties( t, list );
-
- var immList = list.ToImmutableList();
-
- s_propCache = s_propCache.Add( t, immList );
-
- return immList;
- }
-
-
- static ImmutableDictionary> s_fieldCache = ImmutableDictionary>.Empty;
- static ImmutableDictionary> s_propCache = ImmutableDictionary>.Empty;
-
-
-
-
- //SLOW
- static public string TypeToIdentifier( string typename )
- {
- return typename.Replace( '<', '_' ).Replace( '>', '_' ).Replace( ',', '_' ).Replace( ' ', '_' ).Replace( '.', '_' ).Replace( '+', '_' ).Replace( '[', '_' ).Replace( ']', '_' ).Replace( '$', '_' ).Replace( ':', '_' );
- }
-
-
-
-
-
-}
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+
+
+
+
+
+
+
+static public class scr
+{
+
+ public class PredEnumerator
+ {
+ public static PredEnumerator Create( IEnumerator en, Predicate pred )
+ {
+ return new PredEnumerator( en, pred );
+ }
+
+ public static PredEnumerator Create( IEnumerable en, Predicate pred )
+ {
+ return new PredEnumerator( en.GetEnumerator(), pred );
+ }
+ }
+
+ public class PredEnumerator : PredEnumerator, IEnumerator
+ {
+
+ public T Current => m_en.Current;
+
+ object IEnumerator.Current => m_en.Current;
+
+ public PredEnumerator( IEnumerator en, Predicate pred )
+ {
+ m_en = en;
+ m_pred = pred;
+ }
+
+
+ public bool MoveNext()
+ {
+ var success = m_en.MoveNext();
+
+ if( !success )
+ return false;
+
+ while( !m_pred( m_en.Current ) && ( success = m_en.MoveNext() ) )
+ {
+
+ }
+
+ return success;
+ }
+
+ public void Reset()
+ {
+ m_en.Reset();
+ }
+
+ #region IDisposable Support
+ private bool disposedValue = false; // To detect redundant calls
+
+ protected virtual void Dispose( bool disposing )
+ {
+ if( !disposedValue )
+ {
+ if( disposing )
+ {
+ // TODO: dispose managed state (managed objects).
+ }
+
+ // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
+ // TODO: set large fields to null.
+
+ disposedValue = true;
+ }
+ }
+
+ // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
+ // ~MyEnumerator()
+ // {
+ // // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
+ // Dispose(false);
+ // }
+
+ // This code added to correctly implement the disposable pattern.
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
+ Dispose( true );
+ // TODO: uncomment the following line if the finalizer is overridden above.
+ // GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ IEnumerator m_en;
+ Predicate m_pred;
+ }
+
+
+ public class PredEnumerable : IEnumerable
+ {
+ public PredEnumerable( PredEnumerator en )
+ {
+ m_en = en;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return m_en;
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return m_en;
+ }
+
+ PredEnumerator m_en;
+ }
+
+
+ public static void GetAllFields( Type t, List list )
+ {
+ var fieldArr = t.GetFields(
+ BindingFlags.DeclaredOnly |
+ BindingFlags.NonPublic |
+ BindingFlags.Public |
+ BindingFlags.Instance);
+
+ var en = PredEnumerator.Create( fieldArr.AsEnumerable(), fa => fa.GetCustomAttribute( typeof( NonSerializedAttribute ) ) == null );
+
+ list.AddRange( new PredEnumerable( en ) );
+
+ if( t.BaseType != null && t.BaseType != typeof( object ) )
+ {
+ GetAllFields( t.BaseType, list );
+ }
+ }
+
+
+ public static ImmutableList GetAllFields( Type t )
+ {
+ if( s_fieldCache.TryGetValue( t, out var info ) )
+ return info;
+
+ var list = new List();
+
+ GetAllFields( t, list );
+
+ var immList = list.ToImmutableList();
+
+ s_fieldCache = s_fieldCache.Add( t, immList );
+
+ return immList;
+ }
+
+
+ public static void GetAllProperties( Type t, List list )
+ {
+ var propArr = t.GetProperties(
+ BindingFlags.DeclaredOnly |
+ BindingFlags.NonPublic |
+ BindingFlags.Public |
+ BindingFlags.Instance
+ );
+
+
+
+ var en = PredEnumerator.Create( propArr.AsEnumerable(),
+ fa => fa.GetCustomAttribute( typeof( NonSerializedAttribute ) ) == null && !list.Exists( f => f.Name == fa.Name ) );
+
+ list.AddRange( new PredEnumerable( en ) );
+
+ if( t.BaseType != null && t.BaseType != typeof( object ) )
+ {
+ GetAllProperties( t.BaseType, list );
+ }
+ }
+
+ public static ImmutableList GetAllProperties( Type t )
+ {
+ if( s_propCache.TryGetValue( t, out var info ) )
+ return info;
+
+ var list = new List();
+
+ GetAllProperties( t, list );
+
+ var immList = list.ToImmutableList();
+
+ s_propCache = s_propCache.Add( t, immList );
+
+ return immList;
+ }
+
+
+ static ImmutableDictionary> s_fieldCache = ImmutableDictionary>.Empty;
+ static ImmutableDictionary> s_propCache = ImmutableDictionary>.Empty;
+
+
+
+
+ //SLOW
+ static public string TypeToIdentifier( string typename )
+ {
+ return typename.Replace( '<', '_' ).Replace( '>', '_' ).Replace( ',', '_' ).Replace( ' ', '_' ).Replace( '.', '_' ).Replace( '+', '_' ).Replace( '[', '_' ).Replace( ']', '_' ).Replace( '$', '_' ).Replace( ':', '_' );
+ }
+
+
+
+
+
+}
diff --git a/SerializableDictionary.cs b/ser/SerializableDictionary.cs
similarity index 96%
rename from SerializableDictionary.cs
rename to ser/SerializableDictionary.cs
index 229453d..8873863 100644
--- a/SerializableDictionary.cs
+++ b/ser/SerializableDictionary.cs
@@ -9,157 +9,157 @@ using System.IO;
using System.Security.Permissions;
namespace lib
-{
- [Serializable]
- public class SerializableDictionary : Dictionary, IXmlSerializable, ISerializable
- {
+{
+ [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";
+ 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 )
- {
- }
-
+ 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{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{itemIdx}" ), kvp, typeof( KeyValuePair ) );
- itemIdx++;
- }
- }
-
+
+ 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{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{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;
- }
-
+
+ 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;
- }
- }
+ 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;
+ private XmlSerializer keySerializer = null;
+ private XmlSerializer valueSerializer = null;
#endregion
}
}
diff --git a/VersionFormatter.cs b/ser/VersionFormatter.cs
similarity index 94%
rename from VersionFormatter.cs
rename to ser/VersionFormatter.cs
index 85883fd..bde4613 100644
--- a/VersionFormatter.cs
+++ b/ser/VersionFormatter.cs
@@ -1,677 +1,677 @@
-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 < length; ++i )
- {
- int val = reader.ReadInt32();
-
- //m_fixups[ val ] = new Fixup( obj, fi );
-
- if( fi != null )
- {
- m_fixupList.Add( new Fixup( val, array, i ) );
- }
- }
- }
-
- void readRef( BinaryReader reader, object obj, FieldInfo fi )
- {
- int val = reader.ReadInt32();
-
- //m_fixups[ val ] = new Fixup( obj, fi );
-
- m_fixupList.Add( new Fixup( val, obj, fi ) );
- }
-
- void readInt( BinaryReader reader, object obj, FieldInfo fi )
- {
- int val = reader.ReadInt32();
-
- if( fi == null )
- return;
-
- if( !fi.FieldType.IsEnum )
- {
- fi.SetValue( obj, val );
- }
- else
- {
- object enumVal = Enum.Parse( fi.FieldType, val.ToString() );
- fi.SetValue( obj, Convert.ChangeType( enumVal, fi.FieldType ) );
- }
-
- }
-
- void readSingle( BinaryReader reader, object obj, FieldInfo fi )
- {
- float val = reader.ReadSingle();
-
- if( fi == null )
- return;
-
- fi.SetValue( obj, val );
- }
-
- void readDouble( BinaryReader reader, object obj, FieldInfo fi )
- {
- double val = reader.ReadDouble();
-
- if( fi == null )
- return;
-
- fi.SetValue( obj, val );
- }
-
- void readChar( BinaryReader reader, object obj, FieldInfo fi )
- {
- char val = reader.ReadChar();
-
- if( fi == null )
- return;
-
- fi.SetValue( obj, val );
- }
-
- void readString( BinaryReader reader, object obj, FieldInfo fi )
- {
- string val = reader.ReadString();
-
- if( fi == null )
- return;
-
- fi.SetValue( obj, val );
- }
-
- void readBool( BinaryReader reader, object obj, FieldInfo fi )
- {
- bool val = reader.ReadBoolean();
-
- if( fi == null )
- return;
-
- fi.SetValue( obj, val );
- }
-
- #endregion Deserialize
-
-
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+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 < length; ++i )
+ {
+ int val = reader.ReadInt32();
+
+ //m_fixups[ val ] = new Fixup( obj, fi );
+
+ if( fi != null )
+ {
+ m_fixupList.Add( new Fixup( val, array, i ) );
+ }
+ }
+ }
+
+ void readRef( BinaryReader reader, object obj, FieldInfo fi )
+ {
+ int val = reader.ReadInt32();
+
+ //m_fixups[ val ] = new Fixup( obj, fi );
+
+ m_fixupList.Add( new Fixup( val, obj, fi ) );
+ }
+
+ void readInt( BinaryReader reader, object obj, FieldInfo fi )
+ {
+ int val = reader.ReadInt32();
+
+ if( fi == null )
+ return;
+
+ if( !fi.FieldType.IsEnum )
+ {
+ fi.SetValue( obj, val );
+ }
+ else
+ {
+ object enumVal = Enum.Parse( fi.FieldType, val.ToString() );
+ fi.SetValue( obj, Convert.ChangeType( enumVal, fi.FieldType ) );
+ }
+
+ }
+
+ void readSingle( BinaryReader reader, object obj, FieldInfo fi )
+ {
+ float val = reader.ReadSingle();
+
+ if( fi == null )
+ return;
+
+ fi.SetValue( obj, val );
+ }
+
+ void readDouble( BinaryReader reader, object obj, FieldInfo fi )
+ {
+ double val = reader.ReadDouble();
+
+ if( fi == null )
+ return;
+
+ fi.SetValue( obj, val );
+ }
+
+ void readChar( BinaryReader reader, object obj, FieldInfo fi )
+ {
+ char val = reader.ReadChar();
+
+ if( fi == null )
+ return;
+
+ fi.SetValue( obj, val );
+ }
+
+ void readString( BinaryReader reader, object obj, FieldInfo fi )
+ {
+ string val = reader.ReadString();
+
+ if( fi == null )
+ return;
+
+ fi.SetValue( obj, val );
+ }
+
+ void readBool( BinaryReader reader, object obj, FieldInfo fi )
+ {
+ bool val = reader.ReadBoolean();
+
+ if( fi == null )
+ return;
+
+ fi.SetValue( obj, val );
+ }
+
+ #endregion Deserialize
+
+
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XmlFormatter.cs b/ser/XmlFormatter.cs
similarity index 96%
rename from XmlFormatter.cs
rename to ser/XmlFormatter.cs
index 371b8ca..310b083 100644
--- a/XmlFormatter.cs
+++ b/ser/XmlFormatter.cs
@@ -7,28 +7,28 @@ using System.Collections;
using System.Collections.Generic;
-using System.Reflection;
-//using System.Collections;
-//using System.Diagnostics;
-//using System.Globalization;
-//using System.ComponentModel;
-
-
+using System.Reflection;
+//using System.Collections;
+//using System.Diagnostics;
+//using System.Globalization;
+//using System.ComponentModel;
+
+
namespace lib
-{
- //Old, use 2 now.
+{
+ //Old, use 2 now.
class XmlFormatter : IFormatter
{
StreamingContext m_context;
- //SerializationMode m_mode;
- //KnownTypeCollection known_types;
- //IDataContractSurrogate m_surrogate;
- //int m_maxItems;
-
+ //SerializationMode m_mode;
+ //KnownTypeCollection known_types;
+ //IDataContractSurrogate m_surrogate;
+ //int m_maxItems;
+
public XmlFormatter()
{
}
-
+
/*
public XmlFormatter( SerializationMode mode )
{
@@ -45,33 +45,33 @@ namespace lib
{
m_mode = mode;
m_context = context;
- }
- */
-
- //public XmlFormatter (SerializationMode mode,
- // StreamingContext context, KnownTypeCollection knownTypes)
- //{
- //}
-
- SerializationBinder IFormatter.Binder
+ }
+ */
+
+ //public XmlFormatter (SerializationMode mode,
+ // StreamingContext context, KnownTypeCollection knownTypes)
+ //{
+ //}
+
+ SerializationBinder IFormatter.Binder
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
- ISurrogateSelector IFormatter.SurrogateSelector
+ ISurrogateSelector IFormatter.SurrogateSelector
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
- public StreamingContext Context
+ public StreamingContext Context
{
get { return m_context; }
set { m_context = value; }
}
-
+
/*
public KnownTypeCollection KnownTypes {
get { return known_types; }
@@ -81,8 +81,8 @@ namespace lib
get { return m_maxItems; }
set { m_maxItems= value; }
}
- */
-
+ */
+
object IFormatter.Deserialize( Stream stream )
{
@@ -142,9 +142,9 @@ namespace lib
MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type );
- object obj = Activator.CreateInstance( type );
-
-
+ object obj = Activator.CreateInstance( type );
+
+
/*
object obj = FormatterServices.GetUninitializedObject( type );
@@ -157,8 +157,8 @@ namespace lib
return null;
obj = ci.Invoke( null );
- */
-
+ */
+
for( int i = 0; i < miArr.Length; ++i )
{
FieldInfo fi = (FieldInfo)miArr[ i ];
@@ -198,9 +198,9 @@ namespace lib
}
}
else
- {
- //FormatterServices.GetUninitializedObject()
-
+ {
+ //FormatterServices.GetUninitializedObject()
+
int length = s_conv.ToInt32( child.GetAttribute( "c" ) );
string elemType = child.GetAttribute( "t" );
@@ -223,28 +223,28 @@ namespace lib
else
{
if( nodeList.Count == 0 )
- {
- // Should be
-
- //object obj2 = fi.GetRawConstantValue();
+ {
+ // Should be
+
+ //object obj2 = fi.GetRawConstantValue();
}
- else //More than 1.
- {
- //Log.error( "Too many fields named the same thing" );
+ 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 );
-
+ }
+
+ //FieldInfo fi = (FieldInfo)miArr[0];
+
+ //ConstructorInfo ci = fi.FieldType.TypeInitializer;
+
+ //ci.Invoke( null );
+
return obj;
- }
-
-
+ }
+
+
/*
public T Deserialize (Stream stream)
{
@@ -260,18 +260,18 @@ namespace lib
{
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;
@@ -291,10 +291,10 @@ namespace lib
bool writeContentOnly,
bool ignoreUnknownSerializationData )
{
- Type t = graph.GetType();
-
- //writer.WriteStartDocument();
-
+ Type t = graph.GetType();
+
+ //writer.WriteStartDocument();
+
if( Type.GetTypeCode( t ) == TypeCode.Object )
{
writer.WriteStartElement( "root" );
@@ -309,8 +309,8 @@ namespace lib
foreach( FieldInfo fi in fiArr )
{
- Serialize( writer, fi.Name, fi.GetValue( graph ) );
-
+ Serialize( writer, fi.Name, fi.GetValue( graph ) );
+
/*
if( fi.FieldType.IsClass )
{
@@ -320,13 +320,13 @@ namespace lib
{
SerializePod( writer, fi.GetValue( graph ) );
}
- */
+ */
}
writer.WriteEndElement();
- }
-
- //writer.WriteEndDocument();
+ }
+
+ //writer.WriteEndDocument();
}
private ObjectIDGenerator m_idGenerator = new ObjectIDGenerator();
@@ -379,14 +379,14 @@ namespace lib
for( int i = 0; i < arr.Length; ++i )
{
Serialize( writer, "val", arr.GetValue( i ) );
- }
-
- //writer.WriteStartElement( "values" );
-
-
-
- //writer.WriteEndElement();
-
+ }
+
+ //writer.WriteStartElement( "values" );
+
+
+
+ //writer.WriteEndElement();
+
}
}
else
@@ -410,685 +410,685 @@ namespace lib
}
}
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*
-///
-///
-///
-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
+///
+///
+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 )
- {
- 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 Type[] mm_consType = new Type[ 2 ];
- private object[] mm_args = new object[ 2 ];
- 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( finalType, new FormatterConverter() );
-
- //var serInfoForTypes = new SerializationInfo( type, new FormatterConverter() );
-
- //ser.GetObjectData( serInfoForTypes, Context );
-
- foreach( var objNode in allChildren )
- {
- var node = objNode as XmlElement;
-
- String name = node.Name;
-
- String childType = node.GetAttribute( "t" );
-
- name = scr.TypeToIdentifier( name );
-
- XmlElement childElem = getNamedChild( allChildren, name );
-
- var des = Deserialize( childElem, childType );
-
- serInfo.AddValue( name, des, des.GetType() );
- }
-
- //ConstructorInfo[] allCons = obj.GetType().GetConstructors( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
-
- //var serMem = FormatterServices.GetSerializableMembers( finalType );
-
- //object objUn = FormatterServices.GetSafeUninitializedObject( finalType );
-
- IDeserializationCallback objUnOnDeser = obj as IDeserializationCallback;
-
- mm_consType[0] = typeof( SerializationInfo );
- mm_consType[1] = typeof( StreamingContext );
- ConstructorInfo serCons = finalType.GetConstructor( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, mm_consType, null );
-
- mm_args[0] = serInfo;
- mm_args[1] = Context;
- serCons.Invoke( obj, mm_args );
-
- if( objUnOnDeser != null )
- {
- objUnOnDeser.OnDeserialization( objUnOnDeser );
- }
-
- /*
- ser.GetObjectData( serInfo, Context );
-
- //var serEnum = ;
-
- foreach( var serMember in serInfo )
- {
- String name = serMember.Name;
-
- name = scr.TypeToIdentifier( name );
-
- XmlElement childElem = getNamedChild( allChildren, name );
-
- var des = Deserialize( childElem, name );
- }
- */
- }
- else
- {
- XmlNodeList allChildren = elem.ChildNodes;
-
- var fields = scr.GetAllFields( type );
-
- //MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type, Context );
-
- foreach( var childFi in fields )
- {
-
- String name = childFi.Name;
-
- name = scr.TypeToIdentifier( name );
-
- XmlElement childElem = getNamedChild( allChildren, name );
-
-
- if( childElem != null )
- {
- object childObj = Deserialize( childElem, childFi.FieldType, obj );
-
- childFi.SetValue( obj, childObj );
- }
- else if( fields.Count == 1 )
- {
- object childObj = Deserialize( elem, 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( m_cfg.datastructure == Datastructure.Full && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
- {
- //lib.log.info( "Reusing object for {0}", refInt );
- return m_alreadySerialized[refInt];
- }
- else
- {
- object obj = null;
-
- try
- {
- //Trying the nice way to creat objects first.
- obj = Activator.CreateInstance( type );
-
- }
- catch( Exception )
- {
- try
- {
- obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
- }
- catch( Exception exInner )
- {
- lib.Log.error( $"Got exception {exInner.Message} trying to make an uninitialized object" );
- }
-
- }
-
- if( obj == null )
- {
- lib.Log.warn( $"Could not create object of type {type.Name}" );
-
- return obj;
- }
-
- if( m_cfg.datastructure == Datastructure.Full && refInt > 0 )
- {
- m_alreadySerialized[refInt] = obj;
- }
-
- return obj;
- }
- }
-
- 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( m_cfg.datastructure == Datastructure.Full && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
- {
- return (Array)m_alreadySerialized[refInt];
- }
- else
- {
- Array arr = Array.CreateInstance( elemType, length ) ;
-
- if( m_cfg.datastructure == Datastructure.Full )
- {
- 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", true );
- //writer.WriteEndDocument();
- }
-
- private void Serialize( XmlWriter writer, object root, string name, bool forceType )
- {
- writer.WriteStartElement( name );
-
- if( root != null )
- {
- Type type = root.GetType();
-
- TypeCode typeCode = Type.GetTypeCode( type );
-
- if( typeCode != TypeCode.Object )
- {
- SerializeConcrete( writer, root, forceType );
- }
- 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, bool forceType )
- {
- //TODO: Only write this out if debugging.
- if( forceType )
- {
- 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 );
-
- if( m_cfg.datastructure == Datastructure.Full )
- {
- writer.WriteAttributeString( "ref", refInt.ToString() );
-
- }
-
- if( first )
- {
- if( m_cfg.datastructure == Datastructure.Full )
- {
- 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 = scr.TypeToIdentifier( name );
-
- Serialize( writer, serMember.Value, name, true );
- }
-
- //var sc = new SerializationContext(
-
- //ser.GetObjectData(
- }
- else
- //*/
- {
- var fields = scr.GetAllFields( type );
-
- //MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type, Context );
-
- foreach( var childFi in fields )
- {
-
- object[] objs = childFi.GetCustomAttributes( typeof( NonSerializedAttribute ), true );
-
- if( objs.Length > 0 )
- {
- continue;
- }
-
- String name = childFi.Name;
-
- name = scr.TypeToIdentifier( name );
-
- Serialize( writer, childFi.GetValue( root ), name, false );
- }
- }
- }
- }
-
- private void SerializeArray( XmlWriter writer, object root )
- {
- Array arr = (Array)root;
-
- Type typeElem = arr.GetType().GetElementType();
-
- Type type = root.GetType();
-
- writer.WriteAttributeString( "t", getTypeName( type ) );
-
- bool first;
-
- long refInt = m_objectID.GetId( root, out first );
-
- if( m_cfg.datastructure == Datastructure.Full )
- {
- writer.WriteAttributeString( "ref", refInt.ToString() );
- }
-
- if( first )
- {
- if( m_cfg.datastructure == Datastructure.Full )
- {
- m_alreadySerialized[refInt] = root;
- }
-
-
- for( int i = 0; i < arr.Length; ++i )
- {
- Serialize( writer, arr.GetValue( i ), "i" + i.ToString(), false );
- }
- }
- }
- #endregion
- }
-
-}
+using System;
+using System.IO;
+using System.Xml;
+using System.Runtime.Serialization;
+//using System.Web.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+
+
+using System.Reflection;
+using System.Diagnostics;
+
+using System.Runtime.InteropServices;
+
+namespace lib
+{
+
+ public interface I_Serialize
+ {
+ void OnSerialize();
+ void OnDeserialize( object enclosing );
+ }
+
+ public enum Datastructure
+ {
+ Invalid,
+ Tree,
+ Full,
+
+ }
+
+ public class XmlFormatter2Cfg : Config
+ {
+ public readonly Datastructure datastructure = Datastructure.Full;
+ }
+
+ public class XmlFormatter2 : IFormatter
+ {
+ public StreamingContext Context { get; set; }
+
+ static Random s_rnd = new Random();
+ int m_rndVal = s_rnd.Next();
+
+ XmlFormatter2Cfg m_cfg = new XmlFormatter2Cfg();
+
+
+
+ #region Unimplimented
+ public ISurrogateSelector SurrogateSelector
+ {
+ get { throw new NotImplementedException(); }
+ set { throw new NotImplementedException(); }
+ }
+
+ public SerializationBinder Binder
+ {
+ get { throw new NotImplementedException(); }
+ set { throw new NotImplementedException(); }
+ }
+ #endregion
+
+
+
+
+
+
+ public XmlFormatter2()
+ {
+ Context = new StreamingContext( StreamingContextStates.All );
+ }
+
+
+
+
+ public XmlFormatter2( XmlFormatter2Cfg cfg )
+ {
+ Context = new StreamingContext( StreamingContextStates.All );
+
+ m_cfg = cfg;
+ }
+
+
+
+ #region Deserialize
+ private static FormatterConverter s_conv = new FormatterConverter();
+
+ public object Deserialize( Stream stream )
+ {
+ //lib.log.info( "Deserialize( Stream stream ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
+ return DeserializeKnownType( stream, null );
+ //lib.log.info( "Deserialize END ( Stream stream ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
+ }
+
+ public object DeserializeKnownType( Stream stream, Type t )
+ {
+ //lib.log.info( "DeserializeKnownType( Stream stream, Type t ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
+
+ XmlTextReader reader = new XmlTextReader( stream );
+ //reader.Settings = System.Text.Encoding.ASCII;
+
+ object obj = Deserialize( reader, t );
+ //lib.log.info( "DeserializeKnownType END( Stream stream, Type t ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
+ return obj;
+ }
+
+ private object Deserialize( XmlReader reader, Type t )
+ {
+ //lib.log.info( "Deserialize( XmlReader reader, Type t ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
+
+ m_alreadySerialized.Clear();
+ m_objectID = new ObjectIDGenerator();
+
+ reader.Read();
+
+ XmlDocument doc = new XmlDocument();
+
+ doc.Load( reader );
+
+ ////lib.log.info( "What to deserialize {0}", doc.OuterXml.ToString() );
+
+ if( t == null )
+ return Deserialize( doc.DocumentElement );
+
+ return Deserialize( doc.DocumentElement, t );
+ }
+
+ private object Deserialize( XmlElement elem )
+ {
+ //lib.log.info( "object Deserialize( XmlElement elem ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
+
+ string typename = elem.HasAttribute( "t" ) ? elem.GetAttribute( "t" ) : elem.Name;
+
+ return Deserialize( elem, typename );
+ }
+
+ private object Deserialize( XmlElement elem, string typename )
+ {
+ AppDomain currentDomain = AppDomain.CurrentDomain;
+ Assembly[] assems = currentDomain.GetAssemblies();
+
+ Type type = null;
+
+ // @@@@: This should go backwards, we tend to lookup our own stuff, then builtins.
+ // Also, cache a typename into its assembly.
+ foreach( Assembly a in assems )
+ {
+ type = a.GetType( typename );
+
+ if( type != null )
+ break;
+ }
+
+ if( type == null )
+ {
+ return null;
+ }
+
+ return Deserialize( elem, type );
+ }
+
+ private object Deserialize( XmlElement elem, Type type, object enclosing = null )
+ {
+ TypeCode typeCode = Type.GetTypeCode( type );
+
+ if( typeCode != TypeCode.Object )
+ {
+ return DeserializeConcrete( elem, type );
+ }
+ else
+ {
+ if( !type.IsArray )
+ {
+ object obj = DeserializeObject( elem, type );
+
+ if( obj is I_Serialize )
+ {
+ var iser = obj as I_Serialize;
+
+ iser.OnDeserialize( enclosing );
+ }
+
+ return obj;
+ }
+ else
+ {
+ return DeserializeArray( elem, type );
+ }
+ }
+ }
+
+ Type[] mm_types = new Type[1];
+ private object GetDefault( Type t )
+ {
+ mm_types[0] = t;
+
+ var fn = GetType().GetMethod( "GetDefaultGeneric" ).MakeGenericMethod( mm_types );
+
+ return fn.Invoke( this, null );
+ }
+
+ public T GetDefaultGeneric()
+ {
+ 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 )
+ {
+ 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 Type[] mm_consType = new Type[ 2 ];
+ private object[] mm_args = new object[ 2 ];
+ 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( finalType, new FormatterConverter() );
+
+ //var serInfoForTypes = new SerializationInfo( type, new FormatterConverter() );
+
+ //ser.GetObjectData( serInfoForTypes, Context );
+
+ foreach( var objNode in allChildren )
+ {
+ var node = objNode as XmlElement;
+
+ String name = node.Name;
+
+ String childType = node.GetAttribute( "t" );
+
+ name = scr.TypeToIdentifier( name );
+
+ XmlElement childElem = getNamedChild( allChildren, name );
+
+ var des = Deserialize( childElem, childType );
+
+ serInfo.AddValue( name, des, des.GetType() );
+ }
+
+ //ConstructorInfo[] allCons = obj.GetType().GetConstructors( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
+
+ //var serMem = FormatterServices.GetSerializableMembers( finalType );
+
+ //object objUn = FormatterServices.GetSafeUninitializedObject( finalType );
+
+ IDeserializationCallback objUnOnDeser = obj as IDeserializationCallback;
+
+ mm_consType[0] = typeof( SerializationInfo );
+ mm_consType[1] = typeof( StreamingContext );
+ ConstructorInfo serCons = finalType.GetConstructor( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, mm_consType, null );
+
+ mm_args[0] = serInfo;
+ mm_args[1] = Context;
+ serCons.Invoke( obj, mm_args );
+
+ if( objUnOnDeser != null )
+ {
+ objUnOnDeser.OnDeserialization( objUnOnDeser );
+ }
+
+ /*
+ ser.GetObjectData( serInfo, Context );
+
+ //var serEnum = ;
+
+ foreach( var serMember in serInfo )
+ {
+ String name = serMember.Name;
+
+ name = scr.TypeToIdentifier( name );
+
+ XmlElement childElem = getNamedChild( allChildren, name );
+
+ var des = Deserialize( childElem, name );
+ }
+ */
+ }
+ else
+ {
+ XmlNodeList allChildren = elem.ChildNodes;
+
+ var fields = scr.GetAllFields( type );
+
+ //MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type, Context );
+
+ foreach( var childFi in fields )
+ {
+
+ String name = childFi.Name;
+
+ name = scr.TypeToIdentifier( name );
+
+ XmlElement childElem = getNamedChild( allChildren, name );
+
+
+ if( childElem != null )
+ {
+ object childObj = Deserialize( childElem, childFi.FieldType, obj );
+
+ childFi.SetValue( obj, childObj );
+ }
+ else if( fields.Count == 1 )
+ {
+ object childObj = Deserialize( elem, 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( m_cfg.datastructure == Datastructure.Full && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
+ {
+ //lib.log.info( "Reusing object for {0}", refInt );
+ return m_alreadySerialized[refInt];
+ }
+ else
+ {
+ object obj = null;
+
+ try
+ {
+ //Trying the nice way to creat objects first.
+ obj = Activator.CreateInstance( type );
+
+ }
+ catch( Exception )
+ {
+ try
+ {
+ obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject( type );
+ }
+ catch( Exception exInner )
+ {
+ lib.Log.error( $"Got exception {exInner.Message} trying to make an uninitialized object" );
+ }
+
+ }
+
+ if( obj == null )
+ {
+ lib.Log.warn( $"Could not create object of type {type.Name}" );
+
+ return obj;
+ }
+
+ if( m_cfg.datastructure == Datastructure.Full && refInt > 0 )
+ {
+ m_alreadySerialized[refInt] = obj;
+ }
+
+ return obj;
+ }
+ }
+
+ 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( m_cfg.datastructure == Datastructure.Full && refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
+ {
+ return (Array)m_alreadySerialized[refInt];
+ }
+ else
+ {
+ Array arr = Array.CreateInstance( elemType, length ) ;
+
+ if( m_cfg.datastructure == Datastructure.Full )
+ {
+ 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", true );
+ //writer.WriteEndDocument();
+ }
+
+ private void Serialize( XmlWriter writer, object root, string name, bool forceType )
+ {
+ writer.WriteStartElement( name );
+
+ if( root != null )
+ {
+ Type type = root.GetType();
+
+ TypeCode typeCode = Type.GetTypeCode( type );
+
+ if( typeCode != TypeCode.Object )
+ {
+ SerializeConcrete( writer, root, forceType );
+ }
+ 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, bool forceType )
+ {
+ //TODO: Only write this out if debugging.
+ if( forceType )
+ {
+ 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 );
+
+ if( m_cfg.datastructure == Datastructure.Full )
+ {
+ writer.WriteAttributeString( "ref", refInt.ToString() );
+
+ }
+
+ if( first )
+ {
+ if( m_cfg.datastructure == Datastructure.Full )
+ {
+ 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 = scr.TypeToIdentifier( name );
+
+ Serialize( writer, serMember.Value, name, true );
+ }
+
+ //var sc = new SerializationContext(
+
+ //ser.GetObjectData(
+ }
+ else
+ //*/
+ {
+ var fields = scr.GetAllFields( type );
+
+ //MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type, Context );
+
+ foreach( var childFi in fields )
+ {
+
+ object[] objs = childFi.GetCustomAttributes( typeof( NonSerializedAttribute ), true );
+
+ if( objs.Length > 0 )
+ {
+ continue;
+ }
+
+ String name = childFi.Name;
+
+ name = scr.TypeToIdentifier( name );
+
+ Serialize( writer, childFi.GetValue( root ), name, false );
+ }
+ }
+ }
+ }
+
+ private void SerializeArray( XmlWriter writer, object root )
+ {
+ Array arr = (Array)root;
+
+ Type typeElem = arr.GetType().GetElementType();
+
+ Type type = root.GetType();
+
+ writer.WriteAttributeString( "t", getTypeName( type ) );
+
+ bool first;
+
+ long refInt = m_objectID.GetId( root, out first );
+
+ if( m_cfg.datastructure == Datastructure.Full )
+ {
+ writer.WriteAttributeString( "ref", refInt.ToString() );
+ }
+
+ if( first )
+ {
+ if( m_cfg.datastructure == Datastructure.Full )
+ {
+ m_alreadySerialized[refInt] = root;
+ }
+
+
+ for( int i = 0; i < arr.Length; ++i )
+ {
+ Serialize( writer, arr.GetValue( i ), "i" + i.ToString(), false );
+ }
+ }
+ }
+ #endregion
+ }
+
+}
diff --git a/Clock.cs b/time/Clock.cs
similarity index 94%
rename from Clock.cs
rename to time/Clock.cs
index 8ce82aa..caa86e8 100644
--- a/Clock.cs
+++ b/time/Clock.cs
@@ -1,52 +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;
-
- }
-}
+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/Timer.cs b/time/Timer.cs
similarity index 95%
rename from Timer.cs
rename to time/Timer.cs
index 0c6ee33..4f4cf73 100644
--- a/Timer.cs
+++ b/time/Timer.cs
@@ -1,377 +1,377 @@
-using System;
-using System.Runtime.InteropServices;
-using System.ComponentModel;
-using System.Threading;
-
-namespace lib
-{
-
- public class MicroStopwatch : System.Diagnostics.Stopwatch
- {
- readonly double _microSecPerTick
- = 1000000D / System.Diagnostics.Stopwatch.Frequency;
-
- public MicroStopwatch()
- {
- if( !System.Diagnostics.Stopwatch.IsHighResolution )
- {
- throw new Exception( "On this system the high-resolution " +
- "performance counter is not available" );
- }
- }
-
- public long ElapsedMicroseconds
- {
- get
- {
- return (long)( ElapsedTicks * _microSecPerTick );
- }
- }
- }
-
- ///
- /// MicroTimer class
- ///
- public class MicroTimer
- {
- public delegate void MicroTimerElapsedEventHandler(
- object sender,
- MicroTimerEventArgs timerEventArgs );
- public event MicroTimerElapsedEventHandler MicroTimerElapsed;
-
- System.Threading.Thread _threadTimer = null;
- long _ignoreEventIfLateBy = long.MaxValue;
- long _timerIntervalInMicroSec = 0;
- bool _stopTimer = true;
-
- public MicroTimer()
- {
- }
-
- public MicroTimer( long timerIntervalInMicroseconds )
- {
- Interval = timerIntervalInMicroseconds;
- }
-
- public long Interval
- {
- get
- {
- return System.Threading.Interlocked.Read(
- ref _timerIntervalInMicroSec );
- }
- set
- {
- System.Threading.Interlocked.Exchange(
- ref _timerIntervalInMicroSec, value );
- }
- }
-
- public long IgnoreEventIfLateBy
- {
- get
- {
- return System.Threading.Interlocked.Read(
- ref _ignoreEventIfLateBy );
- }
- set
- {
- System.Threading.Interlocked.Exchange(
- ref _ignoreEventIfLateBy, value <= 0 ? long.MaxValue : value );
- }
- }
-
- public bool Enabled
- {
- set
- {
- if( value )
- {
- Start();
- }
- else
- {
- Stop();
- }
- }
- get
- {
- return ( _threadTimer != null && _threadTimer.IsAlive );
- }
- }
-
- public void Start()
- {
- if( Enabled || Interval <= 0 )
- {
- return;
- }
-
- _stopTimer = false;
-
- System.Threading.ThreadStart threadStart = delegate()
- {
- NotificationTimer(ref _timerIntervalInMicroSec,
- ref _ignoreEventIfLateBy,
- ref _stopTimer);
- };
-
- _threadTimer = new System.Threading.Thread( threadStart );
- _threadTimer.Priority = System.Threading.ThreadPriority.Highest;
- _threadTimer.Start();
- }
-
- public void Stop()
- {
- _stopTimer = true;
-
- if( _threadTimer != null && _threadTimer.ManagedThreadId ==
- System.Threading.Thread.CurrentThread.ManagedThreadId )
- {
- return;
- }
-
- while( Enabled )
- {
- System.Threading.Thread.SpinWait( 10 );
- }
- }
-
- void NotificationTimer( ref long timerIntervalInMicroSec,
- ref long ignoreEventIfLateBy,
- ref bool stopTimer )
- {
- int timerCount = 0;
- long nextNotification = 0;
-
- MicroStopwatch microStopwatch = new MicroStopwatch();
- microStopwatch.Start();
-
- while( !stopTimer )
- {
- long callbackFunctionExecutionTime =
- microStopwatch.ElapsedMicroseconds - nextNotification;
-
- long timerIntervalInMicroSecCurrent =
- System.Threading.Interlocked.Read(ref timerIntervalInMicroSec);
- long ignoreEventIfLateByCurrent =
- System.Threading.Interlocked.Read(ref ignoreEventIfLateBy);
-
- nextNotification += timerIntervalInMicroSecCurrent;
- timerCount++;
- long elapsedMicroseconds = 0;
-
- while( ( elapsedMicroseconds = microStopwatch.ElapsedMicroseconds )
- < nextNotification )
- {
- System.Threading.Thread.SpinWait( 10 );
- }
-
- long timerLateBy = elapsedMicroseconds - nextNotification;
-
- if( timerLateBy >= ignoreEventIfLateByCurrent )
- {
- continue;
- }
-
- MicroTimerEventArgs microTimerEventArgs =
- new MicroTimerEventArgs(timerCount,
- elapsedMicroseconds,
- timerLateBy,
- callbackFunctionExecutionTime);
- MicroTimerElapsed( this, microTimerEventArgs );
- }
-
- microStopwatch.Stop();
- }
- }
-
- ///
- /// MicroTimer Event Argument class
- ///
- public class MicroTimerEventArgs : EventArgs
- {
- // Simple counter, number times timed event (callback function) executed
- public int TimerCount { get; private set; }
-
- // Time when timed event was called since timer started
- public long ElapsedMicroseconds { get; private set; }
-
- // How late the timer was compared to when it should have been called
- public long TimerLateBy { get; private set; }
-
- // Time it took to execute previous call to callback function (OnTimedEvent)
- public long CallbackFunctionExecutionTime { get; private set; }
-
- public MicroTimerEventArgs( int timerCount,
- long elapsedMicroseconds,
- long timerLateBy,
- long callbackFunctionExecutionTime )
- {
- TimerCount = timerCount;
- ElapsedMicroseconds = elapsedMicroseconds;
- TimerLateBy = timerLateBy;
- CallbackFunctionExecutionTime = callbackFunctionExecutionTime;
- }
- }
-
-
- public class Timer
- {
- MicroStopwatch m_watch;
- private long startTime;
- private long stopTime;
- private long freq;
- private long freq_millis;
-
- public Timer()
- {
- m_watch = new MicroStopwatch();
- //startTime = m_watch.ElapsedMicroseconds;
- //stopTime = m_watch.ElapsedMicroseconds;
- freq = 1000 * 1000;
- freq_millis = freq / 1000;
-
- Start();
- }
-
- // Start the timer
-
- public Timer Start()
- {
- m_watch.Start();
- startTime = m_watch.ElapsedMicroseconds;
- stopTime = m_watch.ElapsedMicroseconds;
- return this;
- }
-
- // Stop the timer
-
- public Timer Stop()
- {
- m_watch.Stop();
- stopTime = m_watch.ElapsedMicroseconds;
- return this;
- }
-
- public double Seconds
- {
- get
- {
- long current = m_watch.ElapsedMicroseconds;
- return (double)( current - startTime ) / freq;
- }
- }
-
- public long Current
- {
- get
- {
- long current = m_watch.ElapsedMicroseconds;
- return ( current - startTime ) / freq_millis;
- }
- }
-
- public double Duration
- {
- get
- {
- return (double)( stopTime - startTime ) / (double)freq;
- }
- }
-
- public long DurationMS
- {
- get { return ( stopTime - startTime ) / freq_millis; }
- }
- }
-
-
- public class TimerWin
- {
- [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 TimerWin()
- {
- 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; }
- }
- }
-}
+using System;
+using System.Runtime.InteropServices;
+using System.ComponentModel;
+using System.Threading;
+
+namespace lib
+{
+
+ public class MicroStopwatch : System.Diagnostics.Stopwatch
+ {
+ readonly double _microSecPerTick
+ = 1000000D / System.Diagnostics.Stopwatch.Frequency;
+
+ public MicroStopwatch()
+ {
+ if( !System.Diagnostics.Stopwatch.IsHighResolution )
+ {
+ throw new Exception( "On this system the high-resolution " +
+ "performance counter is not available" );
+ }
+ }
+
+ public long ElapsedMicroseconds
+ {
+ get
+ {
+ return (long)( ElapsedTicks * _microSecPerTick );
+ }
+ }
+ }
+
+ ///
+ /// MicroTimer class
+ ///
+ public class MicroTimer
+ {
+ public delegate void MicroTimerElapsedEventHandler(
+ object sender,
+ MicroTimerEventArgs timerEventArgs );
+ public event MicroTimerElapsedEventHandler MicroTimerElapsed;
+
+ System.Threading.Thread _threadTimer = null;
+ long _ignoreEventIfLateBy = long.MaxValue;
+ long _timerIntervalInMicroSec = 0;
+ bool _stopTimer = true;
+
+ public MicroTimer()
+ {
+ }
+
+ public MicroTimer( long timerIntervalInMicroseconds )
+ {
+ Interval = timerIntervalInMicroseconds;
+ }
+
+ public long Interval
+ {
+ get
+ {
+ return System.Threading.Interlocked.Read(
+ ref _timerIntervalInMicroSec );
+ }
+ set
+ {
+ System.Threading.Interlocked.Exchange(
+ ref _timerIntervalInMicroSec, value );
+ }
+ }
+
+ public long IgnoreEventIfLateBy
+ {
+ get
+ {
+ return System.Threading.Interlocked.Read(
+ ref _ignoreEventIfLateBy );
+ }
+ set
+ {
+ System.Threading.Interlocked.Exchange(
+ ref _ignoreEventIfLateBy, value <= 0 ? long.MaxValue : value );
+ }
+ }
+
+ public bool Enabled
+ {
+ set
+ {
+ if( value )
+ {
+ Start();
+ }
+ else
+ {
+ Stop();
+ }
+ }
+ get
+ {
+ return ( _threadTimer != null && _threadTimer.IsAlive );
+ }
+ }
+
+ public void Start()
+ {
+ if( Enabled || Interval <= 0 )
+ {
+ return;
+ }
+
+ _stopTimer = false;
+
+ System.Threading.ThreadStart threadStart = delegate()
+ {
+ NotificationTimer(ref _timerIntervalInMicroSec,
+ ref _ignoreEventIfLateBy,
+ ref _stopTimer);
+ };
+
+ _threadTimer = new System.Threading.Thread( threadStart );
+ _threadTimer.Priority = System.Threading.ThreadPriority.Highest;
+ _threadTimer.Start();
+ }
+
+ public void Stop()
+ {
+ _stopTimer = true;
+
+ if( _threadTimer != null && _threadTimer.ManagedThreadId ==
+ System.Threading.Thread.CurrentThread.ManagedThreadId )
+ {
+ return;
+ }
+
+ while( Enabled )
+ {
+ System.Threading.Thread.SpinWait( 10 );
+ }
+ }
+
+ void NotificationTimer( ref long timerIntervalInMicroSec,
+ ref long ignoreEventIfLateBy,
+ ref bool stopTimer )
+ {
+ int timerCount = 0;
+ long nextNotification = 0;
+
+ MicroStopwatch microStopwatch = new MicroStopwatch();
+ microStopwatch.Start();
+
+ while( !stopTimer )
+ {
+ long callbackFunctionExecutionTime =
+ microStopwatch.ElapsedMicroseconds - nextNotification;
+
+ long timerIntervalInMicroSecCurrent =
+ System.Threading.Interlocked.Read(ref timerIntervalInMicroSec);
+ long ignoreEventIfLateByCurrent =
+ System.Threading.Interlocked.Read(ref ignoreEventIfLateBy);
+
+ nextNotification += timerIntervalInMicroSecCurrent;
+ timerCount++;
+ long elapsedMicroseconds = 0;
+
+ while( ( elapsedMicroseconds = microStopwatch.ElapsedMicroseconds )
+ < nextNotification )
+ {
+ System.Threading.Thread.SpinWait( 10 );
+ }
+
+ long timerLateBy = elapsedMicroseconds - nextNotification;
+
+ if( timerLateBy >= ignoreEventIfLateByCurrent )
+ {
+ continue;
+ }
+
+ MicroTimerEventArgs microTimerEventArgs =
+ new MicroTimerEventArgs(timerCount,
+ elapsedMicroseconds,
+ timerLateBy,
+ callbackFunctionExecutionTime);
+ MicroTimerElapsed( this, microTimerEventArgs );
+ }
+
+ microStopwatch.Stop();
+ }
+ }
+
+ ///
+ /// MicroTimer Event Argument class
+ ///
+ public class MicroTimerEventArgs : EventArgs
+ {
+ // Simple counter, number times timed event (callback function) executed
+ public int TimerCount { get; private set; }
+
+ // Time when timed event was called since timer started
+ public long ElapsedMicroseconds { get; private set; }
+
+ // How late the timer was compared to when it should have been called
+ public long TimerLateBy { get; private set; }
+
+ // Time it took to execute previous call to callback function (OnTimedEvent)
+ public long CallbackFunctionExecutionTime { get; private set; }
+
+ public MicroTimerEventArgs( int timerCount,
+ long elapsedMicroseconds,
+ long timerLateBy,
+ long callbackFunctionExecutionTime )
+ {
+ TimerCount = timerCount;
+ ElapsedMicroseconds = elapsedMicroseconds;
+ TimerLateBy = timerLateBy;
+ CallbackFunctionExecutionTime = callbackFunctionExecutionTime;
+ }
+ }
+
+
+ public class Timer
+ {
+ MicroStopwatch m_watch;
+ private long startTime;
+ private long stopTime;
+ private long freq;
+ private long freq_millis;
+
+ public Timer()
+ {
+ m_watch = new MicroStopwatch();
+ //startTime = m_watch.ElapsedMicroseconds;
+ //stopTime = m_watch.ElapsedMicroseconds;
+ freq = 1000 * 1000;
+ freq_millis = freq / 1000;
+
+ Start();
+ }
+
+ // Start the timer
+
+ public Timer Start()
+ {
+ m_watch.Start();
+ startTime = m_watch.ElapsedMicroseconds;
+ stopTime = m_watch.ElapsedMicroseconds;
+ return this;
+ }
+
+ // Stop the timer
+
+ public Timer Stop()
+ {
+ m_watch.Stop();
+ stopTime = m_watch.ElapsedMicroseconds;
+ return this;
+ }
+
+ public double Seconds
+ {
+ get
+ {
+ long current = m_watch.ElapsedMicroseconds;
+ return (double)( current - startTime ) / freq;
+ }
+ }
+
+ public long Current
+ {
+ get
+ {
+ long current = m_watch.ElapsedMicroseconds;
+ return ( current - startTime ) / freq_millis;
+ }
+ }
+
+ public double Duration
+ {
+ get
+ {
+ return (double)( stopTime - startTime ) / (double)freq;
+ }
+ }
+
+ public long DurationMS
+ {
+ get { return ( stopTime - startTime ) / freq_millis; }
+ }
+ }
+
+
+ public class TimerWin
+ {
+ [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 TimerWin()
+ {
+ 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; }
+ }
+ }
+}