medfall

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit c3d3144e9c77e720583619ecc9087549eb3f3883
parent 296d2ef944256a47e8e89ea21c8c9b6077aa4230
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Sun Oct 16 20:40:38 +0300

Use runtime endianness checking

Diffstat:
intrinsics.h | 7+++++++
platform_atomic.h | 6------
platform_endian.h | 18------------------
stream.h | 38+++++++++++++-------------------------
4 files changed, 20 insertions(+), 49 deletions(-)
diff --git a/intrinsics.h b/intrinsics.h @@ -116,6 +116,13 @@ inline void mike_assert( const bool predicate, const char * message ) { #define CONCAT( a, b ) CONCAT_HELPER( a, b ) #define assert( predicate ) mike_assert( predicate, "\x1b[1;31massertion failed at " __FILE__ " line " STRINGIFY( __LINE__ ) ": \x1b[0;1m" #predicate "\x1b[0m" ) +#define ASSERT assert + +#if __cplusplus < 201103L +#define STATIC_ASSERT( p ) static int CONCAT( STATIC_ASSERT, __COUNTER__ )[ int( p ) - 1 ] +#else +#define STATIC_ASSERT( p ) static_assert( p ) +#endif // TODO: this sucks inline u8 * file_get_contents( const char * path, size_t * out_len = NULL ) { diff --git a/platform_atomic.h b/platform_atomic.h @@ -118,11 +118,5 @@ struct atomic_u64 { #define exchange_seqcst( atom, x ) ( atom )->exchange( x, std::memory_order_seq_cst ) #define compare_exchange_seqcst( atom, before, after ) ( atom )->compare_exchange_strong( *( before ), after, std::memory_order_seq_cst, std::memory_order_seq_cst ) -// relacy requires C++98 which doesn't have static_assert -// TODO: maybe this should go somewhere else? -#if __cplusplus < 201103L -#define static_assert( p ) static int CONCAT( static_assert, __COUNTER__ )[ int( p ) - 1 ] -#endif - #endif // RL_TEST #endif // _PLATFORM_ATOMIC_H_ diff --git a/platform_endian.h b/platform_endian.h @@ -1,18 +0,0 @@ -#ifndef _PLATFORM_ENDIAN_H_ -#define _PLATFORM_ENDIAN_H_ - -#if defined( __linux__) || defined( __APPLE__ ) || defined( __OpenBSD__ ) -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define PLATFORM_LITTLE_ENDIAN 1 -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define PLATFORM_BIG_ENDIAN 1 -# else -# error "I can't tell what byte order this machine uses" -# endif -#elif defined( _WIN32 ) -# define PLATFORM_LITTLE_ENDIAN 1 -#else -# error new platform -#endif - -#endif // _PLATFORM_ENDIAN_H_ diff --git a/stream.h b/stream.h @@ -2,49 +2,37 @@ #define _STREAM_H_ #include "intrinsics.h" -#include "platform_endian.h" struct Stream { char * ptr; }; -#if PLATFORM_LITTLE_ENDIAN +bool cpu_is_little_endian() { +#if FORCE_LITTLE_ENDIAN + return true; +#else + u16 i = 1; + char * c = ( char * ) &i; + return c[ 0 ] == 1; +#endif +} +// TODO: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html +// maybe use __builtin_bswap16/32/64 and http://stackoverflow.com/a/13208789 #define DEF_READ_WRITE( type ) \ inline Stream read_##type( Stream stream, type * v ) { \ + ASSERT( cpu_is_little_endian() ); \ *v = *( type * ) stream.ptr; \ stream.ptr += sizeof( type ); \ return stream; \ } \ inline Stream write_##type( Stream stream, const type * v ) { \ + ASSERT( cpu_is_little_endian() ); \ *( type * ) stream.ptr = *v; \ stream.ptr += sizeof( type ); \ return stream; \ } -#elif PLATFORM_BIG_ENDIAN - -#define DEF_READ_WRITE( type ) \ - inline Stream read_##type( Stream stream, type * v ) { \ - char swapped[ sizeof( type ) ]; \ - for( int i = 0; i < sizeof( type ); i++ ) { \ - swapped[ i ] = stream.ptr[ sizeof( swapped ) - 1 - i ]; \ - } \ - *v = *( type * ) swapped; \ - stream.ptr += sizeof( type ); \ - return stream; \ - } \ - inline Stream write_##type( Stream stream, const type * v ) { \ - char * v_as_string = ( char * ) v; \ - for( int i = 0; i < sizeof( type ); i++ ) { \ - stream.ptr[ i ] = v_as_string[ sizeof( type ) - 1 - i ]; \ - } \ - stream.ptr += sizeof( type ); \ - return stream; \ - } - -#endif - DEF_READ_WRITE( u8 ) DEF_READ_WRITE( u16 ) DEF_READ_WRITE( u32 )