diff options
-rw-r--r-- | Alc/compat.h | 135 | ||||
-rw-r--r-- | Alc/helpers.cpp | 131 |
2 files changed, 141 insertions, 125 deletions
diff --git a/Alc/compat.h b/Alc/compat.h index dc652bca..2e0ad1e7 100644 --- a/Alc/compat.h +++ b/Alc/compat.h @@ -54,115 +54,18 @@ class filebuf final : public std::streambuf { std::array<char_type,4096> mBuffer; HANDLE mFile{INVALID_HANDLE_VALUE}; - int_type underflow() override - { - if(mFile != INVALID_HANDLE_VALUE && gptr() == egptr()) - { - // Read in the next chunk of data, and set the pointers on success - DWORD got = 0; - if(ReadFile(mFile, mBuffer.data(), (DWORD)mBuffer.size(), &got, nullptr)) - setg(mBuffer.data(), mBuffer.data(), mBuffer.data()+got); - } - if(gptr() == egptr()) - return traits_type::eof(); - return traits_type::to_int_type(*gptr()); - } - - pos_type seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode) override - { - if(mFile == INVALID_HANDLE_VALUE || (mode&std::ios_base::out) || !(mode&std::ios_base::in)) - return traits_type::eof(); - - LARGE_INTEGER fpos; - switch(whence) - { - case std::ios_base::beg: - fpos.QuadPart = offset; - if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_BEGIN)) - return traits_type::eof(); - break; - - case std::ios_base::cur: - // If the offset remains in the current buffer range, just - // update the pointer. - if((offset >= 0 && offset < off_type(egptr()-gptr())) || - (offset < 0 && -offset <= off_type(gptr()-eback()))) - { - // Get the current file offset to report the correct read - // offset. - fpos.QuadPart = 0; - if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_CURRENT)) - return traits_type::eof(); - setg(eback(), gptr()+offset, egptr()); - return fpos.QuadPart - off_type(egptr()-gptr()); - } - // Need to offset for the file offset being at egptr() while - // the requested offset is relative to gptr(). - offset -= off_type(egptr()-gptr()); - fpos.QuadPart = offset; - if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_CURRENT)) - return traits_type::eof(); - break; - - case std::ios_base::end: - fpos.QuadPart = offset; - if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_END)) - return traits_type::eof(); - break; - - default: - return traits_type::eof(); - } - setg(nullptr, nullptr, nullptr); - return fpos.QuadPart; - } - - pos_type seekpos(pos_type pos, std::ios_base::openmode mode) override - { - // Simplified version of seekoff - if(mFile == INVALID_HANDLE_VALUE || (mode&std::ios_base::out) || !(mode&std::ios_base::in)) - return traits_type::eof(); - - LARGE_INTEGER fpos; - fpos.QuadPart = pos; - if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_BEGIN)) - return traits_type::eof(); - - setg(nullptr, nullptr, nullptr); - return fpos.QuadPart; - } + int_type underflow() override; + pos_type seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode) override; + pos_type seekpos(pos_type pos, std::ios_base::openmode mode) override; public: - bool open(const wchar_t *filename, std::ios_base::openmode mode) - { - if((mode&std::ios_base::out) || !(mode&std::ios_base::in)) - return false; - HANDLE f{CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)}; - if(f == INVALID_HANDLE_VALUE) return false; - - if(mFile != INVALID_HANDLE_VALUE) - CloseHandle(mFile); - mFile = f; - - setg(nullptr, nullptr, nullptr); - return true; - } - bool open(const char *filename, std::ios_base::openmode mode) - { - std::wstring wname{utf8_to_wstr(filename)}; - return open(wname.c_str(), mode); - } + filebuf() = default; + ~filebuf() override; - bool is_open() const noexcept { return mFile != INVALID_HANDLE_VALUE; } + bool open(const wchar_t *filename, std::ios_base::openmode mode); + bool open(const char *filename, std::ios_base::openmode mode); - filebuf() = default; - ~filebuf() override - { - if(mFile != INVALID_HANDLE_VALUE) - CloseHandle(mFile); - mFile = INVALID_HANDLE_VALUE; - } + bool is_open() const noexcept { return mFile != INVALID_HANDLE_VALUE; } }; // Inherit from std::istream to use our custom streambuf @@ -170,31 +73,13 @@ class ifstream final : public std::istream { filebuf mStreamBuf; public: + ifstream(const wchar_t *filename, std::ios_base::openmode mode = std::ios_base::in); ifstream(const std::wstring &filename, std::ios_base::openmode mode = std::ios_base::in) : ifstream(filename.c_str(), mode) { } - ifstream(const wchar_t *filename, std::ios_base::openmode mode = std::ios_base::in) - : std::istream{nullptr} - { - init(&mStreamBuf); - - // Set the failbit if the file failed to open. - if((mode&std::ios_base::out) || - !mStreamBuf.open(filename, mode|std::ios_base::in)) - clear(failbit); - } + ifstream(const char *filename, std::ios_base::openmode mode = std::ios_base::in); ifstream(const std::string &filename, std::ios_base::openmode mode = std::ios_base::in) : ifstream(filename.c_str(), mode) { } - ifstream(const char *filename, std::ios_base::openmode mode = std::ios_base::in) - : std::istream{nullptr} - { - init(&mStreamBuf); - - // Set the failbit if the file failed to open. - if((mode&std::ios_base::out) || - !mStreamBuf.open(filename, mode|std::ios_base::in)) - clear(failbit); - } bool is_open() const noexcept { return mStreamBuf.is_open(); } }; diff --git a/Alc/helpers.cpp b/Alc/helpers.cpp index 813b954f..fb7addd3 100644 --- a/Alc/helpers.cpp +++ b/Alc/helpers.cpp @@ -305,6 +305,137 @@ void FPUCtl::leave() #ifdef _WIN32 +namespace al { + +auto filebuf::underflow() -> int_type +{ + if(mFile != INVALID_HANDLE_VALUE && gptr() == egptr()) + { + // Read in the next chunk of data, and set the pointers on success + DWORD got{}; + if(ReadFile(mFile, mBuffer.data(), (DWORD)mBuffer.size(), &got, nullptr)) + setg(mBuffer.data(), mBuffer.data(), mBuffer.data()+got); + } + if(gptr() == egptr()) + return traits_type::eof(); + return traits_type::to_int_type(*gptr()); +} + +auto filebuf::seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode) -> pos_type +{ + if(mFile == INVALID_HANDLE_VALUE || (mode&std::ios_base::out) || !(mode&std::ios_base::in)) + return traits_type::eof(); + + LARGE_INTEGER fpos{}; + switch(whence) + { + case std::ios_base::beg: + fpos.QuadPart = offset; + if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_BEGIN)) + return traits_type::eof(); + break; + + case std::ios_base::cur: + // If the offset remains in the current buffer range, just + // update the pointer. + if((offset >= 0 && offset < off_type(egptr()-gptr())) || + (offset < 0 && -offset <= off_type(gptr()-eback()))) + { + // Get the current file offset to report the correct read + // offset. + fpos.QuadPart = 0; + if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_CURRENT)) + return traits_type::eof(); + setg(eback(), gptr()+offset, egptr()); + return fpos.QuadPart - off_type(egptr()-gptr()); + } + // Need to offset for the file offset being at egptr() while + // the requested offset is relative to gptr(). + offset -= off_type(egptr()-gptr()); + fpos.QuadPart = offset; + if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_CURRENT)) + return traits_type::eof(); + break; + + case std::ios_base::end: + fpos.QuadPart = offset; + if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_END)) + return traits_type::eof(); + break; + + default: + return traits_type::eof(); + } + setg(nullptr, nullptr, nullptr); + return fpos.QuadPart; +} + +auto filebuf::seekpos(pos_type pos, std::ios_base::openmode mode) -> pos_type +{ + // Simplified version of seekoff + if(mFile == INVALID_HANDLE_VALUE || (mode&std::ios_base::out) || !(mode&std::ios_base::in)) + return traits_type::eof(); + + LARGE_INTEGER fpos{}; + fpos.QuadPart = pos; + if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_BEGIN)) + return traits_type::eof(); + + setg(nullptr, nullptr, nullptr); + return fpos.QuadPart; +} + +filebuf::~filebuf() +{ + if(mFile != INVALID_HANDLE_VALUE) + CloseHandle(mFile); + mFile = INVALID_HANDLE_VALUE; +} + +bool filebuf::open(const wchar_t *filename, std::ios_base::openmode mode) +{ + if((mode&std::ios_base::out) || !(mode&std::ios_base::in)) + return false; + HANDLE f{CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, nullptr)}; + if(f == INVALID_HANDLE_VALUE) return false; + + if(mFile != INVALID_HANDLE_VALUE) + CloseHandle(mFile); + mFile = f; + + setg(nullptr, nullptr, nullptr); + return true; +} +bool filebuf::open(const char *filename, std::ios_base::openmode mode) +{ + std::wstring wname{utf8_to_wstr(filename)}; + return open(wname.c_str(), mode); +} + + +ifstream::ifstream(const wchar_t *filename, std::ios_base::openmode mode) + : std::istream{nullptr} +{ + init(&mStreamBuf); + + // Set the failbit if the file failed to open. + if((mode&std::ios_base::out) || !mStreamBuf.open(filename, mode|std::ios_base::in)) + clear(failbit); +} + +ifstream::ifstream(const char *filename, std::ios_base::openmode mode) + : std::istream{nullptr} +{ + init(&mStreamBuf); + + // Set the failbit if the file failed to open. + if((mode&std::ios_base::out) || !mStreamBuf.open(filename, mode|std::ios_base::in)) + clear(failbit); +} + +} // namespace al + const PathNamePair &GetProcBinary() { static PathNamePair ret; |