00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #define DBCNV_DBGENERICCONVERTER_CPP
00027
00028
00029 #include "GaudiDb/DbOOMs.h"
00030 #include "GaudiDb/IOODataBase.h"
00031 #include "GaudiDb/DbContainer.h"
00032 #include "GaudiDb/DbDefObject.h"
00033 #include "GaudiDb/DbGenericConverter.h"
00034
00035 #include "GaudiKernel/StreamBuffer.h"
00036 #include "GaudiKernel/ContainedObject.h"
00037 #include "GaudiKernel/ObjectContainerBase.h"
00038
00039 inline bool __WRITE__(char mask, StreamBuffer& buf, long item) {
00040 switch(mask) {
00041 case 1: buf << char (item); return true;
00042 case 2: buf << short(item); return true;
00043 case 3: buf << long (item); return true;
00044 default: return false;
00045 }
00046 }
00047
00048 inline bool __READ__(char mask, StreamBuffer& buf, long& item) {
00049 switch(mask) {
00050 case 1: { char ___i; buf >> ___i; item = ___i; return true; }
00051 case 2: { short ___i; buf >> ___i; item = ___i; return true; }
00052 case 3: { buf >> item; return true; }
00053 default: { return false; }
00054 }
00055 }
00056
00058 DbGenericConverter::DbGenericConverter(const CLID& clid, IOODataBase* db, ISvcLocator* svc)
00059 : DbBaseConverter( clid, db, svc )
00060 {
00061 std::string typName = System::typeinfoName(typeid(DbDefObject));
00062 m_type = db->typeInfo(typName);
00063 }
00064
00066 DbGenericConverter::~DbGenericConverter() {
00067 }
00068
00070 dbHandle<DbObject> DbGenericConverter::createPersistent(dbHandle<DbContainer>& cntH) {
00071 dbHandle<DbObject> handle = new(cntH, *m_type) DbDefObject();
00072 return handle;
00073 }
00074
00076 void DbGenericConverter::clearBuffers(dbHandle<DbDefObject>& objH ) {
00077 StreamBuffer& objBuf = objH->streamBuffer();
00078 StreamBuffer& lnkBuf = objH->linkBuffer();
00079
00080 objBuf.setMode(StreamBuffer::WRITING);
00081 objBuf.setBuffPointer(0);
00082
00083 lnkBuf.setMode(StreamBuffer::WRITING);
00084 lnkBuf.setBuffPointer(0);
00085 }
00086
00088 StatusCode DbGenericConverter::beginPersistentUpdate( DefHandle& objH, const DataObject* ) {
00089 clearBuffers(objH);
00090 return StatusCode::SUCCESS;
00091 }
00092
00094 StatusCode DbGenericConverter::endPersistentUpdate( DefHandle& objH, const DataObject* pObject) {
00095 typedef StreamBuffer::ContainedLinks CLinks;
00096 typedef StreamBuffer::IdentifiedLinks ILinks;
00097 StreamBuffer& objBuf = objH->streamBuffer();
00098 CLinks& c_links = objBuf.containedLinks();
00099 ILinks& i_links = objBuf.identifiedLinks();
00100
00101
00102 objH->setObjSize (objBuf.buffPointer());
00103 if ( c_links.size() > 0 || i_links.size() > 0 ) {
00104 StreamBuffer& linkBuf = objH->linkBuffer();
00105 CLinks::iterator i, end;
00106 ILinks::iterator j;
00107 DataObject* pD;
00108 const long INVALID = StreamBuffer::INVALID;
00109 long linkMax = 0, hintMax = 0, num, k;
00110 char linkMask, hintMask;
00111 num = (i_links.size() > c_links.size()) ? i_links.size() : c_links.size();
00112 long* hints = new long[num];
00113 long* links = new long[c_links.size()];
00114
00115 try {
00116
00117 const ObjectContainerBase* last_par = 0;
00118 long last_hint = INVALID;
00119 std::string path;
00120 for (num = c_links.size()-1, i = c_links.begin(), end = c_links.end(); i != end; i++ ) {
00121 hints[num] = links[num] = INVALID;
00122 if ( 0 != (*i).first && 0 != (*i).first->parent() ) {
00123 const ObjectContainerBase* par = (*i).first->parent();
00124 if ( par != last_par ) {
00125 last_par = par;
00126 path = par->fullpath();
00127 last_hint = pObject->addLink(path, par);
00128 if ( last_hint > hintMax ) hintMax = last_hint;
00129 }
00130 hints[num] = last_hint;
00131 links[num] = last_par->distance((*i).first);
00132 if ( links[num] > linkMax ) linkMax = links[num];
00133 }
00134 num--;
00135 }
00136 num = c_links.size();
00137 (linkBuf) << num;
00138 if ( num > 0 ) {
00139 hintMask = (hintMax < SCHAR_MAX) ? 1 : (hintMax < SHRT_MAX) ? 2 : 3;
00140 linkMask = (linkMax < SCHAR_MAX) ? 1 : (linkMax < SHRT_MAX) ? 2 : 3;
00141 (linkBuf) << hintMask << linkMask;
00142 for ( k = 0; k < num; k++ ) {
00143 if ( !__WRITE__(hintMask, linkBuf, hints[k]) )
00144 goto Error;
00145 if ( !__WRITE__(linkMask, linkBuf, links[k]) )
00146 goto Error;
00147 }
00148 }
00149
00150 for (j = i_links.begin(), num = 0; j != i_links.end(); j++) {
00151 pD = (*j).first;
00152 hints[num] = (0 == pD) ? INVALID : pObject->addLink(pD->fullpath(), pD);
00153 if ( hints[num] > hintMax ) hintMax = hints[num];
00154 num++;
00155 }
00156 num = i_links.size();
00157 (linkBuf) << num;
00158 if ( num > 0 ) {
00159 hintMask = (hintMax < SCHAR_MAX) ? 1 : (hintMax < SHRT_MAX) ? 2 : 3;
00160 (linkBuf) << hintMask;
00161 for ( k = 0; k < num; k++ ) {
00162 if ( !__WRITE__(hintMask, linkBuf, hints[k]) )
00163 goto Error;
00164 }
00165 }
00166 goto Done;
00167 }
00168 catch(...) {
00169 }
00170 Error:
00171 delete links;
00172 delete hints;
00173 return StatusCode::FAILURE;
00174 Done:
00175 delete links;
00176 delete hints;
00177 }
00178 return StatusCode::SUCCESS;
00179 }
00180
00182 StatusCode DbGenericConverter::doPersistentUpdate( dbHandle<DbDefObject>& objH, const DataObject* pObject) {
00183 StreamBuffer& objBuf = objH->streamBuffer();
00184 objBuf << pObject->clID();
00185 pObject->serialize(objBuf);
00186 return StatusCode::SUCCESS;
00187 }
00188
00190 StatusCode DbGenericConverter::beginTransientUpdate( dbHandle<DbDefObject>& objH, DataObject* pObject) {
00191 ObjectContainerBase* pCont;
00192 DataObject::Link* link;
00193 ContainedObject* pContained;
00194 StreamBuffer& objBuf = objH->streamBuffer();
00195
00196 objBuf.reserve(objH->objSize());
00197 objBuf.setMode(StreamBuffer::READING);
00198 objBuf.setBuffPointer(0);
00199 if ( objH->linkSize() > 0 ) {
00200 StreamBuffer& linkBuf = objH->linkBuffer();
00201 const long INVALID = StreamBuffer::INVALID;
00202 long i, hint_id, link_id, numContd, numIdent;
00203 char linkMask, hintMask;
00204 linkBuf.setMode(StreamBuffer::READING);
00205 linkBuf.reserve(objH->linkSize());
00206 linkBuf.setBuffPointer(0);
00207 linkBuf >> numContd;
00208 if ( numContd > 0 ) {
00209 (linkBuf) >> hintMask >> linkMask;
00210 objBuf.containedLinks().reserve ( numContd );
00211
00212 for ( i = 0; i < numContd; i++ ) {
00213 if ( !__READ__(hintMask, linkBuf, hint_id) ||
00214 !__READ__(linkMask, linkBuf, link_id) )
00215 goto Error;
00216 if ( INVALID == link_id || INVALID == hint_id ) {
00217 objBuf.addContainedLink(0, INVALID, INVALID);
00218 }
00219 else {
00220 link = pObject->symLink(hint_id);
00221 DataObject* linkObj = (link) ? link->object() : 0;
00222 pContained = 0;
00223 if ( 0 != linkObj ) {
00224 try {
00225 pCont = dynamic_cast<ObjectContainerBase*>(linkObj);
00226 if ( 0 != pCont ) {
00227 pContained = pCont->containedObject(link_id);
00228 }
00229 }
00230 catch(...) {
00231 }
00232 }
00233 objBuf.addContainedLink(pContained, hint_id, link_id);
00234 }
00235 }
00236 }
00237 linkBuf >> numIdent;
00238 if ( numIdent > 0 ) {
00239 (linkBuf) >> hintMask;
00240 objBuf.identifiedLinks().reserve( numIdent );
00241
00242 for ( i = 0; i < numIdent; i++ ) {
00243 if ( !__READ__(hintMask, linkBuf, hint_id) )
00244 goto Error;
00245 if ( INVALID == hint_id ) {
00246 objBuf.addIdentifiedLink(0, INVALID);
00247 }
00248 else {
00249 link = pObject->symLink(hint_id);
00250 objBuf.addIdentifiedLink((link) ? link->object() : 0, hint_id);
00251 }
00252 }
00253 }
00254 }
00255 return StatusCode::SUCCESS;
00256 Error:
00257 return StatusCode::FAILURE;
00258 }
00259
00261 StatusCode DbGenericConverter::endTransientUpdate( dbHandle<DbDefObject>& , DataObject* ) {
00262 return StatusCode::SUCCESS;
00263 }
00264
00266 StatusCode DbGenericConverter::doTransientUpdate( dbHandle<DbDefObject>& objH, DataObject* pObject) {
00267 if ( 0 != pObject && objH.isValid() ) {
00268 StreamBuffer& s = objH->streamBuffer();
00269 CLID clid;
00270 s >> clid;
00271 if ( clid == pObject->clID() ) {
00272 pObject->serialize(s);
00273 return StatusCode::SUCCESS;
00274 }
00275 }
00276 return StatusCode::FAILURE;
00277 }