corelib/include/ebcl/BinaryStreams.hh

180 lines
4 KiB
C++

/******************************************************************************/
/* BINARY READER/WRITER FOR STREAMS *******************************************/
/******************************************************************************/
#ifndef _H_EBCL_BINARYSTREAMS
#define _H_EBCL_BINARYSTREAMS
#include <ebcl/Streams.hh>
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 <ebcl/inline/BinaryStreams.hh>