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. |