cfl_basevector.cpp
Go to the documentation of this file.
1 /** @file cfl_basevector.cpp @brief */
2 
3 /* FAU Discrete Event Systems Library (libfaudes)
4 
5  Copyright (C) 2006 Bernd Opitz
6  Copyright (C) 2007 Thomas Moor
7  Exclusive copyright is granted to Klaus Schmidt
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #include "cfl_basevector.h"
24 #include "cfl_nameset.h"
25 
26 namespace faudes {
27 
28 
29 /*
30 ******************************************************************************************
31 ******************************************************************************************
32 ******************************************************************************************
33 
34 Implementation of TBaseVector
35 
36 ******************************************************************************************
37 ******************************************************************************************
38 ******************************************************************************************
39 */
40 
41 // faudes type std
42 FAUDES_TYPE_IMPLEMENTATION(Void,vBaseVector,Type)
43 
44 
45 // vBaseVector()
47  Type()
48 {
49  FD_DC("vBaseVector(" << this << ")::vBaseVector()");
50  // my members
51  mMyName="Vector";
52 }
53 
54 
55 // vBaseVector(filename)
56 vBaseVector::vBaseVector(const std::string& rFileName, const std::string& rLabel) :
57  Type()
58 {
59  FD_DC("vBaseVector(" << this << ")::vBaseVector()");
60  // other members
61  mMyName="Vector";
62  // do read;
63  Read(rFileName,rLabel);
64 }
65 
66 
67 // vBaseVector(rOtherSet)
68 vBaseVector::vBaseVector(const vBaseVector& rOtherVector) :
69  Type(rOtherVector)
70 {
71  FD_DC("vBaseVector(" << this << ")::vBaseVector(rOtherVector " << &rOtherVector << "): copy construct");
72  DoAssign(rOtherVector);
73 }
74 
75 // destructor
77  FD_DC("vBaseVector(" << this << ")::~vBaseVector()");
78  // delete entries
79  for(Position pos=0; pos<mVector.size(); pos++)
80  if(mVector[pos].mMine) delete mVector[pos].pElement;
81  // done
82  FD_DC("vBaseVector(" << this << ")::~vBaseVector(): done");
83 }
84 
85 
86 // element prototype
87 const Type* vBaseVector::Elementp(void) const {
88  static Type proto;
89  return &proto;
90 }
91 
92 // element prototype
93 const Type& vBaseVector::Element(void) const {
94  return *Elementp();
95 }
96 
97 // element factory
99  return Element().New();
100 }
101 
102 // test element type
103 bool vBaseVector::ElementTry(const Type& rElement) const {
104  return Elementp()->Cast(&rElement)!=NULL;
105 }
106 
107 // assignment (here, we know the type to match)
108 void vBaseVector::DoAssign(const vBaseVector& rSourceVector) {
109  FD_DC("vBaseVector(" << this << ")::DoAssign(rOtherVector " << &rSourceVector << ")");
110  // bail out on selfref
111  if(this==&rSourceVector) return;
112  // virtual clear
113  Clear();
114  // allocate
115  mVector.resize(rSourceVector.Size());
116  // copy entries
117  for(Position pos=0; pos<mVector.size(); pos++) {
118  mVector[pos].pElement = rSourceVector.mVector[pos].pElement->Copy();
119  mVector[pos].mMine=true;
120  mVector[pos].mFileName="";
121  }
122  // done
123  FD_DC("vBaseVector(" << this << ")::DoAssign(rOtherVector " << &rSourceVector << "): done");
124 }
125 
126 // clear
127 void vBaseVector::Clear(void) {
128  // delete entries
129  for(Position pos=0; pos<mVector.size(); pos++) {
130  if(mVector[pos].mMine) delete mVector[pos].pElement;
131  }
132  // resize
133  mVector.resize(0);
134 }
135 
136 
137 // Name
138 const std::string& vBaseVector::Name(void) const {
139  return mMyName;
140 }
141 
142 // Name
143 void vBaseVector::Name(const std::string& rName) {
144  mMyName = rName;
145 }
146 
147 // Size()
148 Idx vBaseVector::Size(void) const {
149  return (Idx) mVector.size();
150 }
151 
152 // Size(idx)
154  FD_DC("vBaseVector(" << this << ")::Size(..): from " << mVector.size() << " to " << len);
155  // record
156  Position olen=mVector.size();
157  // delete
158  for(Position pos=len; pos<olen; pos++)
159  if(mVector[pos].mMine) delete mVector[pos].pElement;
160  // allocate
161  mVector.resize(len);
162  // initialize
163  for(Position pos=olen; pos < len; pos++) {
164  mVector[pos].pElement = NewElement();
165  mVector[pos].mMine=true;
166  mVector[pos].mFileName = "";
167  }
168  // done
169  FD_DC("vBaseVector(" << this << ")::Size(..): done");
170 }
171 
172 
173 // Empty()
174 bool vBaseVector::Empty(void) const {
175  return mVector.empty();
176 }
177 
178 
179 // At()
180 const Type& vBaseVector::At(const Position& pos) const {
181 #ifdef FAUDES_CHECKED
182  if(pos >= mVector.size()) {
183  std::stringstream errstr;
184  errstr << "index out of range" << std::endl;
185  throw Exception("vBaseVector::At", errstr.str(), 62);
186  }
187 #endif
188  return *mVector[pos].pElement;
189 }
190 
191 // At()
193 #ifdef FAUDES_CHECKED
194  if(pos >= mVector.size()) {
195  std::stringstream errstr;
196  errstr << "index out of range" << std::endl;
197  throw Exception("vBaseVector::At", errstr.str(), 62);
198  }
199 #endif
200  return *mVector[pos].pElement;
201 }
202 
203 
204 
205 // replace (copy)
206 void vBaseVector::Replace(const Position& pos, const Type& rElem) {
207 #ifdef FAUDES_CHECKED
208  if(pos >= mVector.size()) {
209  std::stringstream errstr;
210  errstr << "index out of range" << std::endl;
211  throw Exception("vBaseVector::At", errstr.str(), 62);
212  }
213 #endif
214  if(!ElementTry(rElem)) {
215  std::stringstream errstr;
216  errstr << "cannot cast element " << std::endl;
217  throw Exception("vBaseVector::Replace(pos,elem)", errstr.str(), 63);
218  }
219  iterator pit=mVector.begin()+pos;
220  if(pit->mMine) delete pit->pElement;
221  pit->pElement=rElem.Copy();
222  pit->mMine=true;
223  pit->mFileName="";
224 }
225 
226 // replace (take)
227 void vBaseVector::Replace(const Position& pos, Type* pElem) {
228 #ifdef FAUDES_CHECKED
229  if(pos >= mVector.size()) {
230  std::stringstream errstr;
231  errstr << "index out of range" << std::endl;
232  throw Exception("vBaseVector::At", errstr.str(), 62);
233  }
234 #endif
235  if(!ElementTry(*pElem)) {
236  std::stringstream errstr;
237  errstr << "cannot cast element " << std::endl;
238  throw Exception("vBaseVector::Replace(pos,elem)", errstr.str(), 63);
239  }
240  iterator pit=mVector.begin()+pos;
241  if(pit->mMine) delete pit->pElement;
242  pit->pElement=pElem;
243  pit->mMine=false;
244  pit->mFileName="";
245 }
246 
247 // replace (file)
248 void vBaseVector::Replace(const Position& pos, const std::string& rFileName) {
249 #ifdef FAUDES_CHECKED
250  if(pos >= mVector.size()) {
251  std::stringstream errstr;
252  errstr << "index out of range" << std::endl;
253  throw Exception("vBaseVector::At", errstr.str(), 62);
254  }
255 #endif
256  iterator pit=mVector.begin()+pos;
257  if(pit->mMine) delete pit->pElement;
258  pit->pElement = NewElement();
259  pit->mMine=true;
260  pit->pElement->Read(rFileName);
261  pit->mFileName=rFileName;
262 }
263 
264 // erase
265 void vBaseVector::Erase(const Position& pos) {
266 #ifdef FAUDES_CHECKED
267  if(pos >= mVector.size()) {
268  std::stringstream errstr;
269  errstr << "index out of range" << std::endl;
270  throw Exception("vBaseVector::At", errstr.str(), 62);
271  }
272 #endif
273  iterator pit=mVector.begin()+pos;
274  if(pit->mMine) delete pit->pElement;
275  mVector.erase(pit);
276 }
277 
278 
279 // insert (copy)
280 void vBaseVector::Insert(const Position& pos, const Type& rElem) {
281 #ifdef FAUDES_CHECKED
282  if(pos > mVector.size()) {
283  std::stringstream errstr;
284  errstr << "index out of range" << std::endl;
285  throw Exception("vBaseVector::At", errstr.str(), 62);
286  }
287 #endif
288  if(!ElementTry(rElem)) {
289  std::stringstream errstr;
290  errstr << "cannot cast element " << std::endl;
291  throw Exception("vBaseVector::Insert(pos,elem)", errstr.str(), 63);
292  }
293  ElementRecord elem;
294  elem.pElement = rElem.Copy();
295  elem.mMine=true;
296  elem.mFileName="";
297  iterator pit=mVector.begin()+pos;
298  mVector.insert(pit,elem);
299 }
300 
301 // insert (take)
302 void vBaseVector::Insert(const Position& pos, Type* pElem) {
303 #ifdef FAUDES_CHECKED
304  if(pos > mVector.size()) {
305  std::stringstream errstr;
306  errstr << "index out of range" << std::endl;
307  throw Exception("vBaseVector::At", errstr.str(), 62);
308  }
309 #endif
310  if(!ElementTry(*pElem)) {
311  std::stringstream errstr;
312  errstr << "cannot cast element " << std::endl;
313  throw Exception("vBaseVector::Insert(pos,elem)", errstr.str(), 63);
314  }
315  ElementRecord elem;
316  elem.pElement = pElem;
317  elem.mMine=false;
318  elem.mFileName="";
319  iterator pit=mVector.begin()+pos;
320  mVector.insert(pit,elem);
321 }
322 
323 // insert (file)
324 void vBaseVector::Insert(const Position& pos, const std::string& rFileName) {
325 #ifdef FAUDES_CHECKED
326  if(pos > mVector.size()) {
327  std::stringstream errstr;
328  errstr << "index out of range" << std::endl;
329  throw Exception("vBaseVector::At", errstr.str(), 62);
330  }
331 #endif
332  ElementRecord elem;
333  elem.pElement =NewElement();
334  elem.mMine=true;
335  elem.pElement->Read(rFileName);
336  elem.mFileName=rFileName;
337  iterator pit=mVector.begin()+pos;
338  mVector.insert(pit,elem);
339 }
340 
341 
342 // append (copy)
343 void vBaseVector::PushBack(const Type& rElem) {
344  if(!ElementTry(rElem)) {
345  std::stringstream errstr;
346  errstr << "cannot cast element " << std::endl;
347  throw Exception("vBaseVector::PushBack(elem)", errstr.str(), 63);
348  }
349  ElementRecord elem;
350  elem.pElement = rElem.Copy();
351  elem.mMine=true;
352  elem.mFileName="";
353  mVector.push_back(elem);
354 }
355 
356 // append (take)
358  if(!ElementTry(*pElem)) {
359  std::stringstream errstr;
360  errstr << "cannot cast element " << std::endl;
361  throw Exception("vBaseVector::PushBack(elem)", errstr.str(), 63);
362  }
363  ElementRecord elem;
364  elem.pElement = pElem;
365  elem.mMine=false;
366  elem.mFileName="";
367  mVector.push_back(elem);
368 }
369 
370 // append (file)
371  void vBaseVector::PushBack(const std::string& rFileName) {
372  ElementRecord elem;
373  elem.pElement = NewElement();
374  elem.mMine=true;
375  elem.pElement->Read(rFileName);
376  elem.mFileName=rFileName;
377  mVector.push_back(elem);
378 }
379 
380 
381 // append (copy)
382 void vBaseVector::Append(const Type& rElem) {
383  PushBack(rElem);
384 }
385 
386 // append (take)
387 void vBaseVector::Append(Type* pElem) {
388  PushBack(pElem);
389 }
390 
391 // append (file)
392 void vBaseVector::Append(const std::string& rFileName) {
393  PushBack(rFileName);
394 }
395 
396 
397 // FilenameAt()
398 const std::string& vBaseVector::FilenameAt(const Position& pos) const {
399 #ifdef FAUDES_CHECKED
400  if(pos >= mVector.size()) {
401  std::stringstream errstr;
402  errstr << "index out of range" << std::endl;
403  throw Exception("vBaseVector::FilenameAt", errstr.str(), 62);
404  }
405 #endif
406  return mVector[pos].mFileName;
407 }
408 
409 // FilenameAt()
410 void vBaseVector::FilenameAt(const Position& pos, const std::string& rFileName) {
411 #ifdef FAUDES_CHECKED
412  if(pos >= mVector.size()) {
413  std::stringstream errstr;
414  errstr << "index out of range" << std::endl;
415  throw Exception("vBaseVector::FilenameAt", errstr.str(), 62);
416  }
417 #endif
418  mVector[pos].mFileName = rFileName;
419 }
420 
421 // take ownership
423  iterator pit=mVector.begin();
424  for(;pit!=mVector.end();++pit) {
425  if(pit->mMine) continue;
426  pit->pElement=pit->pElement->Copy();
427  pit->mMine=true;
428  }
429 }
430 
431 // take ownership
433  iterator pit=mVector.begin();
434  for(;pit!=mVector.end();++pit)
435  pit->mMine=true;
436 }
437 
438 // DoWrite(tw, label, context)
439 void vBaseVector::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
440  // figure whether we write individual files
441  bool ifiles=rTw.FileMode();
442  for(Position pos=0; pos<mVector.size() && ifiles; pos++)
443  if(mVector[pos].mFileName=="") ifiles=false;
444  // extract base directory
445  std::string dirname="";
446  if(rTw.FileMode())
447  dirname = ExtractDirectory(rTw.FileName());
448  // have a section
449  Token btag=XBeginTag(rLabel,"Vector");
450  FD_DC("vBaseVector(" << this << ")::DoWrite(..): #" << Size());
451  rTw.Write(btag);
452  // loop entries
453  for(Position pos=0; pos<mVector.size(); pos++) {
454  // just stream tokens
455  if(!ifiles) {
456  mVector[pos].pElement->Write(rTw,"",pContext);
457  continue;
458  }
459  // write individual files
460  std::string filename= ExtractFilename(mVector[pos].mFileName);
461  rTw.WriteString(filename);
462  mVector[pos].pElement->Write(PrependPath(dirname,filename),"",pContext);
463  }
464  rTw.WriteEnd(btag.StringValue());
465 }
466 
467 
468 // DoDWrite(tw,rLabel,context)
469 void vBaseVector::DoDWrite(TokenWriter& rTw,const std::string& rLabel, const Type* pContext) const {
470  // have a section
471  Token btag=XBeginTag(rLabel,"Vector");
472  FD_DC("vBaseVector(" << this << ")::DoWrite(..): #" << Size());
473  rTw.Write(btag);
474  for(Position pos=0; pos<mVector.size(); pos++) {
475  mVector[pos].pElement->DWrite(rTw,"",pContext);
476  }
477  rTw.WriteEnd(btag.StringValue());
478 }
479 
480 
481 // DoSWrite(tw)
483  FD_DC("vBaseVector(" << this << ")::DoSWrite(..)");
484  rTw.WriteComment(" Vector Size: "+ ToStringInteger(Size()));
485  for(Position pos=0; pos<mVector.size(); pos++) {
486  rTw.WriteComment(" Vector Entry " + ToStringInteger(pos));
487  mVector[pos].pElement->SWrite(rTw);
488  }
489  rTw.WriteComment("");
490 }
491 
492 
493 // DoRead(rTr, rLabel, pContext)
494 void vBaseVector::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
495  //prepare token
496  Token token;
497  //prepare string
498  std::string filename = "";
499  std::string dirname = "";
500  std::string path;
501  // have default section
502  std::string label=rLabel;
503  if(label=="") label="Vector";
504  Name(label);
505  rTr.ReadBegin(label);
506  // fill my entries from token stream
507  while(!rTr.Eos(label)){
508  //peek token
509  rTr.Peek(token);
510  // if Token is a String we assume its the name of a file containing a device
511  if(token.Type()==Token::String) {
512  //read Token
513  rTr.Get(token);
514  // read relative filename
515  filename = token.StringValue();
516  // build up path to base-file
517  if(rTr.SourceMode()==TokenReader::File) dirname = ExtractDirectory(rTr.FileName());
518  //build up path to specified file
519  path = dirname.append(filename);
520  //insert device
521  Insert(mVector.size(),path);
522  continue;
523  }
524  // if its not a file it has to be an entry
525  else if(token.Type()==Token::Begin) {
526  // prepare
527  Type* elemp = NewElement();
528  // read entry
529  elemp->Read(rTr);
530  // insert device mDevices
531  Insert(mVector.size(),elemp);
532  // fix ownership
533  (--mVector.end())->mMine=true;
534  continue;
535  }
536  // token mismatch
537  std::stringstream errstr;
538  errstr << "token mismatch" << std::endl;
539  throw Exception("vBaseVector::At", errstr.str(), 50);
540  }
541  // done
542  rTr.ReadEnd(label);
543 }
544 
545 
546 
547 
548 } // namespace faudes
549 
Class TBaseVector.
#define FD_DC(message)
Debug: optional report on container operations.
Classes NameSet, TaNameSet.
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
faudes type implementation macros, overall
Definition: cfl_types.h:946
Faudes exception class.
A TokenReader reads sequential tokens from a file or string.
bool Eos(const std::string &rLabel)
Peek a token and check whether it ends the specified section.
void ReadEnd(const std::string &rLabel)
Close the current section by matching the previous ReadBegin().
void ReadBegin(const std::string &rLabel)
Open a section by specified label.
bool Get(Token &token)
Get next token.
bool Peek(Token &token)
Peek next token.
std::string FileName(void) const
Access the filename.
Mode SourceMode(void) const
Access stream mode.
A TokenWriter writes sequential tokens to a file, a string or stdout.
std::string FileName(void) const
Get the filename.
void WriteComment(const std::string &rComment)
Write comment in faudes format.
void Write(Token &rToken)
Write next token.
void WriteString(const std::string &rString)
Write string.
bool FileMode(void) const
Test for file mode (incl.
void WriteEnd(const std::string &rLabel)
Write end label.
Tokens model atomic data for stream IO.
Definition: cfl_token.h:54
const std::string & StringValue(void) const
Get string value of a name token.
Definition: cfl_token.cpp:178
@ Begin
<label> (begin of section)
Definition: cfl_token.h:84
@ String
any string, space separated or quoted, must start with a letter
Definition: cfl_token.h:86
TokenType Type(void) const
Get token Type.
Definition: cfl_token.cpp:199
Base class of all libFAUDES objects that participate in the run-time interface.
Definition: cfl_types.h:239
virtual Token XBeginTag(const std::string &rLabel="", const std::string &rFallbackLabel="") const
Definition: cfl_types.cpp:315
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
Read configuration data from file with label specified.
Definition: cfl_types.cpp:261
virtual Type * New(void) const
Construct on heap.
Definition: cfl_types.cpp:54
virtual Type * Copy(void) const
Construct on heap.
Definition: cfl_types.cpp:60
virtual const Type * Cast(const Type *pOther) const
Cast other object to this type.
Definition: cfl_types.cpp:66
Internal entry data type.
Vector bass class.
virtual void DoSWrite(TokenWriter &rTw) const
Token output, see Type::SWrite for public wrappers.
void FilenameAt(const Position &pos, const std::string &rFileName)
Specify a filename.
virtual ~vBaseVector(void)
Virtual destructor.
virtual Type * NewElement(void)
Factory method for vector entries.
size_t Position
convenience typedef for positions (must be unsigned)
virtual const Type & At(const Position &pos) const
Access element.
bool Empty(void) const
Check if the vBaseVector ist Empty.
virtual const Type & Element(void) const
Prototype for vector entries.
virtual void Insert(const Position &pos, const Type &rElem)
Insert specified entry.
void TakeOwnership(void)
Take ownership of all entries.
virtual const Type * Elementp(void) const
Prototype for vector entries.
virtual bool ElementTry(const Type &rElement) const
Test whether the specified element is acceptebla for this vector.
std::string mMyName
Name of TBaseVector.
virtual void Erase(const Position &pos)
Erase entry by position.
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Token output, see Type::Write for public wrappers.
vBaseVector(void)
Constructor.
virtual void Append(const Type &rElem)
Append specified entry.
virtual void DoDWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Token output, debugging see Type::DWrite for public wrappers.
void TakeCopies(void)
Take local copies of all entries.
virtual void PushBack(const Type &rElem)
Append specified entry.
virtual void Replace(const Position &pos, const Type &rElem)
Replace specified entry.
Idx Size(void) const
Get size of vector.
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
Token input, see Type::Read for public wrappers.
const std::string & Name(void) const
Return name of vBaseVector.
void DoAssign(const vBaseVector &rSourceVector)
Assignment method
std::vector< ElementRecord >::iterator iterator
convenience typedef
virtual void Clear(void)
Clear all vector.
std::vector< ElementRecord > mVector
STL vector of element.
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
std::string ExtractDirectory(const std::string &rFullPath)
Extract directory from (full) path; i.e., remove the last separator and anything thereafer.
Definition: cfl_utils.cpp:256
std::string PrependPath(const std::string &rLeft, const std::string &rRight)
Prepend one path before another.
Definition: cfl_utils.cpp:303
std::string ExtractFilename(const std::string &rFullPath)
Extract file name from full path.
Definition: cfl_utils.cpp:265
std::string ToStringInteger(Int number)
integer to string
Definition: cfl_utils.cpp:43

libFAUDES 2.32f --- 2024.12.22 --- c++ api documentaion by doxygen