/******************************************************************************/ /* BINARY READER/WRITER FOR STREAMS - INLINE CODE *****************************/ /******************************************************************************/ #pragma once #include namespace lw { /*= T_BinaryReader ===========================================================*/ inline T_BinaryReader::T_BinaryReader( A_InputStream& stream , E_Endian endian ) noexcept : stream_( stream ) , endian_( endian ) { } inline A_InputStream& T_BinaryReader::stream( ) const { return stream_; } inline E_Endian T_BinaryReader::endian( ) const { return endian_; } /*----------------------------------------------------------------------------*/ template< typename T > inline T T_BinaryReader::readNumericNative( ) const { static_assert( std::is_integral< T >( ) || std::is_floating_point< T >( ) , "numeric type expected" ); T value = 0; auto r = stream_.read( &value , sizeof( T ) ); if ( r != sizeof( T ) ) { throw X_StreamError( E_StreamError::BAD_DATA ); } return value; } template< typename T > inline T T_BinaryReader::readNumericLittleEndian( ) const { return T_LittleEndian< T >::convert( readNumericNative< T >( ) ); } template< typename T > inline T T_BinaryReader::readNumericBigEndian( ) const { return T_BigEndian< T >::convert( readNumericNative< T >( ) ); } template< typename T > inline T T_BinaryReader::read( ) const { return T_Reader_< T >::read( *this ); } /*----------------------------------------------------------------------------*/ template< typename T > inline T T_BinaryReader::T_Reader_< T , true >::read( T_BinaryReader const& reader ) { if ( reader.endian_ == E_Endian::BIG ) { return reader.readNumericBigEndian< T >( ); } else { return reader.readNumericLittleEndian< T >( ); } } template< typename T > inline T T_BinaryReader::T_Reader_< T , false >::read( T_BinaryReader const& reader ) { typedef T_ObjectReader< T > Reader; return Reader::read( reader ); } /*= T_BinaryWriter ===========================================================*/ inline T_BinaryWriter::T_BinaryWriter( A_OutputStream& stream , E_Endian endian ) noexcept : stream_( stream ) , endian_( endian ) { } /*----------------------------------------------------------------------------*/ inline A_OutputStream& T_BinaryWriter::stream( ) const { return stream_; } inline E_Endian T_BinaryWriter::endian( ) const { return endian_; } /*----------------------------------------------------------------------------*/ template< typename T > inline void T_BinaryWriter::writeNumericNative( T value ) const { static_assert( std::is_integral< T >( ) || std::is_floating_point< T >( ) , "numeric type expected" ); stream_.write( &value , sizeof( T ) ); } template< typename T > inline void T_BinaryWriter::writeNumericLittleEndian( T const& value ) const { writeNumericNative( T_LittleEndian< T >::convert( value ) ); } template< typename T > inline void T_BinaryWriter::writeNumericBigEndian( T const& value ) const { writeNumericNative( T_BigEndian< T >::convert( value ) ); } template< typename T > inline void T_BinaryWriter::write( T const& value ) const { T_Writer_< T >::write( *this , value ); } /*----------------------------------------------------------------------------*/ template< typename T > inline void T_BinaryWriter::T_Writer_< T , true >::write( T_BinaryWriter const& writer , T value ) { if ( writer.endian_ == E_Endian::BIG ) { writer.writeNumericBigEndian( value ); } else { writer.writeNumericLittleEndian( value ); } } template< typename T > inline void T_BinaryWriter::T_Writer_< T , false >::write( T_BinaryWriter const& writer , T const& value ) { typedef T_ObjectWriter< T > Writer; Writer::write( writer , value ); } } // namespace