00001 00002 00003 00004 #ifndef GOSU_IO_HPP 00005 #define GOSU_IO_HPP 00006 00007 #include <boost/utility.hpp> 00008 #include <boost/scoped_ptr.hpp> 00009 #include <cstddef> 00010 #include <algorithm> 00011 #include <string> 00012 #include <vector> 00013 00014 namespace Gosu 00015 { 00016 class Resource; 00017 00018 enum ByteOrder { boLittle, boBig, boDontCare }; 00019 #ifdef __BIG_ENDIAN__ 00020 const ByteOrder nativeByteOrder = boBig, otherByteOrder = boLittle; 00021 #else 00022 const ByteOrder nativeByteOrder = boLittle, otherByteOrder = boBig; 00023 #endif 00024 00027 class Reader 00028 { 00029 const Resource* res; 00030 std::size_t pos; 00031 00032 public: 00033 Reader(const Resource& resource, std::size_t position) 00034 : res(&resource), pos(position) 00035 { 00036 } 00037 00038 const Resource& resource() const 00039 { 00040 return *res; 00041 } 00042 00043 std::size_t position() const 00044 { 00045 return pos; 00046 } 00047 00048 void setPosition(std::size_t value) 00049 { 00050 // TODO: Check? 00051 pos = value; 00052 } 00053 00054 void seek(std::ptrdiff_t offset) 00055 { 00056 // TODO: Check? 00057 pos += offset; 00058 } 00059 00060 void read(void* destBuffer, std::size_t length); 00061 00063 template<typename T> 00064 void readPod(T& t, ByteOrder bo = boDontCare) 00065 { 00066 read(&t, sizeof t); 00067 if (bo == otherByteOrder) 00068 { 00069 char* begin = reinterpret_cast<char*>(&t); 00070 std::reverse(begin, begin + sizeof t); 00071 } 00072 } 00073 00075 template<typename T> 00076 T getPod(ByteOrder bo = boDontCare) 00077 { 00078 T t; 00079 readPod<T>(t, bo); 00080 return t; 00081 } 00082 }; 00083 00086 class Writer 00087 { 00088 Resource* res; 00089 std::size_t pos; 00090 00091 public: 00092 Writer(Resource& resource, std::size_t position) 00093 : res(&resource), pos(position) 00094 { 00095 } 00096 00097 Resource& resource() const 00098 { 00099 return *res; 00100 } 00101 00102 std::size_t position() const 00103 { 00104 return pos; 00105 } 00106 00107 void setPosition(std::size_t value) 00108 { 00109 // TODO: Check? 00110 pos = value; 00111 } 00112 00113 void seek(std::ptrdiff_t offset) 00114 { 00115 // TODO: Check? 00116 pos += offset; 00117 } 00118 00119 void write(const void* sourceBuffer, std::size_t length); 00120 00122 template<typename T> 00123 void writePod(const T& t, ByteOrder bo = boDontCare) 00124 { 00125 if (bo == otherByteOrder) 00126 { 00127 char buf[sizeof t]; 00128 const char* begin = reinterpret_cast<const char*>(&t); 00129 std::reverse_copy(begin, begin + sizeof t, buf); 00130 write(buf, sizeof buf); 00131 } 00132 else 00133 write(&t, sizeof t); 00134 } 00135 }; 00136 00142 class Resource : boost::noncopyable 00143 { 00144 public: 00145 virtual ~Resource() 00146 { 00147 } 00148 00151 Reader frontReader() const 00152 { 00153 return Reader(*this, 0); 00154 } 00155 00158 Writer backWriter() 00159 { 00160 return Writer(*this, size()); 00161 } 00162 00163 virtual std::size_t size() const = 0; 00164 00165 virtual void resize(std::size_t newSize) = 0; 00166 00167 virtual void read(std::size_t offset, std::size_t length, 00168 void* destBuffer) const = 0; 00169 00170 virtual void write(std::size_t offset, std::size_t length, 00171 const void* sourceBuffer) = 0; 00172 }; 00173 00175 class Buffer : public Resource 00176 { 00177 std::vector<char> buf; 00178 00179 public: 00180 Buffer() 00181 { 00182 } 00183 00184 Buffer(const Buffer& other) 00185 : buf(other.buf) 00186 { 00187 } 00188 00189 Buffer& operator=(const Buffer& other) 00190 { 00191 buf = other.buf; 00192 return *this; 00193 } 00194 00195 std::size_t size() const 00196 { 00197 return buf.size(); 00198 } 00199 00200 void resize(std::size_t newSize) 00201 { 00202 buf.resize(newSize); 00203 } 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 boost::scoped_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
Documentation not clear enough? Please go to one of the places listed on http://www.libgosu.org/ and leave feedback. Thanks!