#pragma once
#ifndef __HWINBINARYREADER_H__
#define __HWINBINARYREADER_H__
#include "hwinDef.h"
#include "hwinException.h"
#include "hwinString.h"
#include "hwinDateTime.h"
#include "hwinGuid.h"
#include "hwinIO.h"
#include "hwinNullable.h"
#ifdef _MANAGED
#pragma managed(push,off)
#endif
#pragma pack(push,8)
namespace harlinn
{
namespace windows
{
class BinaryReader : public std::enable_shared_from_this<BinaryReader>
{
protected:
std::shared_ptr<StreamBase> InStream;
private:
std::array<byte, 256> buffer_;
public:
BinaryReader( const std::shared_ptr<StreamBase>& stream )
: InStream( stream )
{
}
virtual std::shared_ptr<StreamBase> BaseStream( )
{
return InStream;
}
protected:
virtual void FillBuffer( size_t numBytes )
{
if ( numBytes > buffer_.size( ) )
{
throw ArgumentOutOfRangeException( "numBytes" );
}
auto ptr = buffer_.data( );
auto numberOfBytesRead = InStream->Read( ptr, numBytes );
if ( numberOfBytesRead < static_cast<long long>( numBytes ) )
{
throw IO::EndOfStreamException( );
}
}
int Read7BitEncodedInt( )
{
// Read out an Int32 7 bits at a time. The high bit
// of the byte when on means to continue reading more bytes.
int count = 0;
int shift = 0;
byte b;
do
{
// Check for a corrupted stream. Read a max of 5 bytes.
// In a future version, add a DataFormatException.
if ( shift == 5 * 7 ) // 5 bytes max per Int32, shift += 7
{
throw Exception( "Bad 7-Bit Int32 format" );
}
// ReadByte handles end of stream cases for us.
b = ReadByte( );
count |= ( b & 0x7F ) << shift;
shift += 7;
} while ( ( b & 0x80 ) != 0 );
return count;
}
public:
virtual int PeekChar( )
{
if ( !InStream->CanSeek( ) )
{
return -1;
}
long long origPos = InStream->Position( );
int ch = ReadSByte( );
InStream->SetPosition( origPos );
return ch;
}
virtual int Read( )
{
return ReadSByte( );
}
virtual bool ReadBoolean( )
{
FillBuffer( 1 );
return ( buffer_[0] != 0 );
}
virtual Nullable<bool> ReadNullableBoolean( )
{
FillBuffer( 1 );
if ( buffer_[0] != 0 )
{
FillBuffer( 1 );
Nullable<bool> result( buffer_[0] != 0 );
return result;
}
return Nullable<bool>( );
}
virtual byte ReadByte( )
{
byte result = 0;
auto bytesRead = InStream->Read( &result, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
return result;
}
virtual Nullable<byte> ReadNullableByte( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
byte value;
auto bytesRead = InStream->Read( &value, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
Nullable<byte> result( value );
return result;
}
return Nullable<byte>( );
}
virtual char ReadSByte( )
{
char result = 0;
auto bytesRead = InStream->Read( &result, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
return result;
}
virtual Nullable<char> ReadNullableSByte( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
char value;
auto bytesRead = InStream->Read( &value, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
Nullable<char> result( value );
return result;
}
return Nullable<char>( );
}
virtual char ReadChar( )
{
char result = 0;
auto bytesRead = InStream->Read( &result, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
return result;
}
virtual Nullable<char> ReadNullableChar( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
char value;
auto bytesRead = InStream->Read( &value, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
Nullable<char> result( value );
return result;
}
return Nullable<char>( );
}
virtual wchar_t ReadWideChar( )
{
FillBuffer( 2 );
auto result = ( wchar_t )( buffer_[0] | buffer_[1] << 8 );
return result;
}
virtual Nullable<wchar_t> ReadNullableWideChar( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
FillBuffer( 2 );
auto value = ( wchar_t )( buffer_[0] | buffer_[1] << 8 );
Nullable<wchar_t> result( value );
return result;
}
return Nullable<wchar_t>( );
}
virtual short ReadInt16( )
{
FillBuffer( 2 );
auto result = ( short )( buffer_[0] | buffer_[1] << 8 );
return result;
}
virtual Nullable<short> ReadNullableInt16( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
FillBuffer( 2 );
auto value = ( short )( buffer_[0] | buffer_[1] << 8 );
Nullable<short> result( value );
return result;
}
return Nullable<short>( );
}
virtual unsigned short ReadUInt16( )
{
FillBuffer( 2 );
auto result = ( unsigned short )( buffer_[0] | buffer_[1] << 8 );
return result;
}
virtual Nullable<unsigned short> ReadNullableUInt16( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
FillBuffer( 2 );
auto value = ( unsigned short )( buffer_[0] | buffer_[1] << 8 );
Nullable<unsigned short> result( value );
return result;
}
return Nullable<unsigned short>( );
}
virtual int ReadInt32( )
{
FillBuffer( 4 );
auto result = ( int )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
return result;
}
virtual Nullable<int> ReadNullableInt32( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
FillBuffer( 4 );
auto value = ( int )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
Nullable<int> result( value );
return result;
}
return Nullable<int>( );
}
virtual uint ReadUInt32( )
{
FillBuffer( 4 );
return ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
}
virtual Nullable<uint> ReadNullableUInt32( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
FillBuffer( 4 );
auto value = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
Nullable<uint> result( value );
return result;
}
return Nullable<uint>( );
}
virtual long long ReadInt64( )
{
FillBuffer( 8 );
uint lo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint hi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
return ( long long )( ( unsigned long long ) hi ) << 32 | lo;
}
virtual Nullable<long long> ReadNullableInt64( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
FillBuffer( 8 );
uint lo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint hi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
auto value = ( long long )( ( unsigned long long ) hi ) << 32 | lo;
Nullable<long long> result( value );
return result;
}
return Nullable<long long>( );
}
virtual unsigned long long ReadUInt64( )
{
FillBuffer( 8 );
uint lo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint hi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
return ( ( unsigned long long ) hi ) << 32 | lo;
}
virtual Nullable<unsigned long long> ReadNullableUInt64( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
FillBuffer( 8 );
uint lo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint hi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
auto value = ( ( unsigned long long ) hi ) << 32 | lo;
Nullable<unsigned long long> result( value );
return result;
}
return Nullable<unsigned long long>( );
}
virtual float ReadSingle( )
{
FillBuffer( 4 );
uint tmpBuffer = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
return *( ( float* )&tmpBuffer );
}
virtual Nullable<float> ReadNullableSingle( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
FillBuffer( 4 );
uint tmpBuffer = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
auto value = *( ( float* )&tmpBuffer );
Nullable<float> result( value );
return result;
}
return Nullable<float>( );
}
virtual std::complex<float> ReadComplexSingle( )
{
float real = ReadSingle( );
float imag = ReadSingle( );
std::complex<float> result( real, imag );
return result;
}
virtual Nullable< std::complex<float> > ReadNullableComplexSingle( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
float real = ReadSingle( );
float imag = ReadSingle( );
std::complex<float> value( real, imag );
Nullable< std::complex<float> > result( value );
return result;
}
return Nullable< std::complex<float> >( );
}
virtual double ReadDouble( )
{
FillBuffer( 8 );
uint lo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint hi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
unsigned long long tmpBuffer = ( ( unsigned long long ) hi ) << 32 | lo;
return *( ( double* )&tmpBuffer );
}
virtual Nullable<double> ReadNullableDouble( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
FillBuffer( 8 );
uint lo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint hi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
unsigned long long tmpBuffer = ( ( unsigned long long ) hi ) << 32 | lo;
auto value = *( ( double* )&tmpBuffer );
Nullable<double> result( value );
return result;
}
return Nullable<double>( );
}
virtual std::complex<double> ReadComplexDouble( )
{
auto real = ReadDouble( );
auto imag = ReadDouble( );
std::complex<double> result( real, imag );
return result;
}
virtual Nullable< std::complex<double> > ReadNullableComplexDouble( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
auto real = ReadDouble( );
auto imag = ReadDouble( );
std::complex<double> value( real, imag );
Nullable< std::complex<double> > result( value );
return result;
}
return Nullable< std::complex<double> >( );
}
virtual Guid ReadGuid( )
{
std::array<Byte, 16> bytes;
auto bytesRead = InStream->Read( bytes.data( ), 16 );
if ( bytesRead < 16 )
{
throw IO::EndOfStreamException( );
}
Guid result( bytes );
return result;
}
virtual Nullable< Guid > ReadNullableGuid( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
auto value = ReadGuid( );
Nullable< Guid > result( value );
return result;
}
return Nullable< Guid >( );
}
virtual DateTime ReadDateTime( )
{
auto ticks = this->ReadInt64( );
DateTime result( ticks );
return result;
}
virtual Nullable< DateTime > ReadNullableDateTime( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
auto value = ReadDateTime( );
Nullable< DateTime > result( value );
return result;
}
return Nullable< DateTime >( );
}
virtual TimeSpan ReadTimeSpan( )
{
auto ticks = this->ReadInt64( );
TimeSpan result( ticks );
return result;
}
virtual Nullable< TimeSpan > ReadNullableTimeSpan( )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
auto value = ReadTimeSpan( );
Nullable< TimeSpan > result( value );
return result;
}
return Nullable< TimeSpan >( );
}
virtual AnsiString ReadAnsiString( )
{
// Length of the string in bytes, not chars
int stringLength = Read7BitEncodedInt( );
if ( stringLength < 0 )
{
throw new IO::IOException( "Invalid string length" );
}
if ( stringLength == 0 )
{
return AnsiString( );
}
AnsiString result;
result.SetLength( stringLength );
auto bytesRead = InStream->Read( result.c_str( ), static_cast<size_t>( stringLength ) );
if ( bytesRead < static_cast<long long>( stringLength ) )
{
throw IO::EndOfStreamException( );
}
return result;
}
virtual WideString ReadWideString( )
{
auto s = ReadAnsiString( );
auto result = WideString::From( s );
return result;
}
#ifdef HWIN_STRING_IS_WIDE
String ReadString( )
{
return this->ReadWideString( );
}
#else
String ReadString( )
{
return this->ReadAnsiString( );
}
#endif
virtual long long Read( char* buffer, size_t bufferLength, size_t index, size_t count )
{
if ( buffer == nullptr )
{
throw ArgumentNullException( "buffer" );
}
if ( bufferLength - index < count )
{
throw new ArgumentException( "bufferLength" );
}
auto result = InStream->Read( &buffer[index], count );
return result;
}
virtual long long Read( char* buffer, size_t index, size_t count )
{
if ( buffer == nullptr )
{
throw ArgumentNullException( "buffer" );
}
auto result = InStream->Read( &buffer[index], count );
return result;
}
void ReadBooleanArray( std::vector<bool>& destination )
{
FillBuffer( 8 );
uint lo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint hi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
auto size = ( ( unsigned long long ) hi ) << 32 | lo;
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 1 );
destination.push_back( buffer_[0] != 0 );
}
}
void ReadNullableBooleanArray( Nullable< std::vector<bool> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<bool> values;
ReadBooleanArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
size_t ReadSize( )
{
auto size = static_cast<size_t>( ReadInt32( ) );
return size;
}
std::vector< bool > ReadBooleanArray( )
{
std::vector< bool > result;
ReadBooleanArray( result );
return result;
}
void ReadByteArray( std::vector<byte>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 1 );
destination.push_back( buffer_[0] != 0 );
}
}
void ReadNullableByteArray( Nullable< std::vector<byte> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<byte> values;
ReadByteArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< byte > ReadByteArray( )
{
std::vector< byte > result;
ReadByteArray( result );
return result;
}
void ReadSByteArray( std::vector<char>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 1 );
destination.push_back( buffer_[0] != 0 );
}
}
void ReadNullableSByteArray( Nullable< std::vector<char> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<char> values;
ReadSByteArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< char > ReadSByteArray( )
{
std::vector< char > result;
ReadSByteArray( result );
return result;
}
void ReadInt16Array( std::vector<short>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 2 );
destination.push_back( ( short )( buffer_[0] | buffer_[1] << 8 ) );
}
}
void ReadNullableInt16Array( Nullable< std::vector<short> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<short> values;
ReadInt16Array( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< short > ReadInt16Array( )
{
std::vector< short > result;
ReadInt16Array( result );
return result;
}
void ReadUInt16Array( std::vector<unsigned short>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 2 );
destination.push_back( ( unsigned short )( buffer_[0] | buffer_[1] << 8 ) );
}
}
void ReadNullableUInt16Array( Nullable< std::vector<unsigned short> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<unsigned short> values;
ReadUInt16Array( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< unsigned short > ReadUInt16Array( )
{
std::vector< unsigned short > result;
ReadUInt16Array( result );
return result;
}
void ReadInt32Array( std::vector<int>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 4 );
destination.push_back( ( int )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 ) );
}
}
void ReadNullableInt32Array( Nullable< std::vector<int> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<int> values;
ReadInt32Array( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< int > ReadInt32Array( )
{
std::vector< int > result;
ReadInt32Array( result );
return result;
}
void ReadUInt32Array( std::vector<unsigned int>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 4 );
destination.push_back( ( unsigned int )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 ) );
}
}
void ReadNullableUInt32Array( Nullable< std::vector<unsigned int> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<unsigned int> values;
ReadUInt32Array( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< unsigned int > ReadUInt32Array( )
{
std::vector< unsigned int > result;
ReadUInt32Array( result );
return result;
}
void ReadInt64Array( std::vector<long long>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 8 );
uint vlo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint vhi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
destination.push_back( ( long long )( ( unsigned long long ) vhi ) << 32 | vlo );
}
}
void ReadNullableInt64Array( Nullable< std::vector<long long> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<long long> values;
ReadInt64Array( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< long long > ReadInt64Array( )
{
std::vector< long long > result;
ReadInt64Array( result );
return result;
}
void ReadUInt64Array( std::vector<unsigned long long>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 8 );
uint vlo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint vhi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
destination.push_back( ( ( unsigned long long ) vhi ) << 32 | vlo );
}
}
void ReadNullableUInt64Array( Nullable< std::vector<unsigned long long> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<unsigned long long> values;
ReadUInt64Array( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< unsigned long long > ReadUInt64Array( )
{
std::vector< unsigned long long > result;
ReadUInt64Array( result );
return result;
}
void ReadSingleArray( std::vector<float>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 4 );
uint tmpBuffer = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
destination.push_back( *( ( float* )&tmpBuffer ) );
}
}
void ReadNullableSingleArray( Nullable< std::vector<float> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<float> values;
ReadSingleArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< float > ReadSingleArray( )
{
std::vector< float > result;
ReadSingleArray( result );
return result;
}
void ReadComplexSingleArray( std::vector< std::complex< float > >& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 4 );
uint realTmpBuffer = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
FillBuffer( 4 );
uint imagTmpBuffer = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
destination.emplace_back( *( ( float* )&realTmpBuffer ), *( ( float* )&imagTmpBuffer ) );
}
}
void ReadNullableComplexSingleArray( Nullable< std::vector< std::complex< float > > >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<std::complex< float >> values;
ReadComplexSingleArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< std::complex< float > > ReadComplexSingleArray( )
{
std::vector< std::complex< float > > result;
ReadComplexSingleArray( result );
return result;
}
void ReadDoubleArray( std::vector<double>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 8 );
uint lo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint hi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
unsigned long long tmpBuffer = ( ( unsigned long long ) hi ) << 32 | lo;
destination.push_back( *( ( float* )&tmpBuffer ) );
}
}
void ReadNullableDoubleArray( Nullable< std::vector<double> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<double> values;
ReadDoubleArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< double > ReadDoubleArray( )
{
std::vector< double > result;
ReadDoubleArray( result );
return result;
}
void ReadComplexDoubleArray( std::vector< std::complex< double > >& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 8 );
uint vlo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint vhi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
unsigned long long tmpBufferReal = ( ( unsigned long long ) vhi ) << 32 | vlo;
vlo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
vhi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
unsigned long long tmpBufferImag = ( ( unsigned long long ) vhi ) << 32 | vlo;
destination.emplace_back( *( ( double* )&tmpBufferReal ), *( ( double* )&tmpBufferImag ) );
}
}
void ReadNullableComplexDoubleArray( Nullable< std::vector< std::complex< double > > >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<std::complex< double >> values;
ReadComplexDoubleArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< std::complex< double > > ReadComplexDoubleArray( )
{
std::vector< std::complex< double > > result;
ReadComplexDoubleArray( result );
return result;
}
void ReadDateTimeArray( std::vector<DateTime>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 8 );
uint vlo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint vhi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
destination.emplace_back( ( long long )( ( unsigned long long ) vhi ) << 32 | vlo );
}
}
void ReadNullableDateTimeArray( Nullable< std::vector<DateTime> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<DateTime> values;
ReadDateTimeArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< DateTime > ReadDateTimeArray( )
{
std::vector< DateTime > result;
ReadDateTimeArray( result );
return result;
}
void ReadTimeSpanArray( std::vector<TimeSpan>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
FillBuffer( 8 );
uint vlo = ( uint )( buffer_[0] | buffer_[1] << 8 | buffer_[2] << 16 | buffer_[3] << 24 );
uint vhi = ( uint )( buffer_[4] | buffer_[5] << 8 | buffer_[6] << 16 | buffer_[7] << 24 );
destination.emplace_back( ( long long )( ( unsigned long long ) vhi ) << 32 | vlo );
}
}
void ReadNullableTimeSpanArray( Nullable< std::vector<TimeSpan> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<TimeSpan> values;
ReadTimeSpanArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< TimeSpan > ReadTimeSpanArray( )
{
std::vector< TimeSpan > result;
ReadTimeSpanArray( result );
return result;
}
void ReadAnsiStringArray( std::vector<AnsiString>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
int stringLength = Read7BitEncodedInt( );
if ( stringLength < 0 )
{
throw new IO::IOException( "Invalid string length" );
}
if ( stringLength == 0 )
{
destination.emplace_back( AnsiString( ) );
}
else
{
AnsiString result;
result.SetLength( stringLength );
auto bytesRead = InStream->Read( result.c_str( ), static_cast<size_t>( stringLength ) );
if ( bytesRead < static_cast<long long>( stringLength ) )
{
throw IO::EndOfStreamException( );
}
destination.push_back( result );
}
}
}
void ReadNullableAnsiStringArray( Nullable< std::vector<AnsiString> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<AnsiString> values;
ReadAnsiStringArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
void ReadStringArray( std::vector<String>& destination )
{
#ifdef HWIN_STRING_IS_WIDE
ReadWideStringArray( destination );
#else
ReadAnsiStringArray( destination );
#endif
}
std::vector<AnsiString> ReadAnsiStringArray( )
{
std::vector<AnsiString> result;
ReadAnsiStringArray( result );
return result;
}
void ReadWideStringArray( std::vector<WideString>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
for ( size_t i = 0; i < size; i++ )
{
int stringLength = Read7BitEncodedInt( );
if ( stringLength < 0 )
{
throw new IO::IOException( "Invalid string length" );
}
if ( stringLength == 0 )
{
destination.emplace_back( WideString( ) );
}
else
{
AnsiString result;
result.SetLength( stringLength );
auto bytesRead = InStream->Read( result.c_str( ), static_cast<size_t>( stringLength ) );
if ( bytesRead < static_cast<long long>( stringLength ) )
{
throw IO::EndOfStreamException( );
}
destination.push_back( WideString::From( result ) );
}
}
}
void ReadNullableWideStringArray( Nullable< std::vector<WideString> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<WideString> values;
ReadWideStringArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector<WideString> ReadWideStringArray( )
{
std::vector<WideString> result;
ReadWideStringArray( result );
return result;
}
#ifdef HWIN_STRING_IS_WIDE
std::vector<String> ReadStringArray( )
{
return this->ReadWideStringArray( );
}
#else
std::vector<String> ReadStringArray( )
{
return this->ReadAnsiStringArray( );
}
#endif
void ReadGuidArray( std::vector<Guid>& destination )
{
auto size = ReadSize( );
destination.resize( 0 );
destination.reserve( size );
std::array<Byte, 16> bytes;
for ( size_t i = 0; i < size; i++ )
{
auto bytesRead = InStream->Read( bytes.data( ), 16 );
if ( bytesRead < 16 )
{
throw IO::EndOfStreamException( );
}
destination.emplace_back( bytes );
}
}
void ReadNullableGuidArray( Nullable< std::vector<Guid> >& destination )
{
byte isNotNull = 0;
auto bytesRead = InStream->Read( &isNotNull, 1 );
if ( bytesRead == 0 )
{
throw IO::EndOfStreamException( );
}
if ( isNotNull )
{
std::vector<Guid> values;
ReadGuidArray( values );
destination.SetValue( values );
}
else
{
destination.SetValue( nullptr );
}
}
std::vector< Guid > ReadGuidArray( )
{
std::vector< Guid > result;
ReadGuidArray( result );
return result;
}
};
}
}
#pragma pack(pop)
#ifdef _MANAGED
#pragma managed(pop)
#endif
#endif