From 9849a71d58c77f9ebaafb3b631224f25fa05a189 Mon Sep 17 00:00:00 2001 From: bkaradzic Date: Sun, 25 Nov 2012 18:22:04 -0800 Subject: [PATCH] Added readerwriter interfaces. --- include/bx/blockalloc.h | 2 +- include/bx/bx.h | 2 +- include/bx/commandline.h | 16 +- include/bx/countof.h | 2 +- include/bx/endian.h | 2 +- include/bx/float4_sse.h | 2 +- include/bx/float4_t.h | 2 +- include/bx/foreach.h | 2 +- include/bx/handlealloc.h | 2 +- include/bx/hash.h | 194 ++++++++-------- include/bx/macros.h | 151 +++++++------ include/bx/maputil.h | 2 +- include/bx/os.h | 2 +- include/bx/radixsort.h | 2 +- include/bx/readerwriter.h | 454 ++++++++++++++++++++++++++++++++++++++ include/bx/ringbuffer.h | 2 +- include/bx/rng.h | 2 +- include/bx/sem.h | 2 +- include/bx/spscqueue.h | 2 +- include/bx/string.h | 153 +++++++++++++ include/bx/timer.h | 2 +- 21 files changed, 816 insertions(+), 184 deletions(-) create mode 100644 include/bx/readerwriter.h create mode 100644 include/bx/string.h diff --git a/include/bx/blockalloc.h b/include/bx/blockalloc.h index 7597653..6bf3e73 100644 --- a/include/bx/blockalloc.h +++ b/include/bx/blockalloc.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/bx.h b/include/bx/bx.h index 1907430..f3481e0 100644 --- a/include/bx/bx.h +++ b/include/bx/bx.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/commandline.h b/include/bx/commandline.h index d15ec7e..522c86f 100644 --- a/include/bx/commandline.h +++ b/include/bx/commandline.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ @@ -7,13 +7,7 @@ #define __BX_COMMANDLINE_H__ #include "bx.h" -#include - -#if BX_PLATFORM_POSIX -# include -# define _stricmp strcasecmp -# define _snprintf snprintf -#endif // BX_PLATFORM_ +#include "string.h" namespace bx { @@ -98,11 +92,11 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - if ('0' == *arg || _stricmp(arg, "false") ) + if ('0' == *arg || stricmp(arg, "false") ) { _value = false; } - else if ('0' != *arg || _stricmp(arg, "true") ) + else if ('0' != *arg || stricmp(arg, "true") ) { _value = true; } @@ -141,7 +135,7 @@ namespace bx } else if (NULL != _long && '-' == *arg - && 0 == _stricmp(arg+1, _long) ) + && 0 == stricmp(arg+1, _long) ) { if (0 == _numParams) { diff --git a/include/bx/countof.h b/include/bx/countof.h index 984f3b9..128e427 100644 --- a/include/bx/countof.h +++ b/include/bx/countof.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/endian.h b/include/bx/endian.h index 0bca59d..4056dce 100644 --- a/include/bx/endian.h +++ b/include/bx/endian.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/float4_sse.h b/include/bx/float4_sse.h index 239fdaa..93636f3 100644 --- a/include/bx/float4_sse.h +++ b/include/bx/float4_sse.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/float4_t.h b/include/bx/float4_t.h index 9b251f8..5ce22b7 100644 --- a/include/bx/float4_t.h +++ b/include/bx/float4_t.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/foreach.h b/include/bx/foreach.h index ce9beb7..76ba6fb 100644 --- a/include/bx/foreach.h +++ b/include/bx/foreach.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/handlealloc.h b/include/bx/handlealloc.h index 685b526..fd66642 100644 --- a/include/bx/handlealloc.h +++ b/include/bx/handlealloc.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/hash.h b/include/bx/hash.h index 7582eb2..43f8a82 100644 --- a/include/bx/hash.h +++ b/include/bx/hash.h @@ -1,96 +1,108 @@ -/* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. - * License: http://www.opensource.org/licenses/BSD-2-Clause - */ - -#ifndef __BX_HASH_H__ -#define __BX_HASH_H__ - -#include "bx.h" - -namespace bx -{ - // MurmurHash2 was written by Austin Appleby, and is placed in the public - // domain. The author hereby disclaims copyright to this source code. - #define MURMUR_M 0x5bd1e995 - #define MURMUR_R 24 - - #define mmix(_h, _k) { _k *= MURMUR_M; _k ^= _k >> MURMUR_R; _k *= MURMUR_M; _h *= MURMUR_M; _h ^= _k; } - - class HashMurmur2A - { - public: - void begin(uint32_t _seed = 0) - { - m_hash = _seed; - m_tail = 0; - m_count = 0; - m_size = 0; - } - - void add(const void* _data, int _len) - { - const uint8_t* data = (uint8_t*)_data; - m_size += _len; - - mixTail(data, _len); - - while(_len >= 4) - { - uint32_t kk = *(uint32_t*)data; - - mmix(m_hash, kk); - - data += 4; - _len -= 4; - } - - mixTail(data, _len); - } - +/* + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef __BX_HASH_H__ +#define __BX_HASH_H__ + +#include "bx.h" + +namespace bx +{ +// MurmurHash2 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +#define MURMUR_M 0x5bd1e995 +#define MURMUR_R 24 +#define mmix(_h, _k) { _k *= MURMUR_M; _k ^= _k >> MURMUR_R; _k *= MURMUR_M; _h *= MURMUR_M; _h ^= _k; } + + class HashMurmur2A + { + public: + void begin(uint32_t _seed = 0) + { + m_hash = _seed; + m_tail = 0; + m_count = 0; + m_size = 0; + } + + void add(const void* _data, int _len) + { + const uint8_t* data = (uint8_t*)_data; + m_size += _len; + + mixTail(data, _len); + + while(_len >= 4) + { + uint32_t kk = *(uint32_t*)data; + + mmix(m_hash, kk); + + data += 4; + _len -= 4; + } + + mixTail(data, _len); + } + template void add(Ty _value) { add(&_value, sizeof(Ty) ); } - - uint32_t end() - { - mmix(m_hash, m_tail); - mmix(m_hash, m_size); - - m_hash ^= m_hash >> 13; - m_hash *= MURMUR_M; - m_hash ^= m_hash >> 15; - - return m_hash; - } - - private: - void mixTail(const uint8_t*& _data, int& _len) - { - while( _len && ((_len<4) || m_count) ) - { - m_tail |= (*_data++) << (m_count * 8); - - m_count++; - _len--; - - if(m_count == 4) - { - mmix(m_hash, m_tail); - m_tail = 0; - m_count = 0; - } - } - } - - uint32_t m_hash; - uint32_t m_tail; - uint32_t m_count; - uint32_t m_size; - }; - -} // namespace bx - -#endif // __BX_HASH_H__ + + uint32_t end() + { + mmix(m_hash, m_tail); + mmix(m_hash, m_size); + + m_hash ^= m_hash >> 13; + m_hash *= MURMUR_M; + m_hash ^= m_hash >> 15; + + return m_hash; + } + + private: + void mixTail(const uint8_t*& _data, int& _len) + { + while( _len && ((_len<4) || m_count) ) + { + m_tail |= (*_data++) << (m_count * 8); + + m_count++; + _len--; + + if(m_count == 4) + { + mmix(m_hash, m_tail); + m_tail = 0; + m_count = 0; + } + } + } + + uint32_t m_hash; + uint32_t m_tail; + uint32_t m_count; + uint32_t m_size; + }; + +#undef MURMUR_M +#undef MURMUR_R +#undef mmix + + inline uint32_t hashMurmur2A(const void* _data, uint32_t _size) + { + HashMurmur2A murmur; + murmur.begin(); + murmur.add(_data, (int)_size); + return murmur.end(); + } + +} // namespace bx + +#endif // __BX_HASH_H__ diff --git a/include/bx/macros.h b/include/bx/macros.h index 29a1fe1..825fac9 100644 --- a/include/bx/macros.h +++ b/include/bx/macros.h @@ -1,66 +1,85 @@ -/* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. - * License: http://www.opensource.org/licenses/BSD-2-Clause - */ - -#ifndef __BX_MACROS_H__ -#define __BX_MACROS_H__ - -#include "bx.h" - -#define BX_VA_ARGS_COUNT_DETAIL(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10, _a11, _a12, _a13, _a14, _a15, _a16, _last, ...) _last -#define BX_VA_ARGS_COUNT(...) BX_VA_ARGS_COUNT_DETAIL(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) - -#define BX_MACRO_DISPATCHER_DETAIL1(_func, _argCount) _func ## _argCount -#define BX_MACRO_DISPATCHER_DETAIL2(_func, _argCount) BX_MACRO_DISPATCHER_DETAIL1(_func, _argCount) -#define BX_MACRO_DISPATCHER(_func, ...) BX_MACRO_DISPATCHER_DETAIL2(_func, VA_ARGS_COUNT(__VA_ARGS__) ) - -#define BX_STRINGIZE(_x) BX_STRINGIZE_(_x) -#define BX_STRINGIZE_(_x) #_x - -#define BX_FILE_LINE_LITERAL "" __FILE__ "(" BX_STRINGIZE(__LINE__) "): " - -#define BX_ALIGN_MASK(_value, _mask) ( ( (_value)+(_mask) ) & ( (~0)&(~(_mask) ) ) ) -#define BX_ALIGN_16(_value) BX_ALIGN_MASK(_value, 0xf) -#define BX_ALIGN_256(_value) BX_ALIGN_MASK(_value, 0xff) - -#if BX_COMPILER_GCC || BX_COMPILER_CLANG -# define BX_ALIGN_STRUCT(_align, _struct) _struct __attribute__( (aligned(_align) ) ) -# define BX_FUNCTION __PRETTY_FUNCTION__ -# define BX_NO_INLINE __attribute__( (noinline) ) -# define BX_FORCE_INLINE __extension__ static __inline __attribute__( (__always_inline__) ) -# define BX_ALLOW_UNUSED __attribute__( (unused) ) -# if BX_COMPILER_CLANG -# define BX_THREAD /* not supported right now */ -# else -# define BX_THREAD __thread -# endif // BX_COMPILER_CLANG -#elif BX_COMPILER_MSVC -# define BX_ALIGN_STRUCT(_align, _struct) __declspec(align(_align) ) _struct -# define BX_FUNCTION __FUNCTION__ -# define BX_NO_INLINE __declspec(noinline) -# define BX_FORCE_INLINE __forceinline -# define BX_THREAD __declspec(thread) -# define BX_ALLOW_UNUSED -#else -# error "Unknown BX_COMPILER_?" -#endif - -#define BX_ALIGN_STRUCT_16(_struct) BX_ALIGN_STRUCT(16, _struct) -#define BX_ALIGN_STRUCT_256(_struct) BX_ALIGN_STRUCT(256, _struct) - -#define BX_UNUSED(_unused) do { (void)sizeof(_unused); } while(0) - -#ifndef BX_CHECK -# define BX_CHECK(...) do {} while(0) -#endif // BX_CHECK - -#ifndef BX_TRACE -# define BX_TRACE(...) do {} while(0) -#endif // BX_TRACE - -#ifndef BX_CONFIG_SPSCQUEUE_USE_MUTEX -# define BX_CONFIG_SPSCQUEUE_USE_MUTEX 0 -#endif // BX_CONFIG_SPSCQUEUE_USE_MUTEX - -#endif // __BX_MACROS_H__ +/* + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef __BX_MACROS_H__ +#define __BX_MACROS_H__ + +#include "bx.h" + +#define BX_VA_ARGS_COUNT_DETAIL(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10, _a11, _a12, _a13, _a14, _a15, _a16, _last, ...) _last +#define BX_VA_ARGS_COUNT(...) BX_VA_ARGS_COUNT_DETAIL(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) + +#define BX_MACRO_DISPATCHER_DETAIL1(_func, _argCount) _func ## _argCount +#define BX_MACRO_DISPATCHER_DETAIL2(_func, _argCount) BX_MACRO_DISPATCHER_DETAIL1(_func, _argCount) +#define BX_MACRO_DISPATCHER(_func, ...) BX_MACRO_DISPATCHER_DETAIL2(_func, BX_VA_ARGS_COUNT(__VA_ARGS__) ) + +#define BX_MAKEFOURCC(_a, _b, _c, _d) ( ( (uint32_t)(_a) | ( (uint32_t)(_b) << 8) | ( (uint32_t)(_c) << 16) | ( (uint32_t)(_d) << 24) ) ) + +#define BX_STRINGIZE(_x) BX_STRINGIZE_(_x) +#define BX_STRINGIZE_(_x) #_x + +#define BX_FILE_LINE_LITERAL "" __FILE__ "(" BX_STRINGIZE(__LINE__) "): " + +#define BX_ALIGN_MASK(_value, _mask) ( ( (_value)+(_mask) ) & ( (~0)&(~(_mask) ) ) ) +#define BX_ALIGN_16(_value) BX_ALIGN_MASK(_value, 0xf) +#define BX_ALIGN_256(_value) BX_ALIGN_MASK(_value, 0xff) +#define BX_ALIGN_4096(_value) BX_ALIGN_MASK(_value, 0xfff) + +#if BX_COMPILER_GCC || BX_COMPILER_CLANG +# define BX_ALIGN_STRUCT(_align, _struct) _struct __attribute__( (aligned(_align) ) ) +# define BX_ALLOW_UNUSED __attribute__( (unused) ) +# define BX_FORCE_INLINE __extension__ static __inline __attribute__( (__always_inline__) ) +# define BX_FUNCTION __PRETTY_FUNCTION__ +# define BX_NO_INLINE __attribute__( (noinline) ) +# define BX_NO_RETURN __attribute__( (noreturn) ) +# define BX_NO_VTABLE +# define BX_OVERRIDE +# define BX_PRINTF_ARGS(_format, _args) __attribute__ ( (format(__printf__, _format, _args) ) ) +# if BX_COMPILER_CLANG +# define BX_THREAD /* not supported right now */ +# else +# define BX_THREAD __thread +# endif // BX_COMPILER_CLANG +#elif BX_COMPILER_MSVC +# define BX_ALIGN_STRUCT(_align, _struct) __declspec(align(_align) ) _struct +# define BX_ALLOW_UNUSED +# define BX_FORCE_INLINE __forceinline +# define BX_FUNCTION __FUNCTION__ +# define BX_NO_INLINE __declspec(noinline) +# define BX_NO_RETURN +# define BX_NO_VTABLE __declspec(novtable) +# define BX_OVERRIDE override +# define BX_PRINTF_ARGS(_format, _args) +# define BX_THREAD __declspec(thread) +#else +# error "Unknown BX_COMPILER_?" +#endif + +#define BX_ALIGN_STRUCT_16(_struct) BX_ALIGN_STRUCT(16, _struct) +#define BX_ALIGN_STRUCT_256(_struct) BX_ALIGN_STRUCT(256, _struct) + +#define BX_UNUSED(_unused) do { (void)sizeof(_unused); } while(0) + +#ifndef BX_CHECK +# define BX_CHECK(...) do {} while(0) +#endif // BX_CHECK + +#ifndef BX_TRACE +# define BX_TRACE(...) do {} while(0) +#endif // BX_TRACE + +#ifndef BX_WARN +# define BX_WARN(...) do {} while(0) +#endif // BX_CHECK + +#ifndef BX_CONFIG_SPSCQUEUE_USE_MUTEX +# define BX_CONFIG_SPSCQUEUE_USE_MUTEX 0 +#endif // BX_CONFIG_SPSCQUEUE_USE_MUTEX + +#ifndef BX_CONFIG_CRT_FILE_READER_WRITER +# define BX_CONFIG_CRT_FILE_READER_WRITER BX_PLATFORM_WINDOWS|BX_PLATFORM_LINUX|BX_PLATFORM_OSX +#endif // BX_CONFIG_CRT_FILE_READER_WRITER + +#endif // __BX_MACROS_H__ diff --git a/include/bx/maputil.h b/include/bx/maputil.h index daa7248..b92c9cc 100644 --- a/include/bx/maputil.h +++ b/include/bx/maputil.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/os.h b/include/bx/os.h index 57e8e78..77a9822 100644 --- a/include/bx/os.h +++ b/include/bx/os.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/radixsort.h b/include/bx/radixsort.h index 78b33f2..f5ab322 100644 --- a/include/bx/radixsort.h +++ b/include/bx/radixsort.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/readerwriter.h b/include/bx/readerwriter.h new file mode 100644 index 0000000..58d1cec --- /dev/null +++ b/include/bx/readerwriter.h @@ -0,0 +1,454 @@ +/* + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef __BX_READERWRITER_H__ +#define __BX_READERWRITER_H__ + +#include + +#include "bx.h" + +#if BX_COMPILER_MSVC +# define fseeko64 _fseeki64 +# define ftello64 _ftelli64 +#endif // BX_COMPILER_MSVC + +namespace bx +{ + struct Whence + { + enum Enum + { + Begin, + Current, + End, + }; + }; + + struct BX_NO_VTABLE ReaderI + { + virtual ~ReaderI() = 0; + virtual int32_t read(void* _data, int32_t _size) = 0; + }; + + inline ReaderI::~ReaderI() + { + } + + struct BX_NO_VTABLE WriterI + { + virtual ~WriterI() = 0; + virtual int32_t write(const void* _data, int32_t _size) = 0; + }; + + inline WriterI::~WriterI() + { + } + + struct BX_NO_VTABLE SeekerI + { + virtual ~SeekerI() = 0; + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) = 0; + }; + + inline SeekerI::~SeekerI() + { + } + + inline int32_t read(ReaderI* _reader, void* _data, int32_t _size) + { + return _reader->read(_data, _size); + } + + template + inline int32_t read(ReaderI* _reader, Ty& _value) + { + return _reader->read(&_value, sizeof(Ty) ); + } + + inline int32_t write(WriterI* _writer, const void* _data, int32_t _size) + { + return _writer->write(_data, _size); + } + + template + inline int32_t write(WriterI* _writer, const Ty& _value) + { + return _writer->write(&_value, sizeof(Ty) ); + } + + inline int64_t skip(SeekerI* _seeker, int64_t _offset) + { + return _seeker->seek(_offset, Whence::Current); + } + + inline int64_t getSize(SeekerI* _seeker) + { + int64_t offset = _seeker->seek(); + int64_t size = _seeker->seek(0, Whence::End); + _seeker->seek(offset, Whence::Begin); + return size; + } + + struct BX_NO_VTABLE ReaderSeekerI : public ReaderI, public SeekerI + { + }; + + struct BX_NO_VTABLE WriterSeekerI : public WriterI, public SeekerI + { + }; + + struct BX_NO_VTABLE FileReaderI : public ReaderSeekerI + { + virtual int32_t open(const char* _filePath) = 0; + virtual int32_t close() = 0; + }; + + struct BX_NO_VTABLE FileWriterI : public WriterSeekerI + { + virtual int32_t open(const char* _filePath, bool _append = false) = 0; + virtual int32_t close() = 0; + }; + + struct BX_NO_VTABLE MemoryBlockI + { + virtual void* more(uint32_t _size = 0) = 0; + virtual uint32_t getSize() = 0; + }; + + class StaticMemoryBlock : public MemoryBlockI + { + public: + StaticMemoryBlock(void* _data, uint32_t _size) + : m_data(_data) + , m_size(_size) + { + } + + ~StaticMemoryBlock() + { + } + + virtual void* more(uint32_t _size = 0) BX_OVERRIDE + { + return m_data; + } + + virtual uint32_t getSize() BX_OVERRIDE + { + return m_size; + } + + private: + void* m_data; + uint32_t m_size; + }; + + inline int64_t int64_min(int64_t _a, int64_t _b) + { + return _a < _b ? _a : _b; + } + + inline int64_t int64_max(int64_t _a, int64_t _b) + { + return _a > _b ? _a : _b; + } + + inline int64_t int64_clamp(int64_t _a, int64_t _min, int64_t _max) + { + const int64_t min = int64_min(_a, _max); + const int64_t result = int64_max(_min, min); + + return result; + } + + class SizerWriter : public WriterSeekerI + { + public: + SizerWriter() + : m_pos(0) + , m_top(0) + { + } + + virtual ~SizerWriter() + { + } + + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE + { + switch (_whence) + { + case Whence::Begin: + m_pos = _offset; + break; + + case Whence::Current: + m_pos = int64_clamp(m_pos + _offset, 0, m_top); + break; + + case Whence::End: + m_pos = int64_clamp(m_top - _offset, 0, m_top); + break; + } + + return m_pos; + } + + virtual int32_t write(const void* _data, int32_t _size) BX_OVERRIDE + { + int32_t morecore = int32_t(m_pos - m_top) + _size; + + if (0 < morecore) + { + m_top += morecore; + } + + int64_t reminder = m_top-m_pos; + int32_t size = uint32_min(_size, int32_t(reminder > INT32_MAX ? INT32_MAX : reminder) ); + m_pos += size; + return size; + } + + private: + int64_t m_pos; + int64_t m_top; + }; + + class MemoryReader : public ReaderSeekerI + { + public: + MemoryReader(const void* _data, uint32_t _size) + : m_data( (const uint8_t*)_data) + , m_pos(0) + , m_top(_size) + { + } + + virtual ~MemoryReader() + { + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) BX_OVERRIDE + { + switch (_whence) + { + case Whence::Begin: + m_pos = _offset; + break; + + case Whence::Current: + m_pos = int64_clamp(m_pos + _offset, 0, m_top); + break; + + case Whence::End: + m_pos = int64_clamp(m_top - _offset, 0, m_top); + break; + } + + return m_pos; + } + + virtual int32_t read(void* _data, int32_t _size) BX_OVERRIDE + { + int64_t reminder = m_top-m_pos; + int32_t size = uint32_min(_size, int32_t(reminder > INT32_MAX ? INT32_MAX : reminder) ); + memcpy(_data, &m_data[m_pos], size); + m_pos += size; + return size; + } + + const uint8_t* getDataPtr() const + { + return &m_data[m_pos]; + } + + int64_t getPos() const + { + return m_pos; + } + + int64_t remaining() const + { + return m_top-m_pos; + } + + private: + const uint8_t* m_data; + int64_t m_pos; + int64_t m_top; + }; + + class MemoryWriter : public WriterSeekerI + { + public: + MemoryWriter(MemoryBlockI* _memBlock) + : m_memBlock(_memBlock) + , m_data(NULL) + , m_pos(0) + , m_top(0) + , m_size(0) + { + } + + virtual ~MemoryWriter() + { + } + + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE + { + switch (_whence) + { + case Whence::Begin: + m_pos = _offset; + break; + + case Whence::Current: + m_pos = int64_clamp(m_pos + _offset, 0, m_top); + break; + + case Whence::End: + m_pos = int64_clamp(m_top - _offset, 0, m_top); + break; + } + + return m_pos; + } + + virtual int32_t write(const void* _data, int32_t _size) BX_OVERRIDE + { + int32_t morecore = int32_t(m_pos - m_size) + _size; + + if (0 < morecore) + { + morecore = BX_ALIGN_MASK(morecore, 0xfff); + m_data = (uint8_t*)m_memBlock->more(morecore); + m_size = m_memBlock->getSize(); + } + + int64_t reminder = m_size-m_pos; + int32_t size = uint32_min(_size, int32_t(reminder > INT32_MAX ? INT32_MAX : reminder) ); + memcpy(&m_data[m_pos], _data, size); + m_pos += size; + m_top = int64_max(m_top, m_pos); + return size; + } + + private: + MemoryBlockI* m_memBlock; + uint8_t* m_data; + int64_t m_pos; + int64_t m_top; + int64_t m_size; + }; + + class StaticMemoryBlockWriter : public MemoryWriter + { + public: + StaticMemoryBlockWriter(void* _data, uint32_t _size) + : MemoryWriter(&m_smb) + , m_smb(_data, _size) + { + } + + ~StaticMemoryBlockWriter() + { + } + + private: + StaticMemoryBlock m_smb; + }; + +#if BX_CONFIG_CRT_FILE_READER_WRITER + class CrtFileReader : public FileReaderI + { + public: + CrtFileReader() + : m_file(NULL) + { + } + + virtual ~CrtFileReader() + { + } + + virtual int32_t open(const char* _filePath) BX_OVERRIDE + { + m_file = fopen(_filePath, "rb"); + return NULL == m_file; + } + + virtual int32_t close() BX_OVERRIDE + { + fclose(m_file); + return 0; + } + + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE + { + fseeko64(m_file, _offset, _whence); + return ftello64(m_file); + } + + virtual int32_t read(void* _data, int32_t _size) BX_OVERRIDE + { + return (int32_t)fread(_data, 1, _size, m_file); + } + + private: + FILE* m_file; + }; + + class CrtFileWriter : public FileWriterI + { + public: + CrtFileWriter() + : m_file(NULL) + { + } + + virtual ~CrtFileWriter() + { + } + + virtual int32_t open(const char* _filePath, bool _append = false) BX_OVERRIDE + { + if (_append) + { + m_file = fopen(_filePath, "ab"); + } + else + { + m_file = fopen(_filePath, "wb"); + } + + return NULL == m_file; + } + + virtual int32_t close() BX_OVERRIDE + { + fclose(m_file); + return 0; + } + + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE + { + fseeko64(m_file, _offset, _whence); + return ftello64(m_file); + } + + virtual int32_t write(const void* _data, int32_t _size) BX_OVERRIDE + { + return (int32_t)fwrite(_data, 1, _size, m_file); + } + + private: + FILE* m_file; + }; +#endif // BX_CONFIG_CRT_FILE_READER_WRITER + +} // namespace bx + +#endif // __BX_READERWRITER_H__ diff --git a/include/bx/ringbuffer.h b/include/bx/ringbuffer.h index a3c69e6..844dff9 100644 --- a/include/bx/ringbuffer.h +++ b/include/bx/ringbuffer.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/rng.h b/include/bx/rng.h index 1bcd894..93d453d 100644 --- a/include/bx/rng.h +++ b/include/bx/rng.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/sem.h b/include/bx/sem.h index 118e4f7..b12d246 100644 --- a/include/bx/sem.h +++ b/include/bx/sem.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/spscqueue.h b/include/bx/spscqueue.h index 6ca4ab8..3b36083 100644 --- a/include/bx/spscqueue.h +++ b/include/bx/spscqueue.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ diff --git a/include/bx/string.h b/include/bx/string.h new file mode 100644 index 0000000..48b9e28 --- /dev/null +++ b/include/bx/string.h @@ -0,0 +1,153 @@ +/* + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef __BX_PRINTF_H__ +#define __BX_PRINTF_H__ + +#include "bx.h" +#include +#include // va_list +#include + +namespace bx +{ + inline int32_t stricmp(const char* _a, const char* _b) + { +#if BX_COMPILER_MSVC + return _stricmp(_a, _b); +#else + return strcasecmp(_a, _b); +#endif // BX_COMPILER_ + } + + /// Find new line. Returns pointer after new line terminator. + inline const char* strnl(const char* _str) + { + const char* eol = strstr(_str, "\n\r"); + if (NULL != eol) + { + return eol + 2; + } + + eol = strstr(_str, "\n"); + if (NULL != eol) + { + return eol + 1; + } + + return eol + strlen(_str); + } + + /// Find end of line. Retuns pointer to new line terminator. + inline const char* streol(const char* _str) + { + const char* eol = strstr(_str, "\n\r"); + if (NULL != eol) + { + return eol; + } + + eol = strstr(_str, "\n"); + if (NULL != eol) + { + return eol; + } + + return eol + strlen(_str); + } + + /// Skip whitespace. + inline const char* strws(const char* _str) + { + for (; isspace(*_str); ++_str); + return _str; + } + + /// Skip non-whitespace. + inline const char* strnws(const char* _str) + { + for (; !isspace(*_str); ++_str); + return _str; + } + + /// Skip word. + inline const char* strword(const char* _str) + { + for (char ch = *_str++; isalnum(ch) || '_' == ch; ch = *_str++); + return _str-1; + } + + /// Find matching block. + inline const char* strmb(const char* _str, char _open, char _close) + { + int count = 0; + for (char ch = *_str++; ch != '\0' && count >= 0; ch = *_str++) + { + if (ch == _open) + { + count++; + } + else if (ch == _close) + { + count--; + if (0 == count) + { + return _str-1; + } + } + } + + return NULL; + } + + /// Cross platform implementation of vsnprintf that returns number of + /// characters which would have been written to the final string if + /// enough space had been available. + inline int32_t vsnprintf(char* _str, size_t _size, const char* _format, va_list _argList) + { +#if BX_COMPILER_MSVC + int32_t len = ::vsnprintf(_str, _size, _format, _argList); + return -1 == len ? ::_vscprintf(_format, _argList) : len; +#else + return ::vsnprintf(_str, _size, _format, _argList); +#endif // BX_COMPILER_MSVC + } + + inline int32_t snprintf(char* _str, size_t _size, const char* _format, ...) BX_PRINTF_ARGS(3, 4) + { + va_list argList; + va_start(argList, _format); + int32_t len = vsnprintf(_str, _size, _format, argList); + va_end(argList); + return len; + } + + inline std::string stringPrintfVargs(const char* _format, va_list _argList) + { + char temp[2048]; + + char* out = temp; + int32_t len = bx::vsnprintf(out, sizeof(temp), _format, _argList); + if ( (int32_t)sizeof(temp) < len) + { + out = (char*)alloca(len+1); + len = bx::vsnprintf(out, len, _format, _argList); + } + out[len] = '\0'; + + return out; + } + + inline std::string stringPrintf(const char* _format, ...) + { + va_list argList; + va_start(argList, _format); + std::string str = stringPrintfVargs(_format, argList); + va_end(argList); + return str; + } +} // namespace bx + +#endif // __BX_PRINTF_H__ diff --git a/include/bx/timer.h b/include/bx/timer.h index ae6c0bb..1b1b47c 100644 --- a/include/bx/timer.h +++ b/include/bx/timer.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Branimir Karadzic. All rights reserved. + * Copyright 2010-2012 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */