2020-01-23 00:21:03 +00:00
#nullable disable
using System ;
2013-12-14 00:03:03 +00:00
using System.Collections.Generic ;
using System.Globalization ;
using System.IO ;
2014-07-03 17:13:09 +00:00
using BizHawk.Common.IOExtensions ;
2014-07-03 19:05:56 +00:00
using BizHawk.Common.BufferExtensions ;
2014-07-03 17:13:09 +00:00
2013-12-14 00:03:03 +00:00
namespace BizHawk.Common
{
public unsafe class Serializer
{
public Serializer ( ) { }
#region Public
2019-12-07 00:12:57 +00:00
public bool IsReader = > _isReader ;
2013-12-14 00:03:03 +00:00
2019-12-07 00:12:57 +00:00
public bool IsWriter = > ! IsReader ;
2013-12-14 00:03:03 +00:00
2019-12-07 00:12:57 +00:00
public bool IsText = > _isText ;
2013-12-14 00:03:03 +00:00
2019-12-07 00:12:57 +00:00
public BinaryReader BinaryReader = > _br ;
2013-12-14 00:03:03 +00:00
2019-12-07 00:12:57 +00:00
public BinaryWriter BinaryWriter = > _bw ;
2013-12-14 00:03:03 +00:00
2019-12-07 00:12:57 +00:00
public TextReader TextReader = > _tr ;
2013-12-14 00:03:03 +00:00
2019-12-07 00:12:57 +00:00
public TextWriter TextWriter = > _tw ;
2013-12-14 00:03:03 +00:00
public Serializer ( BinaryWriter bw )
{
StartWrite ( bw ) ;
}
public Serializer ( BinaryReader br )
{
StartRead ( br ) ;
}
public Serializer ( TextWriter tw )
{
StartWrite ( tw ) ;
}
public Serializer ( TextReader tr )
{
StartRead ( tr ) ;
}
public static Serializer CreateBinaryWriter ( BinaryWriter bw )
{
return new Serializer ( bw ) ;
}
public static Serializer CreateBinaryReader ( BinaryReader br )
{
return new Serializer ( br ) ;
}
public static Serializer CreateTextWriter ( TextWriter tw )
{
return new Serializer ( tw ) ;
}
public static Serializer CreateTextReader ( TextReader tr )
{
return new Serializer ( tr ) ;
}
public void StartWrite ( BinaryWriter bw )
{
_bw = bw ;
_isReader = false ;
}
public void StartRead ( BinaryReader br )
{
_br = br ;
_isReader = true ;
}
public void StartWrite ( TextWriter tw )
{
_tw = tw ;
_isReader = false ;
_isText = true ;
}
public void StartRead ( TextReader tr )
{
_tr = tr ;
_isReader = true ;
_isText = true ;
BeginTextBlock ( ) ;
}
public void BeginSection ( string name )
{
2019-12-07 00:12:57 +00:00
_sections . Push ( name ) ;
2013-12-14 00:03:03 +00:00
if ( IsText )
{
if ( IsWriter )
{
_tw . WriteLine ( "[{0}]" , name ) ;
}
else
{
_sectionStack . Push ( _currSection ) ;
_currSection = _currSection [ name ] ;
}
}
}
public void EndSection ( )
{
2019-12-07 00:12:57 +00:00
var name = _sections . Pop ( ) ;
2013-12-14 00:03:03 +00:00
if ( IsText )
{
if ( IsWriter )
{
_tw . WriteLine ( "[/{0}]" , name ) ;
}
else
{
_currSection = _sectionStack . Pop ( ) ;
}
}
}
2019-12-27 19:41:54 +00:00
/// <exception cref="InvalidOperationException"><typeparamref name="T"/> does not inherit <see cref="Enum"/></exception>
2013-12-14 00:03:03 +00:00
public void SyncEnum < T > ( string name , ref T val ) where T : struct
{
if ( typeof ( T ) . BaseType ! = typeof ( Enum ) )
{
throw new InvalidOperationException ( ) ;
}
else if ( _isText )
{
SyncEnumText ( name , ref val ) ;
}
else if ( IsReader )
{
val = ( T ) Enum . ToObject ( typeof ( T ) , _br . ReadInt32 ( ) ) ;
}
else
{
_bw . Write ( Convert . ToInt32 ( val ) ) ;
}
}
public void SyncEnumText < T > ( string name , ref T val ) where T : struct
{
if ( IsReader )
{
if ( Present ( name ) )
{
val = ( T ) Enum . Parse ( typeof ( T ) , Item ( name ) ) ;
}
}
else
{
_tw . WriteLine ( "{0} {1}" , name , val ) ;
}
}
public void Sync ( string name , ref byte [ ] val , bool useNull )
{
if ( IsText )
{
SyncText ( name , ref val , useNull ) ;
}
else if ( IsReader )
{
2020-01-23 00:22:54 +00:00
val = _br . ReadByteBuffer ( useNull ) ;
2013-12-14 00:03:03 +00:00
}
else
{
2020-01-23 00:22:54 +00:00
_bw . WriteByteBuffer ( val ) ;
2013-12-14 00:03:03 +00:00
}
}
public void SyncText ( string name , ref byte [ ] val , bool useNull )
{
if ( IsReader )
{
if ( Present ( name ) )
{
2020-01-23 00:22:54 +00:00
val = Item ( name ) . HexStringToBytes ( ) ;
2013-12-14 00:03:03 +00:00
}
if ( val ! = null & & val . Length = = 0 & & useNull )
{
val = null ;
}
}
else
{
var temp = val ? ? new byte [ 0 ] ;
2014-07-03 19:05:56 +00:00
_tw . WriteLine ( "{0} {1}" , name , temp . BytesToHexString ( ) ) ;
2013-12-14 00:03:03 +00:00
}
}
2014-10-06 16:00:24 +00:00
public void Sync ( string name , ref bool [ ] val , bool useNull )
{
if ( IsText )
{
SyncText ( name , ref val , useNull ) ;
}
else if ( IsReader )
{
2020-01-23 00:22:54 +00:00
val = _br . ReadByteBuffer ( false ) . ToBoolBuffer ( ) ;
2014-10-06 16:00:24 +00:00
if ( val = = null & & ! useNull )
{
val = new bool [ 0 ] ;
}
}
else
{
2020-01-23 00:22:54 +00:00
_bw . WriteByteBuffer ( val . ToUByteBuffer ( ) ) ;
2014-10-06 16:00:24 +00:00
}
}
public void SyncText ( string name , ref bool [ ] val , bool useNull )
{
if ( IsReader )
{
if ( Present ( name ) )
{
2020-01-23 00:22:54 +00:00
var bytes = Item ( name ) . HexStringToBytes ( ) ;
val = bytes . ToBoolBuffer ( ) ;
2014-10-06 16:00:24 +00:00
}
if ( val ! = null & & val . Length = = 0 & & useNull )
{
val = null ;
}
}
else
{
var temp = val ? ? new bool [ 0 ] ;
2020-01-23 00:22:54 +00:00
_tw . WriteLine ( "{0} {1}" , name , temp . ToUByteBuffer ( ) . BytesToHexString ( ) ) ;
2014-10-06 16:00:24 +00:00
}
}
2013-12-14 00:03:03 +00:00
public void Sync ( string name , ref short [ ] val , bool useNull )
{
if ( IsText )
{
SyncText ( name , ref val , useNull ) ;
}
else if ( IsReader )
{
2020-01-23 00:22:54 +00:00
val = _br . ReadByteBuffer ( false ) . ToShortBuffer ( ) ;
2013-12-14 00:03:03 +00:00
if ( val = = null & & ! useNull )
{
val = new short [ 0 ] ;
}
}
else
{
2020-01-23 00:22:54 +00:00
_bw . WriteByteBuffer ( val . ToUByteBuffer ( ) ) ;
2013-12-14 00:03:03 +00:00
}
}
2014-04-07 04:50:19 +00:00
public void Sync ( string name , ref ushort [ ] val , bool useNull )
{
if ( IsText )
{
SyncText ( name , ref val , useNull ) ;
}
else if ( IsReader )
{
2020-01-23 00:22:54 +00:00
val = _br . ReadByteBuffer ( false ) . ToUShortBuffer ( ) ;
2014-04-07 04:50:19 +00:00
if ( val = = null & & ! useNull )
{
val = new ushort [ 0 ] ;
}
}
else
{
2020-01-23 00:22:54 +00:00
_bw . WriteByteBuffer ( val . ToUByteBuffer ( ) ) ;
2014-04-07 04:50:19 +00:00
}
}
2013-12-14 00:03:03 +00:00
public void SyncText ( string name , ref short [ ] val , bool useNull )
{
if ( IsReader )
{
if ( Present ( name ) )
{
2020-01-23 00:22:54 +00:00
var bytes = Item ( name ) . HexStringToBytes ( ) ;
val = bytes . ToShortBuffer ( ) ;
2013-12-14 00:03:03 +00:00
}
if ( val ! = null & & val . Length = = 0 & & useNull )
{
val = null ;
}
}
else
{
var temp = val ? ? new short [ 0 ] ;
2020-01-23 00:22:54 +00:00
_tw . WriteLine ( "{0} {1}" , name , temp . ToUByteBuffer ( ) . BytesToHexString ( ) ) ;
2013-12-14 00:03:03 +00:00
}
}
2014-04-07 04:50:19 +00:00
public void SyncText ( string name , ref ushort [ ] val , bool useNull )
{
if ( IsReader )
{
if ( Present ( name ) )
{
2020-01-23 00:22:54 +00:00
var bytes = Item ( name ) . HexStringToBytes ( ) ;
val = bytes . ToUShortBuffer ( ) ;
2014-04-07 04:50:19 +00:00
}
if ( val ! = null & & val . Length = = 0 & & useNull )
{
val = null ;
}
}
else
{
var temp = val ? ? new ushort [ 0 ] ;
2020-01-23 00:22:54 +00:00
_tw . WriteLine ( "{0} {1}" , name , temp . ToUByteBuffer ( ) . BytesToHexString ( ) ) ;
2014-04-07 04:50:19 +00:00
}
}
2013-12-14 00:03:03 +00:00
public void Sync ( string name , ref int [ ] val , bool useNull )
{
if ( IsText )
{
SyncText ( name , ref val , useNull ) ;
}
else if ( IsReader )
{
2020-01-23 00:22:54 +00:00
val = _br . ReadByteBuffer ( false ) . ToIntBuffer ( ) ;
2013-12-14 00:03:03 +00:00
if ( val = = null & & ! useNull )
{
val = new int [ 0 ] ;
}
}
else
{
2020-01-23 00:22:54 +00:00
_bw . WriteByteBuffer ( val . ToUByteBuffer ( ) ) ;
2013-12-14 00:03:03 +00:00
}
}
public void SyncText ( string name , ref int [ ] val , bool useNull )
{
if ( IsReader )
{
if ( Present ( name ) )
{
2020-01-23 00:22:54 +00:00
var bytes = Item ( name ) . HexStringToBytes ( ) ;
val = bytes . ToIntBuffer ( ) ;
2013-12-14 00:03:03 +00:00
}
if ( val ! = null & & val . Length = = 0 & & useNull )
{
val = null ;
}
}
else
{
var temp = val ? ? new int [ 0 ] ;
2020-01-23 00:22:54 +00:00
_tw . WriteLine ( "{0} {1}" , name , temp . ToUByteBuffer ( ) . BytesToHexString ( ) ) ;
2013-12-14 00:03:03 +00:00
}
}
public void Sync ( string name , ref uint [ ] val , bool useNull )
{
if ( IsText )
{
SyncText ( name , ref val , useNull ) ;
}
else if ( IsReader )
{
2020-01-23 00:22:54 +00:00
val = _br . ReadByteBuffer ( false ) . ToUIntBuffer ( ) ;
2013-12-14 00:03:03 +00:00
if ( val = = null & & ! useNull )
{
val = new uint [ 0 ] ;
}
}
else
{
2020-01-23 00:22:54 +00:00
_bw . WriteByteBuffer ( val . ToUByteBuffer ( ) ) ;
2013-12-14 00:03:03 +00:00
}
}
public void SyncText ( string name , ref uint [ ] val , bool useNull )
{
if ( IsReader )
{
if ( Present ( name ) )
{
2020-01-23 00:22:54 +00:00
var bytes = Item ( name ) . HexStringToBytes ( ) ;
val = bytes . ToUIntBuffer ( ) ;
2013-12-14 00:03:03 +00:00
}
if ( val ! = null & & val . Length = = 0 & & useNull )
{
val = null ;
}
}
else
{
var temp = val ? ? new uint [ 0 ] ;
2020-01-23 00:22:54 +00:00
_tw . WriteLine ( "{0} {1}" , name , temp . ToUByteBuffer ( ) . BytesToHexString ( ) ) ;
2013-12-14 00:03:03 +00:00
}
}
2019-04-08 07:59:01 +00:00
public void Sync ( string name , ref float [ ] val , bool useNull )
{
if ( IsText )
{
SyncText ( name , ref val , useNull ) ;
}
else if ( IsReader )
{
2020-01-23 00:22:54 +00:00
val = _br . ReadByteBuffer ( false ) . ToFloatBuffer ( ) ;
2019-04-08 07:59:01 +00:00
if ( val = = null & & ! useNull )
{
val = new float [ 0 ] ;
}
}
else
{
2020-01-23 00:22:54 +00:00
_bw . WriteByteBuffer ( val . ToUByteBuffer ( ) ) ;
2019-04-08 07:59:01 +00:00
}
}
public void SyncText ( string name , ref float [ ] val , bool useNull )
{
if ( IsReader )
{
if ( Present ( name ) )
{
2020-01-23 00:22:54 +00:00
var bytes = Item ( name ) . HexStringToBytes ( ) ;
val = bytes . ToFloatBuffer ( ) ;
2019-04-08 07:59:01 +00:00
}
if ( val ! = null & & val . Length = = 0 & & useNull )
{
val = null ;
}
}
else
{
var temp = val ? ? new float [ 0 ] ;
2020-01-23 00:22:54 +00:00
_tw . WriteLine ( "{0} {1}" , name , temp . ToUByteBuffer ( ) . BytesToHexString ( ) ) ;
2019-04-08 07:59:01 +00:00
}
}
public void Sync ( string name , ref double [ ] val , bool useNull )
{
if ( IsText )
{
SyncText ( name , ref val , useNull ) ;
}
else if ( IsReader )
{
2020-01-23 00:22:54 +00:00
val = _br . ReadByteBuffer ( false ) . ToDoubleBuffer ( ) ;
2019-04-08 07:59:01 +00:00
if ( val = = null & & ! useNull )
{
val = new double [ 0 ] ;
}
}
else
{
2020-01-23 00:22:54 +00:00
_bw . WriteByteBuffer ( val . ToUByteBuffer ( ) ) ;
2019-04-08 07:59:01 +00:00
}
}
public void SyncText ( string name , ref double [ ] val , bool useNull )
{
if ( IsReader )
{
if ( Present ( name ) )
{
2020-01-23 00:22:54 +00:00
var bytes = Item ( name ) . HexStringToBytes ( ) ;
val = bytes . ToDoubleBuffer ( ) ;
2019-04-08 07:59:01 +00:00
}
if ( val ! = null & & val . Length = = 0 & & useNull )
{
val = null ;
}
}
else
{
var temp = val ? ? new double [ 0 ] ;
2020-01-23 00:22:54 +00:00
_tw . WriteLine ( "{0} {1}" , name , temp . ToUByteBuffer ( ) . BytesToHexString ( ) ) ;
2019-04-08 07:59:01 +00:00
}
}
2013-12-14 00:03:03 +00:00
public void Sync ( string name , ref Bit val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
public void SyncText ( string name , ref Bit val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
public void Sync ( string name , ref byte val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
public void Sync ( string name , ref ushort val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
public void Sync ( string name , ref uint val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
public void Sync ( string name , ref sbyte val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
public void Sync ( string name , ref short val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
public void Sync ( string name , ref int val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
2014-04-07 04:50:19 +00:00
public void Sync ( string name , ref long val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
2014-05-26 00:55:12 +00:00
public void Sync ( string name , ref ulong val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
2014-04-07 04:50:19 +00:00
public void Sync ( string name , ref float val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
2019-04-08 07:59:01 +00:00
public void Sync ( string name , ref double val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
2013-12-14 00:03:03 +00:00
public void Sync ( string name , ref bool val )
{
if ( IsText )
{
SyncText ( name , ref val ) ;
}
else if ( IsReader )
{
Read ( ref val ) ;
}
else
{
Write ( ref val ) ;
}
}
2019-12-27 19:41:54 +00:00
/// <exception cref="InvalidOperationException"><see cref="IsReader"/> is <see langword="false"/> and <paramref name="name"/> is longer than <paramref name="length"/> chars</exception>
2013-12-14 00:03:03 +00:00
public void SyncFixedString ( string name , ref string val , int length )
{
// TODO - this could be made more efficient perhaps just by writing values right out of the string..
if ( IsReader )
{
var buf = new char [ length ] ;
if ( _isText )
{
_tr . Read ( buf , 0 , length ) ;
}
else
{
_br . Read ( buf , 0 , length ) ;
}
var len = 0 ;
for ( ; len < length ; len + + )
{
if ( buf [ len ] = = 0 )
{
break ;
}
}
val = new string ( buf , 0 , len ) ;
}
else
{
if ( name . Length > length )
{
2019-03-28 03:17:14 +00:00
throw new InvalidOperationException ( $"{nameof(SyncFixedString)} too long" ) ;
2013-12-14 00:03:03 +00:00
}
var buf = val . ToCharArray ( ) ;
var remainder = new char [ length - buf . Length ] ;
if ( IsText )
{
_tw . Write ( buf ) ;
_tw . Write ( remainder ) ;
}
else
{
_bw . Write ( buf ) ;
_bw . Write ( remainder ) ;
}
}
}
#endregion
#region Privates
private BinaryReader _br ;
private BinaryWriter _bw ;
private TextReader _tr ;
private TextWriter _tw ;
private bool _isText ;
private bool _isReader ;
private readonly Stack < string > _sections = new Stack < string > ( ) ;
private Section _readerSection , _currSection ;
private readonly Stack < Section > _sectionStack = new Stack < Section > ( ) ;
private void BeginTextBlock ( )
{
if ( ! IsText | | IsWriter )
{
return ;
}
_readerSection = new Section ( ) ;
var ss = new Stack < Section > ( ) ;
ss . Push ( _readerSection ) ;
var curs = _readerSection ;
var rxEnd = new System . Text . RegularExpressions . Regex ( @"\[/(.*?)\]" , System . Text . RegularExpressions . RegexOptions . Compiled ) ;
var rxBegin = new System . Text . RegularExpressions . Regex ( @"\[(.*?)\]" , System . Text . RegularExpressions . RegexOptions . Compiled ) ;
// read the entire file into a data structure for flexi-parsing
string str ;
while ( ( str = _tr . ReadLine ( ) ) ! = null )
{
var end = rxEnd . Match ( str ) ;
var begin = rxBegin . Match ( str ) ;
if ( end . Success )
{
var name = end . Groups [ 1 ] . Value ;
if ( name ! = curs . Name )
{
throw new InvalidOperationException ( "Mis-formed savestate blob" ) ;
}
curs = ss . Pop ( ) ;
// consume no data past the end of the last proper section
if ( curs = = _readerSection )
{
_currSection = curs ;
return ;
}
}
else if ( begin . Success )
{
var name = begin . Groups [ 1 ] . Value ;
ss . Push ( curs ) ;
var news = new Section { Name = name } ;
if ( ! curs . ContainsKey ( name ) )
{
curs [ name ] = news ;
}
else
{
2019-03-20 05:13:04 +00:00
throw new Exception ( $"Duplicate key \" { name } \ " in serializer savestate!" ) ;
2013-12-14 00:03:03 +00:00
}
curs = news ;
}
else
{
// add to current section
if ( str . Trim ( ) . Length = = 0 )
{
continue ;
}
var parts = str . Split ( ' ' ) ;
var key = parts [ 0 ] ;
// UGLY: adds whole string instead of splitting the key. later, split the key, and have the individual Sync methods give up that responsibility
if ( ! curs . Items . ContainsKey ( key ) )
{
curs . Items [ key ] = parts [ 1 ] ;
}
else
{
2019-03-20 05:13:04 +00:00
throw new Exception ( $"Duplicate key \" { key } \ " in serializer savestate!" ) ;
2013-12-14 00:03:03 +00:00
}
}
}
_currSection = _readerSection ;
}
private string Item ( string key )
{
return _currSection . Items [ key ] ;
}
private bool Present ( string key )
{
return _currSection . Items . ContainsKey ( key ) ;
}
private void SyncBuffer ( string name , int elemsize , int len , void * ptr )
{
if ( IsReader )
{
byte [ ] temp = null ;
Sync ( name , ref temp , false ) ;
int todo = Math . Min ( temp . Length , len * elemsize ) ;
System . Runtime . InteropServices . Marshal . Copy ( temp , 0 , new IntPtr ( ptr ) , todo ) ;
}
else
{
int todo = len * elemsize ;
var temp = new byte [ todo ] ;
System . Runtime . InteropServices . Marshal . Copy ( new IntPtr ( ptr ) , temp , 0 , todo ) ;
Sync ( name , ref temp , false ) ;
}
}
private void SyncText ( string name , ref byte val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
private void SyncText ( string name , ref ushort val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
private void SyncText ( string name , ref uint val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
private void SyncText ( string name , ref sbyte val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
private void SyncText ( string name , ref short val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
private void SyncText ( string name , ref int val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
2014-04-07 04:50:19 +00:00
private void SyncText ( string name , ref long val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
2014-05-26 00:55:12 +00:00
private void SyncText ( string name , ref ulong val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
2014-04-07 04:50:19 +00:00
private void SyncText ( string name , ref float val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
2019-04-08 07:59:01 +00:00
private void SyncText ( string name , ref double val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
2013-12-14 00:03:03 +00:00
private void SyncText ( string name , ref bool val )
{
if ( IsReader )
{
ReadText ( name , ref val ) ;
}
else
{
WriteText ( name , ref val ) ;
}
}
private void Read ( ref Bit val )
{
val = _br . ReadBit ( ) ;
}
private void Write ( ref Bit val )
{
_bw . WriteBit ( val ) ;
}
private void ReadText ( string name , ref Bit val )
{
if ( Present ( name ) )
{
val = int . Parse ( this . Item ( name ) ) ;
}
}
private void WriteText ( string name , ref Bit val )
{
_tw . WriteLine ( "{0} {1}" , name , ( int ) val ) ;
}
private void Read ( ref byte val )
{
val = _br . ReadByte ( ) ;
}
private void Write ( ref byte val )
{
_bw . Write ( val ) ;
}
private void ReadText ( string name , ref byte val )
{
if ( Present ( name ) )
{
val = byte . Parse ( Item ( name ) . Replace ( "0x" , "" ) , NumberStyles . HexNumber ) ;
}
}
private void WriteText ( string name , ref byte val )
{
_tw . WriteLine ( "{0} 0x{1:X2}" , name , val ) ;
}
private void Read ( ref ushort val )
{
val = _br . ReadUInt16 ( ) ;
}
private void Write ( ref ushort val )
{
_bw . Write ( val ) ;
}
private void ReadText ( string name , ref ushort val )
{
if ( Present ( name ) )
{
val = ushort . Parse ( Item ( name ) . Replace ( "0x" , "" ) , NumberStyles . HexNumber ) ;
}
}
private void WriteText ( string name , ref ushort val )
{
_tw . WriteLine ( "{0} 0x{1:X4}" , name , val ) ;
}
private void Read ( ref uint val )
{
{ val = _br . ReadUInt32 ( ) ; }
}
private void Write ( ref uint val )
{
_bw . Write ( val ) ;
}
private void ReadText ( string name , ref uint val )
{
if ( Present ( name ) )
{
val = uint . Parse ( Item ( name ) . Replace ( "0x" , "" ) , NumberStyles . HexNumber ) ;
}
}
private void WriteText ( string name , ref uint val )
{
_tw . WriteLine ( "{0} 0x{1:X8}" , name , val ) ;
}
private void Read ( ref sbyte val )
{
val = _br . ReadSByte ( ) ;
}
private void Write ( ref sbyte val )
{
_bw . Write ( val ) ;
}
private void ReadText ( string name , ref sbyte val )
{
if ( Present ( name ) )
{
val = sbyte . Parse ( Item ( name ) . Replace ( "0x" , "" ) , NumberStyles . HexNumber ) ;
}
}
private void WriteText ( string name , ref sbyte val )
{
_tw . WriteLine ( "{0} 0x{1:X2}" , name , val ) ;
}
private void Read ( ref short val )
{
val = _br . ReadInt16 ( ) ;
}
private void Write ( ref short val )
{
_bw . Write ( val ) ;
}
private void ReadText ( string name , ref short val )
{
if ( Present ( name ) )
{
val = short . Parse ( Item ( name ) . Replace ( "0x" , "" ) , NumberStyles . HexNumber ) ;
}
}
private void WriteText ( string name , ref short val )
{
_tw . WriteLine ( "{0} 0x{1:X4}" , name , val ) ;
}
private void Read ( ref int val )
{
val = _br . ReadInt32 ( ) ;
}
private void Write ( ref int val )
{
_bw . Write ( val ) ;
}
private void ReadText ( string name , ref int val )
{
if ( Present ( name ) )
{
val = int . Parse ( Item ( name ) . Replace ( "0x" , "" ) , NumberStyles . HexNumber ) ;
}
}
private void WriteText ( string name , ref int val )
{
_tw . WriteLine ( "{0} 0x{1:X8}" , name , val ) ;
}
2014-04-07 04:50:19 +00:00
private void Read ( ref long val )
{
val = _br . ReadInt64 ( ) ;
}
private void Write ( ref long val )
{
_bw . Write ( val ) ;
}
2014-05-26 00:55:12 +00:00
private void Read ( ref ulong val )
{
val = _br . ReadUInt64 ( ) ;
}
private void Write ( ref ulong val )
{
_bw . Write ( val ) ;
}
2014-04-07 04:50:19 +00:00
private void ReadText ( string name , ref long val )
{
if ( Present ( name ) )
{
2014-04-08 01:08:47 +00:00
val = long . Parse ( Item ( name ) . Replace ( "0x" , "" ) , NumberStyles . HexNumber ) ;
2014-04-07 04:50:19 +00:00
}
}
private void WriteText ( string name , ref long val )
{
_tw . WriteLine ( "{0} 0x{1:X16}" , name , val ) ;
2014-05-26 00:55:12 +00:00
}
private void ReadText ( string name , ref ulong val )
{
if ( Present ( name ) )
{
val = ulong . Parse ( Item ( name ) . Replace ( "0x" , "" ) , NumberStyles . HexNumber ) ;
}
}
private void WriteText ( string name , ref ulong val )
{
_tw . WriteLine ( "{0} 0x{1:X16}" , name , val ) ;
2014-04-07 04:50:19 +00:00
}
private void Read ( ref float val )
{
val = _br . ReadSingle ( ) ;
}
private void Write ( ref float val )
{
_bw . Write ( val ) ;
}
2019-04-08 07:59:01 +00:00
private void Read ( ref double val )
{
val = _br . ReadDouble ( ) ;
}
private void Write ( ref double val )
{
_bw . Write ( val ) ;
}
2014-04-07 04:50:19 +00:00
private void ReadText ( string name , ref float val )
{
if ( Present ( name ) )
{
val = float . Parse ( Item ( name ) ) ;
}
}
private void WriteText ( string name , ref float val )
{
_tw . WriteLine ( "{0} {1}" , name , val ) ;
}
2019-04-08 07:59:01 +00:00
private void ReadText ( string name , ref double val )
{
if ( Present ( name ) )
{
val = double . Parse ( Item ( name ) ) ;
}
}
private void WriteText ( string name , ref double val )
{
_tw . WriteLine ( "{0} {1}" , name , val ) ;
}
2013-12-14 00:03:03 +00:00
private void Read ( ref bool val )
{
val = _br . ReadBoolean ( ) ;
}
private void Write ( ref bool val )
{
_bw . Write ( val ) ;
}
private void ReadText ( string name , ref bool val )
{
if ( Present ( name ) )
{
val = bool . Parse ( Item ( name ) ) ;
}
}
private void WriteText ( string name , ref bool val )
{
_tw . WriteLine ( "{0} {1}" , name , val ) ;
}
2014-07-03 18:02:22 +00:00
private sealed class Section : Dictionary < string , Section >
2013-12-14 00:03:03 +00:00
{
2017-05-10 11:45:23 +00:00
public string Name = "" ;
2013-12-14 00:03:03 +00:00
public readonly Dictionary < string , string > Items = new Dictionary < string , string > ( ) ;
}
#endregion
}
}