fixes in streams
This commit is contained in:
parent
4a7baa40a0
commit
9f35909660
|
@ -12,19 +12,18 @@
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ostd/types.hh"
|
|
||||||
#include "ostd/stream.hh"
|
#include "ostd/stream.hh"
|
||||||
|
|
||||||
namespace ostd {
|
namespace ostd {
|
||||||
namespace sdl {
|
namespace sdl {
|
||||||
|
|
||||||
#ifdef OSTD_EXT_SDL_USE_SDL1
|
#ifdef OSTD_EXT_SDL_USE_SDL1
|
||||||
using SDLRWopsOffset = int;
|
using sdl_rwops_off_t = int;
|
||||||
#else
|
#else
|
||||||
using SDLRWopsOffset = int64_t;
|
using sdl_rwops_off_t = int64_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline SDL_RWops *stream_to_rwops(Stream &s) {
|
inline SDL_RWops *stream_to_rwops(stream &s) {
|
||||||
SDL_RWops *rwr = SDL_AllocRW();
|
SDL_RWops *rwr = SDL_AllocRW();
|
||||||
if (!rwr) {
|
if (!rwr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -32,32 +31,52 @@ inline SDL_RWops *stream_to_rwops(Stream &s) {
|
||||||
|
|
||||||
rwr->hidden.unknown.data1 = &s;
|
rwr->hidden.unknown.data1 = &s;
|
||||||
|
|
||||||
rwr->size = [](SDL_RWops *rw) -> SDLRWopsOffset {
|
rwr->size = [](SDL_RWops *rw) -> sdl_rwops_off_t {
|
||||||
Stream *is = static_cast<Stream *>(rw->hidden.unknown.data1);
|
auto &is = *static_cast<stream *>(rw->hidden.unknown.data1);
|
||||||
return static_cast<SDLRWopsOffset>(is->size());
|
try {
|
||||||
|
return static_cast<sdl_rwops_off_t>(is.size());
|
||||||
|
} catch (stream_error const &) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rwr->seek = [](SDL_RWops *rw, SDLRWopsOffset pos, int whence) ->
|
rwr->seek = [](SDL_RWops *rw, sdl_rwops_off_t pos, int whence) ->
|
||||||
SDLRWopsOffset
|
sdl_rwops_off_t
|
||||||
{
|
{
|
||||||
Stream *is = static_cast<Stream *>(rw->hidden.unknown.data1);
|
auto &is = *static_cast<stream *>(rw->hidden.unknown.data1);
|
||||||
if (!pos && whence == SEEK_CUR) {
|
try {
|
||||||
return static_cast<SDLRWopsOffset>(is->tell());
|
if (!pos && whence == SEEK_CUR) {
|
||||||
}
|
return static_cast<sdl_rwops_off_t(is.tell());
|
||||||
if (is->seek(((StreamOffset)pos, (StreamSeek)whence)) {
|
}
|
||||||
return static_cast<SDLRWopsOffset>(is->tell());
|
if (is->seek((stream_off_t(pos), stream_seek(whence)))) {
|
||||||
|
return static_cast<sdl_rwops_off_t>(is.tell());
|
||||||
|
}
|
||||||
|
} catch (stream_error const &) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
rwr->read = [](SDL_RWops *rw, void *buf, size_t size, size_t nb) -> size_t {
|
rwr->read = [](SDL_RWops *rw, void *buf, size_t size, size_t nb) ->
|
||||||
Stream *is = static_cast<Stream *>(rw->hidden.unknown.data1);
|
size_t
|
||||||
return is->read_bytes(buf, size * nb) / size;
|
{
|
||||||
|
auto &is = *static_cast<stream *>(rw->hidden.unknown.data1);
|
||||||
|
try {
|
||||||
|
return is.read_bytes(buf, size * nb) / size;
|
||||||
|
} catch (stream_error const &) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rwr->write = [](SDL_RWops *rw, const void *buf, size_t size, size_t nb) -> size_t {
|
rwr->write = [](SDL_RWops *rw, void const *buf, size_t size, size_t nb) ->
|
||||||
Stream *is = static_cast<Stream *>(rw->hidden.unknown.data1);
|
size_t
|
||||||
return is->write_bytes(buf, size * nb) / size;
|
{
|
||||||
|
stream &is = *static_cast<stream *>(rw->hidden.unknown.data1);
|
||||||
|
try {
|
||||||
|
return is->write_bytes(buf, size * nb) / size;
|
||||||
|
} catch (stream_error const &) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rwr->close = [](SDL_RWops *) -> int {
|
rwr->close = [](SDL_RWops *) -> int {
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct OSTD_EXPORT file_stream: stream {
|
||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
void read_bytes(void *buf, size_t count);
|
size_t read_bytes(void *buf, size_t count);
|
||||||
void write_bytes(void const *buf, size_t count);
|
void write_bytes(void const *buf, size_t count);
|
||||||
|
|
||||||
int get_char();
|
int get_char();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#ifndef OSTD_STREAM_HH
|
#ifndef OSTD_STREAM_HH
|
||||||
#define OSTD_STREAM_HH
|
#define OSTD_STREAM_HH
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
@ -66,18 +67,30 @@ struct stream {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void seek(offset_type, stream_seek = stream_seek::SET) {}
|
virtual void seek(offset_type, stream_seek = stream_seek::SET) {
|
||||||
|
throw stream_error{EINVAL, std::generic_category()};
|
||||||
|
}
|
||||||
|
|
||||||
virtual offset_type tell() const { return -1; }
|
virtual offset_type tell() const {
|
||||||
|
throw stream_error{EINVAL, std::generic_category()};
|
||||||
|
}
|
||||||
|
|
||||||
virtual void flush() {}
|
virtual void flush() {
|
||||||
|
throw stream_error{EINVAL, std::generic_category()};
|
||||||
|
}
|
||||||
|
|
||||||
virtual void read_bytes(void *, size_t) {}
|
virtual size_t read_bytes(void *, size_t) {
|
||||||
virtual void write_bytes(void const *, size_t) {}
|
throw stream_error{EINVAL, std::generic_category()};
|
||||||
|
}
|
||||||
|
virtual void write_bytes(void const *, size_t) {
|
||||||
|
throw stream_error{EINVAL, std::generic_category()};
|
||||||
|
}
|
||||||
|
|
||||||
virtual int get_char() {
|
virtual int get_char() {
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
read_bytes(&c, 1);
|
if (!read_bytes(&c, 1)) {
|
||||||
|
throw stream_error{EIO, std::generic_category()};
|
||||||
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,13 +163,16 @@ struct stream {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void get(T *v, size_t count) {
|
size_t get(T *v, size_t count) {
|
||||||
read_bytes(v, count * sizeof(T));
|
/* if eof was reached, at least return how many values succeeded */
|
||||||
|
return read_bytes(v, count * sizeof(T)) / sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void get(T &v) {
|
void get(T &v) {
|
||||||
read_bytes(&v, sizeof(T));
|
if (read_bytes(&v, sizeof(T)) != sizeof(T)) {
|
||||||
|
throw stream_error{EIO, std::generic_category()};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -84,10 +84,15 @@ void file_stream::flush() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_stream::read_bytes(void *buf, size_t count) {
|
size_t file_stream::read_bytes(void *buf, size_t count) {
|
||||||
if (std::fread(buf, 1, count, p_f) != count) {
|
size_t readn = std::fread(buf, 1, count, p_f);
|
||||||
|
if (readn != count) {
|
||||||
|
if (std::feof(p_f) != 0) {
|
||||||
|
return readn;
|
||||||
|
}
|
||||||
throw stream_error{EIO, std::generic_category()};
|
throw stream_error{EIO, std::generic_category()};
|
||||||
}
|
}
|
||||||
|
return readn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_stream::write_bytes(void const *buf, size_t count) {
|
void file_stream::write_bytes(void const *buf, size_t count) {
|
||||||
|
|
Loading…
Reference in a new issue