databuf.h

Go to the documentation of this file.
00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00015  */
00016 
00017 #ifndef DATA_H
00018 #define DATA_H
00019 
00020 #ifndef ALPHA_LINUX_CXX
00021 #  include <cstdio>
00022 #  include <cstring>
00023 #endif
00024 #include <cassert>
00025 #include <fstream>
00026 #include <iomanip>
00027 #include "U7file.h"
00028 #include "utils.h"
00029 
00030 typedef char * charptr;
00031 
00032 class DataSource
00033 {
00034 public:
00035   DataSource() {};
00036   virtual ~DataSource() {};
00037 
00038   virtual uint32 peek() =0;
00039   
00040   virtual uint32 read1() =0;
00041   virtual uint16 read2() =0;
00042   virtual uint16 read2high() =0;
00043   virtual uint32 read4() =0;
00044   virtual uint32 read4high() =0;
00045   virtual void read(char *, int) =0;
00046   
00047   virtual void write1(uint32) =0;
00048   virtual void write2(uint16) =0;
00049   virtual void write2high(uint16) =0;
00050   virtual void write4(uint32) =0;
00051   virtual void write4high(uint32) =0;
00052   virtual void write(char *, int) =0;
00053   
00054   virtual void seek(unsigned int) =0;
00055   virtual void skip(int) =0;
00056   virtual unsigned int getSize() =0;
00057   virtual unsigned int getPos() =0;
00058   virtual bool eof() =0;
00059 };
00060 
00061 class StreamDataSource: public DataSource
00062 {
00063 private:
00064   std::ifstream *in;
00065   std::ofstream *out;
00066 public:
00067   StreamDataSource(std::ifstream *data_stream) : in(data_stream), out(0)
00068   {
00069   };
00070   
00071   StreamDataSource(std::ofstream *data_stream) : in(0), out(data_stream)
00072   {
00073   };
00074   
00075   virtual ~StreamDataSource() {};
00076 
00077   virtual uint32 peek()   { return in->peek(); };
00078   
00079   virtual uint32 read1()      { return Read1(*in); };
00080   
00081   virtual uint16 read2()      { return Read2(*in); };
00082   
00083   virtual uint16 read2high()  { return Read2high(*in); };
00084   
00085   virtual uint32 read4()      { return Read4(*in); };
00086   
00087   virtual uint32 read4high()  { return Read4high(*in); };
00088   
00089   void read(char *b, int len) { in->read(b, len); };
00090   
00091   virtual void write1(uint32 val)      { Write1(*out, val); };
00092   
00093   virtual void write2(uint16 val)      { Write2(*out, val); };
00094 
00095   virtual void write2high(uint16 val)  { Write2high(*out, val); };
00096 
00097   virtual void write4(uint32 val)      { Write4(*out, val); };
00098 
00099   virtual void write4high(uint32 val)  { Write4high(*out, val); };
00100 
00101   virtual void write(char *b, int len) { out->write(b, len); };
00102   
00103   virtual void seek(unsigned int pos)
00104   {
00105     if (in) in->seekg(pos);
00106     else out->seekp(pos);
00107   };
00108 
00109   virtual void skip(int pos) { in->seekg(pos, std::ios::cur); };
00110   
00111   virtual unsigned int getSize()
00112   {
00113     if (in) {
00114       long pos = in->tellg();
00115       in->seekg(0, std::ios::end);
00116       long len = in->tellg();
00117       in->seekg(pos);
00118       return len;
00119     }
00120     else {
00121       long pos = out->tellp();
00122       out->seekp(0, std::ios::end);
00123       long len = out->tellp();
00124       out->seekp(pos);
00125       return len;
00126     }
00127   };
00128   
00129   virtual unsigned int getPos() { return in?in->tellg():out->tellp(); };
00130   
00131   virtual bool eof() { return in->eof(); }
00132 };
00133 
00134 class FileDataSource: public DataSource
00135 {
00136 private:
00137   std::FILE *f;
00138 public:
00139   FileDataSource(std::FILE *fp)
00140   {
00141     f = fp;
00142   };
00143   
00144   virtual ~FileDataSource() {};
00145   
00146   virtual uint32 peek()
00147   { 
00148     unsigned char b0;
00149     b0 = fgetc(f);
00150     fseek(f, -1, SEEK_CUR);
00151     return (b0);
00152   };
00153   
00154   virtual uint32 read1() 
00155   { 
00156     unsigned char b0;
00157     b0 = fgetc(f);
00158     return (b0);
00159   };
00160   
00161   virtual uint16 read2()
00162   {
00163     unsigned char b0, b1;
00164     b0 = fgetc(f);
00165     b1 = fgetc(f);
00166     return (b0 | (b1 << 8));
00167   };
00168   
00169   virtual uint16 read2high()
00170   {
00171     unsigned char b0, b1;
00172     b1 = fgetc(f);
00173     b0 = fgetc(f);
00174     return (b0 | (b1 << 8));
00175   };
00176   
00177   virtual uint32 read4()
00178   {
00179     unsigned char b0, b1, b2, b3;
00180     b0 = fgetc(f);
00181     b1 = fgetc(f);
00182     b2 = fgetc(f);
00183     b3 = fgetc(f);
00184     return (b0 | (b1<<8) | (b2<<16) | (b3<<24));
00185   };
00186   
00187   virtual uint32 read4high()
00188   {
00189     unsigned char b0, b1, b2, b3;
00190     b3 = fgetc(f);
00191     b2 = fgetc(f);
00192     b1 = fgetc(f);
00193     b0 = fgetc(f);
00194     return (b0 | (b1<<8) | (b2<<16) | (b3<<24));
00195   };
00196   
00197   void read(char *b, int len) {
00198     fread(b, 1, len, f);
00199   };
00200   
00201   virtual void write1(uint32 val)
00202   {
00203     fputc(static_cast<char>(val&0xff),f);
00204   };
00205   
00206   virtual void write2(uint16 val)
00207   {
00208     fputc(static_cast<char>(val&0xff),f);
00209     fputc(static_cast<char>((val>>8)&0xff),f);
00210   };
00211   
00212   virtual void write2high(uint16 val)
00213   {
00214     fputc(static_cast<char>((val>>8)&0xff),f);
00215     fputc(static_cast<char>(val&0xff),f);
00216   };
00217   
00218   virtual void write4(uint32 val)
00219   {
00220     fputc(static_cast<char>(val&0xff),f);
00221     fputc(static_cast<char>((val>>8)&0xff),f);
00222     fputc(static_cast<char>((val>>16)&0xff),f);
00223     fputc(static_cast<char>((val>>24)&0xff),f);
00224   };
00225 
00226   virtual void write4high(uint32 val)
00227   {
00228     fputc(static_cast<char>((val>>24)&0xff),f);
00229     fputc(static_cast<char>((val>>16)&0xff),f);
00230     fputc(static_cast<char>((val>>8)&0xff),f);
00231     fputc(static_cast<char>(val&0xff),f);
00232   };
00233 
00234   virtual void write(char *b, int len)
00235   {
00236     fwrite(b, 1, len, f);
00237   };
00238   
00239   
00240   virtual void seek(unsigned int pos) { fseek(f, pos, SEEK_SET); };
00241   
00242   virtual void skip(int pos) { fseek(f, pos, SEEK_CUR); };
00243   
00244   virtual unsigned int getSize()
00245   {
00246     long pos = ftell(f);
00247     fseek(f, 0, SEEK_END);
00248     long len = ftell(f);
00249     fseek(f, pos, SEEK_SET);
00250     return len;
00251   };
00252   
00253   virtual unsigned int getPos()
00254   {
00255     return ftell(f);
00256   };
00257 
00258   virtual bool eof() { return feof(f) != 0; } 
00259 };
00260 
00261 class BufferDataSource: public DataSource
00262 {
00263 protected:
00264   /* const solely so that no-one accidentally modifies it.
00265     data is being passed 'non-const' anyway */
00266   const unsigned char *buf;
00267   unsigned char *buf_ptr;
00268   std::size_t size;
00269 public:
00270   BufferDataSource(char *data, unsigned int len)
00271   {
00272     // data can be NULL if len is also 0
00273     assert(data!=0 || len==0);
00274     buf = buf_ptr = reinterpret_cast<unsigned char*>(data);
00275     size = len;
00276   };
00277   
00278   void load(char *data, unsigned int len)
00279   {
00280     // data can be NULL if len is also 0
00281     assert(data!=0 || len==0);
00282     buf = buf_ptr = reinterpret_cast<unsigned char*>(data);
00283     size = len;
00284   };
00285   
00286   virtual ~BufferDataSource() {};
00287   
00288   virtual uint32 peek() 
00289   { 
00290     unsigned char b0;
00291     b0 = static_cast<unsigned char>(*buf_ptr);
00292     return (b0);
00293   };
00294   
00295   virtual uint32 read1() 
00296   { 
00297     unsigned char b0;
00298     b0 = static_cast<unsigned char>(*buf_ptr++);
00299     return (b0);
00300   };
00301   
00302   virtual uint16 read2()
00303   {
00304     unsigned char b0, b1;
00305     b0 = static_cast<unsigned char>(*buf_ptr++);
00306     b1 = static_cast<unsigned char>(*buf_ptr++);
00307     return (b0 | (b1 << 8));
00308   };
00309   
00310   virtual uint16 read2high()
00311   {
00312     unsigned char b0, b1;
00313     b1 = static_cast<unsigned char>(*buf_ptr++);
00314     b0 = static_cast<unsigned char>(*buf_ptr++);
00315     return (b0 | (b1 << 8));
00316   };
00317   
00318   virtual uint32 read4()
00319   {
00320     unsigned char b0, b1, b2, b3;
00321     b0 = static_cast<unsigned char>(*buf_ptr++);
00322     b1 = static_cast<unsigned char>(*buf_ptr++);
00323     b2 = static_cast<unsigned char>(*buf_ptr++);
00324     b3 = static_cast<unsigned char>(*buf_ptr++);
00325     return (b0 | (b1<<8) | (b2<<16) | (b3<<24));
00326   };
00327   
00328   virtual uint32 read4high()
00329   {
00330     unsigned char b0, b1, b2, b3;
00331     b3 = static_cast<unsigned char>(*buf_ptr++);
00332     b2 = static_cast<unsigned char>(*buf_ptr++);
00333     b1 = static_cast<unsigned char>(*buf_ptr++);
00334     b0 = static_cast<unsigned char>(*buf_ptr++);
00335     return (b0 | (b1<<8) | (b2<<16) | (b3<<24));
00336   };
00337   
00338   void read(char *b, int len) {
00339     std::memcpy(b, buf_ptr, len);
00340     buf_ptr += len;
00341   };
00342   
00343   virtual void write1(uint32 val)
00344   {
00345     *buf_ptr++ = val & 0xff;
00346   };
00347   
00348   virtual void write2(uint16 val)
00349   {
00350     *buf_ptr++ = val & 0xff;
00351     *buf_ptr++ = (val>>8) & 0xff;
00352   };
00353 
00354   virtual void write2high(uint16 val)
00355   {
00356     *buf_ptr++ = (val>>8) & 0xff;
00357     *buf_ptr++ = val & 0xff;
00358   };
00359 
00360   
00361   virtual void write4(uint32 val)
00362   {
00363     *buf_ptr++ = val & 0xff;
00364     *buf_ptr++ = (val>>8) & 0xff;
00365     *buf_ptr++ = (val>>16)&0xff;
00366     *buf_ptr++ = (val>>24)&0xff;
00367   };
00368   
00369   virtual void write4high(uint32 val)
00370   {
00371     *buf_ptr++ = (val>>24)&0xff;
00372     *buf_ptr++ = (val>>16)&0xff;
00373     *buf_ptr++ = (val>>8) & 0xff;
00374     *buf_ptr++ = val & 0xff;
00375   };
00376 
00377   virtual void write(char *b, int len)
00378   {
00379     std::memcpy(buf_ptr, b, len);
00380     buf_ptr += len;
00381   };
00382   
00383   virtual void seek(unsigned int pos) { buf_ptr = const_cast<unsigned char *>(buf)+pos; };
00384   
00385   virtual void skip(int pos) { buf_ptr += pos; };
00386   
00387   virtual unsigned int getSize() { return size; };
00388   
00389   virtual unsigned int getPos() { return (buf_ptr-buf); };
00390   
00391   unsigned char *getPtr() { return buf_ptr; };
00392 
00393   virtual bool eof() { return (buf_ptr-buf) >= (int)size; } 
00394 
00395 };
00396 
00397 class StackBufferDataSource : protected BufferDataSource
00398 {
00399   public:
00400     StackBufferDataSource(unsigned int len=0x1000) : BufferDataSource(new char[len], len)
00401     {
00402       buf_ptr = const_cast<unsigned char *>(buf)+len;
00403     };
00404     ~StackBufferDataSource() { 
00405       delete [] const_cast<unsigned char *>(buf);
00406     };
00407     
00408     //
00409     // Push values to the stack
00410     //
00411 
00412     inline void push2(uint16 val)
00413     {
00414       buf_ptr-=2;
00415       buf_ptr[0] =  val     & 0xFF;
00416       buf_ptr[1] = (val>>8) & 0xFF;
00417     }
00418     inline void push4(uint32 val)
00419     {
00420       buf_ptr-=4;
00421       buf_ptr[0] =  val      & 0xFF;
00422       buf_ptr[1] = (val>>8)  & 0xFF;
00423       buf_ptr[2] = (val>>16) & 0xFF;
00424       buf_ptr[3] = (val>>24) & 0xFF;
00425     }
00426     // Push an arbitrary number of bytes of 0
00427     inline void push0(const uint32 size) { 
00428       buf_ptr -= size;
00429       std::memset (buf_ptr, 0, size);
00430     };
00431     // Push an arbitrary number of bytes
00432     inline void push(const uint8 *in, const uint32 size) { 
00433       buf_ptr -= size;
00434       std::memcpy (buf_ptr, in, size);
00435     };
00436     
00437     //
00438     // Pop values from the stack
00439     //
00440 
00441     inline uint16 pop2() { return read2(); }
00442     inline uint32 pop4() { return read4(); }
00443     inline void pop(uint8 *out, const uint32 size) { read(reinterpret_cast<char*>(out), size); };
00444     
00445     //
00446     // Access a value from a location in the stacck
00447     //
00448 
00449     inline uint8 access1(const uint32 offset) const
00450     {
00451       return buf[offset];
00452     }
00453     inline uint16 access2(const uint32 offset) const
00454     {
00455       return (buf[offset] | (buf[offset+1] << 8));
00456     }
00457     inline uint32 access4(const uint32 offset) const
00458     {
00459       return buf[offset] | (buf[offset+1]<<8) | (buf[offset+2]<<16) | (buf[offset+3]<<24);
00460     }
00461     inline const uint8* access(const uint32 offset) const
00462     {
00463       return buf+offset;
00464     }
00465     
00466     //
00467     // Assign a value to a location in the stack
00468     //
00469 
00470     inline void assign1(const uint32 offset, const uint8 val)
00471     {
00472       const_cast<unsigned char *>(buf)[offset]   =  val     & 0xFF;
00473     }
00474     inline void assign2(const uint32 offset, const uint16 val)
00475     {
00476       const_cast<unsigned char *>(buf)[offset]   =  val     & 0xFF;
00477       const_cast<unsigned char *>(buf)[offset+1] = (val>>8) & 0xFF;
00478     }
00479     inline void assign4(const uint32 offset, const uint32 val)
00480     {
00481       const_cast<unsigned char *>(buf)[offset]   =  val      & 0xFF;
00482       const_cast<unsigned char *>(buf)[offset+1] = (val>>8)  & 0xFF;
00483       const_cast<unsigned char *>(buf)[offset+2] = (val>>16) & 0xFF;
00484       const_cast<unsigned char *>(buf)[offset+3] = (val>>24) & 0xFF;
00485     }
00486     inline void assign(const uint32 offset, const uint8 *in, const uint32 len)
00487     {
00488       std::memcpy (const_cast<unsigned char *>(buf+offset), in, len);
00489     }
00490 
00491     inline uint32 stacksize() const { return buf+size-buf_ptr; };
00492 
00493     inline void resize(const uint32 newsize) { 
00494       buf_ptr = const_cast<unsigned char *>(buf)+size-newsize;
00495     };
00496     
00497     inline void addSP(const sint32 offset) {
00498       skip(offset);
00499     }
00500 
00501     virtual unsigned int getSP() { return getPos(); };
00502 
00503     inline void moveSP(unsigned int pos) {
00504       seek(pos);
00505     }
00506 
00507     /* temp debugging */
00508     inline std::ostream &print(std::ostream &o, uint32 bp)
00509     {
00510       for(const unsigned char *c=buf_ptr; c!=buf+size; ++c) {
00511         if (c != buf+bp)
00512           std::printf(" %02X", static_cast<unsigned int>(*c));
00513         else
00514           std::printf(":%02X", static_cast<unsigned int>(*c));
00515       }
00516       return o;
00517     }
00518     
00519   private:
00520 };
00521 
00522 class ExultDataSource: public BufferDataSource {
00523 public:
00524   ExultDataSource(const char *fname, int index):
00525     BufferDataSource(0,0)
00526   {
00527     U7object obj(fname, index);
00528     buf = reinterpret_cast<unsigned char*>(obj.retrieve(size));
00529     buf_ptr = const_cast<unsigned char *>(buf);
00530   };
00531   
00532   ~ExultDataSource()
00533   {
00534           delete [] const_cast<unsigned char *>(buf);
00535   }
00536 };
00537 
00538 #endif

Generated on Mon Jul 9 14:42:45 2007 for ExultEngine by  doxygen 1.5.1