| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #include "StdInc.h"
- #define INC_FROM_FILESTREAM_CPP
- #include "FileStream.h"
- #include "../minizip/unzip.h"
- #include <cstdio>
- #ifdef _WIN32
- #ifndef _CRT_SECURE_NO_WARNINGS
- #define _CRT_SECURE_NO_WARNINGS
- #endif
- #include <cwchar>
- #define CHAR_LITERAL(s) L##s
- #define DO_OPEN(name, mode) _wfopen(name, mode)
- using CharType = wchar_t;
- #else
- #define CHAR_LITERAL(s) s
- #define DO_OPEN(name, mode) fopen(name, mode)
- using CharType = char;
- #endif
- #define GETFILE static_cast<std::FILE*>(filePtr)
- voidpf ZCALLBACK MinizipOpenFunc(voidpf opaque, const void* filename, int mode)
- {
- const CharType* mode_fopen = [mode]() -> const CharType*
- {
- if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
- return CHAR_LITERAL("rb");
- else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
- return CHAR_LITERAL("r+b");
- else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
- return CHAR_LITERAL("wb");
- return nullptr;
- }();
- if (filename != nullptr && mode_fopen != nullptr)
- return DO_OPEN(static_cast<const CharType*>(filename), mode_fopen);
- else
- return nullptr;
- }
- zlib_filefunc64_def* FileStream::GetMinizipFilefunc()
- {
- static zlib_filefunc64_def MinizipFilefunc;
- static bool initialized = false;
- if (!initialized) {
- fill_fopen64_filefunc((&MinizipFilefunc));
- MinizipFilefunc.zopen64_file = &MinizipOpenFunc;
- initialized = true;
- }
- return &MinizipFilefunc;
- }
- template class DLL_LINKAGE boost::iostreams::stream<FileBuf>;
- /*static*/
- bool FileStream::CreateFile(const boost::filesystem::path& filename)
- {
- FILE* f = DO_OPEN(filename.c_str(), CHAR_LITERAL("wb"));
- bool result = (f != nullptr);
- fclose(f);
- return result;
- }
- FileBuf::FileBuf(const boost::filesystem::path& filename, std::ios_base::openmode mode)
- {
- std::string openmode = [mode]() -> std::string
- {
- using namespace std;
- switch (mode & (~ios_base::ate & ~ios_base::binary))
- {
- case (ios_base::in):
- return "r";
- case (ios_base::out):
- case (ios_base::out | ios_base::trunc):
- return "w";
- case (ios_base::app):
- case (ios_base::out | ios_base::app):
- return "a";
- case (ios_base::out | ios_base::in):
- return "r+";
- case (ios_base::out | ios_base::in | ios_base::trunc):
- return "w+";
- case (ios_base::out | ios_base::in | ios_base::app):
- case (ios_base::in | ios_base::app):
- return "a+";
- default:
- throw std::ios_base::failure("invalid open mode");
- }
- }();
- if (mode & std::ios_base::binary)
- openmode += 'b';
- #if defined(_WIN32)
- filePtr = _wfopen(filename.c_str(), std::wstring(openmode.begin(), openmode.end()).c_str());
- #else
- filePtr = std::open(filename.c_str(), openmode);
- #endif
- if (filePtr == nullptr)
- throw std::ios_base::failure("could not open file");
- if (mode & std::ios_base::ate) {
- if (std::fseek(GETFILE, 0, SEEK_END)) {
- fclose(GETFILE);
- throw std::ios_base::failure("could not open file");
- }
- }
- }
- void FileBuf::close()
- {
- std::fclose(GETFILE);
- }
- std::streamsize FileBuf::read(char* s, std::streamsize n)
- {
- return static_cast<std::streamsize>(std::fread(s, 1, n, GETFILE));
- }
- std::streamsize FileBuf::write(const char* s, std::streamsize n)
- {
- return static_cast<std::streamsize>(std::fwrite(s, 1, n, GETFILE));
- }
- std::streamoff FileBuf::seek(std::streamoff off, std::ios_base::seekdir way)
- {
- auto src = [way]() -> int
- {
- switch(way)
- {
- case std::ios_base::beg:
- return SEEK_SET;
- case std::ios_base::cur:
- return SEEK_CUR;
- case std::ios_base::end:
- return SEEK_END;
- default:
- throw std::ios_base::failure("bad seek direction");
- }
- }();
- if(std::fseek(GETFILE, off, src))
- throw std::ios_base::failure("bad seek offset");
- return static_cast<std::streamsize>(std::ftell(GETFILE));
- }
|