diff --git a/include/bx/crtimpl.h b/include/bx/crtimpl.h index 8176c6b..c37ccb2 100644 --- a/include/bx/crtimpl.h +++ b/include/bx/crtimpl.h @@ -35,6 +35,15 @@ namespace bx #endif // BX_CONFIG_ALLOCATOR_CRT #if BX_CONFIG_CRT_FILE_READER_WRITER + /// + ReaderI* getStdIn(); + + /// + WriterI* getStdOut(); + + /// + WriterI* getStdErr(); + /// class CrtFileReader : public FileReaderI { @@ -58,7 +67,7 @@ namespace bx virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE; private: - void* m_file; + BX_ALIGN_DECL(16, uint8_t) m_internal[64]; }; /// @@ -84,7 +93,7 @@ namespace bx virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE; private: - void* m_file; + BX_ALIGN_DECL(16, uint8_t) m_internal[64]; }; #endif // BX_CONFIG_CRT_FILE_READER_WRITER diff --git a/include/bx/debug.h b/include/bx/debug.h index 7c2ca86..e8266cd 100644 --- a/include/bx/debug.h +++ b/include/bx/debug.h @@ -25,6 +25,9 @@ namespace bx /// void debugPrintfData(const void* _data, uint32_t _size, const char* _format, ...); + /// + class WriterI* getDebugOut(); + } // namespace bx #endif // BX_DEBUG_H_HEADER_GUARD diff --git a/src/crtimpl.cpp b/src/crtimpl.cpp index 064b9f6..754efcb 100644 --- a/src/crtimpl.cpp +++ b/src/crtimpl.cpp @@ -90,135 +90,244 @@ namespace bx # define ftello64 ftell # endif // BX_ - CrtFileReader::CrtFileReader() - : m_file(NULL) + class FileReaderImpl : public bx::FileReaderI { + public: + FileReaderImpl(FILE* _file) + : m_file(_file) + , m_open(false) + { + } + + ~FileReaderImpl() + { + } + + virtual bool open(const char* _filePath, Error* _err) BX_OVERRIDE + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + if (NULL != m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open."); + return false; + } + + m_file = fopen(_filePath, "rb"); + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileReader: Failed to open file."); + return false; + } + + m_open = true; + return true; + } + + virtual void close() BX_OVERRIDE + { + if (m_open + && NULL != m_file) + { + fclose(m_file); + m_file = NULL; + } + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) BX_OVERRIDE + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + fseeko64(m_file, _offset, _whence); + return ftello64(m_file); + } + + virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + int32_t size = (int32_t)fread(_data, 1, _size, m_file); + if (size != _size) + { + if (0 != feof(m_file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "CrtFileReader: EOF."); + } + else if (0 != ferror(m_file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "CrtFileReader: read error."); + } + + return size >= 0 ? size : 0; + } + + return size; + } + + private: + FILE* m_file; + bool m_open; + }; + + ReaderI* getStdIn() + { + static FileReaderImpl s_stdIn(stdout); + return &s_stdIn; + } + + CrtFileReader::CrtFileReader() + { + BX_STATIC_ASSERT(sizeof(FileReaderImpl) <= sizeof(m_internal) ); + new(m_internal) FileReaderImpl(NULL); } CrtFileReader::~CrtFileReader() { + FileReaderImpl* impl = reinterpret_cast(m_internal); + impl->~FileReaderImpl(); } bool CrtFileReader::open(const char* _filePath, Error* _err) { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - if (NULL != m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open."); - return false; - } - - m_file = fopen(_filePath, "rb"); - if (NULL == m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileReader: Failed to open file."); - return false; - } - - return true; + FileReaderImpl* impl = reinterpret_cast(m_internal); + return impl->open(_filePath, _err); } void CrtFileReader::close() { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fclose(file); - m_file = NULL; + FileReaderImpl* impl = reinterpret_cast(m_internal); + impl->close(); } int64_t CrtFileReader::seek(int64_t _offset, Whence::Enum _whence) { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fseeko64(file, _offset, _whence); - return ftello64(file); + FileReaderImpl* impl = reinterpret_cast(m_internal); + return impl->seek(_offset, _whence); } int32_t CrtFileReader::read(void* _data, int32_t _size, Error* _err) { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + FileReaderImpl* impl = reinterpret_cast(m_internal); + return impl->read(_data, _size, _err); + } - FILE* file = (FILE*)m_file; - int32_t size = (int32_t)fread(_data, 1, _size, file); - if (size != _size) + class FileWriterImpl : public bx::FileWriterI + { + public: + FileWriterImpl(FILE* _file) + : m_file(_file) + , m_open(false) { - if (0 != feof(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "CrtFileReader: EOF."); - } - else if (0 != ferror(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "CrtFileReader: read error."); - } - - return size >= 0 ? size : 0; } - return size; + ~FileWriterImpl() + { + } + + virtual bool open(const char* _filePath, bool _append, Error* _err) BX_OVERRIDE + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + if (NULL != m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open."); + return false; + } + + m_file = fopen(_filePath, _append ? "ab" : "wb"); + + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileWriter: Failed to open file."); + return false; + } + + return true; + } + + virtual void close() BX_OVERRIDE + { + if (m_open + && NULL != m_file) + { + fclose(m_file); + m_file = NULL; + } + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) BX_OVERRIDE + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + fseeko64(m_file, _offset, _whence); + return ftello64(m_file); + } + + virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + int32_t size = (int32_t)fwrite(_data, 1, _size, m_file); + if (size != _size) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "CrtFileWriter: write failed."); + return size >= 0 ? size : 0; + } + + return size; + } + + private: + FILE* m_file; + bool m_open; + }; + + WriterI* getStdOut() + { + static FileWriterImpl s_stdOut(stdout); + return &s_stdOut; + } + + WriterI* getStdErr() + { + static FileWriterImpl s_stdOut(stderr); + return &s_stdOut; } CrtFileWriter::CrtFileWriter() - : m_file(NULL) { + BX_STATIC_ASSERT(sizeof(FileWriterImpl) <= sizeof(m_internal) ); + new(m_internal) FileWriterImpl(NULL); } CrtFileWriter::~CrtFileWriter() { + FileWriterImpl* impl = reinterpret_cast(m_internal); + impl->~FileWriterImpl(); } bool CrtFileWriter::open(const char* _filePath, bool _append, Error* _err) { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - if (NULL != m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open."); - return false; - } - - m_file = fopen(_filePath, _append ? "ab" : "wb"); - - if (NULL == m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileWriter: Failed to open file."); - return false; - } - - return true; + FileWriterImpl* impl = reinterpret_cast(m_internal); + return impl->open(_filePath, _append, _err); } void CrtFileWriter::close() { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fclose(file); - m_file = NULL; + FileWriterImpl* impl = reinterpret_cast(m_internal); + impl->close(); } int64_t CrtFileWriter::seek(int64_t _offset, Whence::Enum _whence) { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fseeko64(file, _offset, _whence); - return ftello64(file); + FileWriterImpl* impl = reinterpret_cast(m_internal); + return impl->seek(_offset, _whence); } int32_t CrtFileWriter::write(const void* _data, int32_t _size, Error* _err) { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - FILE* file = (FILE*)m_file; - int32_t size = (int32_t)fwrite(_data, 1, _size, file); - if (size != _size) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "CrtFileWriter: write failed."); - return size >= 0 ? size : 0; - } - - return size; + FileWriterImpl* impl = reinterpret_cast(m_internal); + return impl->write(_data, _size, _err); } #endif // BX_CONFIG_CRT_FILE_READER_WRITER diff --git a/src/debug.cpp b/src/debug.cpp index 072379b..5596c05 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -4,8 +4,9 @@ */ #include -#include // isPrint -#include // PRIx* +#include // isPrint +#include // WriterI +#include // PRIx* #if BX_PLATFORM_ANDROID # include @@ -142,4 +143,32 @@ namespace bx #undef HEX_DUMP_FORMAT } + class DebugWriter : public WriterI + { + virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE + { + BX_UNUSED(_err); + + int32_t total = 0; + + char temp[4096]; + while (total != _size) + { + uint32_t len = bx::uint32_min(sizeof(temp)-1, _size-total); + memCopy(temp, _data, len); + temp[len] = '\0'; + debugOutput(temp); + total += len; + } + + return total; + } + }; + + WriterI* getDebugOut() + { + static DebugWriter s_debugOut; + return &s_debugOut; + } + } // namespace bx diff --git a/src/string.cpp b/src/string.cpp index 1568a7b..add9a29 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -27,7 +27,7 @@ namespace bx inline bool isInRange(char _ch, char _from, char _to) { - return unsigned(_ch - _from) < unsigned(_to-_from); + return unsigned(_ch - _from) <= unsigned(_to-_from); } bool isUpper(char _ch)