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);
57 ERR_FS <<
"make_read_RWops: istream_file returned NULL on " <<
path;
62 rw->hidden.unknown.data1 = ifs.release();
80 ERR_FS <<
"make_write_RWops: ostream_file returned NULL on " <<
path;
85 rw->hidden.unknown.data1 = ofs.release();
90 static int64_t
ifs_size (
struct SDL_RWops * context) {
91 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
92 std::streampos orig = ifs->tellg();
94 ifs->seekg(0, std::ios::end);
96 std::streampos len = ifs->tellg();
102 static int64_t
ofs_size (
struct SDL_RWops * context) {
103 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
104 std::streampos orig = ofs->tellp();
106 ofs->seekp(0, std::ios::end);
108 std::streampos len = ofs->tellp();
115 typedef std::pair<int64_t, std::ios_base::seekdir>
offset_dir;
120 return std::pair(std::max<int64_t>(0, offset), std::ios_base::beg);
122 return std::pair(offset, std::ios_base::cur);
124 return std::pair(std::min<int64_t>(0, offset), std::ios_base::end);
127 throw "assertion ignored";
130 static int64_t SDLCALL
ifs_seek(
struct SDL_RWops *context, int64_t offset,
int whence) {
131 std::ios_base::seekdir seekdir;
134 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
135 const std::ios_base::iostate saved_state = ifs->rdstate();
137 ifs->seekg(offset, seekdir);
139 if(saved_state != ifs->rdstate() && offset < 0) {
140 ifs->clear(saved_state);
141 ifs->seekg(0, std::ios_base::beg);
144 std::streamsize pos = ifs->tellg();
145 return static_cast<int>(pos);
147 static int64_t SDLCALL
ofs_seek(
struct SDL_RWops *context, int64_t offset,
int whence) {
148 std::ios_base::seekdir seekdir;
151 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
152 const std::ios_base::iostate saved_state = ofs->rdstate();
154 ofs->seekp(offset, seekdir);
156 if(saved_state != ofs->rdstate() && offset < 0) {
157 ofs->clear(saved_state);
158 ofs->seekp(0, std::ios_base::beg);
161 std::streamsize pos = ofs->tellp();
162 return static_cast<int>(pos);
165 static std::size_t SDLCALL
ifs_read(
struct SDL_RWops *context,
void *ptr, std::size_t
size, std::size_t maxnum) {
166 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
169 ifs->read(static_cast<char*>(ptr), maxnum * size);
170 std::streamsize num = ifs->good() ? maxnum : ifs->gcount() /
size;
176 return static_cast<int>(num);
178 static std::size_t SDLCALL
ofs_read(
struct SDL_RWops * ,
void * , std::size_t , std::size_t ) {
179 SDL_SetError(
"Reading not implemented");
183 static std::size_t SDLCALL
ifs_write(
struct SDL_RWops * ,
const void * , std::size_t , std::size_t ) {
184 SDL_SetError(
"Writing not implemented");
187 static std::size_t SDLCALL
ofs_write(
struct SDL_RWops *context,
const void *ptr, std::size_t
size, std::size_t num) {
188 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
190 const std::streampos before = ofs->tellp();
191 ofs->write(static_cast<const char*>(ptr), num * size);
192 const std::streampos after = ofs->tellp();
193 const std::streamoff bytes_written = after - before;
194 const int num_written = bytes_written /
size;
199 static int SDLCALL
ifs_close(
struct SDL_RWops *context) {
201 std::istream *ifs =
static_cast<std::istream*
>(context->hidden.unknown.data1);
207 static int SDLCALL
ofs_close(
struct SDL_RWops *context) {
209 std::ostream *ofs =
static_cast<std::ostream*
>(context->hidden.unknown.data1);
static int SDLCALL ofs_close(struct SDL_RWops *context)
static offset_dir translate_seekdir(int64_t offset, int whence)
static int SDLCALL ifs_close(struct SDL_RWops *context)
std::pair< int64_t, std::ios_base::seekdir > offset_dir
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_read_RWops(const std::string &path)
filesystem::scoped_istream istream_file(const std::string &fname, bool treat_failure_as_error)
filesystem::scoped_ostream ostream_file(const std::string &fname, std::ios_base::openmode mode, bool create_directory)
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
rwops_ptr make_write_RWops(const std::string &path)
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
static std::size_t SDLCALL ifs_write(struct SDL_RWops *context, const void *ptr, std::size_t size, std::size_t num)
static int64_t SDLCALL ofs_seek(struct SDL_RWops *context, int64_t offset, int whence)
std::unique_ptr< std::ostream > scoped_ostream
static std::size_t SDLCALL ofs_read(struct SDL_RWops *context, void *ptr, std::size_t size, std::size_t maxnum)
Declarations for File-IO.
std::unique_ptr< SDL_RWops, void(*)(SDL_RWops *)> rwops_ptr
static int64_t ifs_size(struct SDL_RWops *context)
static const uint32_t write_type
Standard logging facilities (interface).
static const uint32_t read_type
static int64_t SDLCALL ifs_seek(struct SDL_RWops *context, int64_t offset, int whence)
static lg::log_domain log_filesystem("filesystem")
static int64_t ofs_size(struct SDL_RWops *context)