cfl_basevector.cpp

Go 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