There is a problem with your code: when you use the
reinterpret_cast
, you don't actually know what you are writing
to the stream, so you don't know what you are testing. If you
want to test how your code reacts to a stream of bytes in
a binary format, you can easily initialize an
std::istringstream
with an arbitrary stream of bytes:
char bytes[] = { /*...*/ };
std::istringstream( std::string( std::begin( bytes ), std::end( bytes ) ) );
(If you don't have C++11, you can easily write your own begin
and end
.)
In this way, you'll know exactly what the bytes are, rather than depending on the aleas of how your implementation represents any specific type.
Alternatively: if you're reading and writing binary data, you
may want to define classes which do it, using >>
and <<
.
Such classes would be unrelated to std::istream
and
std::ostream
, but could logically use std::ios_base
to
provide support for the conventional error reporting and the
interface to std::streambuf
. The class would then have
members something like the following:
namespace {
class ByteGetter
{
public:
explicit ByteGetter( ixdrstream& stream )
: mySentry( stream )
, myStream( stream )
, mySB( stream->rdbuf() )
, myIsFirst( true )
{
if ( ! mySentry ) {
mySB = NULL ;
}
}
std::uint8_t get()
{
int result = 0 ;
if ( mySB != NULL ) {
result = mySB->sgetc() ;
if ( result == EOF ) {
result = 0 ;
myStream.setstate( myIsFirst
? std::ios::failbit | std::ios::eofbit
: std::ios::failbit | std::ios::eofbit | std::ios::badbit ) ;
}
}
myIsFirst = false ;
return result ;
}
private:
ixdrstream::sentry mySentry ;
ixdrstream& myStream ;
std::streambuf* mySB ;
bool myIsFirst ;
} ;
}
ixdrstream&
ixdrstream::operator>>( std::uint32_t& dest )
{
ByteGetter source( *this ) ;
std::uint32_t tmp = source.get() << 24 ;
tmp |= source.get() << 16 ;
tmp |= source.get() << 8 ;
tmp |= source.get() ;
if ( *this ) {
dest = tmp ;
}
return *this ;
}
(For a maximum of portability, you might wont to avoid the
uint8_t
and uint32_t
. At this level, writing code without
knowing the exact size of the type is a little more difficult,
so if you are certain you'll never have to port to an exotic
system where they may not be defined, it's probably worth saving
yourself the extra work.)