15 #include <SDL2/SDL_rwops.h>
24 #define ERR_FS LOG_STREAM(err, log_filesystem)
32 static int64_t
ifs_size (
struct SDL_RWops * context);
33 static int64_t
ofs_size (
struct SDL_RWops * context);
34 static int64_t SDLCALL
ifs_seek(
struct SDL_RWops *context, int64_t offset,
int whence);
35 static int64_t SDLCALL
ofs_seek(
struct SDL_RWops *context, int64_t offset,
int whence);
36 static std::size_t SDLCALL
ifs_read(
struct SDL_RWops *context,
void *ptr, std::size_t
size, std::size_t maxnum);
37 static std::size_t SDLCALL
ofs_read(
struct SDL_RWops *context,
void *ptr, std::size_t
size, std::size_t maxnum);
38 static std::size_t SDLCALL
ifs_write(
struct SDL_RWops *context,
const void *ptr, std::size_t
size, std::size_t num);
39 static std::size_t SDLCALL
ofs_write(
struct SDL_RWops *context,
const void *ptr, std::size_t
size, std::size_t num);
40 static int SDLCALL
ifs_close(
struct SDL_RWops *context);
41 static int SDLCALL
ofs_close(
struct SDL_RWops *context);
61 ERR_FS <<
"make_read_RWops: istream_file returned NULL on " <<
path;
66 rw->hidden.unknown.data1 = ifs.release();
84 ERR_FS <<
"make_write_RWops: ostream_file returned NULL on " <<
path;
89 rw->hidden.unknown.data1 = ofs.release();
94 static int64_t
ifs_size (
struct SDL_RWops * context) {
95 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
96 std::streampos orig = ifs->tellg();
98 ifs->seekg(0, std::ios::end);
100 std::streampos len = ifs->tellg();
106 static int64_t
ofs_size (
struct SDL_RWops * context) {
107 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
108 std::streampos orig = ofs->tellp();
110 ofs->seekp(0, std::ios::end);
112 std::streampos len = ofs->tellp();
119 typedef std::pair<int64_t, std::ios_base::seekdir>
offset_dir;
124 return std::pair(std::max<int64_t>(0, offset), std::ios_base::beg);
126 return std::pair(offset, std::ios_base::cur);
128 return std::pair(std::min<int64_t>(0, offset), std::ios_base::end);
131 throw "assertion ignored";
134 static int64_t SDLCALL
ifs_seek(
struct SDL_RWops *context, int64_t offset,
int whence) {
135 std::ios_base::seekdir seekdir;
138 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
139 const std::ios_base::iostate saved_state = ifs->rdstate();
141 ifs->seekg(offset, seekdir);
143 if(saved_state != ifs->rdstate() && offset < 0) {
144 ifs->clear(saved_state);
145 ifs->seekg(0, std::ios_base::beg);
148 std::streamsize pos = ifs->tellg();
149 return static_cast<int>(pos);
151 static int64_t SDLCALL
ofs_seek(
struct SDL_RWops *context, int64_t offset,
int whence) {
152 std::ios_base::seekdir seekdir;
155 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
156 const std::ios_base::iostate saved_state = ofs->rdstate();
158 ofs->seekp(offset, seekdir);
160 if(saved_state != ofs->rdstate() && offset < 0) {
161 ofs->clear(saved_state);
162 ofs->seekp(0, std::ios_base::beg);
165 std::streamsize pos = ofs->tellp();
166 return static_cast<int>(pos);
169 static std::size_t SDLCALL
ifs_read(
struct SDL_RWops *context,
void *ptr, std::size_t
size, std::size_t maxnum) {
170 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
173 ifs->read(
static_cast<char*
>(ptr), maxnum *
size);
174 std::streamsize num = ifs->good() ? maxnum : ifs->gcount() /
size;
180 return static_cast<int>(num);
182 static std::size_t SDLCALL
ofs_read(
struct SDL_RWops * ,
void * , std::size_t , std::size_t ) {
183 SDL_SetError(
"Reading not implemented");
187 static std::size_t SDLCALL
ifs_write(
struct SDL_RWops * ,
const void * , std::size_t , std::size_t ) {
188 SDL_SetError(
"Writing not implemented");
191 static std::size_t SDLCALL
ofs_write(
struct SDL_RWops *context,
const void *ptr, std::size_t
size, std::size_t num) {
192 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
194 const std::streampos before = ofs->tellp();
195 ofs->write(
static_cast<const char*
>(ptr), num *
size);
196 const std::streampos after = ofs->tellp();
197 const std::streamoff bytes_written = after - before;
198 const int num_written = bytes_written /
size;
203 static int SDLCALL
ifs_close(
struct SDL_RWops *context) {
205 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
211 static int SDLCALL
ofs_close(
struct SDL_RWops *context) {
213 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(std::string_view str)
Length in characters of a UTF-8 string.
void operator()(SDL_RWops *) const noexcept