Implement proper Size() handling in custom rwops

This commit is contained in:
Dmitry Marakasov 2017-04-21 18:16:49 +03:00
parent 5f6191dfc1
commit f28e873d17
4 changed files with 62 additions and 0 deletions

View File

@ -82,6 +82,19 @@ public:
ContainerRWops(C& container) : container_(container), position_(0) {
}
////////////////////////////////////////////////////////////
/// \brief Get the size of the data stream
///
/// \returns Size of the data stream on success, -1 if unknown
///
/// \see SDL2pp::RWops::Size
/// \see http://wiki.libsdl.org/SDL_RWsize
///
////////////////////////////////////////////////////////////
virtual Sint64 Size() override {
return static_cast<Sint64>(container_.size());
}
////////////////////////////////////////////////////////////
/// \brief Seek within the container
///

View File

@ -26,6 +26,13 @@
namespace SDL2pp {
Sint64 RWops::StdSizeFuncWrapper(SDL_RWops* context) {
assert(context != nullptr);
SDL_RWops* sdl_rwops = reinterpret_cast<SDL_RWops*>(context->hidden.unknown.data1);
assert(sdl_rwops != nullptr);
return sdl_rwops->size(sdl_rwops);
}
Sint64 RWops::StdSeekFuncWrapper(SDL_RWops* context, Sint64 offset, int whence) {
assert(context != nullptr);
SDL_RWops* sdl_rwops = reinterpret_cast<SDL_RWops*>(context->hidden.unknown.data1);
@ -63,6 +70,13 @@ int RWops::StdCloseFuncWrapper(SDL_RWops* context) {
return ret;
}
Sint64 RWops::CustomSizeFuncWrapper(SDL_RWops* context) {
assert(context != nullptr);
CustomRWops* custom_rwops = reinterpret_cast<CustomRWops*>(context->hidden.unknown.data1);
assert(custom_rwops != nullptr);
return custom_rwops->Size();
}
Sint64 RWops::CustomSeekFuncWrapper(SDL_RWops* context, Sint64 offset, int whence) {
assert(context != nullptr);
CustomRWops* custom_rwops = reinterpret_cast<CustomRWops*>(context->hidden.unknown.data1);
@ -136,6 +150,7 @@ RWops::RWops(SDL_RWops* rwops) {
if (rwops_ == nullptr)
throw Exception("SDL_AllocRW");
rwops_->size = StdSizeFuncWrapper;
rwops_->seek = StdSeekFuncWrapper;
rwops_->read = StdReadFuncWrapper;
rwops_->write = StdWriteFuncWrapper;

View File

@ -53,6 +53,16 @@ public:
////////////////////////////////////////////////////////////
virtual ~CustomRWops() {}
////////////////////////////////////////////////////////////
/// \brief Get the size of the data stream
///
/// \returns Size of the data stream on success, -1 if unknown
///
/// \see http://wiki.libsdl.org/SDL_RWsize
///
////////////////////////////////////////////////////////////
virtual Sint64 Size() = 0;
////////////////////////////////////////////////////////////
/// \brief Seek within the data stream
///
@ -148,11 +158,13 @@ protected:
SDL_RWops* rwops_; ///< Managed SDL_RWops object
private:
static Sint64 StdSizeFuncWrapper(SDL_RWops* context);
static Sint64 StdSeekFuncWrapper(SDL_RWops* context, Sint64 offset, int whence);
static size_t StdReadFuncWrapper(SDL_RWops* context, void *ptr, size_t size, size_t maxnum);
static size_t StdWriteFuncWrapper(SDL_RWops* context, const void *ptr, size_t size, size_t maxnum);
static int StdCloseFuncWrapper(SDL_RWops* context);
static Sint64 CustomSizeFuncWrapper(SDL_RWops* context);
static Sint64 CustomSeekFuncWrapper(SDL_RWops* context, Sint64 offset, int whence);
static size_t CustomReadFuncWrapper(SDL_RWops* context, void *ptr, size_t size, size_t maxnum);
static size_t CustomWriteFuncWrapper(SDL_RWops* context, const void *ptr, size_t size, size_t maxnum);
@ -272,6 +284,7 @@ public:
if (rwops_ == nullptr)
throw Exception("SDL_AllocRW");
rwops_->size = CustomSizeFuncWrapper;
rwops_->seek = CustomSeekFuncWrapper;
rwops_->read = CustomReadFuncWrapper;
rwops_->write = CustomWriteFuncWrapper;

View File

@ -24,6 +24,7 @@
#include <SDL2pp/RWops.hh>
#include <cassert>
#include <stdexcept>
#include <iostream>
#include <type_traits>
@ -147,6 +148,26 @@ public:
StreamRWops(S& stream) : stream_(stream) {
}
////////////////////////////////////////////////////////////
/// \brief Get the size of the data stream
///
/// \returns Size of the data stream on success, -1 if unknown
///
/// \see SDL2pp::RWops::Size
/// \see http://wiki.libsdl.org/SDL_RWsize
///
////////////////////////////////////////////////////////////
virtual Sint64 Size() override {
Sint64 old_pos = TellHelper<S>();
if (old_pos == -1) // not seekable?
return -1;
SeekHelper<S>(0, std::ios_base::end);
Sint64 size = TellHelper<S>();
SeekHelper<S>(old_pos, std::ios_base::beg);
assert(TellHelper<S>() == old_pos); // make sure we're back to where we were
return size;
}
////////////////////////////////////////////////////////////
/// \brief Seek within the stream
///