OpenASIP 2.2
Loading...
Searching...
No Matches
ObjectState.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file ObjectState.cc
26 *
27 * Implementation of class ObjectState.
28 *
29 * @author Lasse Laasonen 2003 (lasse.laasonen-no.spam-tut.fi)
30 * @note reviewed 8 Jun 2004 by tr, jm, am, ll
31 * @note rating: red
32 */
33
34#include <iostream>
35
36#include "ObjectState.hh"
37#include "Conversion.hh"
38#include "SequenceTools.hh"
39#include "ContainerTools.hh"
40#include "Application.hh"
41
42using std::string;
43
44/**
45 * Constructor.
46 *
47 * @param name Name of the ObjectState.
48 * @param parent Parent of this object. If non-NULL, this object is
49 * added to the parent with addChild().
50 */
51ObjectState::ObjectState(const std::string& name, ObjectState* parent) :
52 name_(name), value_(""), parent_(parent) {
53 if (parent != NULL) {
54 parent->addChild(this);
55 }
56}
57
58/**
59 * Copy constructor.
60 *
61 * Makes a deep copy.
62 *
63 * @param old The ObjectState tree to copy.
64 */
66 name_(old.name_), value_(old.value_), parent_(NULL),
67 attributes_(old.attributes_) {
68
69 for (int i = 0; i < old.childCount(); i++) {
70 ObjectState* newChild = new ObjectState(*old.child(i));
71 addChild(newChild);
72 }
73}
74
75/**
76 * Destructor.
77 *
78 * Deletes all the children as well and removes itself from the list of child
79 * objects of the parent object. That is, the parent object will stay valid.
80 */
82 if (parent_ != NULL) {
84 parent_->children_, this);
85 assert(removed);
86 }
88}
89
90/**
91 * Sets an attribute.
92 *
93 * If there is an attribute called the given name, its value is changed
94 * according to the given value. Otherwise a new attribute is created.
95 *
96 * @param name Name of the attribute.
97 * @param value Value of the attribute.
98 */
99void
101 const std::string& name,
102 const std::string& value) {
103
104 AttributeTable::iterator iter = attributes_.begin();
105 while (iter != attributes_.end()) {
106 if ((*iter).name == name) {
107 (*iter).value = value;
108 return;
109 }
110 iter++;
111 }
112 Attribute newAttribute;
113 newAttribute.name = name;
114 newAttribute.value = value;
115 attributes_.push_back(newAttribute);
116}
117
118
119/**
120 * Sets an attribute.
121 *
122 * If there is an attribute called the given name, its value is changed
123 * according to the given value. Otherwise a new attribute is created.
124 *
125 * @param name Name of the attribute.
126 * @param value Value of the attribute.
127 */
128void
129ObjectState::setAttribute(const std::string& name, int value) {
130 string valueAsString = Conversion::toString(value);
131 setAttribute(name, valueAsString);
132}
133
134
135/**
136 * Sets an attribute.
137 *
138 * If there is an attribute called the given name, its value is changed
139 * according to the given value. Otherwise a new attribute is created.
140 *
141 * @param name Name of the attribute.
142 * @param value Value of the attribute.
143 */
144void
145ObjectState::setAttribute(const std::string& name, unsigned int value) {
146 string valueAsString = Conversion::toString(value);
147 setAttribute(name, valueAsString);
148}
149
150/**
151 * Sets an attribute.
152 *
153 * If there is an attribute called the given name, its value is changed
154 * according to the given value. Otherwise a new attribute is created.
155 *
156 * @param name Name of the attribute.
157 * @param value Value of the attribute.
158 */
159void
160ObjectState::setAttribute(const std::string& name, ULongWord value) {
161 string valueAsString = Conversion::toString(value);
162 setAttribute(name, valueAsString);
163}
164
165
166/**
167 * Sets an attribute.
168 *
169 * If there is an attribute called the given name, its value is changed
170 * according to the given value. Otherwise a new attribute is created.
171 *
172 * @param name Name of the attribute.
173 * @param value Value of the attribute.
174 */
175void
176ObjectState::setAttribute(const std::string& name, double value) {
177 string valueAsString = Conversion::toString(value);
178 setAttribute(name, valueAsString);
179}
180
181
182/**
183 * Sets an attribute.
184 *
185 * If there is an attribute called the given name, its value is changed
186 * according to the given value. Otherwise a new attribute is created.
187 *
188 * @param name Name of the attribute.
189 * @param value Value of the attribute.
190 */
191void
192ObjectState::setAttribute(const std::string& name, bool value) {
193 string valueAsString = Conversion::toString(value);
194 setAttribute(name, valueAsString);
195}
196
197
198/**
199 * Returns true if the ObjectState has an attribute with the given name.
200 *
201 * @param name Name of the attribute.
202 * @return True if the ObjectState has an attribute with the given name.
203 */
204bool
205ObjectState::hasAttribute(const std::string& name) const {
206 AttributeTable::const_iterator iter = attributes_.begin();
207 while (iter != attributes_.end()) {
208 if ((*iter).name == name) {
209 return true;
210 }
211 iter++;
212 }
213 return false;
214}
215
216
217/**
218 * Returns an attribute by the given index.
219 *
220 * The value of index must be greater or equal to 0 and less than the
221 * number of attributes.
222 *
223 * @param index The index of the requested attribute.
224 * @return Attribute by the given index.
225 * @exception OutOfRange If the given index is out of range.
226 */
228ObjectState::attribute(int index) const {
229 if (index < 0 || index >= attributeCount()) {
230 const string procName = "ObjectState::attribute";
231 string errorMsg = commonErrorMessage();
232 errorMsg += "Requested attribute by index '";
233 errorMsg += Conversion::toString(index);
234 errorMsg += "' which is out of range.";
235 throw OutOfRange(__FILE__, __LINE__, procName, errorMsg);
236 } else {
237 return const_cast<Attribute*>(&attributes_[index]);
238 }
239}
240
241/**
242 * Returns the value of the requested attribute.
243 *
244 * @param name Name of the attribute.
245 * @return Value of the requested attribute.
246 * @exception KeyNotFound If no attribute called the given name is found.
247 */
248std::string
249ObjectState::stringAttribute(const std::string& name) const {
250 AttributeTable::const_iterator iter = attributes_.begin();
251 while (iter != attributes_.end()) {
252 if ((*iter).name == name) {
253 return (*iter).value;
254 }
255 iter++;
256 }
257
258 string procName = "ObjectState::stringAttribute";
259 string errorMsg = commonErrorMessage();
260 errorMsg += "Requested attribute by name '";
261 errorMsg += name;
262 errorMsg += "' which doesn't exist.";
263 throw KeyNotFound(__FILE__, __LINE__, procName, errorMsg);
264}
265
266/**
267 * Returns the value of the requested attribute.
268 *
269 * @param name Name of the attribute.
270 * @return Value of the requested attribute.
271 * @exception KeyNotFound If no attribute called the given name is found.
272 * @exception NumberFormatException If the value of the requested attribute
273 * can't be converted to int.
274 */
275int
276ObjectState::intAttribute(const std::string& name) const {
277 string value = stringAttribute(name);
278 return Conversion::toInt(value);
279}
280
281/**
282 * Returns the value of the requested attribute.
283 *
284 * @param name Name of the attribute.
285 * @return Value of the requested attribute.
286 * @exception KeyNotFound If no attribute called the given name is found.
287 * @exception NumberFormatException If the value of the requested attribute
288 * can't be converted to int.
289 */
291ObjectState::uLongAttribute(const std::string& name) const {
292
293 string value = stringAttribute(name);
294 return Conversion::toUnsignedLong(value);
295}
296
297
298/**
299 * Returns the value of the requested attribute.
300 *
301 * @param name Name of the attribute.
302 * @return Value of the requested attribute.
303 * @exception KeyNotFound If no attribute called the given name is found.
304 * @exception NumberFormatException If the value of the requested attribute
305 * can't be converted to unsigned int.
306 */
307unsigned int
308ObjectState::unsignedIntAttribute(const std::string& name) const {
309 string value = stringAttribute(name);
310 return Conversion::toUnsignedInt(value);
311}
312
313/**
314 * Returns the value of the requested attribute.
315 *
316 * @param name Name of the attribute.
317 * @return Value of the requested attribute.
318 * @exception KeyNotFound If no attribute called the given name is found.
319 * @exception NumberFormatException If the value of the requested attribute
320 * can't be converted to double.
321 */
322double
323ObjectState::doubleAttribute(const std::string& name) const {
324 string value = stringAttribute(name);
325 return Conversion::toDouble(value);
326}
327
328/**
329 * Returns the value of the requested attribute.
330 *
331 * @param name Name of the attribute.
332 * @return Value of the requested attribute.
333 * @exception KeyNotFound If no attribute called the given name is found.
334 * @exception TypeMismatch If the value of the requested attribute can't be
335 * converted to bool.
336 */
337bool
338ObjectState::boolAttribute(const std::string& name) const {
339 string value = stringAttribute(name);
340
341 int intValue;
342 try {
344 } catch (const NumberFormatException&) {
345 const string procName = "ObjectState::boolAttribute";
346 throw TypeMismatch(__FILE__, __LINE__, procName);
347 }
348
349 return intValue;
350}
351
352/**
353 * Returns true if there is a child element called the given name.
354 *
355 * @return True if there is a child element called the given name.
356 */
357bool
358ObjectState::hasChild(const std::string& name) const {
359 ChildTable::const_iterator iter = children_.begin();
360 while (iter != children_.end()) {
361 if ((*iter)->name() == name) {
362 return true;
363 }
364 iter++;
365 }
366 return false;
367}
368
369
370/**
371 * Adds a child object.
372 *
373 * @param child ObjectState object to be added as a child.
374 */
375void
377 children_.push_back(child);
378 child->parent_ = this;
379}
380
381/**
382 * Removes the given child object.
383 *
384 * @param child The child object to be removed.
385 * @exception InstanceNotFound If the object does not have the given child
386 * object.
387 */
388void
391 if (removed) {
392 child->parent_ = NULL;
393 } else {
394 const string procName = "ObjectState::removeChild";
395 throw InstanceNotFound(__FILE__, __LINE__, procName);
396 }
397}
398
399/**
400 * Replaces a child with a new child.
401 *
402 * @param old Child to be replaced.
403 * @param newChild Child to be added in the place of the old child.
404 * @exception InvalidData If the new child given already has a parent
405 * object.
406 */
407void
409 if (newChild->parent() != NULL) {
410 const string procName = "ObjectState::replaceChild";
411 throw InvalidData(__FILE__, __LINE__, procName);
412 }
413
414 ChildTable::iterator it = children_.begin();
415 while (it != children_.end()) {
416 if (*it == old) {
417 ObjectState* toBeRemoved = *it;
418 ChildTable::iterator pt = it;
419 pt++;
420 if (pt == children_.end()) {
421 children_.push_back(newChild);
422 } else {
423 children_.insert(pt, newChild);
424 }
425 newChild->parent_ = this;
426 delete toBeRemoved;
427 break;
428 }
429 it++;
430 }
431}
432
433/**
434 * Returns the child of the requested name.
435 *
436 * If there are many children of that name, returns the first of them.
437 *
438 * @param name Name of the child.
439 * @return First child of the requested name.
440 * @exception InstanceNotFound If the requested child is not found.
441 */
443ObjectState::childByName(const std::string& name) const {
444 ChildTable::const_iterator iter = children_.begin();
445 while (iter != children_.end()) {
446 if ((*iter)->name() == name) {
447 return *iter;
448 }
449 iter++;
450 }
451
452 string procName = "ObjectState::childByName";
453 string errorMsg = commonErrorMessage();
454 errorMsg += "Requested child by name '";
455 errorMsg += name;
456 errorMsg += "' which doesn't exist.";
457 throw InstanceNotFound(__FILE__, __LINE__, procName, errorMsg);
458}
459
460/**
461 * Returns a child by the given index.
462 *
463 * The index must be greater or equal to 0 and less than the number of
464 * children.
465 *
466 * @param index The index.
467 * @return Child by the given index.
468 * @exception OutOfRange If the given index is out of range.
469 */
471ObjectState::child(int index) const {
472 if (index < 0 || index >= childCount()) {
473 const string procName = "ObjectState::child";
474 string errorMsg = commonErrorMessage();
475 errorMsg += "Requested child by index '";
476 errorMsg += Conversion::toString(index);
477 errorMsg += "' which is out of range.";
478 throw OutOfRange(__FILE__, __LINE__, procName, errorMsg);
479 } else {
480 return children_[index];
481 }
482}
483
484/**
485 * Inequality comparison operator.
486 *
487 * @param object Object in which this object is compared to.
488 * @return True if objects are inequal, false otherwise.
489 */
490bool
492
493 if (name_ != object.name() ||
494 value_ != object.stringValue() ||
495 children_.size() != static_cast<unsigned int>(object.childCount()) ||
496 static_cast<int>(attributes_.size()) != object.attributeCount()) {
497
498 return true;
499 }
500
501 for (size_t i = 0; i < attributes_.size(); i++) {
502 Attribute attr = attributes_[i];
503 if (!object.hasAttribute(attr.name)) {
504 return true;
505 } else {
506 if (attr.value != object.stringAttribute(attr.name)) {
507 return true;
508 }
509 }
510 }
511
512 for (size_t i = 0; i < children_.size(); i++) {
514 ObjectState& compare = *object.child(i);
515 if (child != compare) {
516 return true;
517 }
518 }
519
520 return false;
521}
522
523/**
524 * Generates a common beginning of error messages.
525 *
526 * @return The generated error message.
527 */
528std::string
530 string errorMsg = "ObjectState ";
531 errorMsg += name();
532 errorMsg += ": ";
533 return errorMsg;
534}
535
536/**
537 * Prints object state structure for debug purposes into the stream.
538 */
539void
541 const ObjectState& state,
542 std::ostream& output,
543 const std::string& identation) {
544
545 using std::cout;
546 using std::endl;
547
548 cout << identation << "Name: "<< state.name() << " ";
549 if (!state.stringValue().empty()) {
550 cout << "Value: " << state.stringValue() << " ";
551 }
552 cout << endl;
553 for (int i = 0; i < state.attributeCount(); i++) {
554 cout << identation << "Attr: " << state.attribute(i)->name << " = "
555 << state.attribute(i)->value << endl;
556 }
557 for (int i = 0; i < state.childCount(); i++) {
558 dumpObjectState(*state.child(i), output, identation + " ");
559 }
560}
561
562
#define assert(condition)
unsigned long ULongWord
Definition BaseType.hh:51
static bool removeValueIfExists(ContainerType &aContainer, const ElementType &aKey)
static double toDouble(const T &source)
static std::string toString(const T &source)
static int toInt(const T &source)
static ULongWord toUnsignedLong(const T &source)
static unsigned int toUnsignedInt(const T &source)
ChildTable children_
The child elements.
bool hasAttribute(const std::string &name) const
bool operator!=(const ObjectState &object)
std::string name_
Name of the element.
Attribute * attribute(int index) const
ObjectState * childByName(const std::string &name) const
double doubleAttribute(const std::string &name) const
void setAttribute(const std::string &name, const std::string &value)
int attributeCount() const
void removeChild(ObjectState *child)
bool hasChild(const std::string &name) const
static void dumpObjectState(const ObjectState &state, std::ostream &output, const std::string &identation="")
ObjectState * child(int index) const
ObjectState(const std::string &name, ObjectState *parent=NULL)
void addChild(ObjectState *child)
int intValue() const
std::string stringAttribute(const std::string &name) const
std::string value_
The value of a leaf element.
ObjectState * parent() const
AttributeTable attributes_
Contains all the attributes of the element.
void replaceChild(ObjectState *old, ObjectState *newChild)
bool boolAttribute(const std::string &name) const
int intAttribute(const std::string &name) const
std::string stringValue() const
unsigned int unsignedIntAttribute(const std::string &name) const
ULongWord uLongAttribute(const std::string &name) const
std::string commonErrorMessage() const
ObjectState * parent_
The parent element.
std::string name() const
int childCount() const
static void deleteAllItems(SequenceType &aSequence)
Struct for describing an attribute of the XML element.
std::string value
Value of the attribute.
std::string name
Name of the attribute.