Panda3D
xFileNode.cxx
1 // Filename: xFileNode.cxx
2 // Created by: drose (03Oct04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "xFileNode.h"
16 #include "windowsGuid.h"
17 #include "xFile.h"
18 #include "xLexerDefs.h"
19 #include "xFileParseData.h"
20 #include "xFile.h"
21 #include "xFileDataNodeTemplate.h"
22 #include "filename.h"
23 #include "string_utils.h"
24 
25 TypeHandle XFileNode::_type_handle;
26 
27 ////////////////////////////////////////////////////////////////////
28 // Function: XFileNode::Constructor
29 // Access: Public
30 // Description:
31 ////////////////////////////////////////////////////////////////////
32 XFileNode::
33 XFileNode(XFile *x_file, const string &name) :
34  Namable(),
35  _x_file(x_file)
36 {
37  if (x_file && x_file->_keep_names) {
38  set_name(name);
39  } else {
40  set_name(make_nice_name(name));
41  }
42 }
43 
44 ////////////////////////////////////////////////////////////////////
45 // Function: XFileNode::Destructor
46 // Access: Public, Virtual
47 // Description:
48 ////////////////////////////////////////////////////////////////////
49 XFileNode::
50 ~XFileNode() {
51  clear();
52 }
53 
54 ////////////////////////////////////////////////////////////////////
55 // Function: XFileNode::find_child
56 // Access: Public
57 // Description: Returns the child with the indicated name, if any, or
58 // NULL if none.
59 ////////////////////////////////////////////////////////////////////
61 find_child(const string &name) const {
62  ChildrenByName::const_iterator ni;
63  ni = _children_by_name.find(downcase(name));
64  if (ni != _children_by_name.end()) {
65  return get_child((*ni).second);
66  }
67 
68  return NULL;
69 }
70 
71 ////////////////////////////////////////////////////////////////////
72 // Function: XFileNode::find_child_index
73 // Access: Public
74 // Description: Returns the index number of the child with the
75 // indicated name, if any, or -1 if none.
76 ////////////////////////////////////////////////////////////////////
77 int XFileNode::
78 find_child_index(const string &name) const {
79  ChildrenByName::const_iterator ni;
80  ni = _children_by_name.find(downcase(name));
81  if (ni != _children_by_name.end()) {
82  return (*ni).second;
83  }
84 
85  return -1;
86 }
87 
88 ////////////////////////////////////////////////////////////////////
89 // Function: XFileNode::find_child_index
90 // Access: Public
91 // Description: Returns the index number of the indicated child,
92 // or -1 if none.
93 ////////////////////////////////////////////////////////////////////
94 int XFileNode::
95 find_child_index(const XFileNode *child) const {
96  for (int i = 0; i < (int)_children.size(); i++) {
97  if (_children[i] == child) {
98  return i;
99  }
100  }
101 
102  return -1;
103 }
104 
105 ////////////////////////////////////////////////////////////////////
106 // Function: XFileNode::find_descendent
107 // Access: Public
108 // Description: Returns the first child or descendent found with the
109 // indicated name after a depth-first search, if any, or
110 // NULL if none.
111 ////////////////////////////////////////////////////////////////////
113 find_descendent(const string &name) const {
114  XFileNode *child = find_child(name);
115  if (child != (XFileNode *)NULL) {
116  return child;
117  }
118 
119  Children::const_iterator ci;
120  for (ci = _children.begin(); ci != _children.end(); ++ci) {
121  XFileNode *child = (*ci)->find_descendent(name);
122  if (child != (XFileNode *)NULL){
123  return child;
124  }
125  }
126 
127  return NULL;
128 }
129 
130 ////////////////////////////////////////////////////////////////////
131 // Function: XFileNode::has_guid
132 // Access: Public, Virtual
133 // Description: Returns true if this node has a GUID associated.
134 ////////////////////////////////////////////////////////////////////
135 bool XFileNode::
136 has_guid() const {
137  return false;
138 }
139 
140 ////////////////////////////////////////////////////////////////////
141 // Function: XFileNode::get_guid
142 // Access: Public, Virtual
143 // Description: If has_guid() returned true, returns the particular
144 // GUID associated with this node.
145 ////////////////////////////////////////////////////////////////////
147 get_guid() const {
148  static WindowsGuid empty;
149  return empty;
150 }
151 
152 ////////////////////////////////////////////////////////////////////
153 // Function: XFileNode::is_template_def
154 // Access: Public, Virtual
155 // Description: Returns true if this node represents the definition
156 // of some template. This is the template definition,
157 // not an actual data object that represents an instance
158 // of the template. If the file strictly uses standard
159 // templates, the presence of template definitions is
160 // optional.
161 //
162 // If this returns true, the node must be of type
163 // XFileTemplate.
164 ////////////////////////////////////////////////////////////////////
165 bool XFileNode::
167  return false;
168 }
169 
170 ////////////////////////////////////////////////////////////////////
171 // Function: XFileNode::is_reference
172 // Access: Public, Virtual
173 // Description: Returns true if this node represents an indirect
174 // reference to an object defined previously in the
175 // file. References are generally transparent, so in
176 // most cases you never need to call this, unless you
177 // actually need to differentiate between references and
178 // instances; you can simply use the reference node as
179 // if it were itself the object it references.
180 //
181 // If this returns true, the node must be of type
182 // XFileDataNodeReference.
183 ////////////////////////////////////////////////////////////////////
184 bool XFileNode::
185 is_reference() const {
186  return false;
187 }
188 
189 ////////////////////////////////////////////////////////////////////
190 // Function: XFileNode::is_object
191 // Access: Public, Virtual
192 // Description: Returns true if this node represents a data object
193 // that is the instance of some template, or false
194 // otherwise. This also returns true for references to
195 // objects (which are generally treated just like the
196 // objects themselves).
197 //
198 // If this returns true, the node must be of type
199 // XFileDataNode (it is either an XFileDataNodeTemplate
200 // or an XFileDataNodeReference).
201 ////////////////////////////////////////////////////////////////////
202 bool XFileNode::
203 is_object() const {
204  return false;
205 }
206 
207 ////////////////////////////////////////////////////////////////////
208 // Function: XFileNode::is_standard_object
209 // Access: Public, Virtual
210 // Description: Returns true if this node represents an instance of
211 // the standard template with the indicated name, or
212 // false otherwise. This returns also returns true for
213 // references to standard objects.
214 //
215 // If this returns true, the node must be of type
216 // XFileDataNode (it is either an XFileDataNodeTemplate
217 // or an XFileDataNodeReference).
218 ////////////////////////////////////////////////////////////////////
219 bool XFileNode::
220 is_standard_object(const string &template_name) const {
221  return false;
222 }
223 
224 ////////////////////////////////////////////////////////////////////
225 // Function: XFileNode::add_child
226 // Access: Public
227 // Description: Adds the indicated node as a child of this node.
228 ////////////////////////////////////////////////////////////////////
229 void XFileNode::
231  if (node->has_name()) {
232  _children_by_name[downcase(node->get_name())] = (int)_children.size();
233  }
234  if (node->has_guid()) {
235  _x_file->_nodes_by_guid[node->get_guid()] = node;
236  }
237  if (node->is_of_type(XFileDataNode::get_class_type())) {
238  _objects.push_back(DCAST(XFileDataNode, node));
239  }
240  _children.push_back(node);
241 }
242 
243 ////////////////////////////////////////////////////////////////////
244 // Function: XFileNode::clear
245 // Access: Public, Virtual
246 // Description: Removes all children from the node, and otherwise
247 // resets it to its initial state.
248 ////////////////////////////////////////////////////////////////////
249 void XFileNode::
250 clear() {
251  _children.clear();
252  _objects.clear();
253  _children_by_name.clear();
254 }
255 
256 ////////////////////////////////////////////////////////////////////
257 // Function: XFileNode::write_text
258 // Access: Public, Virtual
259 // Description: Writes a suitable representation of this node to an
260 // .x file in text mode.
261 ////////////////////////////////////////////////////////////////////
262 void XFileNode::
263 write_text(ostream &out, int indent_level) const {
264  Children::const_iterator ci;
265  for (ci = _children.begin(); ci != _children.end(); ++ci) {
266  (*ci)->write_text(out, indent_level);
267  }
268 }
269 
270 ////////////////////////////////////////////////////////////////////
271 // Function: XFileNode::repack_data
272 // Access: Public, Virtual
273 // Description: This is called on the template that defines an
274 // object, once the data for the object has been parsed.
275 // It is responsible for identifying which component of
276 // the template owns each data element, and packing the
277 // data elements appropriately back into the object.
278 //
279 // It returns true on success, or false on an error
280 // (e.g. not enough data elements, mismatched data
281 // type).
282 ////////////////////////////////////////////////////////////////////
283 bool XFileNode::
285  const XFileParseDataList &parse_data_list,
286  XFileNode::PrevData &prev_data,
287  size_t &index, size_t &sub_index) const {
288  // This method should be specialized for data types that actually
289  // consume a data element. Here in the base class, it just walks
290  // through its children, asking each one to pull off the appropriate
291  // number of data elements.
292 
293  Children::const_iterator ci;
294  for (ci = _children.begin(); ci != _children.end(); ++ci) {
295  if (!(*ci)->repack_data(object, parse_data_list,
296  prev_data, index, sub_index)) {
297  return false;
298  }
299  }
300 
301  return true;
302 }
303 
304 ////////////////////////////////////////////////////////////////////
305 // Function: XFileNode::fill_zero_data
306 // Access: Public, Virtual
307 // Description: This is similar to repack_data(), except it is used
308 // to fill the initial values for a newly-created
309 // template object to zero.
310 ////////////////////////////////////////////////////////////////////
311 bool XFileNode::
313  Children::const_iterator ci;
314  for (ci = _children.begin(); ci != _children.end(); ++ci) {
315  if (!(*ci)->fill_zero_data(object)) {
316  return false;
317  }
318  }
319 
320  return true;
321 }
322 
323 ////////////////////////////////////////////////////////////////////
324 // Function: XFileNode::matches
325 // Access: Public, Virtual
326 // Description: Returns true if the node, particularly a template
327 // node, is structurally equivalent to the other node
328 // (which must be of the same type). This checks data
329 // element types, but does not compare data element
330 // names.
331 ////////////////////////////////////////////////////////////////////
332 bool XFileNode::
333 matches(const XFileNode *other) const {
334  if (other->get_type() != get_type()) {
335  return false;
336  }
337 
338  if (other->get_num_children() != get_num_children()) {
339  return false;
340  }
341 
342  for (int i = 0; i < get_num_children(); i++) {
343  if (!get_child(i)->matches(other->get_child(i))) {
344  return false;
345  }
346  }
347 
348  return true;
349 }
350 
351 ////////////////////////////////////////////////////////////////////
352 // Function: XFileNode::add_Mesh
353 // Access: Public
354 // Description: Creates a new Mesh instance, as a child of this node.
355 ////////////////////////////////////////////////////////////////////
357 add_Mesh(const string &name) {
358  XFileTemplate *xtemplate = XFile::find_standard_template("Mesh");
359  nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
360  XFileDataNodeTemplate *node =
361  new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
362  add_child(node);
363  node->zero_fill();
364 
365  return node;
366 }
367 
368 ////////////////////////////////////////////////////////////////////
369 // Function: XFileNode::add_MeshNormals
370 // Access: Public
371 // Description: Creates a new MeshNormals instance, as a child of
372 // this node.
373 ////////////////////////////////////////////////////////////////////
375 add_MeshNormals(const string &name) {
376  XFileTemplate *xtemplate = XFile::find_standard_template("MeshNormals");
377  nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
378  XFileDataNodeTemplate *node =
379  new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
380  add_child(node);
381  node->zero_fill();
382 
383  return node;
384 }
385 
386 ////////////////////////////////////////////////////////////////////
387 // Function: XFileNode::add_MeshVertexColors
388 // Access: Public
389 // Description: Creates a new MeshVertexColors instance, as a child of
390 // this node.
391 ////////////////////////////////////////////////////////////////////
393 add_MeshVertexColors(const string &name) {
394  XFileTemplate *xtemplate = XFile::find_standard_template("MeshVertexColors");
395  nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
396  XFileDataNodeTemplate *node =
397  new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
398  add_child(node);
399  node->zero_fill();
400 
401  return node;
402 }
403 
404 ////////////////////////////////////////////////////////////////////
405 // Function: XFileNode::add_MeshTextureCoords
406 // Access: Public
407 // Description: Creates a new MeshTextureCoords instance, as a child of
408 // this node.
409 ////////////////////////////////////////////////////////////////////
411 add_MeshTextureCoords(const string &name) {
412  XFileTemplate *xtemplate = XFile::find_standard_template("MeshTextureCoords");
413  nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
414  XFileDataNodeTemplate *node =
415  new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
416  add_child(node);
417  node->zero_fill();
418 
419  return node;
420 }
421 
422 ////////////////////////////////////////////////////////////////////
423 // Function: XFileNode::add_MeshMaterialList
424 // Access: Public
425 // Description: Creates a new MeshMaterialList instance, as a child of
426 // this node.
427 ////////////////////////////////////////////////////////////////////
429 add_MeshMaterialList(const string &name) {
430  XFileTemplate *xtemplate = XFile::find_standard_template("MeshMaterialList");
431  nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
432  XFileDataNodeTemplate *node =
433  new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
434  add_child(node);
435  node->zero_fill();
436 
437  return node;
438 }
439 
440 ////////////////////////////////////////////////////////////////////
441 // Function: XFileNode::add_Material
442 // Access: Public
443 // Description: Creates a new Material instance, as a child of
444 // this node.
445 ////////////////////////////////////////////////////////////////////
447 add_Material(const string &name, const LColor &face_color,
448  double power, const LRGBColor &specular_color,
449  const LRGBColor &emissive_color) {
450  XFileTemplate *xtemplate = XFile::find_standard_template("Material");
451  nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
452  XFileDataNodeTemplate *node =
453  new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
454  add_child(node);
455  node->zero_fill();
456 
457  (*node)["faceColor"]["red"] = face_color[0];
458  (*node)["faceColor"]["green"] = face_color[1];
459  (*node)["faceColor"]["blue"] = face_color[2];
460  (*node)["faceColor"]["alpha"] = face_color[3];
461  (*node)["power"] = power;
462  (*node)["specularColor"]["red"] = specular_color[0];
463  (*node)["specularColor"]["green"] = specular_color[1];
464  (*node)["specularColor"]["blue"] = specular_color[2];
465  (*node)["emissiveColor"]["red"] = emissive_color[0];
466  (*node)["emissiveColor"]["green"] = emissive_color[1];
467  (*node)["emissiveColor"]["blue"] = emissive_color[2];
468 
469  return node;
470 }
471 
472 ////////////////////////////////////////////////////////////////////
473 // Function: XFileNode::add_TextureFilename
474 // Access: Public
475 // Description: Creates a new TextureFilename instance, as a child of
476 // this node.
477 ////////////////////////////////////////////////////////////////////
479 add_TextureFilename(const string &name, const Filename &filename) {
480  XFileTemplate *xtemplate = XFile::find_standard_template("TextureFilename");
481  nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
482  XFileDataNodeTemplate *node =
483  new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
484  add_child(node);
485  node->zero_fill();
486 
487  (*node)["filename"] = filename.to_os_specific();
488 
489  return node;
490 }
491 
492 ////////////////////////////////////////////////////////////////////
493 // Function: XFileNode::add_Frame
494 // Access: Public
495 // Description: Creates a new Frame instance, as a child of this
496 // node.
497 ////////////////////////////////////////////////////////////////////
499 add_Frame(const string &name) {
500  XFileTemplate *xtemplate = XFile::find_standard_template("Frame");
501  nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
502  XFileDataNodeTemplate *node =
503  new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
504  add_child(node);
505  node->zero_fill();
506 
507  return node;
508 }
509 
510 ////////////////////////////////////////////////////////////////////
511 // Function: XFileNode::add_FrameTransformMatrix
512 // Access: Public
513 // Description: Creates a new FrameTransformMatrix instance, as a
514 // child of this node.
515 ////////////////////////////////////////////////////////////////////
518  XFileTemplate *xtemplate =
519  XFile::find_standard_template("FrameTransformMatrix");
520  nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
521  XFileDataNodeTemplate *node =
522  new XFileDataNodeTemplate(get_x_file(), "", xtemplate);
523  add_child(node);
524  node->zero_fill();
525 
526  XFileDataObject &xmat = (*node)["frameMatrix"]["matrix"];
527  xmat[0] = mat(0, 0);
528  xmat[1] = mat(0, 1);
529  xmat[2] = mat(0, 2);
530  xmat[3] = mat(0, 3);
531 
532  xmat[4] = mat(1, 0);
533  xmat[5] = mat(1, 1);
534  xmat[6] = mat(1, 2);
535  xmat[7] = mat(1, 3);
536 
537  xmat[8] = mat(2, 0);
538  xmat[9] = mat(2, 1);
539  xmat[10] = mat(2, 2);
540  xmat[11] = mat(2, 3);
541 
542  xmat[12] = mat(3, 0);
543  xmat[13] = mat(3, 1);
544  xmat[14] = mat(3, 2);
545  xmat[15] = mat(3, 3);
546 
547  return node;
548 }
549 
550 ////////////////////////////////////////////////////////////////////
551 // Function: XFileNode::make_nice_name
552 // Access: Protected, Static
553 // Description: Transforms the indicated egg name to a name that is
554 // acceptable for a node in the X File format.
555 ////////////////////////////////////////////////////////////////////
556 string XFileNode::
557 make_nice_name(const string &str) {
558  string result;
559 
560  string::const_iterator si;
561  for (si = str.begin(); si != str.end(); ++si) {
562  if (isalnum(*si)) {
563  result += (*si);
564  } else {
565  switch (*si) {
566  case '-':
567  result += (*si);
568  break;
569  default:
570  result += "_";
571  }
572  }
573  }
574 
575  if (str.empty() || isdigit(str[0])) {
576  // If the name begins with a digit, or if it
577  // is empty, then we must make it begin with
578  // something else, like for instance an underscore.
579  result = '_' + result;
580  }
581 
582  return result;
583 }
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
This is our own Panda specialization on the default STL map.
Definition: pmap.h:52
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:4716
virtual bool matches(const XFileNode *other) const
Returns true if the node, particularly a template node, is structurally equivalent to the other node ...
Definition: xFileNode.cxx:333
XFileDataNode * add_Mesh(const string &name)
Creates a new Mesh instance, as a child of this node.
Definition: xFileNode.cxx:357
int get_num_children() const
Returns the list of children of this node.
Definition: xFileNode.I:33
This is an implementation of the Windows GUID object, used everywhere as a world-unique identifier fo...
Definition: windowsGuid.h:29
virtual bool is_object() const
Returns true if this node represents a data object that is the instance of some template, or false otherwise.
Definition: xFileNode.cxx:203
XFileDataNode * add_MeshNormals(const string &name)
Creates a new MeshNormals instance, as a child of this node.
Definition: xFileNode.cxx:375
void add_child(XFileNode *node)
Adds the indicated node as a child of this node.
Definition: xFileNode.cxx:230
void zero_fill()
Fills the data node with zero-valued elements appropriate to the template.
virtual bool is_template_def() const
Returns true if this node represents the definition of some template.
Definition: xFileNode.cxx:166
static XFileTemplate * find_standard_template(const string &name)
Returns the standard template associated with the indicated name, if any, or NULL if none...
Definition: xFile.cxx:262
virtual bool has_guid() const
Returns true if this node has a GUID associated.
Definition: xFileNode.cxx:136
virtual void write_text(ostream &out, int indent_level) const
Writes a suitable representation of this node to an .x file in text mode.
Definition: xFileNode.cxx:263
This is a node which contains all of the data elements defined by a template.
XFileDataNode * add_MeshTextureCoords(const string &name)
Creates a new MeshTextureCoords instance, as a child of this node.
Definition: xFileNode.cxx:411
int find_child_index(const string &name) const
Returns the index number of the child with the indicated name, if any, or -1 if none.
Definition: xFileNode.cxx:78
A single node of an X file.
Definition: xFileNode.h:42
A base class for all things which can have a name.
Definition: namable.h:29
XFileDataNode * add_MeshVertexColors(const string &name)
Creates a new MeshVertexColors instance, as a child of this node.
Definition: xFileNode.cxx:393
virtual const WindowsGuid & get_guid() const
If has_guid() returned true, returns the particular GUID associated with this node.
Definition: xFileNode.cxx:147
XFileDataNode * add_TextureFilename(const string &name, const Filename &filename)
Creates a new TextureFilename instance, as a child of this node.
Definition: xFileNode.cxx:479
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
XFileDataNode * add_Frame(const string &name)
Creates a new Frame instance, as a child of this node.
Definition: xFileNode.cxx:499
virtual bool is_reference() const
Returns true if this node represents an indirect reference to an object defined previously in the fil...
Definition: xFileNode.cxx:185
XFileDataNode * add_FrameTransformMatrix(const LMatrix4d &mat)
Creates a new FrameTransformMatrix instance, as a child of this node.
Definition: xFileNode.cxx:517
A container for a pvector of the above objects.
virtual bool repack_data(XFileDataObject *object, const XFileParseDataList &parse_data_list, PrevData &prev_data, size_t &index, size_t &sub_index) const
This is called on the template that defines an object, once the data for the object has been parsed...
Definition: xFileNode.cxx:284
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
XFileNode * find_child(const string &name) const
Returns the child with the indicated name, if any, or NULL if none.
Definition: xFileNode.cxx:61
virtual void clear()
Removes all children from the node, and otherwise resets it to its initial state. ...
Definition: xFileNode.cxx:250
static string make_nice_name(const string &str)
Transforms the indicated egg name to a name that is acceptable for a node in the X File format...
Definition: xFileNode.cxx:557
This is an abstract base class for an XFileNode which is also an XFileDataObject. ...
Definition: xFileDataNode.h:36
virtual bool fill_zero_data(XFileDataObject *object) const
This is similar to repack_data(), except it is used to fill the initial values for a newly-created te...
Definition: xFileNode.cxx:312
XFileDataNode * add_MeshMaterialList(const string &name)
Creates a new MeshMaterialList instance, as a child of this node.
Definition: xFileNode.cxx:429
This represents the complete contents of an X file (file.x) in memory.
Definition: xFile.h:35
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:63
XFileNode * find_descendent(const string &name) const
Returns the first child or descendent found with the indicated name after a depth-first search...
Definition: xFileNode.cxx:113
A template definition in the X file.
Definition: xFileTemplate.h:29
bool has_name() const
Returns true if the Namable has a nonempty name set, false if the name is empty.
Definition: namable.I:75
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
XFileDataNode * add_Material(const string &name, const LColor &face_color, double power, const LRGBColor &specular_color, const LRGBColor &emissive_color)
Creates a new Material instance, as a child of this node.
Definition: xFileNode.cxx:447
string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
Definition: filename.cxx:1196
The abstract base class for a number of different types of data elements that may be stored in the X ...
virtual bool is_standard_object(const string &template_name) const
Returns true if this node represents an instance of the standard template with the indicated name...
Definition: xFileNode.cxx:220
XFileNode * get_child(int n) const
Returns the nth child of this node.
Definition: xFileNode.I:44