Bläddra i källkod

Implemented stdout, stderr, debug writers.

Branimir Karadžić 8 år sedan
förälder
incheckning
7eb1bb115f
5 ändrade filer med 229 tillägg och 79 borttagningar
  1. 11 2
      include/bx/crtimpl.h
  2. 3 0
      include/bx/debug.h
  3. 183 74
      src/crtimpl.cpp
  4. 31 2
      src/debug.cpp
  5. 1 1
      src/string.cpp

+ 11 - 2
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
 

+ 3 - 0
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

+ 183 - 74
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)
+		{
+		}
 
-	CrtFileReader::~CrtFileReader()
-	{
-	}
+		~FileReaderImpl()
+		{
+		}
 
-	bool CrtFileReader::open(const char* _filePath, Error* _err)
-	{
-		BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+		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)
+			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
 		{
-			BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open.");
-			return false;
+			if (m_open
+			&&  NULL != m_file)
+			{
+				fclose(m_file);
+				m_file = NULL;
+			}
 		}
 
-		m_file = fopen(_filePath, "rb");
-		if (NULL == m_file)
+		virtual int64_t seek(int64_t _offset, Whence::Enum _whence) BX_OVERRIDE
 		{
-			BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileReader: Failed to open file.");
-			return false;
+			BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
+			fseeko64(m_file, _offset, _whence);
+			return ftello64(m_file);
 		}
 
-		return true;
+		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<FileReaderImpl*>(m_internal);
+		impl->~FileReaderImpl();
+	}
+
+	bool CrtFileReader::open(const char* _filePath, Error* _err)
+	{
+		FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(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<FileReaderImpl*>(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<FileReaderImpl*>(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<FileReaderImpl*>(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) )
+		}
+
+		~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_EOF, "CrtFileReader: EOF.");
+				BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open.");
+				return false;
 			}
-			else if (0 != ferror(file) )
+
+			m_file = fopen(_filePath, _append ? "ab" : "wb");
+
+			if (NULL == m_file)
 			{
-				BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "CrtFileReader: read error.");
+				BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileWriter: Failed to open file.");
+				return false;
 			}
 
-			return size >= 0 ? size : 0;
+			return true;
 		}
 
-		return size;
+		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<FileWriterImpl*>(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<FileWriterImpl*>(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<FileWriterImpl*>(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<FileWriterImpl*>(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<FileWriterImpl*>(m_internal);
+		return impl->write(_data, _size, _err);
 	}
 #endif // BX_CONFIG_CRT_FILE_READER_WRITER
 

+ 31 - 2
src/debug.cpp

@@ -4,8 +4,9 @@
  */
 
 #include <bx/debug.h>
-#include <bx/string.h> // isPrint
-#include <inttypes.h>  // PRIx*
+#include <bx/string.h>       // isPrint
+#include <bx/readerwriter.h> // WriterI
+#include <inttypes.h>        // PRIx*
 
 #if BX_PLATFORM_ANDROID
 #	include <android/log.h>
@@ -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

+ 1 - 1
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)