Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Archive.h

Go to the documentation of this file.
00001 /* SimData: Data Infrastructure for Simulations
00002  * Copyright (C) 2002 Mark Rose <tm2@stm.lbl.gov>
00003  * 
00004  * This file is part of SimData.
00005  * 
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (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 
00028 #ifndef __SIMDATA_ARCHIVE_H__
00029 #define __SIMDATA_ARCHIVE_H__
00030 
00031 #include <string>
00032 #include <vector>
00033 #include <cstdlib>
00034 #include <cstdio>
00035 #include <cassert>
00036 #include <SimData/BaseType.h>
00037 #include <SimData/HashUtility.h>
00038 #include <SimData/Exception.h>
00039 #include <SimData/Namespace.h>
00040 
00041 
00042 NAMESPACE_SIMDATA
00043 
00044 
00045 class Packer;
00046 class UnPacker;
00047 class DataArchive;
00048 
00049 
00050 SIMDATA_EXCEPTION(DataUnderflow);
00051 SIMDATA_EXCEPTION(ConstViolation);
00052 
00053 class Archive {
00054         bool __loading;
00055 public:
00056         Archive(bool loading): __loading(loading) {}
00057         virtual ~Archive() {}
00058 
00059         virtual DataArchive* _getArchive() { return 0; }
00060         virtual bool _loadAll() const { return false; }
00061         bool isLoading() { return __loading; }
00062 
00063         virtual void operator()(char &x) = 0;
00064         virtual void operator()(short &x)=0;
00065         virtual void operator()(int &x)=0;
00066         virtual void operator()(bool &x)=0;
00067         virtual void operator()(float &x)=0;
00068         virtual void operator()(double &x)=0;
00069         virtual void operator()(char* &x)=0;
00070         virtual void operator()(BaseType &x)=0;
00071         virtual void operator()(hasht &x)=0;
00072         virtual void operator()(std::string &x)=0;
00073         template<typename T>
00074         void operator()(std::vector<T> &x);
00075 
00076         // explicit packing (use from python)
00077 
00078 #ifdef SWIG
00079 %extend {
00080         double _double(double x=0.0) { 
00081                 double y=x; 
00082                 self->operator()(y); 
00083                 return y; 
00084         }
00085         float _float(double x=0.0f) { 
00086                 float y=x; 
00087                 self->operator()(y); 
00088                 return y; 
00089         }
00090         bool _bool(bool x=false) { 
00091                 bool y=x; 
00092                 self->operator()(y); 
00093                 return y; 
00094         }
00095         int _int(int x=0) { 
00096                 int y=x; 
00097                 self->operator()(y); 
00098                 return y; 
00099         }
00100         short _short(short x=0) { 
00101                 short y=x; 
00102                 self->operator()(y); 
00103                 return y; 
00104         }
00105         char _char(char x=0) { 
00106                 char y=x; 
00107                 self->operator()(y); 
00108                 return y; 
00109         }
00110         hasht _hasht(hasht x=0) { 
00111                 simdata::hasht y=x; 
00112                 self->operator()(y); 
00113                 return y; 
00114         }
00115         std::string _string(std::string const &x="") { 
00116                 std::string y=x; 
00117                 self->operator()(y); 
00118                 return y; 
00119         }
00120         BaseType &_basetype(BaseType &x) { 
00121                 self->operator()(x); 
00122                 return x; 
00123         }
00124 #define __SIMDATA_ARCHIVE(T) SIMDATA(T) _##T() { \
00125                 SIMDATA(T) x; self->operator()(x); return x; \
00126         }
00127         __SIMDATA_ARCHIVE(SimDate);
00128         __SIMDATA_ARCHIVE(Matrix3);
00129         __SIMDATA_ARCHIVE(Vector3);
00130         __SIMDATA_ARCHIVE(Quat);
00131         __SIMDATA_ARCHIVE(Real);
00132         __SIMDATA_ARCHIVE(Curve);
00133         __SIMDATA_ARCHIVE(Table);
00134         __SIMDATA_ARCHIVE(Table1);
00135         __SIMDATA_ARCHIVE(Table2);
00136         __SIMDATA_ARCHIVE(Table3);
00137         __SIMDATA_ARCHIVE(LLA);
00138         __SIMDATA_ARCHIVE(UTM);
00139         __SIMDATA_ARCHIVE(ECEF);
00140         __SIMDATA_ARCHIVE(GeoPos);
00141         __SIMDATA_ARCHIVE(Path);
00142         __SIMDATA_ARCHIVE(External);
00143         __SIMDATA_ARCHIVE(Key);
00144         // TODO List;
00145         // TODO Enum
00146         // TODO Pointer
00147 #undef __SIMDATA_ARCHIVE
00148 }
00149         // more explicit methods for python that instantiate,
00150         // unpack, and return BaseType data objects.
00151 %insert("shadow") %{
00152         def _Pointer(self):
00153                 raise "FIXME: NOT IMPLMENTED"
00154         def _Enum(self):
00155                 raise "FIXME: NOT IMPLMENTED"
00156         def _List(self):
00157                 raise "FIXME: NOT IMPLMENTED"
00158         def __call__(self, *args):
00159                 raise "Use explicit _* methods from Python"
00160 %}
00161 #endif // SWIG
00162         
00163 
00164 };
00165 
00175 class Packer: public Archive {
00176         FILE *_f;
00177         int _n;
00178         void write(const void* x, int n) {
00179                 fwrite(x, n, 1, _f);
00180         }
00181 public:
00182         Packer(FILE* f): Archive(false) {
00183                 _f = f;
00184                 resetCount();
00185         }
00186         void resetCount() { _n = 0; }
00187         int getCount() { return _n; }
00188 
00189         void operator()(char &x) {
00190                 write(&x, sizeof(char));
00191                 _n += sizeof(char);
00192         }
00193         void operator()(short &x) {
00194                 write(&x, sizeof(short));
00195                 _n += sizeof(short);
00196         }
00197         void operator()(int &x) {
00198                 write(&x, sizeof(int));
00199                 _n += sizeof(int);
00200         }
00201         void operator()(bool &x) {
00202                 char c = x ? 1:0;
00203                 operator()(c);
00204         }
00205         void operator()(double &x) {
00206                 write(&x, sizeof(double));
00207                 _n += sizeof(double);
00208         }
00209         void operator()(char* &x) {
00210                 int n = strlen(x);
00211                 operator()(n);
00212                 write(x, n);
00213                 _n += n;
00214         }
00215         void operator()(BaseType &x) {
00216                 x.serialize(*this);
00217         }
00218         void operator()(float &x) {
00219                 write(&x, sizeof(float));
00220                 _n += sizeof(float);
00221         }
00222         void operator()(hasht &x) {
00223                 write(&x, sizeof(hasht));
00224                 _n += sizeof(hasht);
00225         }
00226         void operator()(std::string &x) {
00227                 char *str = const_cast<char*>(x.c_str());
00228                 operator()(str);
00229         }
00230         template<typename T>
00231         void operator()(std::vector<T> &x) {
00232                 int n = static_cast<int>(x.size());
00233                 operator()(n);
00234                 typename std::vector<T>::iterator i = x.begin();
00235                 while (i != x.end()) operator()(*i++);
00236         }
00237 };
00238 
00239 
00249 class UnPacker: public Archive {
00250         const char* _d;
00251         int _n;
00252         DataArchive* _archive;
00253         bool _loadall;
00254         
00255 public:
00256         DataArchive* _getArchive() { return _archive; }
00257         bool _loadAll() const { return _loadall; }
00258 
00259         UnPacker(const char* data, int n, DataArchive* archive=0, bool loadall = true):
00260                 Archive(true) {
00261                 _n = n;
00262                 _d = data;
00263                 _archive = archive;
00264                 _loadall = loadall;
00265         }
00266 
00267         bool isComplete() const { return _n == 0; }
00268         
00269         void operator()(double &y) {
00270                 _n -= sizeof(double);
00271                 if (_n < 0) throw DataUnderflow();
00272                 memcpy(&y, _d, sizeof(double));
00273                 _d += sizeof(double);
00274         }
00275         void operator()(float &y) {
00276                 _n -= sizeof(float);
00277                 if (_n < 0) throw DataUnderflow();
00278                 memcpy(&y, _d, sizeof(float));
00279                 _d += sizeof(float);
00280         }
00281         void operator()(int &y) {
00282                 _n -= sizeof(int);
00283                 if (_n < 0) throw DataUnderflow();
00284                 memcpy(&y, _d, sizeof(int));
00285                 _d += sizeof(int);
00286         }
00287         void operator()(bool &y) {
00288                 char x;
00289                 operator()(x);
00290                 y = (x != 0);
00291         }
00292         void operator()(short &y) {
00293                 _n -= sizeof(short);
00294                 if (_n < 0) throw DataUnderflow();
00295                 memcpy(&y, _d, sizeof(short));
00296                 _d += sizeof(short);
00297         }
00298         void operator()(char &y) {
00299                 _n -= sizeof(char);
00300                 if (_n < 0) throw DataUnderflow();
00301                 memcpy(&y, _d, sizeof(char));
00302                 _d += sizeof(char);
00303         }
00304         void operator()(hasht &y) {
00305                 _n -= sizeof(hasht);
00306                 if (_n < 0) throw DataUnderflow();
00307                 memcpy(&y, _d, sizeof(hasht));
00308                 _d += sizeof(hasht);
00309         }
00310         void operator()(char* &y) {
00311                 int n;
00312                 operator()(n);
00313                 // XXX this not really a data underflow
00314                 if (n < 0) throw DataUnderflow();
00315                 _n -= n;
00316                 if (_n < 0) throw DataUnderflow();
00317                 y = (char*) malloc(sizeof(char)*(n+1));
00318                 assert(y != 0); // XXX should throw a memory exception
00319                 memcpy(y, _d, sizeof(char)*n);
00320                 y[n] = 0;
00321                 _d += n;
00322         }
00323         void operator()(std::string &y) {
00324                 char* c;
00325                 operator()(c);
00326                 y.assign(c);
00327                 free(c);
00328         }
00329         template<typename T>
00330         void operator()(std::vector<T> &y) {
00331                 int n;
00332                 operator()(n);
00333                 y.resize(n);
00334                 typename std::vector<T>::iterator i = y.begin();
00335                 while (n-- > 0) operator()(*i++);
00336         }
00337         void operator()(BaseType &y) {
00338                 y.serialize(*this);
00339         }
00340 };
00341 
00342 /*
00343  *  Need to do explicit casting in this case, since there's
00344  *  no way to have a virtual template method.
00345  */
00346 template<typename T>
00347 void Archive::operator()(std::vector<T> &x) {
00348         Packer *packer = dynamic_cast<Packer*>(this);
00349         if (packer != 0) { 
00350                 packer->operator()(x);
00351                 return;
00352         }
00353         UnPacker *unpacker = dynamic_cast<UnPacker*>(this);
00354         assert(unpacker != 0);
00355         unpacker->operator()(x);
00356 }
00357 
00358 NAMESPACE_SIMDATA_END
00359 
00360 
00361 #endif //__SIMDATA_PACK_H__
00362 

SimData version pre-0.4.0. For more information on SimData, visit the SimData Homepage.

Generated on Tue Oct 14 12:06:38 2003, using Doxygen 1.2.18.

[SF.net]