00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #define DBCNV_NTUPLES_DBTUPLECNV_CPP
00011
00012
00013 #define ALLOW_ALL_TYPES
00014
00015 #include "DbNTupleCnv.h"
00016 #include "GaudiDb/DbColumn.h"
00017 #include "GaudiDb/DbContainer.h"
00018 #include "GaudiDb/IDataBaseMgr.h"
00019 #include "GaudiDb/DbPersistent.h"
00020 #include "GaudiDb/DbCnvFactory.h"
00021 #include "GaudiDb/DbVArray.h"
00022 #include "GaudiDb/DbAddress.h"
00023 #include "GaudiDb/DbFactory.h"
00024
00025 #include "GaudiKernel/xtoa.h"
00026 #include "GaudiKernel/SmartIF.h"
00027 #include "GaudiKernel/SmartRef.h"
00028 #include "GaudiKernel/GenericAddress.h"
00029 #include "GaudiKernel/NTuple.h"
00030 #include "GaudiKernel/IDataDirectory.h"
00031 #include "GaudiKernel/INTupleSvc.h"
00032 #include "GaudiKernel/ISelectStatement.h"
00033 #include "GaudiKernel/ContainedObject.h"
00034
00035 #include "GaudiKernel/MsgStream.h"
00036
00037 class GenericLinkIO {
00038 public:
00039 inline static void writeLink(StreamBuffer &R__b, const GenericLinkBase& link) {
00040 R__b << link.m_clID << link.m_svcType << link.m_gene.m_info[0] << link.m_gene.m_info[1];
00041 }
00042 inline static void readLink(StreamBuffer &R__b, GenericLinkBase& link) {
00043 R__b >> link.m_clID >> link.m_svcType >> link.m_gene.m_info[0] >> link.m_gene.m_info[1];
00044 }
00045 };
00046
00047
00048
00049 static DbOOMsCnvFactory<DbRWNTupleCnv> s_RWNTfactory;
00050 const ICnvFactory& DbOOMsDbRWNTupleCnvFactory = s_RWNTfactory;
00051 static DbOOMsCnvFactory<DbCWNTupleCnv> s_CWNTfactory;
00052 const ICnvFactory& DbOOMsDbCWNTupleCnvFactory = s_CWNTfactory;
00053
00054 static inline std::istream& loadLong(std::istream& is) {
00055 long i;
00056 is >> i;
00057 return is;
00058 }
00059 static inline std::istream& operator>>(std::istream& is, SmartRef<DataObject>& ) {
00060 return loadLong(is);
00061 }
00062 static inline std::istream& operator>>(std::istream& is, SmartRef<ContainedObject>& ) {
00063 return loadLong(is);
00064 }
00065 static inline std::istream& operator>>(std::istream& is, IOpaqueAddress*& ) {
00066 return loadLong(is);
00067 }
00068 static inline std::istream& operator>>(std::istream& is, std::string& ) {
00069 return loadLong(is);
00070 }
00071
00072 template<class TYP>
00073 static StatusCode createItem (INTuple* tuple, std::istream& is,
00074 const std::string& name, const DbTypeInfo* info, const TYP& null)
00075 {
00076 std::string idxName;
00077 long len, ndim, dim[4], hasIdx, idxLow, idxLen;
00078 long dim1 = 1, dim2 = 1;
00079 INTupleItem* it = 0;
00080 char c;
00081 is >> len >> c
00082 >> ndim >> c
00083 >> hasIdx >> c;
00084 if ( hasIdx ) {
00085 std::getline(is, idxName, ';') >> idxLow >> c >> idxLen >> c;
00086 }
00087 for ( int i = 0; i < ndim; i++ )
00088 is >> dim[i] >> c;
00089
00090 TYP low = null, high = null;
00091 is >> low >> c >> high >> c;
00092 is >> c;
00093 switch( ndim ) {
00094 case 0:
00095 it = NTuple::_Item<TYP>::create (tuple, name, low, high, null);
00096 break;
00097 case 1:
00098 dim1 = (hasIdx) ? idxLen : dim[0];
00099 it = NTuple::_Array<TYP>::create (tuple, name, idxName, dim1, low, high, null);
00100 break;
00101 case 2:
00102 dim1 = (hasIdx) ? idxLen : dim[0];
00103 dim2 = (hasIdx) ? dim[0] : dim[1];
00104 it = NTuple::_Matrix<TYP>::create (tuple, name, idxName, dim1, dim2, low, high, null);
00105 break;
00106 default:
00107 return StatusCode::FAILURE;
00108 }
00109 DbColumn* col = const_cast<DbColumn*>(info->column(name));
00110 if ( col ) {
00111 col->setAddress((char*)it->buffer());
00112 }
00113 return tuple->add(it);
00114 }
00115
00116 template <class T> static inline
00117 void putRange(std::ostream& os, NTuple::_Data<T>* it) {
00118 const NTuple::Range<T>& x = it->range();
00119 os << x.lower() << ';' << x.upper() << ';';
00120 }
00121
00122
00123 template <class T> static inline
00124 int readItem(StreamBuffer& s, T* buff, const DbColumn* col) {
00125 if ( col ) {
00126 DbColumn* c = const_cast<DbColumn*>(col);
00127 char* d = c->data();
00128 *buff = *(T*)d;
00129 return 0;
00130 }
00131 else {
00132 long len;
00133 s >> len;
00134 s.swapFromBuffer(buff, len*sizeof(T));
00135 }
00136 return 0;
00137 }
00138
00139
00140 template <> static inline
00141 int readItem(StreamBuffer& s, std::string* buff, const DbColumn* ) {
00142 s >> (*buff);
00143 return 0;
00144 }
00145
00146 template <class T> static inline
00147 int saveItem(StreamBuffer& s, const T* buff, int len) {
00148 if ( len > 1 ) {
00149 s << len;
00150 s.swapToBuffer(buff, len*sizeof(T));
00151 return 0;
00152 }
00153 return 0;
00154 }
00155
00156 template <> static inline
00157 int saveItem(StreamBuffer& s, const std::string* buff, int ) {
00158 s << (*buff);
00159 return 0;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 template int saveItem<unsigned char>(StreamBuffer& s, const unsigned char* buff, int len);
00173 template int saveItem<unsigned short>(StreamBuffer& s, const unsigned short* buff, int len );
00174 template int saveItem<unsigned int>(StreamBuffer& s, const unsigned int* buff, int len );
00175 template int saveItem<unsigned long>(StreamBuffer& s, const unsigned long* buff, int len );
00176 template int saveItem<char>(StreamBuffer& s, const char* buff, int len );
00177 template int saveItem<short>(StreamBuffer& s, const short* buff, int len );
00178 template int saveItem<int>(StreamBuffer& s, const int* buff, int len );
00179 template int saveItem<long>(StreamBuffer& s, const long* buff, int len );
00180 template int saveItem<float>(StreamBuffer& s, const float* buff, int len );
00181 template int saveItem<double>(StreamBuffer& s, const double* buff, int len );
00182
00183
00184 DbNTupleCnv::DbNTupleCnv(const CLID& clid, IOODataBase* db, ISvcLocator* svc)
00185 : DbUserDataBaseCnv(clid, db, svc)
00186 {
00187 }
00188
00189
00190 DbNTupleCnv::~DbNTupleCnv()
00191 {
00192 }
00193
00194
00195 StatusCode DbNTupleCnv::initialize() {
00196 StatusCode status = DbUserDataBaseCnv::initialize();
00197 if ( status.isSuccess() ) {
00198 status = serviceLocator()->getService(m_cnvSvcName, IID_IDataProviderSvc, (IInterface*&)m_helperServices.DataSvc);
00199 }
00200 return status;
00201 }
00202
00203
00204 StatusCode DbNTupleCnv::finalize() {
00205 return DbUserDataBaseCnv::finalize();
00206 }
00207
00208
00209 StatusCode DbNTupleCnv::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject) {
00210 StatusCode status = StatusCode::FAILURE;
00211 DbAddress* pdbA = dynamic_cast<DbAddress*>(pAddress);
00212 if ( 0 != pdbA ) {
00213 SmartIF<INTupleSvc> ntupleSvc(IID_INTupleSvc, m_helperServices.DataSvc);
00214 dbHandle<DbContainer>& cntH = pdbA->containerHdl();
00215 m_type = cntH.typeInfo();
00216 pAddress->genericLink()->genericInfo()->m_info[1] = 0;
00217 if ( 0 != m_type && ntupleSvc.isValid() ) {
00218 char c;
00219 size_t siz;
00220 int typ;
00221 CLID clid;
00222 std::string title;
00223 NTuple::Tuple* nt = 0;
00224 std::istrstream is(m_type->userDescription().c_str());
00225 std::getline(is, title, ';') >> clid >> c >> siz >> c;
00226 status = ntupleSvc->create(clid, title, nt);
00227 for ( size_t j = 0; j < siz && status.isSuccess(); j++ ) {
00228 is >> c;
00229 std::getline(is, title, ';') >> typ >> c;
00230 switch ( typ ) {
00231 case DataTypeInfo::UCHAR:
00232 status = createItem(nt, is, title, m_type, (unsigned char)0);
00233 break;
00234 case DataTypeInfo::USHORT:
00235 status = createItem(nt, is, title, m_type, (unsigned short)0);
00236 break;
00237 case DataTypeInfo::UINT:
00238 status = createItem(nt, is, title, m_type, (unsigned int)0);
00239 break;
00240 case DataTypeInfo::ULONG:
00241 status = createItem(nt, is, title, m_type, (unsigned long)0);
00242 break;
00243 case DataTypeInfo::CHAR:
00244 status = createItem(nt, is, title, m_type, char(0));
00245 break;
00246 case DataTypeInfo::SHORT:
00247 status = createItem(nt, is, title, m_type, short(0));
00248 break;
00249 case DataTypeInfo::INT:
00250 status = createItem(nt, is, title, m_type, int(0));
00251 break;
00252 case DataTypeInfo::LONG:
00253 status = createItem(nt, is, title, m_type, long(0));
00254 break;
00255 case DataTypeInfo::BOOL:
00256 status = createItem(nt, is, title, m_type, false);
00257 break;
00258 case DataTypeInfo::FLOAT:
00259 status = createItem(nt, is, title, m_type, float(0.0));
00260 break;
00261 case DataTypeInfo::DOUBLE:
00262 status = createItem(nt, is, title, m_type, double(0.0));
00263 break;
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 case DataTypeInfo::OBJECT_ADDR:
00279 status = createItem(nt, is, title, m_type, (IOpaqueAddress*)0);
00280 break;
00281 case DataTypeInfo::UNKNOWN:
00282 default:
00283 status = StatusCode::FAILURE;
00284 break;
00285 }
00286 }
00287 if ( status.isSuccess() ) {
00288 refpObject = nt;
00289 }
00290 else {
00291 refpObject = 0;
00292 if ( nt ) nt->release();
00293 }
00294 }
00295 }
00296 return status;
00297 }
00298
00299
00300 StatusCode DbNTupleCnv::fillObjRefs(IOpaqueAddress* , DataObject* ) {
00301 return StatusCode::SUCCESS;
00302 }
00303
00304
00305 StatusCode DbNTupleCnv::updateObj(IOpaqueAddress* pAddress, DataObject* pObject) {
00306 INTuple* tuple = dynamic_cast<INTuple*>(pObject);
00307 if ( 0 != tuple ) {
00308 ISelectStatement* sel = tuple->selector();
00309 if ( 0 != sel ) {
00310 if ( !sel->isActive() ) {
00311 DbAddress* pdbA = dynamic_cast<DbAddress*>(pAddress);
00312 if ( 0 != pdbA ) {
00313 dbHandle<DbContainer>& cntH = pdbA->containerHdl();
00314 DbResult res = cntH.select(sel);
00315 if ( res ) {
00316 return DbUserDataBaseCnv::updateObj(pAddress, pObject);
00317 }
00318 }
00319 return StatusCode::FAILURE;
00320 }
00321 }
00322 return DbUserDataBaseCnv::updateObj(pAddress, pObject);
00323 }
00324 return StatusCode::FAILURE;
00325 }
00326
00327
00328 StatusCode DbNTupleCnv::updateObjRefs(IOpaqueAddress* pAddress, DataObject* pObject) {
00329 DbAddress* pdbA = dynamic_cast<DbAddress*>(pObject->address());
00330 if ( 0 != pdbA ) {
00331 dbHandle<DbContainer>& cntH = pdbA->containerHdl();
00332 m_type = cntH.typeInfo();
00333 if ( 0 != m_type ) {
00334 StatusCode status = DbUserDataBaseCnv::updateObjRefs(pAddress, pObject);
00335 pdbA->genericInfo()->m_info[1] += 1;
00336 return status;
00337 }
00338 }
00339 return StatusCode::FAILURE;
00340 }
00341
00342
00343 StatusCode DbNTupleCnv::doTransientUpdate( dbHandle<DbDefObject>& objH, DataObject* pObject) {
00344 const dbHandle<DbContainer>& cntH = objH.containedIn();
00345 INTuple* nt = dynamic_cast<INTuple*>(pObject);
00346 StreamBuffer& s = objH->streamBuffer();
00347 const DbTypeInfo* info = cntH.typeInfo();
00348 if ( info ) {
00349 const INTuple::ItemContainer& items = nt->items();
00350 for ( INTuple::ItemContainer::const_iterator i = items.begin(); i != items.end(); i++ ) {
00351 char* buf = (char*)(*i)->buffer();
00352 const DbColumn* col = info->column((*i)->name());
00353 switch( (*i)->type() ) {
00354 case DataTypeInfo::UCHAR:
00355 readItem(s, (unsigned char*)buf, col);
00356 break;
00357 case DataTypeInfo::USHORT:
00358 readItem(s, (unsigned short*)buf, col);
00359 break;
00360 case DataTypeInfo::UINT:
00361 readItem(s, (unsigned int*)buf, col);
00362 break;
00363 case DataTypeInfo::ULONG:
00364 readItem(s, (unsigned long*)buf, col);
00365 break;
00366 case DataTypeInfo::CHAR:
00367 readItem(s, (char*)buf, col);
00368 break;
00369 case DataTypeInfo::SHORT:
00370 readItem(s, (short*)buf, col);
00371 break;
00372 case DataTypeInfo::INT:
00373 readItem(s, (int*)buf, col);
00374 break;
00375 case DataTypeInfo::LONG:
00376 readItem(s, (long*)buf, col);
00377 break;
00378 case DataTypeInfo::BOOL:
00379 readItem(s, (bool*)buf, col);
00380 break;
00381 case DataTypeInfo::FLOAT:
00382 readItem(s, (float*)buf, col);
00383 break;
00384 case DataTypeInfo::DOUBLE:
00385 readItem(s, (double*)buf, col);
00386 break;
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 case DataTypeInfo::OBJECT_ADDR: {
00406 dbHandle<DbLink> lnk;
00407 std::string db, cnt, obj;
00408 StatusCode status = StatusCode::FAILURE;
00409 IOpaqueAddress* pA = *(IOpaqueAddress**)buf;
00410 GenericAddress* pAddr = dynamic_cast<GenericAddress*>(pA);
00411 unsigned char valid;
00412 s >> valid;
00413 if ( valid ) {
00414 GenericLinkIO::readLink(s, lnk);
00415 if ( 0 != pAddr ) {
00416 status = objH.validateAssoc(lnk, db, cnt, obj);
00417 }
00418 }
00419 if ( 0 != pAddr ) {
00420 *(pAddr->genericLink()) = lnk;
00421 pAddr->setDbName(db);
00422 pAddr->setContainerName(cnt);
00423 pAddr->setObjectName(obj);
00424 }
00425 break;
00426 }
00427 case DataTypeInfo::UNKNOWN:
00428 default:
00429 break;
00430 }
00431 }
00432 }
00433 return StatusCode::SUCCESS;
00434 }
00435
00437 dbHandle<DbObject> DbNTupleCnv::createPersistent(dbHandle<DbContainer>& cntH) {
00438 dbHandle<DbObject> handle = new(cntH, *m_type) DbDefObject();
00439 return handle;
00440 }
00441
00443 StatusCode DbNTupleCnv::createRep(DataObject* pObject, IOpaqueAddress*& pAddr) {
00444 DbAddress* pdbA = dynamic_cast<DbAddress*>(pObject->address());
00445 if ( 0 == pdbA ) {
00446 const INTuple* nt = dynamic_cast<const INTuple*>(pObject);
00447 const INTuple::ItemContainer& items = nt->items();
00448 std::string loc = containerName(pObject->directory());
00449 const DbTypeInfo* typ = m_db->typeInfo(loc);
00450 if ( 0 != nt ) {
00451 std::vector<DbColumn*> cols;
00452 char txt[4096];
00453 std::ostrstream os(txt,sizeof(txt));
00454 os << nt->title() << ';' << pObject->clID() << ';' << items.size() << ';';
00455 for ( INTuple::ItemContainer::const_iterator i = items.begin(); i != items.end(); i++ ) {
00456 os << '{'
00457 << (*i)->name() << ';'
00458 << (*i)->type() << ';'
00459 << (*i)->length() << ';'
00460 << (*i)->ndim() << ';'
00461 << (*i)->hasIndex() << ';';
00462 if ( (*i)->hasIndex() ) {
00463 os << (*i)->index() << ';';
00464 INTupleItem* idxItem = (*i)->indexItem();
00465 switch( idxItem->type() ) {
00466 case DataTypeInfo::UCHAR:
00467 putRange(os, dynamic_cast<NTuple::_Data<unsigned char>*>(idxItem)); break;
00468 case DataTypeInfo::USHORT:
00469 putRange(os, dynamic_cast<NTuple::_Data<unsigned short>*>(idxItem)); break;
00470 case DataTypeInfo::UINT:
00471 putRange(os, dynamic_cast<NTuple::_Data<unsigned int>*>(idxItem)); break;
00472 case DataTypeInfo::ULONG:
00473 putRange(os, dynamic_cast<NTuple::_Data<unsigned long>*>(idxItem)); break;
00474 case DataTypeInfo::CHAR:
00475 putRange(os, dynamic_cast<NTuple::_Data<char>*>(idxItem)); break;
00476 case DataTypeInfo::SHORT:
00477 putRange(os, dynamic_cast<NTuple::_Data<short>*>(idxItem)); break;
00478 case DataTypeInfo::INT:
00479 putRange(os, dynamic_cast<NTuple::_Data<int>*>(idxItem)); break;
00480 case DataTypeInfo::LONG:
00481 putRange(os, dynamic_cast<NTuple::_Data<long>*>(idxItem)); break;
00482 default: {
00483 MsgStream err(msgSvc(), pObject->fullpath());
00484 err << MSG::ERROR << "Column " << (*i)->index()
00485 << " is not a valid index column!" << endreq;
00486 return StatusCode::FAILURE;
00487 }
00488 }
00489 }
00490 for ( long k = 0; k < (*i)->ndim(); k++ ) os << (*i)->dim(k) << ';';
00491 switch((*i)->type()) {
00492 case DataTypeInfo::STRING:
00493 case DataTypeInfo::NTCHAR:
00494 case DataTypeInfo::OBJECT_REF:
00495 case DataTypeInfo::OBJECT_ADDR:
00496 case DataTypeInfo::CONTAINED_REF:
00497 os << 0 << ';' << 0 << ';';
00498 break;
00499 case DataTypeInfo::UCHAR:
00500 putRange(os, dynamic_cast<NTuple::_Data<unsigned char>*>(*i)); goto MakeCol;
00501 case DataTypeInfo::USHORT:
00502 putRange(os, dynamic_cast<NTuple::_Data<unsigned short>*>(*i)); goto MakeCol;
00503 case DataTypeInfo::UINT:
00504 putRange(os, dynamic_cast<NTuple::_Data<unsigned int>*>(*i)); goto MakeCol;
00505 case DataTypeInfo::ULONG:
00506 putRange(os, dynamic_cast<NTuple::_Data<unsigned long>*>(*i)); goto MakeCol;
00507 case DataTypeInfo::CHAR:
00508 putRange(os, dynamic_cast<NTuple::_Data<char>*>(*i)); goto MakeCol;
00509 case DataTypeInfo::SHORT:
00510 putRange(os, dynamic_cast<NTuple::_Data<short>*>(*i)); goto MakeCol;
00511 case DataTypeInfo::INT:
00512 putRange(os, dynamic_cast<NTuple::_Data<int>*>(*i)); goto MakeCol;
00513 case DataTypeInfo::LONG:
00514 putRange(os, dynamic_cast<NTuple::_Data<long>*>(*i)); goto MakeCol;
00515 case DataTypeInfo::BOOL:
00516 putRange(os, dynamic_cast<NTuple::_Data<bool>*>(*i)); goto MakeCol;
00517 case DataTypeInfo::FLOAT:
00518 putRange(os, dynamic_cast<NTuple::_Data<float>*>(*i)); goto MakeCol;
00519 case DataTypeInfo::DOUBLE:
00520 putRange(os, dynamic_cast<NTuple::_Data<double>*>(*i)); goto MakeCol;
00521 MakeCol:
00522 if ( (*i)->length() == 1 ) {
00523 DbColumn* col = (0==typ) ? new DbColumn((*i)->name(), 0, (*i)->type())
00524 : (DbColumn*)typ->column((*i)->name());
00525 col->setAddress((char*)(*i)->buffer());
00526 cols.push_back(col);
00527 }
00528 break;
00529
00530 default:
00531 break;
00532 }
00533 os << '}';
00534 }
00535 if ( 0 == typ ) {
00536 os << '\0';
00537 typ = m_db->addTypeInfo(loc,"DbDefObject","",txt,cols);
00538 }
00539 }
00540 m_type = typ;
00541 }
00542 else {
00543 dbHandle<DbContainer>& cntH = pdbA->containerHdl();
00544 m_type = cntH.typeInfo();
00545 if ( m_type == 0 ) {
00546 return StatusCode::FAILURE;
00547 }
00548 }
00549 StatusCode status = StatusCode::SUCCESS;
00550 if ( 0 == pdbA || !pdbA->objectHdl().isValid() ) {
00551 status = DbUserDataBaseCnv::createRep(pObject, pAddr);
00552 }
00553 if ( status.isSuccess() ) {
00554 status = DbUserDataBaseCnv::updateRep(pAddr, pObject);
00555 }
00556 return status;
00557 }
00558
00560 StatusCode DbNTupleCnv::updateRep(IOpaqueAddress* , DataObject* ) {
00561 return StatusCode::SUCCESS;
00562 }
00563
00565 StatusCode DbNTupleCnv::updateRepRefs(IOpaqueAddress* , DataObject* ) {
00566 return StatusCode::SUCCESS;
00567 }
00568
00569
00570 StatusCode DbNTupleCnv::doPersistentUpdate( dbHandle<DbDefObject>& objH, const DataObject* pObject) {
00571 const dbHandle<DbContainer>& cntH = objH.containedIn();
00572 const INTuple* nt = dynamic_cast<const INTuple*>(pObject);
00573 StreamBuffer& s = objH->streamBuffer();
00574 clearBuffers(objH);
00575
00576
00577 if ( nt != 0 ) {
00578 const INTuple::ItemContainer& items = nt->items();
00579 m_type = cntH.typeInfo();
00580 for ( INTuple::ItemContainer::const_iterator i = items.begin(); i != items.end(); i++ ) {
00581 char* buf = (char*)(*i)->buffer();
00582 int len = (*i)->filled();
00583 switch( (*i)->type() ) {
00584 case DataTypeInfo::UCHAR:
00585 saveItem(s, (const unsigned char*)buf, len);
00586 break;
00587 case DataTypeInfo::USHORT:
00588 saveItem(s, (const unsigned short*)buf, len);
00589 break;
00590 case DataTypeInfo::UINT:
00591 saveItem(s, (const unsigned int*)buf, len);
00592 break;
00593 case DataTypeInfo::ULONG:
00594 saveItem(s, (const unsigned long*)buf, len);
00595 break;
00596 case DataTypeInfo::CHAR:
00597 saveItem(s, (const char*)buf, len);
00598 break;
00599 case DataTypeInfo::SHORT:
00600 saveItem(s, (const short*)buf, len);
00601 break;
00602 case DataTypeInfo::INT:
00603 saveItem(s, (const int*)buf, len);
00604 break;
00605 case DataTypeInfo::LONG:
00606 saveItem(s, (const long*)buf, len);
00607 break;
00608 case DataTypeInfo::BOOL:
00609 saveItem(s, (const bool*)buf, len);
00610 break;
00611 case DataTypeInfo::FLOAT:
00612 saveItem(s, (const float*)buf, len);
00613 break;
00614 case DataTypeInfo::DOUBLE:
00615 saveItem(s, (const double*)buf, len);
00616 break;
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 case DataTypeInfo::OBJECT_ADDR: {
00636 IOpaqueAddress* pA = *(IOpaqueAddress**)buf;
00637 if ( 0 != pA ) {
00638 dbHandle<DbLink> to2(*pA->genericLink());
00639 dbHandle<DbLink> to(*pA->genericLink());
00640 dbHandle<DbDataBase> dbH = objH.containedIn().containedIn();
00641 if ( dbH.addAssocEntry(pA->dbName(), pA->containerName(), pA->objectName(), to) ) {
00642 s << (unsigned char)1;
00643 GenericLinkIO::writeLink(s, to);
00644 break;
00645 }
00646 }
00647 s << (unsigned char)0;
00648 break;
00649 }
00650 case DataTypeInfo::UNKNOWN:
00651 default:
00652 break;
00653 }
00654 }
00655 }
00656 return StatusCode::SUCCESS;
00657 }
00658
00660 StatusCode DbNTupleCnv::afterPersistentUpdate(dbHandle<DbDefObject>& , const DataObject* pObject) {
00661 const INTuple* tup = dynamic_cast<const INTuple*>(pObject);
00662 if ( 0 != tup ) {
00663 INTuple::ItemContainer& items = const_cast<INTuple::ItemContainer&>(tup->items());
00664 for ( INTuple::ItemContainer::iterator i = items.begin(); i != items.end(); i++ ) {
00665 (*i)->reset();
00666 }
00667 return StatusCode::SUCCESS;
00668 }
00669 return StatusCode::FAILURE;
00670 }