Go to the documentation of this file.00001
00002
00003
00004 #ifndef GOSU_IO_HPP
00005 #define GOSU_IO_HPP
00006
00007 #include <cstddef>
00008 #include <algorithm>
00009 #include <memory>
00010 #include <string>
00011 #include <vector>
00012
00013 namespace Gosu
00014 {
00015 class Resource;
00016
00017 enum ByteOrder { boLittle, boBig, boDontCare };
00018 #ifdef __BIG_ENDIAN__
00019 const ByteOrder nativeByteOrder = boBig, otherByteOrder = boLittle;
00020 #else
00021 const ByteOrder nativeByteOrder = boLittle, otherByteOrder = boBig;
00022 #endif
00023
00026 class Reader
00027 {
00028 const Resource* res;
00029 std::size_t pos;
00030
00031 public:
00032 Reader(const Resource& resource, std::size_t position)
00033 : res(&resource), pos(position)
00034 {
00035 }
00036
00037 const Resource& resource() const
00038 {
00039 return *res;
00040 }
00041
00042 std::size_t position() const
00043 {
00044 return pos;
00045 }
00046
00047 void setPosition(std::size_t value)
00048 {
00049
00050 pos = value;
00051 }
00052
00053 void seek(std::ptrdiff_t offset)
00054 {
00055
00056 pos += offset;
00057 }
00058
00059 void read(void* destBuffer, std::size_t length);
00060
00062 template<typename T>
00063 void readPod(T& t, ByteOrder bo = boDontCare)
00064 {
00065 read(&t, sizeof t);
00066 if (bo == otherByteOrder)
00067 {
00068 char* begin = reinterpret_cast<char*>(&t);
00069 std::reverse(begin, begin + sizeof t);
00070 }
00071 }
00072
00074 template<typename T>
00075 T getPod(ByteOrder bo = boDontCare)
00076 {
00077 T t;
00078 readPod<T>(t, bo);
00079 return t;
00080 }
00081 };
00082
00085 class Writer
00086 {
00087 Resource* res;
00088 std::size_t pos;
00089
00090 public:
00091 Writer(Resource& resource, std::size_t position)
00092 : res(&resource), pos(position)
00093 {
00094 }
00095
00096 Resource& resource() const
00097 {
00098 return *res;
00099 }
00100
00101 std::size_t position() const
00102 {
00103 return pos;
00104 }
00105
00106 void setPosition(std::size_t value)
00107 {
00108
00109 pos = value;
00110 }
00111
00112 void seek(std::ptrdiff_t offset)
00113 {
00114
00115 pos += offset;
00116 }
00117
00118 void write(const void* sourceBuffer, std::size_t length);
00119
00121 template<typename T>
00122 void writePod(const T& t, ByteOrder bo = boDontCare)
00123 {
00124 if (bo == otherByteOrder)
00125 {
00126 char buf[sizeof t];
00127 const char* begin = reinterpret_cast<const char*>(&t);
00128 std::reverse_copy(begin, begin + sizeof t, buf);
00129 write(buf, sizeof buf);
00130 }
00131 else
00132 write(&t, sizeof t);
00133 }
00134 };
00135
00141 class Resource
00142 {
00143
00144 Resource(const Resource&);
00145 Resource& operator=(const Resource&);
00146
00147 public:
00148 Resource()
00149 {
00150 }
00151
00152 virtual ~Resource()
00153 {
00154 }
00155
00158 Reader frontReader() const
00159 {
00160 return Reader(*this, 0);
00161 }
00162
00165 Writer backWriter()
00166 {
00167 return Writer(*this, size());
00168 }
00169
00170 virtual std::size_t size() const = 0;
00171
00172 virtual void resize(std::size_t newSize) = 0;
00173
00174 virtual void read(std::size_t offset, std::size_t length,
00175 void* destBuffer) const = 0;
00176
00177 virtual void write(std::size_t offset, std::size_t length,
00178 const void* sourceBuffer) = 0;
00179 };
00180
00182 class Buffer : public Resource
00183 {
00184 std::vector<char> buf;
00185
00186 public:
00187 Buffer()
00188 {
00189 }
00190
00191 Buffer(const Buffer& other)
00192 : buf(other.buf)
00193 {
00194 }
00195
00196 Buffer& operator=(const Buffer& other)
00197 {
00198 buf = other.buf;
00199 return *this;
00200 }
00201
00202 std::size_t size() const;
00203 void resize(std::size_t newSize);
00204
00205 void read(std::size_t offset, std::size_t length,
00206 void* destBuffer) const;
00207
00208 void write(std::size_t offset, std::size_t length,
00209 const void* sourceBuffer);
00210
00211 const void* data() const
00212 {
00213 return &buf[0];
00214 }
00215
00216 void* data()
00217 {
00218 return &buf[0];
00219 }
00220 };
00221
00222 enum FileMode
00223 {
00226 fmRead,
00229 fmReplace,
00232 fmAlter
00233 };
00234
00236 class File : public Resource
00237 {
00238 struct Impl;
00239 const std::auto_ptr<Impl> pimpl;
00240
00241 public:
00242 explicit File(const std::wstring& filename, FileMode mode = fmRead);
00243 ~File();
00244
00245 std::size_t size() const;
00246 void resize(std::size_t newSize);
00247 void read(std::size_t offset, std::size_t length,
00248 void* destBuffer) const;
00249 void write(std::size_t offset, std::size_t length,
00250 const void* sourceBuffer);
00251 };
00252
00254 void loadFile(Buffer& buffer, const std::wstring& filename);
00256 void saveFile(const Buffer& buffer, const std::wstring& filename);
00257 }
00258
00259 #endif