libSDL2pp
C++11 bindings/wrapper for SDL2
ContainerRWops.hh
1/*
2 libSDL2pp - C++11 bindings/wrapper for SDL2
3 Copyright (C) 2014-2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#ifndef SDL2PP_CONTAINERRWOPS_HH
23#define SDL2PP_CONTAINERRWOPS_HH
24
25#include <SDL2pp/RWops.hh>
26
27#include <type_traits>
28#include <stdexcept>
29#include <algorithm>
30
31namespace SDL2pp {
32
50template <class C>
52protected:
54 size_t position_;
55
56private:
57 template <class CC>
58 typename std::enable_if<!std::is_const<CC>::value, size_t>::type WriteHelper(const void* ptr, size_t size, size_t num) {
59 if (position_ + size * num > container_.size())
60 container_.resize(position_ + size * num);
61
62 std::copy(reinterpret_cast<const unsigned char*>(ptr), reinterpret_cast<const unsigned char*>(ptr) + size * num, container_.begin() + position_);
63
64 position_ += size * num;
65
66 return num;
67 }
68
69 template <class CC>
70 typename std::enable_if<std::is_const<CC>::value, size_t>::type WriteHelper(const void*, size_t, size_t) {
71 SDL_SetError("Can't write to read-only container");
72 return 0;
73 }
74
75public:
82 ContainerRWops(C& container) : container_(container), position_(0) {
83 }
84
94 virtual Sint64 Size() override {
95 return static_cast<Sint64>(container_.size());
96 }
97
111 virtual Sint64 Seek(Sint64 offset, int whence) override {
112 switch (whence) {
113 case RW_SEEK_SET:
114 position_ = static_cast<size_t>(offset);
115 break;
116 case RW_SEEK_CUR:
117 position_ = static_cast<size_t>(position_ + offset);
118 break;
119 case RW_SEEK_END:
120 position_ = static_cast<size_t>(container_.size() + offset);
121 break;
122 default:
123 throw std::logic_error("Unexpected whence value for ContainerRWops::Seek");
124 }
125 return position_;
126 }
127
141 virtual size_t Read(void* ptr, size_t size, size_t maxnum) override {
142 if (position_ + size > container_.size())
143 return 0;
144
145 size_t toread = std::min((container_.size() - position_), maxnum * size);
146
147 std::copy(container_.begin() + position_, container_.begin() + position_ + toread, reinterpret_cast<unsigned char*>(ptr));
148
149 position_ += toread;
150
151 return toread / size;
152 }
153
167 virtual size_t Write(const void* ptr, size_t size, size_t num) override {
168 return WriteHelper<C>(ptr, size, num);
169 }
170
183 virtual int Close() override {
184 return 0;
185 }
186};
187
188}
189
190#endif
RWops adaptor for random access STL containers.
Definition: ContainerRWops.hh:51
ContainerRWops(C &container)
Construct ContainerRWops for specified container.
Definition: ContainerRWops.hh:82
virtual Sint64 Size() override
Get the size of the data stream.
Definition: ContainerRWops.hh:94
size_t position_
Virtual file pointer position.
Definition: ContainerRWops.hh:54
C & container_
Reference to container.
Definition: ContainerRWops.hh:53
virtual size_t Read(void *ptr, size_t size, size_t maxnum) override
Read from a container.
Definition: ContainerRWops.hh:141
virtual int Close() override
Close data source.
Definition: ContainerRWops.hh:183
virtual Sint64 Seek(Sint64 offset, int whence) override
Seek within the container.
Definition: ContainerRWops.hh:111
virtual size_t Write(const void *ptr, size_t size, size_t num) override
Write to container.
Definition: ContainerRWops.hh:167
Base class for custom RWops.
Definition: RWops.hh:48