IO.hpp
Go to the documentation of this file.
1 
2 
3 
4 #ifndef GOSU_IO_HPP
5 #define GOSU_IO_HPP
6 
7 #include <cstddef>
8 #include <algorithm>
9 #include <memory>
10 #include <string>
11 #include <vector>
12 
13 namespace Gosu
14 {
15  class Resource;
16 
18 #ifdef __BIG_ENDIAN__
20 #else
22 #endif
23 
26  class Reader
27  {
28  const Resource* res;
29  std::size_t pos;
30 
31  public:
32  Reader(const Resource& resource, std::size_t position)
33  : res(&resource), pos(position)
34  {
35  }
36 
37  const Resource& resource() const
38  {
39  return *res;
40  }
41 
42  std::size_t position() const
43  {
44  return pos;
45  }
46 
47  void setPosition(std::size_t value)
48  {
49  // TODO: Check?
50  pos = value;
51  }
52 
53  void seek(std::ptrdiff_t offset)
54  {
55  // TODO: Check?
56  pos += offset;
57  }
58 
59  void read(void* destBuffer, std::size_t length);
60 
62  template<typename T>
63  void readPod(T& t, ByteOrder bo = boDontCare)
64  {
65  read(&t, sizeof t);
66  if (bo == otherByteOrder)
67  {
68  char* begin = reinterpret_cast<char*>(&t);
69  std::reverse(begin, begin + sizeof t);
70  }
71  }
72 
74  template<typename T>
76  {
77  T t;
78  readPod<T>(t, bo);
79  return t;
80  }
81  };
82 
85  class Writer
86  {
87  Resource* res;
88  std::size_t pos;
89 
90  public:
92  : res(&resource), pos(position)
93  {
94  }
95 
96  Resource& resource() const
97  {
98  return *res;
99  }
100 
101  std::size_t position() const
102  {
103  return pos;
104  }
105 
106  void setPosition(std::size_t value)
107  {
108  // TODO: Check?
109  pos = value;
110  }
111 
112  void seek(std::ptrdiff_t offset)
113  {
114  // TODO: Check?
115  pos += offset;
116  }
117 
118  void write(const void* sourceBuffer, std::size_t length);
119 
121  template<typename T>
122  void writePod(const T& t, ByteOrder bo = boDontCare)
123  {
124  if (bo == otherByteOrder)
125  {
126  char buf[sizeof t];
127  const char* begin = reinterpret_cast<const char*>(&t);
128  std::reverse_copy(begin, begin + sizeof t, buf);
129  write(buf, sizeof buf);
130  }
131  else
132  write(&t, sizeof t);
133  }
134  };
135 
141  class Resource
142  {
143  // Non-copyable
144  Resource(const Resource&);
145  Resource& operator=(const Resource&);
146 
147  public:
149  {
150  }
151 
152  virtual ~Resource()
153  {
154  }
155 
159  {
160  return Reader(*this, 0);
161  }
162 
166  {
167  return Writer(*this, size());
168  }
169 
170  virtual std::size_t size() const = 0;
171 
172  virtual void resize(std::size_t newSize) = 0;
173 
174  virtual void read(std::size_t offset, std::size_t length,
175  void* destBuffer) const = 0;
176 
177  virtual void write(std::size_t offset, std::size_t length,
178  const void* sourceBuffer) = 0;
179  };
180 
182  class Buffer : public Resource
183  {
184  std::vector<char> buf;
185 
186  public:
188  {
189  }
190 
191  Buffer(const Buffer& other)
192  : buf(other.buf)
193  {
194  }
195 
196  Buffer& operator=(const Buffer& other)
197  {
198  buf = other.buf;
199  return *this;
200  }
201 
202  std::size_t size() const;
203  void resize(std::size_t newSize);
204 
205  void read(std::size_t offset, std::size_t length,
206  void* destBuffer) const;
207 
208  void write(std::size_t offset, std::size_t length,
209  const void* sourceBuffer);
210 
211  const void* data() const
212  {
213  return &buf[0];
214  }
215 
216  void* data()
217  {
218  return &buf[0];
219  }
220  };
221 
222  enum FileMode
223  {
233  };
234 
236  class File : public Resource
237  {
238  struct Impl;
239  const std::auto_ptr<Impl> pimpl;
240 
241  public:
242  explicit File(const std::wstring& filename, FileMode mode = fmRead);
243  ~File();
244 
245  std::size_t size() const;
246  void resize(std::size_t newSize);
247  void read(std::size_t offset, std::size_t length,
248  void* destBuffer) const;
249  void write(std::size_t offset, std::size_t length,
250  const void* sourceBuffer);
251  };
252 
254  void loadFile(Buffer& buffer, const std::wstring& filename);
256  void saveFile(const Buffer& buffer, const std::wstring& filename);
257 }
258 
259 #endif