cfl_basevector.cppGo to the documentation of this file.00001 /** @file cfl_basevector.cpp @brief */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2006 Bernd Opitz 00006 Copyright (C) 2007 Thomas Moor 00007 Exclusive copyright is granted to Klaus Schmidt 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with this library; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00022 00023 #include "cfl_basevector.h" 00024 #include "cfl_nameset.h" 00025 00026 namespace faudes { 00027 00028 00029 /* 00030 ****************************************************************************************** 00031 ****************************************************************************************** 00032 ****************************************************************************************** 00033 00034 Implementation of TBaseVector 00035 00036 ****************************************************************************************** 00037 ****************************************************************************************** 00038 ****************************************************************************************** 00039 */ 00040 00041 // faudes type std 00042 FAUDES_TYPE_IMPLEMENTATION(Void,vBaseVector,Type) 00043 00044 00045 // vBaseVector() 00046 vBaseVector::vBaseVector(void) : 00047 Type() 00048 { 00049 FD_DC("vBaseVector(" << this << ")::vBaseVector()"); 00050 // my members 00051 mMyName="Vector"; 00052 } 00053 00054 00055 // vBaseVector(filename) 00056 vBaseVector::vBaseVector(const std::string& rFileName, const std::string& rLabel) : 00057 Type() 00058 { 00059 FD_DC("vBaseVector(" << this << ")::vBaseVector()"); 00060 // other members 00061 mMyName="Vector"; 00062 // do read; 00063 Read(rFileName,rLabel); 00064 } 00065 00066 00067 // vBaseVector(rOtherSet) 00068 vBaseVector::vBaseVector(const vBaseVector& rOtherVector) : 00069 Type(rOtherVector) 00070 { 00071 FD_DC("vBaseVector(" << this << ")::vBaseVector(rOtherVector " << &rOtherVector << "): copy construct"); 00072 DoAssign(rOtherVector); 00073 } 00074 00075 // destructor 00076 vBaseVector::~vBaseVector(void) { 00077 FD_DC("vBaseVector(" << this << ")::~vBaseVector()"); 00078 // delete entries 00079 for(Position pos=0; pos<mVector.size(); pos++) 00080 if(mVector[pos].mMine) delete mVector[pos].pElement; 00081 // done 00082 FD_DC("vBaseVector(" << this << ")::~vBaseVector(): done"); 00083 } 00084 00085 00086 // element prototype 00087 const Type* vBaseVector::Elementp(void) const { 00088 static Type proto; 00089 return &proto; 00090 } 00091 00092 // element prototype 00093 const Type& vBaseVector::Element(void) const { 00094 return *Elementp(); 00095 } 00096 00097 // element factory 00098 Type* vBaseVector::NewElement(void) { 00099 return Element().New(); 00100 } 00101 00102 // test element type 00103 bool vBaseVector::ElementTry(const Type& rElement) const { 00104 return Elementp()->Cast(&rElement)!=NULL; 00105 } 00106 00107 // assignment (here, we know the type to match) 00108 void vBaseVector::DoAssign(const vBaseVector& rSourceVector) { 00109 FD_DC("vBaseVector(" << this << ")::DoAssign(rOtherVector " << &rSourceVector << ")"); 00110 // bail out on selfref 00111 if(this==&rSourceVector) return; 00112 // virtual clear 00113 Clear(); 00114 // allocate 00115 mVector.resize(rSourceVector.Size()); 00116 // copy entries 00117 for(Position pos=0; pos<mVector.size(); pos++) { 00118 mVector[pos].pElement = rSourceVector.mVector[pos].pElement->Copy(); 00119 mVector[pos].mMine=true; 00120 mVector[pos].mFileName=""; 00121 } 00122 // done 00123 FD_DC("vBaseVector(" << this << ")::DoAssign(rOtherVector " << &rSourceVector << "): done"); 00124 } 00125 00126 // clear 00127 void vBaseVector::Clear(void) { 00128 // delete entries 00129 for(Position pos=0; pos<mVector.size(); pos++) { 00130 if(mVector[pos].mMine) delete mVector[pos].pElement; 00131 } 00132 // resize 00133 mVector.resize(0); 00134 } 00135 00136 00137 // Name 00138 const std::string& vBaseVector::Name(void) const { 00139 return mMyName; 00140 } 00141 00142 // Name 00143 void vBaseVector::Name(const std::string& rName) { 00144 mMyName = rName; 00145 } 00146 00147 // Size() 00148 Idx vBaseVector::Size(void) const { 00149 return (Idx) mVector.size(); 00150 } 00151 00152 // Size(idx) 00153 void vBaseVector::Size(Idx len) { 00154 FD_DC("vBaseVector(" << this << ")::Size(..): from " << mVector.size() << " to " << len); 00155 // record 00156 Position olen=mVector.size(); 00157 // delete 00158 for(Position pos=len; pos<olen; pos++) 00159 if(mVector[pos].mMine) delete mVector[pos].pElement; 00160 // allocate 00161 mVector.resize(len); 00162 // initialize 00163 for(Position pos=olen; pos < len; pos++) { 00164 mVector[pos].pElement = NewElement(); 00165 mVector[pos].mMine=true; 00166 mVector[pos].mFileName = ""; 00167 } 00168 // done 00169 FD_DC("vBaseVector(" << this << ")::Size(..): done"); 00170 } 00171 00172 00173 // Empty() 00174 bool vBaseVector::Empty(void) const { 00175 return mVector.empty(); 00176 } 00177 00178 00179 // At() 00180 const Type& vBaseVector::At(const Position& pos) const { 00181 #ifdef FAUDES_CHECKED 00182 if(pos<0 || pos >= mVector.size()) { 00183 std::stringstream errstr; 00184 errstr << "index out of range" << std::endl; 00185 throw Exception("vBaseVector::At", errstr.str(), 62); 00186 } 00187 #endif 00188 return *mVector[pos].pElement; 00189 } 00190 00191 // At() 00192 Type& vBaseVector::At(const Position& pos) { 00193 #ifdef FAUDES_CHECKED 00194 if(pos<0 || pos >= mVector.size()) { 00195 std::stringstream errstr; 00196 errstr << "index out of range" << std::endl; 00197 throw Exception("vBaseVector::At", errstr.str(), 62); 00198 } 00199 #endif 00200 return *mVector[pos].pElement; 00201 } 00202 00203 00204 00205 // replace (copy) 00206 void vBaseVector::Replace(const Position& pos, const Type& rElem) { 00207 #ifdef FAUDES_CHECKED 00208 if(pos<0 || pos >= mVector.size()) { 00209 std::stringstream errstr; 00210 errstr << "index out of range" << std::endl; 00211 throw Exception("vBaseVector::At", errstr.str(), 62); 00212 } 00213 #endif 00214 if(!ElementTry(rElem)) { 00215 std::stringstream errstr; 00216 errstr << "cannot cast element " << std::endl; 00217 throw Exception("vBaseVector::Replace(pos,elem)", errstr.str(), 63); 00218 } 00219 iterator pit=mVector.begin()+pos; 00220 if(pit->mMine) delete pit->pElement; 00221 pit->pElement=rElem.Copy(); 00222 pit->mMine=true; 00223 pit->mFileName=""; 00224 } 00225 00226 // replace (take) 00227 void vBaseVector::Replace(const Position& pos, Type* pElem) { 00228 #ifdef FAUDES_CHECKED 00229 if(pos<0 || pos >= mVector.size()) { 00230 std::stringstream errstr; 00231 errstr << "index out of range" << std::endl; 00232 throw Exception("vBaseVector::At", errstr.str(), 62); 00233 } 00234 #endif 00235 if(!ElementTry(*pElem)) { 00236 std::stringstream errstr; 00237 errstr << "cannot cast element " << std::endl; 00238 throw Exception("vBaseVector::Replace(pos,elem)", errstr.str(), 63); 00239 } 00240 iterator pit=mVector.begin()+pos; 00241 if(pit->mMine) delete pit->pElement; 00242 pit->pElement=pElem; 00243 pit->mMine=false; 00244 pit->mFileName=""; 00245 } 00246 00247 // replace (file) 00248 void vBaseVector::Replace(const Position& pos, const std::string& rFileName) { 00249 #ifdef FAUDES_CHECKED 00250 if(pos<0 || pos >= mVector.size()) { 00251 std::stringstream errstr; 00252 errstr << "index out of range" << std::endl; 00253 throw Exception("vBaseVector::At", errstr.str(), 62); 00254 } 00255 #endif 00256 iterator pit=mVector.begin()+pos; 00257 if(pit->mMine) delete pit->pElement; 00258 pit->pElement = NewElement(); 00259 pit->mMine=true; 00260 pit->pElement->Read(rFileName); 00261 pit->mFileName=rFileName; 00262 } 00263 00264 // erase 00265 void vBaseVector::Erase(const Position& pos) { 00266 #ifdef FAUDES_CHECKED 00267 if(pos<0 || pos >= mVector.size()) { 00268 std::stringstream errstr; 00269 errstr << "index out of range" << std::endl; 00270 throw Exception("vBaseVector::At", errstr.str(), 62); 00271 } 00272 #endif 00273 iterator pit=mVector.begin()+pos; 00274 if(pit->mMine) delete pit->pElement; 00275 mVector.erase(pit); 00276 } 00277 00278 00279 // insert (copy) 00280 void vBaseVector::Insert(const Position& pos, const Type& rElem) { 00281 #ifdef FAUDES_CHECKED 00282 if(pos<0 || pos > mVector.size()) { 00283 std::stringstream errstr; 00284 errstr << "index out of range" << std::endl; 00285 throw Exception("vBaseVector::At", errstr.str(), 62); 00286 } 00287 #endif 00288 if(!ElementTry(rElem)) { 00289 std::stringstream errstr; 00290 errstr << "cannot cast element " << std::endl; 00291 throw Exception("vBaseVector::Insert(pos,elem)", errstr.str(), 63); 00292 } 00293 ElementRecord elem; 00294 elem.pElement = rElem.Copy(); 00295 elem.mMine=true; 00296 elem.mFileName=""; 00297 iterator pit=mVector.begin()+pos; 00298 mVector.insert(pit,elem); 00299 } 00300 00301 // insert (take) 00302 void vBaseVector::Insert(const Position& pos, Type* pElem) { 00303 #ifdef FAUDES_CHECKED 00304 if(pos<0 || pos > mVector.size()) { 00305 std::stringstream errstr; 00306 errstr << "index out of range" << std::endl; 00307 throw Exception("vBaseVector::At", errstr.str(), 62); 00308 } 00309 #endif 00310 if(!ElementTry(*pElem)) { 00311 std::stringstream errstr; 00312 errstr << "cannot cast element " << std::endl; 00313 throw Exception("vBaseVector::Insert(pos,elem)", errstr.str(), 63); 00314 } 00315 ElementRecord elem; 00316 elem.pElement = pElem; 00317 elem.mMine=false; 00318 elem.mFileName=""; 00319 iterator pit=mVector.begin()+pos; 00320 mVector.insert(pit,elem); 00321 } 00322 00323 // insert (file) 00324 void vBaseVector::Insert(const Position& pos, const std::string& rFileName) { 00325 #ifdef FAUDES_CHECKED 00326 if(pos<0 || pos > mVector.size()) { 00327 std::stringstream errstr; 00328 errstr << "index out of range" << std::endl; 00329 throw Exception("vBaseVector::At", errstr.str(), 62); 00330 } 00331 #endif 00332 ElementRecord elem; 00333 elem.pElement =NewElement(); 00334 elem.mMine=true; 00335 elem.pElement->Read(rFileName); 00336 elem.mFileName=rFileName; 00337 iterator pit=mVector.begin()+pos; 00338 mVector.insert(pit,elem); 00339 } 00340 00341 00342 // append (copy) 00343 void vBaseVector::PushBack(const Type& rElem) { 00344 if(!ElementTry(rElem)) { 00345 std::stringstream errstr; 00346 errstr << "cannot cast element " << std::endl; 00347 throw Exception("vBaseVector::PushBack(elem)", errstr.str(), 63); 00348 } 00349 ElementRecord elem; 00350 elem.pElement = rElem.Copy(); 00351 elem.mMine=true; 00352 elem.mFileName=""; 00353 mVector.push_back(elem); 00354 } 00355 00356 // append (take) 00357 void vBaseVector::PushBack(Type* pElem) { 00358 if(!ElementTry(*pElem)) { 00359 std::stringstream errstr; 00360 errstr << "cannot cast element " << std::endl; 00361 throw Exception("vBaseVector::PushBack(elem)", errstr.str(), 63); 00362 } 00363 ElementRecord elem; 00364 elem.pElement = pElem; 00365 elem.mMine=false; 00366 elem.mFileName=""; 00367 mVector.push_back(elem); 00368 } 00369 00370 // append (file) 00371 void vBaseVector::PushBack(const std::string& rFileName) { 00372 ElementRecord elem; 00373 elem.pElement = NewElement(); 00374 elem.mMine=true; 00375 elem.pElement->Read(rFileName); 00376 elem.mFileName=rFileName; 00377 mVector.push_back(elem); 00378 } 00379 00380 00381 // append (copy) 00382 void vBaseVector::Append(const Type& rElem) { 00383 PushBack(rElem); 00384 } 00385 00386 // append (take) 00387 void vBaseVector::Append(Type* pElem) { 00388 PushBack(pElem); 00389 } 00390 00391 // append (file) 00392 void vBaseVector::Append(const std::string& rFileName) { 00393 PushBack(rFileName); 00394 } 00395 00396 00397 // FilenameAt() 00398 const std::string& vBaseVector::FilenameAt(const Position& pos) const { 00399 #ifdef FAUDES_CHECKED 00400 if(pos<0 || pos >= mVector.size()) { 00401 std::stringstream errstr; 00402 errstr << "index out of range" << std::endl; 00403 throw Exception("vBaseVector::FilenameAt", errstr.str(), 62); 00404 } 00405 #endif 00406 return mVector[pos].mFileName; 00407 } 00408 00409 // FilenameAt() 00410 void vBaseVector::FilenameAt(const Position& pos, const std::string& rFileName) { 00411 #ifdef FAUDES_CHECKED 00412 if(pos<0 || pos >= mVector.size()) { 00413 std::stringstream errstr; 00414 errstr << "index out of range" << std::endl; 00415 throw Exception("vBaseVector::FilenameAt", errstr.str(), 62); 00416 } 00417 #endif 00418 mVector[pos].mFileName = rFileName; 00419 } 00420 00421 // take ownership 00422 void vBaseVector::TakeCopies(void) { 00423 iterator pit=mVector.begin(); 00424 for(;pit!=mVector.end();++pit) { 00425 if(pit->mMine) continue; 00426 pit->pElement=pit->pElement->Copy(); 00427 pit->mMine=true; 00428 } 00429 } 00430 00431 // take ownership 00432 void vBaseVector::TakeOwnership(void) { 00433 iterator pit=mVector.begin(); 00434 for(;pit!=mVector.end();++pit) 00435 pit->mMine=true; 00436 } 00437 00438 // DoWrite(tw, label, context) 00439 void vBaseVector::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00440 // figure whether we write individual files 00441 bool ifiles=rTw.FileMode(); 00442 for(Position pos=0; pos<mVector.size() && ifiles; pos++) 00443 if(mVector[pos].mFileName=="") ifiles=false; 00444 // extract base directory 00445 std::string dirname=""; 00446 if(rTw.FileMode()) 00447 dirname = ExtractDirectory(rTw.FileName()); 00448 // have a section 00449 Token btag=XBeginTag(rLabel,"Vector"); 00450 FD_DC("vBaseVector(" << this << ")::DoWrite(..): #" << Size()); 00451 rTw.Write(btag); 00452 // loop entries 00453 for(Position pos=0; pos<mVector.size(); pos++) { 00454 // just stream tokens 00455 if(!ifiles) { 00456 mVector[pos].pElement->Write(rTw,"",pContext); 00457 continue; 00458 } 00459 // write individual files 00460 std::string filename= ExtractFilename(mVector[pos].mFileName); 00461 rTw.WriteString(filename); 00462 mVector[pos].pElement->Write(PrependDirectory(dirname,filename),"",pContext); 00463 } 00464 rTw.WriteEnd(btag.StringValue()); 00465 } 00466 00467 00468 // DoDWrite(tw,rLabel,context) 00469 void vBaseVector::DoDWrite(TokenWriter& rTw,const std::string& rLabel, const Type* pContext) const { 00470 // have a section 00471 Token btag=XBeginTag(rLabel,"Vector"); 00472 FD_DC("vBaseVector(" << this << ")::DoWrite(..): #" << Size()); 00473 rTw.Write(btag); 00474 for(Position pos=0; pos<mVector.size(); pos++) { 00475 mVector[pos].pElement->DWrite(rTw,"",pContext); 00476 } 00477 rTw.WriteEnd(btag.StringValue()); 00478 } 00479 00480 00481 // DoSWrite(tw) 00482 void vBaseVector::DoSWrite(TokenWriter& rTw) const { 00483 FD_DC("vBaseVector(" << this << ")::DoSWrite(..)"); 00484 rTw.WriteComment(" Vector Size: "+ ToStringInteger(Size())); 00485 for(Position pos=0; pos<mVector.size(); pos++) { 00486 rTw.WriteComment(" Vector Entry " + ToStringInteger(pos)); 00487 mVector[pos].pElement->SWrite(rTw); 00488 } 00489 rTw.WriteComment(""); 00490 } 00491 00492 00493 // DoRead(rTr, rLabel, pContext) 00494 void vBaseVector::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 00495 //prepare token 00496 Token token; 00497 //prepare string 00498 std::string filename = ""; 00499 std::string dirname = ""; 00500 std::string path; 00501 // have default section 00502 std::string label=rLabel; 00503 if(label=="") label="Vector"; 00504 Name(label); 00505 rTr.ReadBegin(label); 00506 // fill my entries from token stream 00507 while(!rTr.Eos(label)){ 00508 //peek token 00509 rTr.Peek(token); 00510 // if Token is a String we assume its the name of a file containing a device 00511 if(token.Type()==Token::String) { 00512 //read Token 00513 rTr.Get(token); 00514 // read relative filename 00515 filename = token.StringValue(); 00516 // build up path to base-file 00517 if(rTr.SourceMode()==TokenReader::File) dirname = ExtractDirectory(rTr.FileName()); 00518 //build up path to specified file 00519 path = dirname.append(filename); 00520 //insert device 00521 Insert(mVector.size(),path); 00522 continue; 00523 } 00524 // if its not a file it has to be an entry 00525 else if(token.Type()==Token::Begin) { 00526 // prepare 00527 Type* elemp = NewElement(); 00528 // read entry 00529 elemp->Read(rTr); 00530 // insert device mDevices 00531 Insert(mVector.size(),elemp); 00532 // fix ownership 00533 (--mVector.end())->mMine=true; 00534 continue; 00535 } 00536 // token mismatch 00537 std::stringstream errstr; 00538 errstr << "token mismatch" << std::endl; 00539 throw Exception("vBaseVector::At", errstr.str(), 50); 00540 } 00541 // done 00542 rTr.ReadEnd(label); 00543 } 00544 00545 00546 00547 00548 } // namespace faudes 00549 libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |