16 #include <SDL2/SDL_rwops.h>
25 #define ERR_FS LOG_STREAM(err, log_filesystem)
33 static int64_t
ifs_size (
struct SDL_RWops * context);
34 static int64_t
ofs_size (
struct SDL_RWops * context);
35 static int64_t SDLCALL
ifs_seek(
struct SDL_RWops *context, int64_t offset,
int whence);
36 static int64_t SDLCALL
ofs_seek(
struct SDL_RWops *context, int64_t offset,
int whence);
37 static std::size_t SDLCALL
ifs_read(
struct SDL_RWops *context,
void *ptr, std::size_t
size, std::size_t maxnum);
38 static std::size_t SDLCALL
ofs_read(
struct SDL_RWops *context,
void *ptr, std::size_t
size, std::size_t maxnum);
39 static std::size_t SDLCALL
ifs_write(
struct SDL_RWops *context,
const void *ptr, std::size_t
size, std::size_t num);
40 static std::size_t SDLCALL
ofs_write(
struct SDL_RWops *context,
const void *ptr, std::size_t
size, std::size_t num);
41 static int SDLCALL
ifs_close(
struct SDL_RWops *context);
42 static int SDLCALL
ofs_close(
struct SDL_RWops *context);
62 ERR_FS <<
"make_read_RWops: istream_file returned NULL on " <<
path;
67 rw->hidden.unknown.data1 = ifs.release();
85 ERR_FS <<
"make_write_RWops: ostream_file returned NULL on " <<
path;
90 rw->hidden.unknown.data1 = ofs.release();
95 static int64_t
ifs_size (
struct SDL_RWops * context) {
96 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
97 std::streampos orig = ifs->tellg();
99 ifs->seekg(0, std::ios::end);
101 std::streampos len = ifs->tellg();
107 static int64_t
ofs_size (
struct SDL_RWops * context) {
108 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
109 std::streampos orig = ofs->tellp();
111 ofs->seekp(0, std::ios::end);
113 std::streampos len = ofs->tellp();
120 typedef std::pair<int64_t, std::ios_base::seekdir>
offset_dir;
125 return std::pair(std::max<int64_t>(0, offset), std::ios_base::beg);
127 return std::pair(offset, std::ios_base::cur);
129 return std::pair(std::min<int64_t>(0, offset), std::ios_base::end);
132 throw "assertion ignored";
135 static int64_t SDLCALL
ifs_seek(
struct SDL_RWops *context, int64_t offset,
int whence) {
136 std::ios_base::seekdir seekdir;
139 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
140 const std::ios_base::iostate saved_state = ifs->rdstate();
142 ifs->seekg(offset, seekdir);
144 if(saved_state != ifs->rdstate() && offset < 0) {
145 ifs->clear(saved_state);
146 ifs->seekg(0, std::ios_base::beg);
149 std::streamsize pos = ifs->tellg();
150 return static_cast<int>(pos);
152 static int64_t SDLCALL
ofs_seek(
struct SDL_RWops *context, int64_t offset,
int whence) {
153 std::ios_base::seekdir seekdir;
156 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
157 const std::ios_base::iostate saved_state = ofs->rdstate();
159 ofs->seekp(offset, seekdir);
161 if(saved_state != ofs->rdstate() && offset < 0) {
162 ofs->clear(saved_state);
163 ofs->seekp(0, std::ios_base::beg);
166 std::streamsize pos = ofs->tellp();
167 return static_cast<int>(pos);
170 static std::size_t SDLCALL
ifs_read(
struct SDL_RWops *context,
void *ptr, std::size_t
size, std::size_t maxnum) {
171 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
174 ifs->read(
static_cast<char*
>(ptr), maxnum *
size);
175 std::streamsize num = ifs->good() ? maxnum : ifs->gcount() /
size;
181 return static_cast<int>(num);
183 static std::size_t SDLCALL
ofs_read(
struct SDL_RWops * ,
void * , std::size_t , std::size_t ) {
184 SDL_SetError(
"Reading not implemented");
188 static std::size_t SDLCALL
ifs_write(
struct SDL_RWops * ,
const void * , std::size_t , std::size_t ) {
189 SDL_SetError(
"Writing not implemented");
192 static std::size_t SDLCALL
ofs_write(
struct SDL_RWops *context,
const void *ptr, std::size_t
size, std::size_t num) {
193 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
195 const std::streampos before = ofs->tellp();
196 ofs->write(
static_cast<const char*
>(ptr), num *
size);
197 const std::streampos after = ofs->tellp();
198 const std::streamoff bytes_written = after - before;
199 const int num_written = bytes_written /
size;
204 static int SDLCALL
ifs_close(
struct SDL_RWops *context) {
206 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
212 static int SDLCALL
ofs_close(
struct SDL_RWops *context) {
214 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
Declarations for File-IO.
static lg::log_domain log_filesystem("filesystem")
Standard logging facilities (interface).
filesystem::scoped_istream istream_file(const std::string &fname, bool treat_failure_as_error)
static int64_t ifs_size(struct SDL_RWops *context)
std::pair< int64_t, std::ios_base::seekdir > offset_dir
static int64_t SDLCALL ofs_seek(struct SDL_RWops *context, int64_t offset, int whence)
static std::size_t SDLCALL ofs_read(struct SDL_RWops *context, void *ptr, std::size_t size, std::size_t maxnum)
static const uint32_t read_type
std::unique_ptr< SDL_RWops, sdl_rwops_deleter > rwops_ptr
rwops_ptr make_read_RWops(const std::string &path)
static int64_t ofs_size(struct SDL_RWops *context)
filesystem::scoped_ostream ostream_file(const std::string &fname, std::ios_base::openmode mode, bool create_directory)
static int SDLCALL ifs_close(struct SDL_RWops *context)
static std::size_t SDLCALL ifs_read(struct SDL_RWops *context, void *ptr, std::size_t size, std::size_t maxnum)
std::unique_ptr< std::istream > scoped_istream
std::unique_ptr< std::ostream > scoped_ostream
static int SDLCALL ofs_close(struct SDL_RWops *context)
static std::size_t SDLCALL ofs_write(struct SDL_RWops *context, const void *ptr, std::size_t size, std::size_t num)
rwops_ptr make_write_RWops(const std::string &path)
static const uint32_t write_type
static std::size_t SDLCALL ifs_write(struct SDL_RWops *context, const void *ptr, std::size_t size, std::size_t num)
static offset_dir translate_seekdir(int64_t offset, int whence)
static int64_t SDLCALL ifs_seek(struct SDL_RWops *context, int64_t offset, int whence)
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
void operator()(SDL_RWops *) const noexcept