BIE |
/home/weinberg/src/BIE/include/AData.h00001 // This is really -*- C++ -*- 00002 00003 #ifndef ADATA_H 00004 #define ADATA_H 00005 00006 #include <iostream> 00007 #include <cstring> 00008 00009 #include "Serializable.h" 00010 00011 #include "gfunction.h" 00012 #include "Node.h" 00013 #include "CliArgList.h" 00014 #include "clivector.h" 00015 00016 class CliArgList; 00017 00018 extern char * stralloc(const char * str); 00019 00031 class AData : public BIE::Serializable 00032 { 00033 00034 public: 00035 00037 AData(int32 typecode); 00038 00040 AData(); 00041 00043 AData(void * pointer, const char * typestring); 00044 00046 ~AData(); 00047 00050 enum VALUE_TYPE { bool_TYPE = -100, 00051 uint32_TYPE, int32_TYPE, 00052 float_TYPE, double_TYPE, 00053 string_TYPE, charstar_TYPE, 00054 pointer_TYPE, variable_TYPE, 00055 arrayelement_TYPE, arrayelementptr_TYPE, 00056 variablearrayindex_TYPE, arrayindex_TYPE, 00057 array_TYPE, unset_TYPE }; 00058 00059 #define DECLARE_GET_SET_IS(typename,prefix) \ 00060 typename get_ ## prefix() const; \ 00061 void set_ ## prefix(typename arg); \ 00062 bool is_ ## prefix() const; 00063 00064 DECLARE_GET_SET_IS(bool,bool) 00065 DECLARE_GET_SET_IS(uint32,uint32) 00066 DECLARE_GET_SET_IS(int32,int32) 00067 DECLARE_GET_SET_IS(float,float) 00068 DECLARE_GET_SET_IS(double,double) 00069 DECLARE_GET_SET_IS(const char *,charstar) 00070 DECLARE_GET_SET_IS(void *,pointer) 00071 DECLARE_GET_SET_IS(const char *,variable) 00072 DECLARE_GET_SET_IS(CliArgList *,arrayelement) 00073 DECLARE_GET_SET_IS(CliArgList *,arrayelementptr) 00074 DECLARE_GET_SET_IS(const char *,variablearrayindex) 00075 DECLARE_GET_SET_IS(uint32,arrayindex) 00076 DECLARE_GET_SET_IS(void*,array) 00077 00079 const char * get_string() const; 00081 void set_string(string str); 00083 bool is_string() const; 00084 00085 #undef DECLARE_GET_SET_IS 00086 00088 void setType(int32 typecode) { this->type = typecode; } 00089 00091 int32 getType() const { return this->type; } 00092 00094 void setNext(AData * next) { this->next = next; } 00095 00097 AData * getNext() const { return this->next; } 00098 00100 const char * getTypeString() const { return this->type_str; } 00101 00103 void setTypeString(const char * str) 00104 { 00105 if (this->type_str != 0) { delete [] this->type_str; } 00106 this->type_str = new char [strlen(str) + 1]; 00107 strcpy(this->type_str, str); 00108 } 00109 00111 string get_type_name(); 00112 00114 const char * getForVariable() const { return this->for_variable; } 00115 00117 void setForVariable(const char * str) 00118 { 00119 if (this->for_variable) { delete [] this->for_variable; } 00120 this->for_variable = stralloc(str); 00121 } 00122 00124 void print_value(ostream & outputstream) const; 00125 00127 void copy_memory_to_value(void * address); 00128 00130 void copy_value_to_memory (void *address); 00131 00133 void copy(const AData *data); 00134 00135 private: 00136 00138 union { 00139 // Actual values a cli variable can have. 00140 bool bool_value; 00141 uint32 uint32_value; 00142 int32 int32_value; 00143 float float_value; 00144 double double_value; 00145 char *string_value; 00146 char *charstar_value; 00147 void *pointer_value; 00148 void *array_value; 00149 00150 // Values used in expression evaluation. 00151 char *variable_value; // holds unresolved variable names. 00152 CliArgList * arrayelement_value; // holds two AData items 1) array name 2) index 00153 CliArgList * arrayelementptr_value; // holds two AData items 1) array name 2) index 00154 char * variablearrayindex_value; // holds a variable array index. 00155 uint32 arrayindex_value; // holds a literal array index 00156 } value; 00157 00159 int32 type; 00160 00162 char *type_str; 00163 00165 AData *next; 00166 00168 uint32 arraylength; 00169 00171 char * for_variable; 00172 00173 // PERSISTENCE code 00174 // We definitely need a custom serlize() routine for this class.. 00175 private: 00176 friend class boost::serialization::access; 00177 00178 // need to split save/load just for the pointer_TYPE 00179 template<class Archive> 00180 void save(Archive & ar, const unsigned int version) const { 00181 string type_str_s = (type_str==NULL)?"":type_str; 00182 string for_variable_s = (for_variable==NULL)?"":type_str; 00183 00184 ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(Serializable); 00185 00186 try { 00187 ar << BOOST_SERIALIZATION_NVP(type); 00188 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00189 } 00190 try { 00191 ar << BOOST_SERIALIZATION_NVP(type_str_s); 00192 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00193 } 00194 try { 00195 ar << BOOST_SERIALIZATION_NVP(next); 00196 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00197 } 00198 try { 00199 ar << BOOST_SERIALIZATION_NVP(arraylength); 00200 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00201 } 00202 try { 00203 ar << BOOST_SERIALIZATION_NVP(for_variable_s); 00204 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00205 } 00206 00207 string string_s; 00208 00209 // for pointer_TYPE (why did Byn split this assignment?) 00210 Serializable* pointer_value_static = (Serializable*)value.pointer_value; 00211 Serializable* pointer_value_dynamic = 00212 dynamic_cast<Serializable*>(pointer_value_static); 00213 00214 switch(type) { 00215 case bool_TYPE: 00216 try { 00217 ar << BOOST_SERIALIZATION_NVP(value.bool_value); 00218 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00219 } 00220 break; 00221 case uint32_TYPE: 00222 try { 00223 ar << BOOST_SERIALIZATION_NVP(value.uint32_value); 00224 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00225 } 00226 break; 00227 case int32_TYPE: 00228 try { 00229 ar << BOOST_SERIALIZATION_NVP(value.int32_value); 00230 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00231 } 00232 break; 00233 case float_TYPE: 00234 try { 00235 ar << BOOST_SERIALIZATION_NVP(value.float_value); 00236 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00237 } 00238 break; 00239 case double_TYPE: 00240 try { 00241 ar << BOOST_SERIALIZATION_NVP(value.double_value); 00242 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00243 } 00244 break; 00245 case string_TYPE: 00246 string_s = value.string_value; 00247 try { 00248 ar << BOOST_SERIALIZATION_NVP(string_s); 00249 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00250 } 00251 break; 00252 case charstar_TYPE: 00253 string_s = value.charstar_value; 00254 try { 00255 ar << BOOST_SERIALIZATION_NVP(string_s); 00256 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00257 } 00258 break; 00259 case pointer_TYPE: 00260 if (value.pointer_value == NULL) { 00261 // just save it 00262 Serializable* tmp = NULL; 00263 try { 00264 ar << boost::serialization::make_nvp("pointer_value", tmp); 00265 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00266 } 00267 } 00268 // rather dirty hack, wish there's cleaner way to deal with this.. 00269 else if (strcmp(type_str, "clivectord") == 0) { 00270 clivectord* p = (clivectord*)value.pointer_value; 00271 try { 00272 ar << boost::serialization::make_nvp("pointer_value", p); 00273 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00274 } 00275 } 00276 else if (strcmp(type_str, "clivectori") == 0) { 00277 clivectori* p = (clivectori*)value.pointer_value; 00278 try { 00279 ar << boost::serialization::make_nvp("pointer_value", p); 00280 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00281 } 00282 } 00283 else if (strcmp(type_str, "clivectors") == 0) { 00284 clivectors* p = (clivectors*)value.pointer_value; 00285 try { 00286 ar << boost::serialization::make_nvp("pointer_value", p); 00287 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00288 } 00289 } 00290 else if (strcmp(type_str, "clivectortess") == 0) { 00291 clivectortess* p = (clivectortess*)value.pointer_value; 00292 try { 00293 ar << boost::serialization::make_nvp("pointer_value", p); 00294 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00295 } 00296 } 00297 else if (pointer_value_dynamic != NULL) { 00298 // value.pointer_value is a subclass of Serializable 00299 try { 00300 ar << boost::serialization::make_nvp("pointer_value", 00301 pointer_value_dynamic); 00302 } catch (::boost::archive::archive_exception & e) { 00303 cout << "AData:" << __LINE__ << " pointer_value: " << type_str_s << endl; 00304 throw new BoostSerializationException(string(e.what()), 00305 "pointer_value: " + type_str_s, 00306 __FILE__,__LINE__); 00307 } catch (BoostSerializationException * e) { 00308 cout << "AData:" << __LINE__ << " pointer_value: " << type_str_s << endl; 00309 throw new BoostSerializationException(e,"pointer_value: " + type_str_s, 00310 __FILE__,__LINE__); 00311 } 00312 } 00313 else { 00314 // value.pointer_value isn't a subclass of Serializable. We'll 00315 // try to serialize and hope for the best this will only 00316 // succeed if non-intrusive version of serialize() function 00317 // for this class is defined somewhere 00318 /* ar << boost::serialization::make_nvp("pointer_value", */ 00319 /* value.pointer_value); */ 00320 // BLOW UP 00321 throw InternalError("Can't save this type.",__FILE__,__LINE__); 00322 } 00323 break; 00324 case variable_TYPE: 00325 string_s = value.variable_value; 00326 try { 00327 ar << BOOST_SERIALIZATION_NVP(string_s); 00328 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00329 } 00330 break; 00331 case arrayelement_TYPE: 00332 try { 00333 ar << BOOST_SERIALIZATION_NVP(value.arrayelement_value); 00334 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00335 } 00336 break; 00337 case arrayelementptr_TYPE: 00338 try { 00339 ar << BOOST_SERIALIZATION_NVP(value.arrayelementptr_value); 00340 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00341 } 00342 break; 00343 case variablearrayindex_TYPE: 00344 string_s = value.variablearrayindex_value; 00345 try { 00346 ar << BOOST_SERIALIZATION_NVP(string_s); 00347 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00348 } 00349 break; 00350 case arrayindex_TYPE: 00351 // uint32 00352 try { 00353 ar << BOOST_SERIALIZATION_NVP(value.arrayindex_value); 00354 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00355 } 00356 break; 00357 case array_TYPE: 00358 // I don't think this type is ever really used, at least within 00359 // the persistence context.. Alistair left similar comments in 00360 // src/AData.cc 00361 throw InternalError("array_TYPE not implemented.",__FILE__,__LINE__); 00362 break; 00363 case unset_TYPE: 00364 break; 00365 default: 00366 // BLOW UP 00367 throw InternalError("Unrecognized data stored in AData object.",__FILE__,__LINE__); 00368 break; 00369 } 00370 } 00371 00372 template<class Archive> 00373 void load(Archive & ar, const unsigned int version) { 00374 string type_str_s, for_variable_s; 00375 00376 ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(Serializable); 00377 00378 try { 00379 ar >> BOOST_SERIALIZATION_NVP(type); 00380 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00381 } 00382 try { 00383 ar >> BOOST_SERIALIZATION_NVP(type_str_s); 00384 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00385 } 00386 setTypeString(type_str_s.c_str()); 00387 try { 00388 ar >> BOOST_SERIALIZATION_NVP(next); 00389 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00390 } 00391 try { 00392 ar >> BOOST_SERIALIZATION_NVP(arraylength); 00393 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00394 } 00395 try { 00396 ar >> BOOST_SERIALIZATION_NVP(for_variable_s); 00397 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00398 } 00399 if (for_variable_s.size() > 0) { 00400 setForVariable(for_variable_s.c_str()); 00401 } 00402 00403 string string_s; 00404 00405 switch(type) { 00406 case bool_TYPE: 00407 try { 00408 ar >> BOOST_SERIALIZATION_NVP(value.bool_value); 00409 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00410 } 00411 break; 00412 case uint32_TYPE: 00413 try { 00414 ar >> BOOST_SERIALIZATION_NVP(value.uint32_value); 00415 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00416 } 00417 break; 00418 case int32_TYPE: 00419 try { 00420 ar >> BOOST_SERIALIZATION_NVP(value.int32_value); 00421 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00422 } 00423 break; 00424 case float_TYPE: 00425 try { 00426 ar >> BOOST_SERIALIZATION_NVP(value.float_value); 00427 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00428 } 00429 break; 00430 case double_TYPE: 00431 try { 00432 ar >> BOOST_SERIALIZATION_NVP(value.double_value); 00433 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00434 } 00435 break; 00436 case string_TYPE: 00437 try { 00438 ar >> BOOST_SERIALIZATION_NVP(string_s); 00439 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00440 } 00441 if (value.string_value != NULL) { 00442 delete [] value.string_value; 00443 } 00444 value.string_value = new char[strlen(string_s.c_str()) + 1]; 00445 strcpy(value.string_value, string_s.c_str()); 00446 break; 00447 case charstar_TYPE: 00448 try { 00449 ar >> BOOST_SERIALIZATION_NVP(string_s); 00450 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00451 } 00452 if (value.charstar_value != NULL) { 00453 delete [] value.charstar_value; 00454 } 00455 value.charstar_value = new char[strlen(string_s.c_str()) + 1]; 00456 strcpy(value.charstar_value, string_s.c_str()); 00457 break; 00458 case pointer_TYPE: 00459 // rather dirty hack, wish there's cleaner way to deal with this.. 00460 if (strcmp(type_str, "clivectord") == 0) { 00461 clivectord* p = (clivectord*)value.pointer_value; 00462 try { 00463 ar >> boost::serialization::make_nvp("pointer_value", p); 00464 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00465 } 00466 } else if (strcmp(type_str, "clivectori") == 0) { 00467 clivectori* p = (clivectori*)value.pointer_value; 00468 try { 00469 ar >> boost::serialization::make_nvp("pointer_value", p); 00470 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00471 } 00472 } else if (strcmp(type_str, "clivectors") == 0) { 00473 clivectors* p = (clivectors*)value.pointer_value; 00474 try { 00475 ar >> boost::serialization::make_nvp("pointer_value", p); 00476 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00477 } 00478 } else if (strcmp(type_str, "clivectortess") == 0) { 00479 clivectortess* p = (clivectortess*)value.pointer_value; 00480 try { 00481 ar >> boost::serialization::make_nvp("pointer_value", p); 00482 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00483 } 00484 } else { 00485 // value.pointer_value isn't a subclass of Serializable. We'll 00486 // try to serialize and hope for the best this will only 00487 // succeed if non-intrusive version of serialize() function 00488 // for this class is defined somewhere 00489 // BLOW UP 00490 Serializable* p; 00491 try { 00492 ar >> boost::serialization::make_nvp("pointer_value", p); 00493 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00494 } 00495 value.pointer_value = p; 00496 } 00497 break; 00498 case variable_TYPE: 00499 try { 00500 ar >> BOOST_SERIALIZATION_NVP(string_s); 00501 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00502 } 00503 if (value.variable_value != NULL) { 00504 delete [] value.variable_value; 00505 } 00506 value.variable_value = new char[strlen(string_s.c_str()) + 1]; 00507 strcpy(value.variable_value, string_s.c_str()); 00508 break; 00509 case arrayelement_TYPE: 00510 try { 00511 ar >> BOOST_SERIALIZATION_NVP(value.arrayelement_value); 00512 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00513 } 00514 break; 00515 case arrayelementptr_TYPE: 00516 try { 00517 ar >> BOOST_SERIALIZATION_NVP(value.arrayelementptr_value); 00518 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00519 } 00520 break; 00521 case variablearrayindex_TYPE: 00522 try { 00523 ar >> BOOST_SERIALIZATION_NVP(string_s); 00524 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00525 } 00526 if (value.variablearrayindex_value != NULL) { 00527 delete [] value.variablearrayindex_value; 00528 } 00529 value.variablearrayindex_value = 00530 new char[strlen(string_s.c_str()) + 1]; 00531 strcpy(value.variablearrayindex_value, string_s.c_str()); 00532 break; 00533 case arrayindex_TYPE: 00534 // uint32 00535 try { 00536 ar >> BOOST_SERIALIZATION_NVP(value.arrayindex_value); 00537 BIE_CATCH_BOOST_SERIALIZATION_EXCEPTION; 00538 } 00539 break; 00540 case array_TYPE: 00541 // I don't think this type is ever really used, at least within 00542 // the persistence context.. Alistair left similar comments in 00543 // src/AData.cc 00544 throw InternalError("array_TYPE not implemented.", 00545 __FILE__,__LINE__); 00546 break; 00547 case unset_TYPE: 00548 break; 00549 default: 00550 // BLOW UP 00551 throw InternalError("Unrecognized data stored in AData object.", 00552 __FILE__,__LINE__); 00553 break; 00554 } 00555 } 00556 00557 BOOST_SERIALIZATION_SPLIT_MEMBER(); 00558 }; 00559 00560 BIE_CLASS_EXPORT_KEY(AData) 00561 00562 #endif Send suggestions, questions, and feedback to WEINBERG at ASTRO dot UMASS dot EDU. Documentation generated at Fri Mar 26 00:35:09 2010 by
|