Project

General

Profile

Statistics
| Branch: | Revision:

root / src / nedxml / nedelement.h @ 79bb12dc

History | View | Annotate | Download (11.8 KB)

1 01873262 Georg Kunz
//==========================================================================
2
// nedelement.h  -
3
//
4
//                     OMNeT++/OMNEST
5
//            Discrete System Simulation in C++
6
//
7
// Contents:
8
//   class NEDElement
9
//
10
//==========================================================================
11
12
/*--------------------------------------------------------------*
13
  Copyright (C) 2002-2008 Andras Varga
14
  Copyright (C) 2006-2008 OpenSim Ltd.
15

16
  This file is distributed WITHOUT ANY WARRANTY. See the file
17
  `license' for details on this and other legal matters.
18
*--------------------------------------------------------------*/
19
20
#ifndef __NEDELEMENT_H
21
#define __NEDELEMENT_H
22
23
#ifdef _MSC_VER
24
// disable 4996: VC8.0 warnings on Unix syscalls
25
#pragma warning(disable: 4996)
26
#endif
27
28
#include <string>
29
#include "nedxmldefs.h"
30
31
NAMESPACE_BEGIN
32
33
34
/**
35
 * Empty. Subclass from this if you want to attach extra data to NEDElement objects.
36
 *
37
 * @ingroup Data
38
 */
39
class NEDXML_API NEDElementUserData
40
{
41
  public:
42
    /** Constructor */
43
    NEDElementUserData() {}
44
45
    /** Destructor */
46
    virtual ~NEDElementUserData() {}
47
};
48
49
50
/**
51
 * Stores a line:col..line:col region in a source file. Used for mapping
52
 * NEDElements back to the source code.
53
 *
54
 * @ingroup Data
55
 */
56
struct NEDSourceRegion
57
{
58
    NEDSourceRegion() {startLine=startColumn=endLine=endColumn=0;}
59
    int startLine;
60
    int startColumn;
61
    int endLine;
62
    int endColumn;
63
};
64
65
/**
66
 * Base class for objects in a NED object tree, the XML-based
67
 * in-memory representation for NED files. An instance of a NEDElement
68
 * subclass represent an XML element.
69
 * NEDElement provides a DOM-like, generic access to the tree;
70
 * subclasses additionally provide a typed interface.
71
 *
72
 * @ingroup Data
73
 */
74
class NEDXML_API NEDElement
75
{
76
  private:
77
    long id;
78
    std::string srcloc;
79
    NEDSourceRegion srcregion;
80
    NEDElement *parent;
81
    NEDElement *firstchild;
82
    NEDElement *lastchild;
83
    NEDElement *prevsibling;
84
    NEDElement *nextsibling;
85
    NEDElementUserData *userdata;
86
87
    static long lastid;
88
    static long numcreated;
89
    static long numexisting;
90
91
  protected:
92
    static bool stringToBool(const char *s);
93
    static const char *boolToString(bool b);
94
    static int stringToEnum(const char *s, const char *vals[], int nums[], int n);
95
    static const char *enumToString(int b, const char *vals[], int nums[], int n);
96
    static void validateEnum(int b, const char *vals[], int nums[], int n);
97
98
  public:
99
    /** @name Constructor, destructor */
100
    //@{
101
102
    /**
103
     * Constructor
104
     */
105
    NEDElement();
106
107
    /**
108
     * Constructor. Takes parent element.
109
     */
110
    NEDElement(NEDElement *parent);
111
112
    /**
113
     * Destructor. Destroys children too.
114
     */
115
    virtual ~NEDElement();
116
117
    /**
118
     * Creates and returns a duplicate of the element. Child elements
119
     * are not copied.
120
     */
121
    virtual NEDElement *dup() const = 0;
122
123
    /**
124
     * Recursive version of dup(): duplicates the whole subtree.
125
     */
126
    virtual NEDElement *dupTree() const;
127
    //@}
128
129
    /** @name Common properties */
130
    //@{
131
132
    /**
133
     * Overridden in subclasses to return the name of the XML element the class
134
     * represents.
135
     */
136
    virtual const char *getTagName() const = 0;
137
138
    /**
139
     * Overridden in subclasses to return the numeric code (NED_xxx) of the
140
     * XML element the class represents.
141
     */
142
    virtual int getTagCode() const = 0;
143
144
    /**
145
     * Returns a unique id, originally set by the constructor.
146
     */
147
    virtual long getId() const;
148
149
    /**
150
     * The unique id assigned by the constructor can be overwritten here.
151
     */
152
    virtual void setId(long id);
153
154
    /**
155
     * Returns a string containing a file/line position showing where this
156
     * element originally came from.
157
     */
158
    virtual const char *getSourceLocation() const;
159
160
    /**
161
     * Sets location string (a string containing a file/line position showing
162
     * where this element originally came from). Called by the (NED/XML) parser.
163
     */
164
    virtual void setSourceLocation(const char *loc);
165
166
    /**
167
     * Returns the source region, containing a line:col region in the source file
168
     * that corresponds to this element.
169
     */
170
    virtual const NEDSourceRegion& getSourceRegion() const;
171
172
    /**
173
     * Sets source region, containing a line:col region in the source file
174
     * that corresponds to this element. Called by the (NED/XML) parser.
175
     */
176
    virtual void setSourceRegion(const NEDSourceRegion& region);
177
    //@}
178
179
    /** @name Generic access to attributes (Methods have to be redefined in subclasses!) */
180
    //@{
181
182
    /**
183
     * Sets every attribute to its default value (as returned by getAttributeDefault()).
184
     * Attributes without a default value are not affected.
185
     *
186
     * This method is called from the constructors of derived classes.
187
     */
188
    virtual void applyDefaults();
189
190
    /**
191
     * Pure virtual method, it should be redefined in subclasses to return
192
     * the number of attributes defined in the DTD.
193
     */
194
    virtual int getNumAttributes() const = 0;
195
196
    /**
197
     * Pure virtual method, it should be redefined in subclasses to return
198
     * the name of the kth attribute as defined in the DTD.
199
     *
200
     * It should return NULL if k is out of range (i.e. negative or greater than
201
     * getNumAttributes()).
202
     */
203
    virtual const char *getAttributeName(int k) const = 0;
204
205
    /**
206
     * Returns the index of the given attribute. It returns -1 if the attribute
207
     * is not found. Relies on getNumAttributes() and getAttributeName().
208
     */
209
    virtual int lookupAttribute(const char *attr) const;
210
211
    /**
212
     * Pure virtual method, it should be redefined in subclasses to return
213
     * the value of the kth attribute (i.e. the attribute with the name
214
     * getAttributeName(k)).
215
     *
216
     * It should return NULL if k is out of range (i.e. negative or greater than
217
     * getNumAttributes()).
218
     */
219
    virtual const char *getAttribute(int k) const = 0;
220
221
    /**
222
     * Returns the value of the attribute with the given name.
223
     * Relies on lookupAttribute() and getAttribute().
224
     *
225
     * It returns NULL if the given attribute is not found.
226
     */
227
    virtual const char *getAttribute(const char *attr) const;
228
229
    /**
230
     * Pure virtual method, it should be redefined in subclasses to set
231
     * the value of the kth attribute (i.e. the attribute with the name
232
     * getAttributeName(k)).
233
     *
234
     * If k is out of range (i.e. negative or greater than getNumAttributes()),
235
     * the call should be ignored.
236
     */
237
    virtual void setAttribute(int k, const char *value) = 0;
238
239
    /**
240
     * Sets the value of the attribute with the given name.
241
     * Relies on lookupAttribute() and setAttribute().
242
     *
243
     * If the given attribute is not found, the call has no effect.
244
     */
245
    virtual void setAttribute(const char *attr, const char *value);
246
247
    /**
248
     * Pure virtual method, it should be redefined in subclasses to return
249
     * the default value of the kth attribute, as defined in the DTD.
250
     *
251
     * It should return NULL if k is out of range (i.e. negative or greater than
252
     * getNumAttributes()), or if the attribute is \#REQUIRED; and return ""
253
     * if the attribute is \#IMPLIED.
254
     */
255
    virtual const char *getAttributeDefault(int k) const = 0;
256
257
    /**
258
     * Returns the default value of the given attribute, as defined in the DTD.
259
     * Relies on lookupAttribute() and getAttributeDefault().
260
     *
261
     * It returns NULL if the given attribute is not found.
262
     */
263
    virtual const char *getAttributeDefault(const char *attr) const;
264
    //@}
265
266
    /** @name Generic access to children and siblings */
267
    //@{
268
269
    /**
270
     * Returns the parent element, or NULL if this element has no parent.
271
     */
272
    virtual NEDElement *getParent() const;
273
274
    /**
275
     * Returns pointer to the first child element, or NULL if this element
276
     * has no children.
277
     */
278
    virtual NEDElement *getFirstChild() const;
279
280
    /**
281
     * Returns pointer to the last child element, or NULL if this element
282
     * has no children.
283
     */
284
    virtual NEDElement *getLastChild() const;
285
286
    /**
287
     * Returns pointer to the next sibling of this element (i.e. the next child
288
     * in the parent element). Returns NULL if there're no subsequent elements.
289
     *
290
     * getFirstChild() and getNextSibling() can be used to loop through
291
     * the child list:
292
     *
293
     * <pre>
294
     * for (NEDElement *child=node->getFirstChild(); child; child = child->getNextSibling())
295
     * {
296
     *    ...
297
     * }
298
     * </pre>
299
     *
300
     */
301
    virtual NEDElement *getNextSibling() const;
302
303
    /**
304
     * Returns pointer to the previous sibling of this element (i.e. the previous child
305
     * in the parent element). Returns NULL if there're no elements before this one.
306
     */
307
    virtual NEDElement *getPrevSibling() const;
308
309
    /**
310
     * Appends the given element at the end of the child element list.
311
     *
312
     * The node pointer passed should not be NULL.
313
     */
314
    virtual void appendChild(NEDElement *node);
315
316
    /**
317
     * Inserts the given element just before the specified child element
318
     * in the child element list, or at the end of the child list if
319
     * NULL is specified as the insert position.
320
     *
321
     * The where element must be a child of this element, or NULL.
322
     * The node pointer passed should not be NULL.
323
     */
324
    virtual void insertChildBefore(NEDElement *where, NEDElement *newnode);
325
326
    /**
327
     * Removes the given element from the child element list.
328
     *
329
     * The pointer passed should be a child of this element.
330
     */
331
    virtual NEDElement *removeChild(NEDElement *node);
332
333
    /**
334
     * Returns pointer to the first child element with the given tag code,
335
     * or NULL if this element has no such children.
336
     */
337
    virtual NEDElement *getFirstChildWithTag(int tagcode) const;
338
339
    /**
340
     * Returns pointer to the next sibling of this element with the given
341
     * tag code. Return NULL if there're no such subsequent elements.
342
     *
343
     * getFirstChildWithTag() and getNextSiblingWithTag() are a convient way
344
     * to loop through elements with a certain tag code in the child list:
345
     *
346
     * <pre>
347
     * for (NEDElement *child=node->getFirstChildWithTag(tagcode); child; child = child->getNextSiblingWithTag(tagcode))
348
     * {
349
     *     ...
350
     * }
351
     * </pre>
352
     */
353
    virtual NEDElement *getNextSiblingWithTag(int tagcode) const;
354
355
    /**
356
     * Returns the number of child elements.
357
     */
358
    virtual int getNumChildren() const;
359
360
    /**
361
     * Returns the number of child elements with the given tag code.
362
     */
363
    virtual int getNumChildrenWithTag(int tagcode) const;
364
    //@}
365
366
    /** @name Utility functions */
367
368
    //@{
369
    /**
370
     * Returns first child element with the given tagcode and the given
371
     * attribute (optionally) having the given value. Returns NULL if not found.
372
     */
373
    NEDElement *getFirstChildWithAttribute(int tagcode, const char *attr, const char *attrvalue=NULL);
374
375
    /**
376
     * Climb up in the element tree until it finds an element with the given tagcode.
377
     * Returns "this" if its tagcode already matches. Returns NULL if not found.
378
     */
379
    NEDElement *getParentWithTag(int tagcode);
380
    //@}
381
382
    /** @name Counters */
383
    //@{
384
385
    /**
386
     * Returns NEDElements constructed so far (this number can only increase).
387
     */
388
    static long getNumCreated() {return numcreated;}
389
390
    /**
391
     * Returns NEDElements currently existing (created minus deleted).
392
     * Useful for detecting memory leaks.
393
     */
394
    static long getNumExisting() {return numexisting;}
395
    //@}
396
397
398
    /** @name User data */
399
    //@{
400
401
    /**
402
     * Replaces user data object with the given one.
403
     */
404
    virtual void setUserData(NEDElementUserData *data);
405
406
    /**
407
     * Return pointer to the user data object, or NULL if
408
     * setUserData() has not been called yet.
409
     */
410
    virtual NEDElementUserData *getUserData() const;
411
    //@}
412
};
413
414
NAMESPACE_END
415
416
417
#endif