ODataSource.h

Go to the documentation of this file.
00001 /*
00002  *      ODataSource.h - DataSource type for writing data
00003  *
00004  *  Copyright (C) 2002-2003 The Pentagram Team
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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                         // FIXME: dubious...
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 /*pos*/) { /*out->seekp(pos); FIXME: Do something here. */ }
00296         virtual void skip(sint32 /*pos*/) { /*out->seekp(pos, std::ios::cur); FIXME: Do something here. */ }
00297 
00298         virtual uint32 getSize()      { return static_cast<uint32>(out.size()); }
00299         
00300         virtual uint32 getPos() { return static_cast<uint32>(out.size()); /*return out->tellp(); FIXME: Do something here. */ }
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                 // Increment loc
00316                 loc+=num_bytes;
00317 
00318                 // Don't need to resize
00319                 if (loc <= size) return; 
00320 
00321                 // Reallocate the buffer
00322                 if (loc > allocated)
00323                 {
00324                         // The old pointer position
00325                         uint32 pos = static_cast<uint32>(buf_ptr-buf);
00326 
00327                         // The new buffer and size (2 times what is needed)
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                 // Update size
00339                 size = loc;
00340         }
00341 
00342 public:
00343         OAutoBufferDataSource(uint32 initial_len)
00344         {
00345                 allocated = initial_len;
00346                 size = 0;
00347 
00348                 // Make the min allocated size 16 bytes
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                 // No seeking past the end of the buffer
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                 // No seeking past the end
00427                 if (pos>=0)
00428                 {
00429                         loc += pos;
00430                         if (loc > size) loc = size;
00431                 }
00432                 // No seeking past the start
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         // Don't actually do anything substantial
00447         virtual void clear()          
00448         { 
00449                 buf_ptr = buf; 
00450                 size = 0;
00451                 loc = 0;
00452         }
00453 
00454 };
00455 
00456 
00457 #endif

Generated on Fri Jul 27 22:27:27 2007 for pentagram by  doxygen 1.4.7