00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef IDATASOURCE_H
00022 #define IDATASOURCE_H
00023
00024 #include <fstream>
00025 #include <cmath>
00026 #include "SDL_rwops.h"
00027
00028 class IDataSource
00029 {
00030 public:
00031 IDataSource() {}
00032 virtual ~IDataSource() {}
00033
00034 virtual uint8 read1()=0;
00035 virtual uint16 read2()=0;
00036 virtual uint16 read2high()=0;
00037 virtual uint32 read3()=0;
00038 virtual uint32 read4()=0;
00039 virtual uint32 read4high()=0;
00040 virtual sint32 read(void *str, sint32 num_bytes)=0;
00041
00042 uint32 readX(uint32 num_bytes)
00043 {
00044 assert(num_bytes > 0 && num_bytes <= 4);
00045 if (num_bytes == 1) return read1();
00046 else if (num_bytes == 2) return read2();
00047 else if (num_bytes == 3) return read3();
00048 else return read4();
00049 }
00050
00051 sint32 readXS(uint32 num_bytes)
00052 {
00053 assert(num_bytes > 0 && num_bytes <= 4);
00054 if (num_bytes == 1) return static_cast<sint8>(read1());
00055 else if (num_bytes == 2) return static_cast<sint16>(read2());
00056 else if (num_bytes == 3) return (((static_cast<sint32>(read3())) << 8)>>8);
00057 else return static_cast<sint32>(read4());
00058 }
00059
00060
00061 float readf()
00062 {
00063 #if 1
00064 union {
00065 uint32 i;
00066 float f;
00067 } int_float;
00068 int_float.i = read4();
00069 return int_float.f;
00070 #else
00071 uint32 i = read4();
00072 uint32 mantissa = i & 0x3FFFFF;
00073 sint32 exponent = ((i >> 23) & 0xFF);
00074
00075
00076 if (!exponent && !mantissa)
00077 return 0.0F;
00078
00079 else if (exponent == 0xFF)
00080 return 0.0F;
00081
00082 else if (exponent)
00083 mantissa |= 0x400000;
00084
00085 else
00086 exponent = 1;
00087
00088 float f = std::ldexp(mantissa/8388608.0,exponent-127);
00089 return (i >> 31)?-f:f;
00090 #endif
00091 }
00092
00093 void readline(std::string &str)
00094 {
00095 str.erase();
00096 while (!eof())
00097 {
00098 char character = static_cast<char>(read1());
00099
00100 if (character == '\r') continue;
00101 else if (character == '\n') break;
00102
00103 str+= character;
00104 }
00105 }
00106
00107 virtual void seek(uint32 pos)=0;
00108 virtual void skip(sint32 delta)=0;
00109 virtual uint32 getSize()=0;
00110 virtual uint32 getPos()=0;
00111 virtual bool eof()=0;
00112
00113 virtual std::ifstream *GetRawIfstream() {
00114 return 0;
00115 }
00116
00117
00118
00119 static int rw_seek(SDL_RWops *context, int offset, int whence)
00120 {
00121 IDataSource*ids = static_cast<IDataSource*>
00122 (context->hidden.unknown.data1);
00123 switch (whence) {
00124 case SEEK_SET:
00125 ids->seek(offset);
00126 break;
00127 case SEEK_CUR:
00128 ids->skip(offset);
00129 break;
00130 case SEEK_END:
00131 ids->seek(ids->getSize()+offset);
00132 break;
00133 default:
00134 return -1;
00135 break;
00136 }
00137 return ids->getPos();
00138 }
00139 static int rw_read(SDL_RWops *context, void *ptr, int size, int maxnum)
00140 {
00141 IDataSource*ids = static_cast<IDataSource*>
00142 (context->hidden.unknown.data1);
00143 if (size == 0) return 0;
00144 int nbytes = ids->read(ptr, maxnum*size);
00145 return (nbytes/size);
00146 }
00147 static int rw_write(SDL_RWops * , const void * ,
00148 int , int )
00149 {
00150 return 0;
00151 }
00152 static int rw_close(SDL_RWops *context)
00153 {
00154 IDataSource* ids = static_cast<IDataSource*>
00155 (context->hidden.unknown.data1);
00156 delete ids;
00157 SDL_FreeRW(context);
00158 return 0;
00159 }
00160
00163 SDL_RWops* getRWops() {
00164 SDL_RWops* rwops = SDL_AllocRW();
00165 rwops->seek = rw_seek;
00166 rwops->read = rw_read;
00167 rwops->write = rw_write;
00168 rwops->close = rw_close;
00169 rwops->hidden.unknown.data1 = static_cast<void*>(this);
00170 return rwops;
00171 }
00172 };
00173
00174
00175 class IFileDataSource: public IDataSource
00176 {
00177 private:
00178 std::ifstream *in;
00179
00180 public:
00181 IFileDataSource(std::ifstream *data_stream)
00182 {
00183 in = data_stream;
00184 }
00185
00186 virtual ~IFileDataSource()
00187 {
00188 FORGET_OBJECT(in);
00189 }
00190
00191 bool good() const { return in->good(); }
00192
00193
00194 virtual uint8 read1()
00195 {
00196 return static_cast<uint8>(in->get());
00197 }
00198
00199
00200 virtual uint16 read2()
00201 {
00202 uint16 val = 0;
00203 val |= static_cast<uint16>(in->get());
00204 val |= static_cast<uint16>(in->get()<<8);
00205 return val;
00206 }
00207
00208
00209 virtual uint16 read2high()
00210 {
00211 uint16 val = 0;
00212 val |= static_cast<uint16>(in->get()<<8);
00213 val |= static_cast<uint16>(in->get());
00214 return val;
00215 }
00216
00217
00218 virtual uint32 read3()
00219 {
00220 uint32 val = 0;
00221 val |= static_cast<uint32>(in->get());
00222 val |= static_cast<uint32>(in->get()<<8);
00223 val |= static_cast<uint32>(in->get()<<16);
00224 return val;
00225 }
00226
00227
00228 virtual uint32 read4()
00229 {
00230 uint32 val = 0;
00231 val |= static_cast<uint32>(in->get());
00232 val |= static_cast<uint32>(in->get()<<8);
00233 val |= static_cast<uint32>(in->get()<<16);
00234 val |= static_cast<uint32>(in->get()<<24);
00235 return val;
00236 }
00237
00238
00239 virtual uint32 read4high()
00240 {
00241 uint32 val = 0;
00242 val |= static_cast<uint32>(in->get()<<24);
00243 val |= static_cast<uint32>(in->get()<<16);
00244 val |= static_cast<uint32>(in->get()<<8);
00245 val |= static_cast<uint32>(in->get());
00246 return val;
00247 }
00248
00249 sint32 read(void *b, sint32 len)
00250 {
00251 in->read(static_cast<char *>(b), len);
00252 sint32 count = in->gcount();
00253 if (in->eof()) in->clear();
00254 return count;
00255 }
00256
00257 virtual void seek(uint32 pos) { in->seekg(pos); }
00258
00259 virtual void skip(sint32 pos) { in->seekg(pos, std::ios::cur); }
00260
00261 virtual uint32 getSize()
00262 {
00263 long pos = in->tellg();
00264 in->seekg(0, std::ios::end);
00265 long len = in->tellg();
00266 in->seekg(pos);
00267 return len;
00268 }
00269
00270 virtual uint32 getPos() { return in->tellg(); }
00271
00272 virtual bool eof() { return in->peek() == std::char_traits<char>::eof(); }
00273
00274 virtual std::ifstream *GetRawIfstream() {
00275 return in;
00276 }
00277 };
00278
00279 class IBufferDataSource : public IDataSource
00280 {
00281 protected:
00282 const uint8* buf;
00283 const uint8* buf_ptr;
00284 bool free_buffer;
00285 uint32 size;
00286
00287 void ConvertTextBuffer()
00288 {
00289 #ifdef WIN32
00290 uint8* new_buf = new uint8[size];
00291 uint8* new_buf_ptr = new_buf;
00292 uint32 new_size = 0;
00293
00294
00295
00296
00297 while (size > 1)
00298 {
00299 if (*(uint16*)buf_ptr == 0x0A0D)
00300 {
00301 buf_ptr++;
00302 size--;
00303 }
00304
00305 *new_buf_ptr = *buf_ptr;
00306
00307 new_buf_ptr++;
00308 new_size++;
00309 buf_ptr++;
00310 size--;
00311 }
00312
00313
00314 if (size) *new_buf_ptr = *buf_ptr;
00315
00316
00317 if (free_buffer) delete[] const_cast<uint8*>(buf);
00318
00319 buf_ptr = buf = new_buf;
00320 size = new_size;
00321 free_buffer = true;
00322 #endif
00323 }
00324
00325 public:
00326 IBufferDataSource(const void* data, unsigned int len, bool is_text = false,
00327 bool delete_data = false) {
00328 assert(data != 0 || len == 0);
00329 buf = buf_ptr = static_cast<const uint8 *>(data);
00330 size = len;
00331 free_buffer = delete_data;
00332
00333 if (is_text) ConvertTextBuffer();
00334 }
00335
00336 virtual void load(const void* data, unsigned int len, bool is_text = false,
00337 bool delete_data = false) {
00338 if (free_buffer && buf) delete [] const_cast<uint8 *>(buf);
00339 free_buffer = false;
00340 buf = buf_ptr = 0;
00341
00342 assert(data != 0 || len == 0);
00343 buf = buf_ptr = static_cast<const uint8 *>(data);
00344 size = len;
00345 free_buffer = delete_data;
00346
00347 if (is_text) ConvertTextBuffer();
00348 }
00349
00350 virtual ~IBufferDataSource() {
00351 if (free_buffer && buf) delete [] const_cast<uint8 *>(buf);
00352 free_buffer = false;
00353 buf = buf_ptr = 0;
00354 }
00355
00356 virtual uint8 read1() {
00357 uint8 b0;
00358 b0 = *buf_ptr++;
00359 return (b0);
00360 }
00361
00362 virtual uint16 read2() {
00363 uint8 b0, b1;
00364 b0 = *buf_ptr++;
00365 b1 = *buf_ptr++;
00366 return (b0 | (b1 << 8));
00367 }
00368
00369 virtual uint16 read2high() {
00370 uint8 b0, b1;
00371 b1 = *buf_ptr++;
00372 b0 = *buf_ptr++;
00373 return (b0 | (b1 << 8));
00374 }
00375
00376 virtual uint32 read3() {
00377 uint8 b0, b1, b2;
00378 b0 = *buf_ptr++;
00379 b1 = *buf_ptr++;
00380 b2 = *buf_ptr++;
00381 return (b0 | (b1 << 8) | (b2 << 16));
00382 }
00383
00384 virtual uint32 read4() {
00385 uint8 b0, b1, b2, b3;
00386 b0 = *buf_ptr++;
00387 b1 = *buf_ptr++;
00388 b2 = *buf_ptr++;
00389 b3 = *buf_ptr++;
00390 return (b0 | (b1<<8) | (b2<<16) | (b3<<24));
00391 }
00392
00393 virtual uint32 read4high() {
00394 uint8 b0, b1, b2, b3;
00395 b3 = *buf_ptr++;
00396 b2 = *buf_ptr++;
00397 b1 = *buf_ptr++;
00398 b0 = *buf_ptr++;
00399 return (b0 | (b1<<8) | (b2<<16) | (b3<<24));
00400 }
00401
00402 virtual sint32 read(void *str, sint32 num_bytes) {
00403 if (buf_ptr >= buf + size) return 0;
00404 sint32 count = num_bytes;
00405 if (buf_ptr + num_bytes > buf + size)
00406 count = static_cast<sint32>(buf - buf_ptr + size);
00407 std::memcpy(str, buf_ptr, count);
00408 buf_ptr += count;
00409 return count;
00410 }
00411
00412 virtual void seek(uint32 pos) {
00413 buf_ptr = buf + pos;
00414 }
00415
00416 virtual void skip(sint32 delta) {
00417 buf_ptr += delta;
00418 }
00419
00420 virtual uint32 getSize() {
00421 return size;
00422 }
00423
00424 virtual uint32 getPos() {
00425 return static_cast<uint32>(buf_ptr - buf);
00426 }
00427
00428 virtual bool eof() { return (static_cast<uint32>(buf_ptr-buf))>=size; }
00429
00430 };
00431
00432
00433 #endif