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