commit fd7ebc309c1b972ebc92484302553e84ad8f23fd parent 019addb26c500bc68ed344efa94fc5bbcea09749 Author: Michael Savage <mikejsavage@gmail.com> Date: Thu Dec 22 22:27:09 +0200 New ReadStream/WriteStream implementation Diffstat:
stream.h | | | 86 | +++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------- |
diff --git a/stream.h b/stream.h @@ -1,19 +1,16 @@ -// TODO: need to come up with something for writers though - -#ifndef _STREAM_H_ -#define _STREAM_H_ +#pragma once #include "intrinsics.h" #include "platform_inline.h" struct ReadStream { ReadStream( char * buf, size_t len ) { - ptr = buf; + cursor = buf; one_past_end = buf + len; ok = true; } - char * ptr; + char * cursor; char * one_past_end; bool ok; }; @@ -21,13 +18,17 @@ struct ReadStream { struct WriteStream { WriteStream( char * buf, size_t len ) { start = buf; - ptr = buf; + cursor = buf; one_past_end = buf + len; ok = true; } + size_t len() const { + return checked_cast< size_t >( cursor - start ); + } + char * start; - char * ptr; + char * cursor; char * one_past_end; bool ok; }; @@ -38,30 +39,61 @@ static bool cpu_is_little_endian() { return c[ 0 ] == 1; } +struct StreamSerialiser { + StreamSerialiser( WriteStream * s ) { + stream = s; + } + + template< typename T > + void operator()( const T & x ) { + ASSERT( cpu_is_little_endian() ); + if( !stream->ok || checked_cast< size_t >( stream->one_past_end - stream->cursor ) < sizeof( T ) ) { + stream->ok = false; + return; + } + memcpy( stream->cursor, &x, sizeof( T ) ); + stream->cursor += sizeof( T ); + } + + WriteStream * stream; +}; + +struct StreamDeserialiser { + StreamDeserialiser( ReadStream * s ) { + stream = s; + } + + template< typename T > + void operator()( T & x ) { + ASSERT( cpu_is_little_endian() ); + if( !stream->ok || checked_cast< size_t >( stream->one_past_end - stream->cursor ) < sizeof( T ) ) { + stream->ok = false; + x = T(); + return; + } + memcpy( &x, stream->cursor, sizeof( T ) ); + stream->cursor += sizeof( T ); + } + + ReadStream * stream; +}; + +template< typename T > +inline void read( ReadStream * stream, T * x ) { + visit( *x, StreamDeserialiser( stream ) ); +} + +template< typename T > +inline void write( WriteStream * stream, const T & x ) { + visit( x, StreamSerialiser( stream ) ); +} + #define DEF_READ_WRITE( T ) \ - inline void read( ReadStream * stream, T * x ) { \ - ASSERT( cpu_is_little_endian() ); \ - if( !stream->ok || checked_cast< size_t >( stream->one_past_end - stream->ptr ) < sizeof( T ) ) { \ - stream->ok = false; \ - *x = T(); \ - } \ - memcpy( x, stream->ptr, sizeof( T ) ); \ - stream->ptr += sizeof( T ); \ - } \ inline T read_##T( ReadStream * stream ) { \ T x; \ read( stream, &x ); \ return x; \ } \ - inline void write( WriteStream * stream, const T & x ) { \ - ASSERT( cpu_is_little_endian() ); \ - if( !stream->ok || checked_cast< size_t >( stream->one_past_end - stream->ptr ) < sizeof( T ) ) { \ - stream->ok = false; \ - return; \ - } \ - memcpy( stream->ptr, &x, sizeof( T ) ); \ - stream->ptr += sizeof( T ); \ - } \ inline void write_##T( WriteStream * stream, const T & x ) { \ write( stream, x ); \ } @@ -78,5 +110,3 @@ DEF_READ_WRITE( float ) DEF_READ_WRITE( double ) #undef DEF_READ_WRITE - -#endif // _STREAM_H_