22#ifndef SDL2PP_STREAMRWOPS_HH
23#define SDL2PP_STREAMRWOPS_HH
25#include <SDL2pp/RWops.hh>
54 static_assert(!(std::is_base_of<std::istream, S>::value && std::is_base_of<std::ostream, S>::value),
"StreamRWops does not support reading and writing at the same time");
61 typename std::enable_if<std::is_base_of<std::istream, SS>::value && !std::is_base_of<std::ostream, SS>::value,
void>::type SeekHelper(
typename SS::off_type off, std::ios_base::seekdir dir) {
66 typename std::enable_if<!std::is_base_of<std::istream, SS>::value && std::is_base_of<std::ostream, SS>::value,
void>::type SeekHelper(
typename SS::off_type off, std::ios_base::seekdir dir) {
71 typename std::enable_if<std::is_base_of<std::istream, SS>::value && !std::is_base_of<std::ostream, SS>::value,
typename SS::off_type>::type TellHelper() {
76 typename std::enable_if<!std::is_base_of<std::istream, SS>::value && std::is_base_of<std::ostream, SS>::value,
typename SS::off_type>::type TellHelper() {
81 typename std::enable_if<std::is_base_of<std::istream, SS>::value,
size_t>::type ReadHelper(
void* ptr,
size_t size,
size_t maxnum) {
82 stream_.read(
static_cast<char*
>(ptr), size * maxnum);
87 size_t nread =
static_cast<size_t>(
stream_.gcount());
90 if (
stream_.rdstate() == (std::ios_base::eofbit | std::ios_base::failbit))
93 if (nread != size * maxnum) {
95 char* pos =
static_cast<char*
>(ptr);
98 size_t count = nread % size;
111 typename std::enable_if<!std::is_base_of<std::istream, SS>::value,
size_t>::type ReadHelper(
void*,
size_t,
size_t) {
116 typename std::enable_if<std::is_base_of<std::ostream, SS>::value,
size_t>::type WriteHelper(
const void* ptr,
size_t size,
size_t num) {
117 stream_.write(
static_cast<const char*
>(ptr), size * num);
120 if (
stream_.rdstate() & std::ios_base::badbit)
126 typename std::enable_if<!std::is_base_of<std::ostream, SS>::value,
size_t>::type WriteHelper(
const void*,
size_t,
size_t) {
131 typename std::enable_if<std::is_base_of<std::ostream, SS>::value,
int>::type CloseHelper() {
133 return (
stream_.rdstate() & std::ios_base::badbit) ? -1 : 0;
137 typename std::enable_if<!std::is_base_of<std::ostream, SS>::value,
int>::type CloseHelper() {
160 virtual Sint64
Size()
override {
161 Sint64 old_pos = TellHelper<S>();
164 SeekHelper<S>(0, std::ios_base::end);
165 Sint64 size = TellHelper<S>();
166 SeekHelper<S>(old_pos, std::ios_base::beg);
167 assert(TellHelper<S>() == old_pos);
184 virtual Sint64
Seek(Sint64 offset,
int whence)
override {
187 SeekHelper<S>(offset, std::ios_base::beg);
190 SeekHelper<S>(offset, std::ios_base::cur);
193 SeekHelper<S>(offset, std::ios_base::end);
196 throw std::logic_error(
"Unexpected whence value for StreamRWops::Seek");
198 return TellHelper<S>();
214 virtual size_t Read(
void* ptr,
size_t size,
size_t maxnum)
override {
215 return ReadHelper<S>(ptr, size, maxnum);
231 virtual size_t Write(
const void* ptr,
size_t size,
size_t num)
override {
232 return WriteHelper<S>(ptr, size, num);
245 return CloseHelper<S>();
Base class for custom RWops.
Definition: RWops.hh:48
RWops adaptor for STL streams.
Definition: StreamRWops.hh:51
virtual Sint64 Size() override
Get the size of the data stream.
Definition: StreamRWops.hh:160
StreamRWops(S &stream)
Construct StreamRWops for specified stream.
Definition: StreamRWops.hh:148
virtual int Close() override
Close stream.
Definition: StreamRWops.hh:244
S & stream_
Reference to stream.
Definition: StreamRWops.hh:57
virtual size_t Read(void *ptr, size_t size, size_t maxnum) override
Read from a stream.
Definition: StreamRWops.hh:214
virtual size_t Write(const void *ptr, size_t size, size_t num) override
Write to a stream.
Definition: StreamRWops.hh:231
virtual Sint64 Seek(Sint64 offset, int whence) override
Seek within the stream.
Definition: StreamRWops.hh:184