/******************************************************************************/ /* BINARY READER/WRITER FOR STREAMS *******************************************/ /******************************************************************************/ #ifndef _H_EBCL_BINARYSTREAMS #define _H_EBCL_BINARYSTREAMS #include namespace ebcl { /*= OBJECT READER/WRITER TEMPLATES ===========================================*/ /* * This pair of templates must be specialized to handle specific types. */ struct T_BinaryReader; struct T_BinaryWriter; template< typename T > struct T_ObjectReader { static T read( T_BinaryReader const& reader ); }; template< typename T > struct T_ObjectWriter { static void write( T_BinaryWriter const& writer , T const& string ); }; // Helper macros to declare and define readers and writers #define M_DECLARE_OBJECT_READER( Type ) \ template< > \ struct T_ObjectReader< Type > \ { \ static Type read( T_BinaryReader const& ); \ } #define M_DEFINE_OBJECT_READER( Type ) \ Type T_ObjectReader< Type >::read( T_BinaryReader const & reader ) #define M_DECLARE_OBJECT_WRITER( Type ) \ template< > \ struct T_ObjectWriter< Type > \ { \ static void write( T_BinaryWriter const& , \ Type const& ); \ } #define M_DEFINE_OBJECT_WRITER( Type ) \ void T_ObjectWriter< Type >::write( T_BinaryWriter const & writer , \ Type const & item ) /*= READER ===================================================================*/ struct T_BinaryReader { private: A_InputStream& stream_; const E_Endian endian_; public: T_BinaryReader( ) = delete; explicit T_BinaryReader( A_InputStream& stream , E_Endian endian = E_Endian::NATIVE ) noexcept; T_BinaryReader( T_BinaryReader const& other ) noexcept = delete; T_BinaryReader( T_BinaryReader&& other ) noexcept = delete; A_InputStream& stream( ) const; E_Endian endian( ) const; template< typename T > T readNumericNative( ) const; template< typename T > T readNumericLittleEndian( ) const; template< typename T > T readNumericBigEndian( ) const; template< typename T > T read( ) const; private: template< typename T , bool IsNum = std::is_integral< T >::value || std::is_floating_point< T >::value > struct T_Reader_ { }; template< typename T > struct T_Reader_< T , true > { static T read( T_BinaryReader const& reader ); }; template< typename T > struct T_Reader_< T , false > { static T read( T_BinaryReader const& reader ); }; }; /*= WRITER ===================================================================*/ struct T_BinaryWriter { private: A_OutputStream& stream_; const E_Endian endian_; public: T_BinaryWriter( ) noexcept = delete; explicit T_BinaryWriter( A_OutputStream& stream , E_Endian endian = E_Endian::NATIVE ) noexcept; T_BinaryWriter( T_BinaryWriter const& other ) noexcept = delete; T_BinaryWriter( T_BinaryWriter&& other ) noexcept = delete; A_OutputStream& stream( ) const; E_Endian endian( ) const; template< typename T > void writeNumericNative( T value ) const; template< typename T > void writeNumericLittleEndian( T const& value ) const; template< typename T > void writeNumericBigEndian( T const& value ) const; template< typename T > void write( T const& value ) const; private: template< typename T , bool IsNum = std::is_integral< T >::value || std::is_floating_point< T >::value > struct T_Writer_ { }; template< typename T > struct T_Writer_< T , true > { static void write( T_BinaryWriter const& writer , T value ); }; template< typename T > struct T_Writer_< T , false > { static void write( T_BinaryWriter const& writer , T const& value ); }; }; /*= STREAM INTERFACES FOR OBJECTS THAT ARE NEEDED BY STREAMS =================*/ M_DECLARE_OBJECT_READER( T_Character ); M_DECLARE_OBJECT_WRITER( T_Character ); M_DECLARE_OBJECT_READER( T_String ); M_DECLARE_OBJECT_WRITER( T_String ); M_DECLARE_OBJECT_WRITER( T_StringBuilder ); } // namespace ebcl #endif // _H_EBCL_BINARYSTREAMS #include