| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- /*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
- */
- #include "bx_p.h"
- #include <bx/file.h>
- #if !BX_CRT_NONE
- # include <stdio.h>
- # include <sys/stat.h>
- #endif // !BX_CRT_NONE
- #ifndef BX_CONFIG_CRT_FILE_READER_WRITER
- # define BX_CONFIG_CRT_FILE_READER_WRITER !(0 \
- || BX_CRT_NONE \
- )
- #endif // BX_CONFIG_CRT_FILE_READER_WRITER
- namespace bx
- {
- class NoopWriterImpl : public FileWriterI
- {
- public:
- NoopWriterImpl(void*)
- {
- }
- virtual ~NoopWriterImpl()
- {
- close();
- }
- virtual bool open(const FilePath& _filePath, bool _append, Error* _err) override
- {
- BX_UNUSED(_filePath, _append, _err);
- return false;
- }
- virtual void close() override
- {
- }
- virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override
- {
- BX_UNUSED(_offset, _whence);
- return 0;
- }
- virtual int32_t write(const void* _data, int32_t _size, Error* _err) override
- {
- BX_UNUSED(_data, _size, _err);
- return 0;
- }
- };
- #if BX_CONFIG_CRT_FILE_READER_WRITER
- # if BX_CRT_MSVC
- # define fseeko64 _fseeki64
- # define ftello64 _ftelli64
- # elif 0 \
- || BX_PLATFORM_ANDROID \
- || BX_PLATFORM_BSD \
- || BX_PLATFORM_IOS \
- || BX_PLATFORM_OSX
- # define fseeko64 fseeko
- # define ftello64 ftello
- # elif BX_PLATFORM_PS4
- # define fseeko64 fseek
- # define ftello64 ftell
- # endif // BX_
- class FileReaderImpl : public FileReaderI
- {
- public:
- FileReaderImpl(FILE* _file)
- : m_file(_file)
- , m_open(false)
- {
- }
- virtual ~FileReaderImpl()
- {
- close();
- }
- virtual bool open(const FilePath& _filePath, Error* _err) 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, "FileReader: File is already open.");
- return false;
- }
- m_file = fopen(_filePath.get(), "rb");
- if (NULL == m_file)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "FileReader: Failed to open file.");
- return false;
- }
- m_open = true;
- return true;
- }
- virtual void close() override
- {
- if (m_open
- && NULL != m_file)
- {
- fclose(m_file);
- m_file = NULL;
- }
- }
- virtual int64_t seek(int64_t _offset, Whence::Enum _whence) 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) 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, "FileReader: EOF.");
- }
- else if (0 != ferror(m_file) )
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "FileReader: read error.");
- }
- return size >= 0 ? size : 0;
- }
- return size;
- }
- private:
- FILE* m_file;
- bool m_open;
- };
- class FileWriterImpl : public FileWriterI
- {
- public:
- FileWriterImpl(FILE* _file)
- : m_file(_file)
- , m_open(false)
- {
- }
- virtual ~FileWriterImpl()
- {
- close();
- }
- virtual bool open(const FilePath& _filePath, bool _append, Error* _err) 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, "FileReader: File is already open.");
- return false;
- }
- m_file = fopen(_filePath.get(), _append ? "ab" : "wb");
- if (NULL == m_file)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "FileWriter: Failed to open file.");
- return false;
- }
- m_open = true;
- return true;
- }
- virtual void close() override
- {
- if (m_open
- && NULL != m_file)
- {
- fclose(m_file);
- m_file = NULL;
- }
- }
- virtual int64_t seek(int64_t _offset, Whence::Enum _whence) 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) 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, "FileWriter: write failed.");
- return size >= 0 ? size : 0;
- }
- return size;
- }
- private:
- FILE* m_file;
- bool m_open;
- };
- ReaderI* getStdIn()
- {
- static FileReaderImpl s_stdIn(stdout);
- return &s_stdIn;
- }
- WriterI* getStdOut()
- {
- static FileWriterImpl s_stdOut(stdout);
- return &s_stdOut;
- }
- WriterI* getStdErr()
- {
- static FileWriterImpl s_stdOut(stderr);
- return &s_stdOut;
- }
- #else
- class FileReaderImpl : public FileReaderI
- {
- public:
- FileReaderImpl(void*)
- {
- }
- virtual ~FileReaderImpl()
- {
- close();
- }
- virtual bool open(const FilePath& _filePath, Error* _err) override
- {
- BX_UNUSED(_filePath, _err);
- return false;
- }
- virtual void close() override
- {
- }
- virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override
- {
- BX_UNUSED(_offset, _whence);
- return 0;
- }
- virtual int32_t read(void* _data, int32_t _size, Error* _err) override
- {
- BX_UNUSED(_data, _size, _err);
- return 0;
- }
- };
- typedef NoopWriterImpl FileWriterImpl;
- ReaderI* getStdIn()
- {
- static FileReaderImpl s_stdIn(NULL);
- return &s_stdIn;
- }
- WriterI* getStdOut()
- {
- static FileWriterImpl s_stdOut(NULL);
- return &s_stdOut;
- }
- WriterI* getStdErr()
- {
- static FileWriterImpl s_stdOut(NULL);
- return &s_stdOut;
- }
- #endif // BX_CONFIG_CRT_FILE_READER_WRITER
- WriterI* getNullOut()
- {
- static NoopWriterImpl s_nullOut(NULL);
- return &s_nullOut;
- }
- FileReader::FileReader()
- {
- BX_STATIC_ASSERT(sizeof(FileReaderImpl) <= sizeof(m_internal) );
- BX_PLACEMENT_NEW(m_internal, FileReaderImpl)(NULL);
- }
- FileReader::~FileReader()
- {
- FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal);
- impl->~FileReaderImpl();
- }
- bool FileReader::open(const FilePath& _filePath, Error* _err)
- {
- FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal);
- return impl->open(_filePath, _err);
- }
- void FileReader::close()
- {
- FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal);
- impl->close();
- }
- int64_t FileReader::seek(int64_t _offset, Whence::Enum _whence)
- {
- FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal);
- return impl->seek(_offset, _whence);
- }
- int32_t FileReader::read(void* _data, int32_t _size, Error* _err)
- {
- FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal);
- return impl->read(_data, _size, _err);
- }
- FileWriter::FileWriter()
- {
- BX_STATIC_ASSERT(sizeof(FileWriterImpl) <= sizeof(m_internal) );
- BX_PLACEMENT_NEW(m_internal, FileWriterImpl)(NULL);
- }
- FileWriter::~FileWriter()
- {
- FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal);
- impl->~FileWriterImpl();
- }
- bool FileWriter::open(const FilePath& _filePath, bool _append, Error* _err)
- {
- FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal);
- return impl->open(_filePath, _append, _err);
- }
- void FileWriter::close()
- {
- FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal);
- impl->close();
- }
- int64_t FileWriter::seek(int64_t _offset, Whence::Enum _whence)
- {
- FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal);
- return impl->seek(_offset, _whence);
- }
- int32_t FileWriter::write(const void* _data, int32_t _size, Error* _err)
- {
- FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal);
- return impl->write(_data, _size, _err);
- }
- bool stat(const FilePath& _filePath, FileInfo& _outFileInfo)
- {
- #if BX_CRT_NONE
- BX_UNUSED(_filePath, _outFileInfo);
- return false;
- #else
- _outFileInfo.m_size = 0;
- _outFileInfo.m_type = FileInfo::Count;
- # if BX_COMPILER_MSVC
- struct ::_stat64 st;
- int32_t result = ::_stat64(_filePath.get(), &st);
- if (0 != result)
- {
- return false;
- }
- if (0 != (st.st_mode & _S_IFREG) )
- {
- _outFileInfo.m_type = FileInfo::Regular;
- }
- else if (0 != (st.st_mode & _S_IFDIR) )
- {
- _outFileInfo.m_type = FileInfo::Directory;
- }
- # else
- struct ::stat st;
- int32_t result = ::stat(_filePath.get(), &st);
- if (0 != result)
- {
- return false;
- }
- if (0 != (st.st_mode & S_IFREG) )
- {
- _outFileInfo.m_type = FileInfo::Regular;
- }
- else if (0 != (st.st_mode & S_IFDIR) )
- {
- _outFileInfo.m_type = FileInfo::Directory;
- }
- # endif // BX_COMPILER_MSVC
- _outFileInfo.m_size = st.st_size;
- return true;
- #endif // BX_CRT_NONE
- }
- } // namespace bx
|