diff --git a/lib/file.cpp b/lib/file.cpp index 47b366f..4c3f22b 100644 --- a/lib/file.cpp +++ b/lib/file.cpp @@ -1,11 +1,19 @@ #include "file.h" -#include "util.h" - namespace si { bool File::Open(const char *c, Mode mode) { +#ifdef _WIN32 + m_Handle = CreateFileA(c, + mode == Read ? GENERIC_READ : GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + mode == Read ? OPEN_EXISTING : CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, + NULL); + return m_Handle != INVALID_HANDLE_VALUE; +#else std::ios::openmode m = std::ios::binary; if (mode == Read) { @@ -21,49 +29,74 @@ bool File::Open(const char *c, Mode mode) } return false; +#endif } #ifdef _WIN32 bool File::Open(const wchar_t *c, Mode mode) { - std::ios::open_mode m = std::ios::binary; - - if (mode == Read) { - m |= std::ios::in; - } else { - m |= std::ios::out; - } - - m_Stream.open(c, m); - if (m_Stream.good() && m_Stream.is_open()) { - m_Mode = mode; - return true; - } - - return false; + m_Handle = CreateFileW(c, + mode == Read ? GENERIC_READ : GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + mode == Read ? OPEN_EXISTING : CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, + NULL); + return m_Handle != INVALID_HANDLE_VALUE; } #endif size_t File::pos() { +#ifdef _WIN32 + DWORD high = 0; + DWORD low = SetFilePointer(m_Handle, 0, &high, FILE_CURRENT); + return (high << 32) | low; +#else if (m_Mode == Read) { return m_Stream.tellg(); } else { return m_Stream.tellp(); } +#endif } size_t File::size() { +#ifdef _WIN32 + DWORD high; + DWORD low = GetFileSize(m_Handle, &high); + return high << 32 | low; +#else size_t before = pos(); seek(0, SeekEnd); size_t sz = pos(); seek(before, SeekStart); return sz; +#endif } void File::seek(size_t p, SeekMode s) { +#ifdef _WIN32 + DWORD high = p >> 32; + DWORD low = p; + + DWORD m; + switch (s) { + case SeekStart: + m = FILE_BEGIN; + break; + case SeekCurrent: + m = FILE_CURRENT; + break; + case SeekEnd: + m = FILE_END; + break; + } + + SetFilePointer(m_Handle, low, &high, m); +#else std::ios::seekdir d; switch (s) { @@ -83,30 +116,42 @@ void File::seek(size_t p, SeekMode s) } else { m_Stream.seekp(p, d); } -} - -bool File::atEnd() -{ - return !m_Stream.good(); +#endif } void File::Close() { +#ifdef _WIN32 + CloseHandle(m_Handle); +#else m_Stream.close(); +#endif } size_t File::ReadData(void *data, size_t size) { +#ifdef _WIN32 + DWORD r; + ReadFile(m_Handle, data, size, &r, NULL); + return r; +#else size_t before = this->pos(); m_Stream.read((char *) data, size); return this->pos() - before; +#endif } size_t File::WriteData(const void *data, size_t size) { +#ifdef _WIN32 + DWORD w; + WriteFile(m_Handle, data, size, &w, NULL); + return w; +#else size_t before = this->pos(); m_Stream.write((const char *) data, size); return this->pos() - before; +#endif } uint8_t FileBase::ReadU8() @@ -232,11 +277,6 @@ void MemoryBuffer::seek(size_t p, SeekMode s) } } -bool MemoryBuffer::atEnd() -{ - return m_Position == m_Internal.size(); -} - size_t MemoryBuffer::ReadData(void *data, size_t size) { size = std::min(size, m_Internal.size() - m_Position); diff --git a/lib/file.h b/lib/file.h index 0c62e19..0e7c95d 100644 --- a/lib/file.h +++ b/lib/file.h @@ -1,7 +1,11 @@ #ifndef FILE_H #define FILE_H +#ifdef _WIN32 +#include <Windows.h> +#else #include <fstream> +#endif #include "types.h" @@ -51,7 +55,7 @@ public: virtual size_t pos() = 0; virtual size_t size() = 0; virtual void seek(size_t p, SeekMode s = SeekStart) = 0; - virtual bool atEnd() = 0; + LIBWEAVER_EXPORT bool atEnd() { return pos() == size(); } }; @@ -72,14 +76,17 @@ public: virtual size_t pos(); virtual size_t size(); virtual void seek(size_t p, SeekMode s = SeekStart); - virtual bool atEnd(); virtual void Close(); virtual size_t ReadData(void *data, size_t size); virtual size_t WriteData(const void *data, size_t size); private: +#ifdef _WIN32 + HANDLE m_Handle; +#else std::fstream m_Stream; +#endif Mode m_Mode; }; @@ -93,7 +100,6 @@ public: LIBWEAVER_EXPORT virtual size_t pos(); LIBWEAVER_EXPORT virtual size_t size(); LIBWEAVER_EXPORT virtual void seek(size_t p, SeekMode s = SeekStart); - LIBWEAVER_EXPORT virtual bool atEnd(); const bytearray &data() const { return m_Internal; }