torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Root.cpp
Go to the documentation of this file.
1 // Torc - Copyright 2011-2013 University of Southern California. All Rights Reserved.
2 // $HeadURL$
3 // $Id$
4 
5 // This program is free software: you can redistribute it and/or modify it under the terms of the
6 // GNU General Public License as published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11 // the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program. If
14 // not, see <http://www.gnu.org/licenses/>.
15 
16 #ifndef HAVE_CONFIG_H
17 #include "torc/generic/config.h"
18 #endif
19 
20 #include <algorithm>
21 #include <fstream>
22 
23 #ifdef GENOM_SERIALIZATION
24 #include <boost/archive/binary_iarchive.hpp>
25 #include <boost/archive/binary_oarchive.hpp>
26 #include <boost/serialization/base_object.hpp>
27 #include <boost/serialization/list.hpp>
28 #include <boost/serialization/shared_ptr.hpp>
29 #include <boost/serialization/string.hpp>
30 #endif //GENOM_SERIALIZATION
31 #include "torc/generic/Log.hpp"
32 #include "torc/generic/Root.hpp"
33 #include "torc/generic/Library.hpp"
34 #include "torc/generic/Design.hpp"
35 
36 namespace torc {
37 namespace generic {
38 
39 /**
40  * Add a library to the list of libraries. If an empty pointer is supplied, it returns without
41  * doing anything.
42  *
43  * @param[in] inLibrary A pointer to a library object.
44  *
45  * @exception Error Library could not be added. because Library name is empty
46  * @exception Error Library could not be added. because Library name is already exists
47  */
48 void Root::addLibrary(const LibrarySharedPtr& inLibrary) throw (Error) {
49  if(!inLibrary) {
50  return;
51  }
52  std::string name = inLibrary->getName();
53  if(name.empty()) {
54  Error e(eMessageIdErrorEmptyItemName, __FUNCTION__, __FILE__, __LINE__);
55  e.saveContextData("Library name", name);
56  throw e;
57  }
58 #ifdef GENOM_SERIALIZATION
59  std::list< std::string >::iterator it = std::find(mDumpedLibraries.begin(),
60  mDumpedLibraries.end(), name);
61  if(it != mDumpedLibraries.end()) {
62  Error e(eMessageIdErrorItemAlreadyExists, __FUNCTION__, __FILE__, __LINE__ );
63  e.saveContextData("Library name", name);
64  throw e;
65  }
66 #endif //GENOM_SERIALIZATION
67  if(false == mLibraries.set(name, inLibrary)) {
68  Error e(eMessageIdErrorItemAlreadyExists, __FUNCTION__, __FILE__, __LINE__);
69  e.saveContextData("Library name", name);
70  throw e;
71  }
72  inLibrary->setParent(getSharedThis());
73  return;
74 }
75 
76 /**
77  * Remove the specified library from the list of libraries. If an empty pointer is passed, it
78  * returns without doing anything
79  *
80  * @param inName Name of the object to be delete
81  *
82  * @exception Error Empty Library name
83  * @exception Error Library not preset in collection
84  */
85 void Root::removeLibrary(const std::string& inName) throw (Error) {
86  if(inName.empty()) {
87  Error e(eMessageIdErrorEmptyItemName, __FUNCTION__, __FILE__, __LINE__);
88  e.saveContextData("Library name", inName);
89  throw e;
90  }
91 #ifdef GENOM_SERIALIZATION
92  std::list< std::string >::iterator it = std::find(mDumpedLibraries.begin(),
93  mDumpedLibraries.end(), inName);
94  if(it == mDumpedLibraries.end()) {
95  Error e(eMessageIdErrorItemNotFound, __FUNCTION__, __FILE__, __LINE__);
96  e.saveContextData("Library name", inName);
97  throw e;
98  } else {
99  mDumpedLibraries.erase(it);
100  }
101 #endif //GENOM_SERIALIZATION
102  if(false == mLibraries.remove(inName)) {
103  Error e(eMessageIdErrorItemNotFound, __FUNCTION__, __FILE__, __LINE__);
104  e.saveContextData("Library name", inName);
105  throw e;
106  }
107  return;
108 }
109 
110 /**
111  * Get the list of libraries.
112  *
113  * @param[out] outLibraries List of libraries
114  */
115 void Root::getLibraries(std::vector<LibrarySharedPtr>& outLibraries) {
116 #ifdef GENOM_SERIALIZATION
117  restoreAllLibraries();
118 #endif //GENOM_SERIALIZATION
119  mLibraries.getValues(outLibraries);
120 }
121 
122 /**
123  * Find a library by name, in the list of libraries.
124  *
125  * @param[in] inName String inSource specifying the name of the library.
126  *
127  * @return A pointer to the libary if found, an empty pointer otherwise.
128  */
130  LibrarySharedPtr library;
131  mLibraries.get(inName, library);
132 #ifdef GENOM_SERIALIZATION
133  if(!library && !mDumpedLibraries.empty()) {
134  library = restoreSingleLibrary(inName);
135  }
136 #endif //GENOM_SERIALIZATION
137  return library;
138 }
139 
140 /**
141  * Add a design to the list of designs. If an empty pointer is supplied, it returns without doing anything.
142  */
143 void Root::addDesign(const DesignSharedPtr& inDesign) throw (Error) {
144  if(!inDesign) {
145  return;
146  }
147  std::string name = inDesign->getName();
148  if(name.empty()) {
149  Error e(eMessageIdErrorEmptyItemName, __FUNCTION__, __FILE__, __LINE__);
150  e.saveContextData("Design name", name);
151  throw e;
152  }
153  if(false == mDesignSymTab.set(name, inDesign)) {
154  Error e(eMessageIdErrorItemAlreadyExists, __FUNCTION__, __FILE__, __LINE__);
155  e.saveContextData("Design name", name);
156  throw e;
157  }
158  inDesign->setParent(getSharedThis());
159  return;
160 }
161 
162 /**
163  * Remove the specified Design from the list of libraries.
164  * If an empty pointer is passed, it returns without doing anything
165  */
166 void Root::removeDesign(const std::string& inName) throw (Error) {
167  if(inName.empty()) {
168  Error e(eMessageIdErrorEmptyItemName, __FUNCTION__, __FILE__, __LINE__);
169  e.saveContextData("Design name", inName);
170  throw e;
171  }
172  if(false == mDesignSymTab.remove(inName)) {
173  Error e(eMessageIdErrorItemNotFound, __FUNCTION__, __FILE__, __LINE__);
174  e.saveContextData("Design name", inName);
175  throw e;
176  }
177  return;
178 }
179 
180 /**
181  * Get the list of designs.
182  *
183  * @param[out] outDesigns List of libraries
184  */
185 void Root::getDesigns(std::vector<DesignSharedPtr>& outDesigns) {
186  mDesignSymTab.getValues(outDesigns);
187 }
188 
189 /**
190  * Find a Design by name, in the list of libraries.
191  *
192  * @param[in] inName String inSource specifying the name of the Design.
193  *
194  * @return A pointer to the design if found, an empty pointer otherwise.
195  */
197  DesignSharedPtr design;
198  mDesignSymTab.get(inName, design);
199  return design;
200 }
201 
202 /**
203  * Create a root
204  *
205  * @param[in] inName Name of the root to be created.
206  * @param[in] inEdifLevel Edif level.
207  * @param[in] inOriginalName Original name of the root [optional]
208  *
209  * @return Pointer to created root.
210  */
212  const std::string& inOriginalName) throw (Error) {
213  try {
214  RootSharedPtr newRoot;
215  create(newRoot);
216  newRoot->setName(inName);
217  newRoot->setLevel(inEdifLevel);
218  newRoot->setOriginalName(inOriginalName);
219  return newRoot;
220  } catch(Error& e) {
221  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
222  throw;
223  }
224 }
225 
226 void Root::accept(BaseVisitor& inoutVisitor) throw (Error) {
227  try {
228  runVisitor(*this, inoutVisitor);
229  } catch(Error& e) {
230  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__);
231  throw;
232  }
233 }
234 
235 /**
236  * Set the version of EDIF being used. This should be 2 0 0 for the current EOM version.
237  *
238  * @param[in] inSource An object of type EdifVersion.
239  */
240 void Root::setVersion(const EdifVersion& inSource) {
241  mVersion = inSource;
242 }
243 
244 /**
245  * Set the EDIF level.
246  *
247  * @note Current parser supports LEVEL_1 edif only.
248  *
249  * @param[in] inSource EdifLevel object
250  */
251 void Root::setLevel(const EdifLevel& inSource) {
252  mLevel = inSource;
253 }
254 
255 #ifdef GENOM_SERIALIZATION
256 
257 void Root::setDumpRestoreData(const DumpRestoreData& inDumpRestoreData) {
258  mDumpRestoreData = inDumpRestoreData;
259 }
260 
261 void Root::handleNewDumpRestoreData(const DumpRestoreData& inDumpRestoreData) throw(Error) {
262  mDumpRestoreData = inDumpRestoreData;
263  if(mDumpRestoreData.getRestoreAllComponents()) {
264  try {
265  restoreAllLibraries();
266  } catch(Error& e) {
267  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__ );
268  throw;
269  }
270  }
271 }
272 
273 #endif //GENOM_SERIALIZATION
275  UserDataContainer(), StatusContainer(), mLevel(), mLibraries(), mDesignSymTab(), mVersion()
276 #ifdef GENOM_SERIALIZATION
277 , mDumpRestoreData(), mDumpedLibraries()
278 #endif //GENOM_SERIALIZATION
279 {}
280 
281 Root::~Root() throw () {
282  log("Root destroyed\n");
283 }
284 
285 #ifdef GENOM_SERIALIZATION
286 template <class Archive> void Root::load(Archive& ar, unsigned int) {
287  ar & boost::serialization::base_object<Commentable>(*this);
288  ar & boost::serialization::base_object<Nameable>(*this);
289  ar & boost::serialization::base_object<Renamable>(*this);
290  ar & boost::serialization::base_object<Visitable>(*this);
291  ar & boost::serialization::base_object<SelfReferencing<Root> >(*this);
292  ar & mLevel;
293  ar & mVersion;
294  //ar & mDumpRestoreData;
295  ar & mDumpedLibraries;
296  //We do not retrieve libraries now
297  //We retrieve when required
298 }
299 
300 template <class Archive> void Root::save(Archive& ar, unsigned int) const {
301  typedef std::vector< LibrarySharedPtr > Libs;
302  ar & boost::serialization::base_object<Commentable>(*this);
303  ar & boost::serialization::base_object<Nameable>(*this);
304  ar & boost::serialization::base_object<Renamable>(*this);
305  ar & boost::serialization::base_object<Visitable>(*this);
306  ar & boost::serialization::base_object<SelfReferencing<Root> >(*this);
307  ar & mLevel;
308  ar & mVersion;
309  //ar & mDumpRestoreData;
310  Libs libs;
311  mLibraries.getValues(libs);
312  Libs::iterator lib = libs.begin();
313  Libs::iterator end = libs.end();
314  for(; lib != end; ++lib) {
315  log("HERE\n");
316  try {
317  dump(*lib);
318  } catch(Error &e) {
319  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__ );
320  throw;
321  }
322  mDumpedLibraries.push_back((*lib)->getName());
323  }
324  ar & mDumpedLibraries; //Dump list of lib names for this root
325  mDumpedLibraries.clear();//We clear this list now, since
326  //the libs are still in memory
327  //Common sense dictates that we remove the dumped libs from root
328  //.. however, they may have been instantiated else where.
329  //So we have to keep them in memory and connected to this root
330  log("Root dumped");
331 }
332 
333 LibrarySharedPtr Root::restoreSingleLibrary(const std::string& inName) throw(Error) {
334  LibrarySharedPtr library;
335  std::list< std::string >::iterator lib = find(mDumpedLibraries.begin(),
336  mDumpedLibraries.end(), inName);
337  if(lib == mDumpedLibraries.end()) {
338  return library;
339  }try {
340  library = restore(*lib, getSharedThis());
341  if(library) {
342  mDumpedLibraries.erase(lib);
343  addLibrary(library);
344  }
345  } catch(Error& e) {
346  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__ );
347  throw;
348  }
349  return library;
350 }
351 
352 void Root::restoreAllLibraries() throw(Error) {
353  try {
354  std::vector<std::string> libs;
355  libs.insert(libs.end(), mDumpedLibraries.begin(), mDumpedLibraries.end());
356  for(std::vector<std::string>::iterator lib = libs.begin(); lib != libs.end(); ++lib) {
357  try {
358  restoreSingleLibrary(*lib);
359  } catch(Error& e) {
360  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__ );
361  throw;
362  }
363  }
364  } catch(Error& e) {
365  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__ );
366  throw;
367  }
368 }
369 
370 //TO SATISFY THE LINKER
371 template void Root::load<boost::archive::binary_iarchive>(boost::archive::binary_iarchive& ar,
372  const unsigned int);
373 
374 template void Root::save<boost::archive::binary_oarchive>(boost::archive::binary_oarchive& ar,
375  const unsigned int) const;
376 
377 void dump(const RootSharedPtr& inRoot) throw(Error) {
378  if(!inRoot) {
379  //TBD::ERROR
380  }
381  try {
382  dump(inRoot, inRoot->getDumpRestoreData());
383  } catch(Error& e) {
384  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__ );
385  throw;
386  }
387 }
388 
389 void dump(const RootSharedPtr& inRoot, const DumpRestoreData& inData ) throw(Error) {
390  if(!inRoot) {
391  //TBD::ERROR
392  }
393  if(inRoot->getName().empty()) {
394  //TBD::ERROR
395  }
396  if(inData.getDumpPath().empty()) {
397  //TBD::ERROR
398  }
399  inRoot->setDumpRestoreData(inData);
400  std::string fileName = inData.getDumpPath() + "/";
401  fileName += inRoot->getName() + ".root";
402  std::ofstream dout(fileName.c_str(), std::ios::out | std::ios::binary);
403  if(!dout) {
404  //TBD::ERROR
405  }
406  boost::archive::binary_oarchive rootAr(dout);
407  rootAr & inRoot;
408 }
409 
410 RootSharedPtr restore(const std::string& inName, const DumpRestoreData& inData) throw(Error) {
411  RootSharedPtr root;
412  if(inName.empty()) {
413  //TBD::ERROR
414  }
415  if(inData.getDumpPath().empty()) {
416  //TBD::ERROR
417  }
418  std::string fileName = inData.getDumpPath() + "/";
419  fileName += inName + ".root";
420  std::ifstream din(fileName.c_str(), std::ios::out | std::ios::binary);
421  if(!din) {
422  //TBD::ERROR
423  }
424  boost::archive::binary_iarchive rootAr(din);
425  rootAr & root;
426  if(root) {
427  try {
428  root->handleNewDumpRestoreData(inData);
429  } catch(Error& e) {
430  e.setCurrentLocation(__FUNCTION__, __FILE__, __LINE__ );
431  throw;
432  }
433  }
434  return root;
435 }
436 #endif //GENOM_SERIALIZATION
437 } // namespace generic
438 } // namespace torc
void getValues(std::vector< ValueType > &outValues) const
Definition: SymTab.hpp:158
void log(const char *fmt,...)
Definition: Log.cpp:89
virtual void getDesigns(std::vector< DesignSharedPtr > &outDesigns)
Definition: Root.cpp:185
EdifVersion mVersion
Definition: Root.hpp:330
void setVersion(const EdifVersion &inSource)
Definition: Root.cpp:240
SymTab< std::string, LibrarySharedPtr > mLibraries
Definition: Root.hpp:328
Represents all classes that can hold user comments.
Definition: Commentable.hpp:36
Represents class that can hold userData.
void runVisitor(_Tp &inoutVisited, BaseVisitor &inoutVisitor)
Definition: VisitorType.hpp:78
std::string string
boost::shared_ptr< Design > DesignSharedPtr
virtual void removeDesign(const std::string &inName)
Definition: Root.cpp:166
The Error object thrown by different methods of EdifOM.
Definition: Error.hpp:41
virtual RootSharedPtr newRootPtr(const std::string &inName, const EdifLevel &inEdifLevel=eEdifLevel0, const std::string &inOriginalName=std::string())
Definition: Root.cpp:211
boost::shared_ptr< Library > LibrarySharedPtr
A base class for Visitor.
Definition: VisitorType.hpp:31
bool get(const KeyType &inKey, ValueType &outValue) const
Definition: SymTab.hpp:121
EdifLevel mLevel
Definition: Root.hpp:327
void saveContextData(const std::string &inName, const boost::any &inSource)
Definition: Error.cpp:79
Root of the EDIF Object Model.
Definition: Root.hpp:66
virtual void getLibraries(std::vector< LibrarySharedPtr > &outLibraries)
Definition: Root.cpp:115
virtual void addLibrary(const LibrarySharedPtr &inLibrary)
Definition: Root.cpp:48
virtual LibrarySharedPtr findLibrary(const std::string &inName)
Definition: Root.cpp:129
An object that has a name.
Definition: Nameable.hpp:34
virtual ~Root()
Definition: Root.cpp:281
virtual void removeLibrary(const std::string &inName)
Definition: Root.cpp:85
Represents objects that can be renamed.
virtual void addDesign(const DesignSharedPtr &inDesign)
Definition: Root.cpp:143
Represents objects that have status.
virtual DesignSharedPtr findDesign(const std::string &inName)
Definition: Root.cpp:196
void setLevel(const EdifLevel &inSource)
Definition: Root.cpp:251
virtual void accept(BaseVisitor &inoutVisitor)
Definition: Root.cpp:226
boost::shared_ptr< Root > RootSharedPtr
SymTab< std::string, DesignSharedPtr > mDesignSymTab
Definition: Root.hpp:329
An object that receives an inoutVisitor.
Definition: Visitable.hpp:38
void setCurrentLocation(const std::string &inFunction, const std::string &inFile, uint32_t inLine)
Definition: Error.cpp:73