00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef ODATASOURCE_H
00022 #define ODATASOURCE_H
00023
00024 #include "common_types.h"
00025 #include <fstream>
00026 #include <deque>
00027 #include <vector>
00028
00029 class ODataSource
00030 {
00031 public:
00032 ODataSource() {}
00033 virtual ~ODataSource() {}
00034
00035 virtual void write1(uint32)=0;
00036 virtual void write2(uint16)=0;
00037 virtual void write2high(uint16)=0;
00038 virtual void write3(uint32)=0;
00039 virtual void write4(uint32)=0;
00040 virtual void write4high(uint32)=0;
00041 virtual void write(const void *str, uint32 num_bytes)=0;
00042
00043 void writeX(uint32 val, uint32 num_bytes)
00044 {
00045 assert(num_bytes > 0 && num_bytes <= 4);
00046 if (num_bytes == 1) write1(static_cast<uint8>(val));
00047 else if (num_bytes == 2) write2(static_cast<uint16>(val));
00048 else if (num_bytes == 3) write3(val);
00049 else write4(val);
00050 }
00051
00052 void writef(float f)
00053 {
00054
00055 union {
00056 uint32 i;
00057 float f;
00058 } int_float;
00059 int_float.f = f;
00060 write4(int_float.i);
00061 }
00062
00063 virtual void seek(uint32 pos)=0;
00064 virtual void skip(sint32 delta)=0;
00065 virtual uint32 getSize()=0;
00066 virtual uint32 getPos()=0;
00067 };
00068
00069
00070 class OFileDataSource : public ODataSource
00071 {
00072 private:
00073 std::ofstream *out;
00074
00075 public:
00076 OFileDataSource(std::ofstream *data_stream)
00077 {
00078 out = data_stream;
00079 }
00080
00081 virtual ~OFileDataSource()
00082 {
00083 FORGET_OBJECT(out);
00084 }
00085
00086 bool good() const { return out->good(); }
00087
00088 virtual void write1(uint32 val)
00089 {
00090 out->put(static_cast<char> (val&0xff));
00091 }
00092
00093 virtual void write2(uint16 val)
00094 {
00095 out->put(static_cast<char> (val&0xff));
00096 out->put(static_cast<char> ((val>>8)&0xff));
00097 }
00098
00099 virtual void write2high(uint16 val)
00100 {
00101 out->put(static_cast<char> ((val>>8)&0xff));
00102 out->put(static_cast<char> (val&0xff));
00103 }
00104
00105 virtual void write3(uint32 val)
00106 {
00107 out->put(static_cast<char> (val&0xff));
00108 out->put(static_cast<char> ((val>>8)&0xff));
00109 out->put(static_cast<char> ((val>>16)&0xff));
00110 }
00111
00112 virtual void write4(uint32 val)
00113 {
00114 out->put(static_cast<char> (val&0xff));
00115 out->put(static_cast<char> ((val>>8)&0xff));
00116 out->put(static_cast<char> ((val>>16)&0xff));
00117 out->put(static_cast<char> ((val>>24)&0xff));
00118 }
00119
00120 virtual void write4high(uint32 val)
00121 {
00122 out->put(static_cast<char> ((val>>24)&0xff));
00123 out->put(static_cast<char> ((val>>16)&0xff));
00124 out->put(static_cast<char> ((val>>8)&0xff));
00125 out->put(static_cast<char> (val&0xff));
00126 }
00127
00128 virtual void write(const void *b, uint32 len)
00129 {
00130 out->write(static_cast<const char *>(b), len);
00131 }
00132
00133 virtual void seek(uint32 pos) { out->seekp(pos); }
00134
00135 virtual void skip(sint32 pos) { out->seekp(pos, std::ios::cur); }
00136
00137 virtual uint32 getSize()
00138 {
00139 long pos = out->tellp();
00140 out->seekp(0, std::ios::end);
00141 long len = out->tellp();
00142 out->seekp(pos);
00143 return len;
00144 }
00145
00146 virtual uint32 getPos() { return out->tellp(); }
00147 };
00148
00149 class OBufferDataSource: public ODataSource
00150 {
00151 protected:
00152 uint8 *buf;
00153 uint8 *buf_ptr;
00154 uint32 size;
00155 public:
00156 OBufferDataSource(void *data, uint32 len)
00157 {
00158 assert(data==0 || len==0);
00159 buf = buf_ptr = reinterpret_cast<uint8*>(data);
00160 size = len;
00161 };
00162
00163 void load(char *data, uint32 len)
00164 {
00165 assert(data==0 || len==0);
00166 buf = buf_ptr = reinterpret_cast<uint8*>(data);
00167 size = len;
00168 };
00169
00170 virtual ~OBufferDataSource() {};
00171
00172 virtual void write1(uint32 val)
00173 {
00174 *buf_ptr++ = val & 0xff;
00175 };
00176
00177 virtual void write2(uint16 val)
00178 {
00179 *buf_ptr++ = val & 0xff;
00180 *buf_ptr++ = (val>>8) & 0xff;
00181 };
00182
00183 virtual void write2high(uint16 val)
00184 {
00185 *buf_ptr++ = (val>>8) & 0xff;
00186 *buf_ptr++ = val & 0xff;
00187 };
00188
00189 virtual void write3(uint32 val)
00190 {
00191 *buf_ptr++ = val & 0xff;
00192 *buf_ptr++ = (val>>8) & 0xff;
00193 *buf_ptr++ = (val>>16)&0xff;
00194 };
00195
00196 virtual void write4(uint32 val)
00197 {
00198 *buf_ptr++ = val & 0xff;
00199 *buf_ptr++ = (val>>8) & 0xff;
00200 *buf_ptr++ = (val>>16)&0xff;
00201 *buf_ptr++ = (val>>24)&0xff;
00202 };
00203
00204 virtual void write4high(uint32 val)
00205 {
00206 *buf_ptr++ = (val>>24)&0xff;
00207 *buf_ptr++ = (val>>16)&0xff;
00208 *buf_ptr++ = (val>>8) & 0xff;
00209 *buf_ptr++ = val & 0xff;
00210 };
00211
00212 virtual void write(const void *b, uint32 len)
00213 {
00214 std::memcpy(buf_ptr, b, len);
00215 buf_ptr += len;
00216 };
00217
00218 virtual void seek(uint32 pos) { buf_ptr = const_cast<unsigned char *>(buf)+pos; };
00219
00220 virtual void skip(sint32 pos) { buf_ptr += pos; };
00221
00222 virtual uint32 getSize() { return size; };
00223
00224 virtual uint32 getPos() { return static_cast<uint32>(buf_ptr-buf); };
00225 };
00226
00227 class ODequeDataSource : public ODataSource
00228 {
00229 private:
00230 std::deque<char> out;
00231
00232 public:
00233 ODequeDataSource() {}
00234
00235 virtual ~ODequeDataSource() {}
00236
00237 const std::deque<char> &buf() const { return out; }
00238
00239 virtual void write1(uint32 val)
00240 {
00241 out.push_back(static_cast<char> (val&0xff));
00242 }
00243
00244 virtual void write2(uint16 val)
00245 {
00246 out.push_back(static_cast<char> (val&0xff));
00247 out.push_back(static_cast<char> ((val>>8)&0xff));
00248 }
00249
00250 virtual void write2high(uint16 val)
00251 {
00252 out.push_back(static_cast<char> ((val>>8)&0xff));
00253 out.push_back(static_cast<char> (val&0xff));
00254 }
00255
00256 virtual void write3(uint32 val)
00257 {
00258 out.push_back(static_cast<char> (val&0xff));
00259 out.push_back(static_cast<char> ((val>>8)&0xff));
00260 out.push_back(static_cast<char> ((val>>16)&0xff));
00261 }
00262
00263 virtual void write4(uint32 val)
00264 {
00265 out.push_back(static_cast<char> (val&0xff));
00266 out.push_back(static_cast<char> ((val>>8)&0xff));
00267 out.push_back(static_cast<char> ((val>>16)&0xff));
00268 out.push_back(static_cast<char> ((val>>24)&0xff));
00269 }
00270
00271 virtual void write4high(uint32 val)
00272 {
00273 out.push_back(static_cast<char> ((val>>24)&0xff));
00274 out.push_back(static_cast<char> ((val>>16)&0xff));
00275 out.push_back(static_cast<char> ((val>>8)&0xff));
00276 out.push_back(static_cast<char> (val&0xff));
00277 }
00278
00279 virtual void write(const void *b, uint32 length)
00280 {
00281 write(b, length, length);
00282 }
00283
00284 virtual void write(const void *b, uint32 length, uint32 pad_length)
00285 {
00286 for(uint32 i=0; i<length; i++)
00287 out.push_back(static_cast<const char *>(b)[i]);
00288 if(pad_length>length)
00289 for(pad_length-=length; pad_length>0; --pad_length)
00290 out.push_back(static_cast<char>(0x00));
00291 }
00292
00293 virtual void clear() { out.clear(); }
00294
00295 virtual void seek(uint32 ) { }
00296 virtual void skip(sint32 ) { }
00297
00298 virtual uint32 getSize() { return static_cast<uint32>(out.size()); }
00299
00300 virtual uint32 getPos() { return static_cast<uint32>(out.size()); }
00301
00302 };
00303
00304 class OAutoBufferDataSource: public ODataSource
00305 {
00306 protected:
00307 uint8 *buf;
00308 uint8 *buf_ptr;
00309 uint32 size;
00310 uint32 loc;
00311 uint32 allocated;
00312
00313 void checkResize(uint32 num_bytes)
00314 {
00315
00316 loc+=num_bytes;
00317
00318
00319 if (loc <= size) return;
00320
00321
00322 if (loc > allocated)
00323 {
00324
00325 uint32 pos = static_cast<uint32>(buf_ptr-buf);
00326
00327
00328 allocated = loc*2;
00329 uint8 *new_buf = new uint8[allocated];
00330
00331 memcpy(new_buf, buf, size);
00332 delete [] buf;
00333
00334 buf = new_buf;
00335 buf_ptr = buf + pos;
00336 }
00337
00338
00339 size = loc;
00340 }
00341
00342 public:
00343 OAutoBufferDataSource(uint32 initial_len)
00344 {
00345 allocated = initial_len;
00346 size = 0;
00347
00348
00349 if (allocated < 16) allocated = 16;
00350 buf = buf_ptr = new uint8[allocated];
00351 loc = 0;
00352 };
00353
00355 const uint8 * getBuf() { return buf; }
00356
00357 virtual ~OAutoBufferDataSource()
00358 {
00359 delete [] buf_ptr;
00360 }
00361
00362 virtual void write1(uint32 val)
00363 {
00364 checkResize(1);
00365 *buf_ptr++ = val & 0xff;
00366 };
00367
00368 virtual void write2(uint16 val)
00369 {
00370 checkResize(2);
00371 *buf_ptr++ = val & 0xff;
00372 *buf_ptr++ = (val>>8) & 0xff;
00373 };
00374
00375 virtual void write2high(uint16 val)
00376 {
00377 checkResize(2);
00378 *buf_ptr++ = (val>>8) & 0xff;
00379 *buf_ptr++ = val & 0xff;
00380 };
00381
00382 virtual void write3(uint32 val)
00383 {
00384 checkResize(3);
00385 *buf_ptr++ = val & 0xff;
00386 *buf_ptr++ = (val>>8) & 0xff;
00387 *buf_ptr++ = (val>>16)&0xff;
00388 };
00389
00390 virtual void write4(uint32 val)
00391 {
00392 checkResize(4);
00393 *buf_ptr++ = val & 0xff;
00394 *buf_ptr++ = (val>>8) & 0xff;
00395 *buf_ptr++ = (val>>16)&0xff;
00396 *buf_ptr++ = (val>>24)&0xff;
00397 };
00398
00399 virtual void write4high(uint32 val)
00400 {
00401 checkResize(4);
00402 *buf_ptr++ = (val>>24)&0xff;
00403 *buf_ptr++ = (val>>16)&0xff;
00404 *buf_ptr++ = (val>>8) & 0xff;
00405 *buf_ptr++ = val & 0xff;
00406 };
00407
00408 virtual void write(const void *b, uint32 len)
00409 {
00410 checkResize(len);
00411 std::memcpy(buf_ptr, b, len);
00412 buf_ptr += len;
00413 };
00414
00415 virtual void seek(uint32 pos)
00416 {
00417
00418 if (pos<=size) loc = pos;
00419 else loc = size;
00420
00421 buf_ptr = const_cast<unsigned char *>(buf)+loc;
00422 };
00423
00424 virtual void skip(sint32 pos)
00425 {
00426
00427 if (pos>=0)
00428 {
00429 loc += pos;
00430 if (loc > size) loc = size;
00431 }
00432
00433 else
00434 {
00435 uint32 invpos = -pos;
00436 if (invpos > loc) invpos = loc;
00437 loc -= invpos;
00438 }
00439 buf_ptr = const_cast<unsigned char *>(buf)+loc;
00440 };
00441
00442 virtual uint32 getSize() { return size; };
00443
00444 virtual uint32 getPos() { return static_cast<uint32>(buf_ptr-buf); };
00445
00446
00447 virtual void clear()
00448 {
00449 buf_ptr = buf;
00450 size = 0;
00451 loc = 0;
00452 }
00453
00454 };
00455
00456
00457 #endif