]> git.mxchange.org Git - simgear.git/blob - simgear/misc/props.hxx
- made getValue methods protected, so that they won't be invoked outside
[simgear.git] / simgear / misc / props.hxx
1 /**
2  * \file props.hxx
3  * Interface definition for a property list.
4  * Started Fall 2000 by David Megginson, david@megginson.com
5  * This code is released into the Public Domain.
6  *
7  * See props.html for documentation [replace with URL when available].
8  *
9  * $Id$
10  */
11
12 #ifndef __PROPS_HXX
13 #define __PROPS_HXX
14
15 #include <simgear/compiler.h>
16
17 #include <stdio.h>
18
19 #include STL_STRING
20 #include <vector>
21 #include STL_IOSTREAM
22
23 SG_USING_STD(string);
24 SG_USING_STD(vector);
25 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
26 SG_USING_STD(istream);
27 SG_USING_STD(ostream);
28 #endif
29
30 #ifdef ALIAS
31 #pragma warn A sloppy coder has defined ALIAS as a macro!
32 #undef ALIAS
33 #endif
34
35 #ifdef UNSPECIFIED
36 #pragma warn A sloppy coder has defined UNSPECIFIED as a macro!
37 #undef UNSPECIFIED
38 #endif
39
40 #ifdef BOOL
41 #pragma warn A sloppy coder has defined BOOL as a macro!
42 #undef BOOL
43 #endif
44
45 #ifdef INT
46 #pragma warn A sloppy coder has defined INT as a macro!
47 #undef INT
48 #endif
49
50 #ifdef LONG
51 #pragma warn A sloppy coder has defined LONG as a macro!
52 #undef LONG
53 #endif
54
55 #ifdef FLOAT
56 #pragma warn A sloppy coder has defined FLOAT as a macro!
57 #undef FLOAT
58 #endif
59
60 #ifdef DOUBLE
61 #pragma warn A sloppy coder has defined DOUBLE as a macro!
62 #undef DOUBLE
63 #endif
64
65 #ifdef STRING
66 #pragma warn A sloppy coder has defined STRING as a macro!
67 #undef STRING
68 #endif
69
70
71 \f
72 ////////////////////////////////////////////////////////////////////////
73 // A raw value.
74 //
75 // This is the mechanism that information-providing routines can
76 // use to link their own values to the property manager.  Any
77 // SGValue can be tied to a raw value and then untied again.
78 ////////////////////////////////////////////////////////////////////////
79
80
81 /**
82  * Abstract base class for a raw value.
83  *
84  * The property manager is implemented in three layers.  The {@link
85  * SGPropertyNode} is the highest and most abstract layer,
86  * representing * an LValue/RValue pair: it * records the position
87  * of the property in the property tree and * contains facilities
88  * for navigation to other nodes.  Each node * may contain an {@link
89  * SGValue}, which is guaranteed persistent: the * {@link SGValue}
90  * will not change during a session, even if the * property is bound
91  * and unbound multiple times.  The SGValue is the * abstraction of
92  * an RValue: it allows for conversion among all of the different
93  * types, and can be bound to external pointers, functions, methods,
94  * or other data sources.  Every SGValue contains an SGRawValue of
95  * a specific type.  The SGRawValue (this class) may change frequently
96  * during a session as a value is retyped or bound and unbound to
97  * various data source, but the abstract SGValue layer insulates
98  * the application from those changes.  The raw value contains no
99  * facilities for data binding or for type conversion: it is simply
100  * the abstraction of a primitive data type (or a compound data
101  * type, in the case of a string).
102  *
103  * The SGValue class always keeps a *copy* of a raw value, not the
104  * original one passed to it; if you override a derived class but do
105  * not replace the {@link #clone} method, strange things will happen.
106  *
107  * All raw values must implement {@link #getValue}, {@link #setValue},
108  * and {@link #clone} for the appropriate type.
109  *
110  * @see SGValue
111  * @see SGPropertyNode */
112 template <class T>
113 class SGRawValue
114 {
115 public:
116
117   /**
118    * The default underlying value for this type.
119    *
120    * Every raw value has a default; the default is false for a
121    * boolean, 0 for the various numeric values, and "" for a string.
122    * If additional types of raw values are added in the future, they
123    * may need different kinds of default values (such as epoch for a
124    * date type).  The default value is used when creating new values.
125    */
126   static const T DefaultValue;  // Default for this kind of raw value.
127
128
129   /**
130    * Constructor.
131    *
132    * Use the default value for this type.
133    */
134   SGRawValue () {}
135
136
137   /**
138    * Destructor.
139    */
140   virtual ~SGRawValue () {}
141
142
143   /**
144    * Return the underlying value.
145    *
146    * @return The actual value for the property.
147    * @see #setValue
148    */
149   virtual T getValue () const = 0;
150
151
152   /**
153    * Assign a new underlying value.
154    *
155    * If the new value cannot be set (because this is a read-only
156    * raw value, or because the new value is not acceptable for
157    * some reason) this method returns false and leaves the original
158    * value unchanged.
159    *
160    * @param value The actual value for the property.
161    * @return true if the value was set successfully, false otherwise.
162    * @see #getValue
163    */
164   virtual bool setValue (T value) = 0;
165
166
167   /**
168    * Create a new deep copy of this raw value.
169    *
170    * The copy will contain its own version of the underlying value
171    * as well.
172    *
173    * @return A deep copy of the current object.
174    */
175   virtual SGRawValue * clone () const = 0;
176 };
177
178
179 /**
180  * An unbound raw value, stored internally.
181  *
182  * Instances of this class are created automatically, by default,
183  * by the SGValue class; ordinarily the application should not
184  * need to touch it.
185  */
186 template <class T>
187 class SGRawValueInternal : public SGRawValue<T>
188 {
189 public:
190
191   /**
192    * Default constructor.
193    *
194    * Initialize with the default value for this type.
195    */
196   SGRawValueInternal () {}
197
198   /**
199    * Explicit value constructor.
200    *
201    * Initialize with the underlying value provided.
202    *
203    * @param value The initial value for this property.
204    */
205   SGRawValueInternal (T value) : _value(value) {}
206
207   /**
208    * Destructor.
209    */
210   virtual ~SGRawValueInternal () {}
211
212   /**
213    * Get the underlying value.
214    */
215   virtual T getValue () const { return _value; }
216
217   /**
218    * Set the underlying value.
219    */
220   virtual bool setValue (T value) { _value = value; return true; }
221
222   /**
223    * Create a deep copy of this raw value.
224    */
225   virtual SGRawValue<T> * clone () const {
226     return new SGRawValueInternal<T>(_value);
227   }
228
229 private:
230   T _value;
231 };
232
233
234 /**
235  * A raw value bound to a pointer.
236  *
237  * This is the most efficient way to tie an external value, but also
238  * the most dangerous, because there is no way for the supplier to
239  * perform bounds checking and derived calculations except by polling
240  * the variable to see if it has changed.  There is no default
241  * constructor, because this class would be meaningless without a
242  * pointer.
243  */
244 template <class T>
245 class SGRawValuePointer : public SGRawValue<T>
246 {
247 public:
248
249   /**
250    * Explicit pointer constructor.
251    *
252    * Create a new raw value bound to the value of the variable
253    * referenced by the pointer.
254    *
255    * @param ptr The pointer to the variable to which this raw value
256    * will be bound.
257    */
258   SGRawValuePointer (T * ptr) : _ptr(ptr) {}
259
260   /**
261    * Destructor.
262    */
263   virtual ~SGRawValuePointer () {}
264
265   /**
266    * Get the underlying value.
267    *
268    * This method will dereference the pointer and return the
269    * variable's value.
270    */
271   virtual T getValue () const { return *_ptr; }
272
273   /**
274    * Set the underlying value.
275    *
276    * This method will dereference the pointer and change the
277    * variable's value.
278    */
279   virtual bool setValue (T value) { *_ptr = value; return true; }
280
281   /**
282    * Create a copy of this raw value.
283    *
284    * The copy will use the same external pointer as the original.
285    */
286   virtual SGRawValue<T> * clone () const {
287     return new SGRawValuePointer<T>(_ptr);
288   }
289
290 private:
291   T * _ptr;
292 };
293
294
295 /**
296  * A value managed through static functions.
297  *
298  * A read-only value will not have a setter; a write-only value will
299  * not have a getter.
300  */
301 template <class T>
302 class SGRawValueFunctions : public SGRawValue<T>
303 {
304 public:
305
306   /**
307    * The template type of a static getter function.
308    */
309   typedef T (*getter_t)();
310
311   /**
312    * The template type of a static setter function.
313    */
314   typedef void (*setter_t)(T);
315
316   /**
317    * Explicit constructor.
318    *
319    * Create a new raw value bound to the getter and setter supplied.
320    *
321    * @param getter A static function for getting a value, or 0
322    * to read-disable the value.
323    * @param setter A static function for setting a value, or 0
324    * to write-disable the value.
325    */
326   SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
327     : _getter(getter), _setter(setter) {}
328
329   /**
330    * Destructor.
331    */
332   virtual ~SGRawValueFunctions () {}
333
334   /**
335    * Get the underlying value.
336    *
337    * This method will invoke the getter function to get a value.
338    * If no getter function was supplied, this method will always
339    * return the default value for the type.
340    */
341   virtual T getValue () const {
342     if (_getter) return (*_getter)();
343     else return SGRawValue<T>::DefaultValue;
344   }
345
346   /**
347    * Set the underlying value.
348    *
349    * This method will invoke the setter function to change the
350    * underlying value.  If no setter function was supplied, this
351    * method will return false.
352    */
353   virtual bool setValue (T value) {
354     if (_setter) { (*_setter)(value); return true; }
355     else return false;
356   }
357
358   /**
359    * Create a copy of this raw value, bound to the same functions.
360    */
361   virtual SGRawValue<T> * clone () const {
362     return new SGRawValueFunctions<T>(_getter,_setter);
363   }
364
365 private:
366   getter_t _getter;
367   setter_t _setter;
368 };
369
370
371 /**
372  * An indexed value bound to static functions.
373  *
374  * A read-only value will not have a setter; a write-only value will
375  * not have a getter.  An indexed value is useful for binding one
376  * of a list of possible values (such as multiple engines for a
377  * plane).  The index is hard-coded at creation time.
378  */
379 template <class T>
380 class SGRawValueFunctionsIndexed : public SGRawValue<T>
381 {
382 public:
383   typedef T (*getter_t)(int);
384   typedef void (*setter_t)(int,T);
385   SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
386     : _index(index), _getter(getter), _setter(setter) {}
387   virtual ~SGRawValueFunctionsIndexed () {}
388   virtual T getValue () const {
389     if (_getter) return (*_getter)(_index);
390     else return SGRawValue<T>::DefaultValue;
391   }
392   virtual bool setValue (T value) {
393     if (_setter) { (*_setter)(_index, value); return true; }
394     else return false;
395   }
396   virtual SGRawValue<T> * clone () const {
397     return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
398   }
399 private:
400   int _index;
401   getter_t _getter;
402   setter_t _setter;
403 };
404
405
406 /**
407  * A value managed through an object and access methods.
408  *
409  * A read-only value will not have a setter; a write-only value will
410  * not have a getter.
411  */
412 template <class C, class T>
413 class SGRawValueMethods : public SGRawValue<T>
414 {
415 public:
416   typedef T (C::*getter_t)() const;
417   typedef void (C::*setter_t)(T);
418   SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
419     : _obj(obj), _getter(getter), _setter(setter) {}
420   virtual ~SGRawValueMethods () {}
421   virtual T getValue () const {
422     if (_getter) { return (_obj.*_getter)(); }
423     else { return SGRawValue<T>::DefaultValue; }
424   }
425   virtual bool setValue (T value) {
426     if (_setter) { (_obj.*_setter)(value); return true; }
427     else return false;
428   }
429   virtual SGRawValue<T> * clone () const {
430     return new SGRawValueMethods<C,T>(_obj, _getter, _setter);
431   }
432 private:
433   C &_obj;
434   getter_t _getter;
435   setter_t _setter;
436 };
437
438
439 /**
440  * An indexed value managed through an object and access methods.
441  *
442  * A read-only value will not have a setter; a write-only value will
443  * not have a getter.
444  */
445 template <class C, class T>
446 class SGRawValueMethodsIndexed : public SGRawValue<T>
447 {
448 public:
449   typedef T (C::*getter_t)(int) const;
450   typedef void (C::*setter_t)(int, T);
451   SGRawValueMethodsIndexed (C &obj, int index,
452                      getter_t getter = 0, setter_t setter = 0)
453     : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
454   virtual ~SGRawValueMethodsIndexed () {}
455   virtual T getValue () const {
456     if (_getter) { return (_obj.*_getter)(_index); }
457     else { return SGRawValue<T>::DefaultValue; }
458   }
459   virtual bool setValue (T value) {
460     if (_setter) { (_obj.*_setter)(_index, value); return true; }
461     else return false;
462   }
463   virtual SGRawValue<T> * clone () const {
464     return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter);
465   }
466 private:
467   C &_obj;
468   int _index;
469   getter_t _getter;
470   setter_t _setter;
471 };
472
473
474 \f
475 /**
476  * A node in a property tree.
477  */
478 class SGPropertyNode
479 {
480
481 public:
482
483
484   /**
485    * Property value types.
486    */
487   enum Type {
488     NONE,
489     ALIAS,
490     BOOL,
491     INT,
492     LONG,
493     FLOAT,
494     DOUBLE,
495     STRING,
496     UNSPECIFIED
497   };
498
499
500   /**
501    * Access mode attributes.
502    *
503    * <p>The ARCHIVE attribute is strictly advisory, and controls
504    * whether the property should normally be saved and restored.</p>
505    */
506   enum Attribute {
507     READ = 1,
508     WRITE = 2,
509     ARCHIVE = 4
510   };
511
512
513   /**
514    * Default constructor.
515    */
516   SGPropertyNode ();
517
518
519   /**
520    * Copy constructor.
521    */
522   SGPropertyNode (const SGPropertyNode &node);
523
524
525   /**
526    * Destructor.
527    */
528   virtual ~SGPropertyNode ();
529
530
531
532   //
533   // Basic properties.
534   //
535
536   /**
537    * Test whether this node contains a primitive leaf value.
538    */
539   bool hasValue () const { return (_type != NONE); }
540
541
542   /**
543    * Get the node's simple (XML) name.
544    */
545   const string &getName () const { return _name; }
546
547
548   /**
549    * Get the node's integer index.
550    */
551   const int getIndex () const { return _index; }
552
553
554   /**
555    * Get a non-const pointer to the node's parent.
556    */
557   SGPropertyNode * getParent () { return _parent; }
558
559
560   /**
561    * Get a const pointer to the node's parent.
562    */
563   const SGPropertyNode * getParent () const { return _parent; }
564
565
566   //
567   // Children.
568   //
569
570
571   /**
572    * Get the number of child nodes.
573    */
574   const int nChildren () const { return _children.size(); }
575
576
577   /**
578    * Get a child node by position (*NOT* index).
579    */
580   SGPropertyNode * getChild (int position);
581
582
583   /**
584    * Get a const child node by position (*NOT* index).
585    */
586   const SGPropertyNode * getChild (int position) const;
587
588
589   /**
590    * Get a child node by name and index.
591    */
592   SGPropertyNode * getChild (const string &name, int index = 0,
593                              bool create = false);
594
595
596   /**
597    * Get a const child node by name and index.
598    */
599   const SGPropertyNode * getChild (const string &name, int index = 0) const;
600
601
602   /**
603    * Get a vector of all children with the specified name.
604    */
605   vector<SGPropertyNode *> getChildren (const string &name);
606
607
608   /**
609    * Get a vector all all children (const) with the specified name.
610    */
611   vector<const SGPropertyNode *> getChildren (const string &name) const;
612
613
614   //
615   // Alias support.
616   //
617
618
619   /**
620    * Alias this node's leaf value to another's.
621    */
622   bool alias (SGPropertyNode * target);
623
624
625   /**
626    * Alias this node's leaf value to another's by relative path.
627    */
628   bool alias (const string &path);
629
630
631   /**
632    * Remove any alias for this node.
633    */
634   bool unalias ();
635
636
637   /**
638    * Test whether the node's leaf value is aliased to another's.
639    */
640   bool isAlias () const { return (_type == ALIAS); }
641
642
643   /**
644    * Get a non-const pointer to the current alias target, if any.
645    */
646   SGPropertyNode * getAliasTarget ();
647
648
649   /**
650    * Get a const pointer to the current alias target, if any.
651    */
652   const SGPropertyNode * getAliasTarget () const;
653
654
655   //
656   // Path information.
657   //
658
659
660   /**
661    * Get the path to this node from the root.
662    */
663   string getPath (bool simplify = false) const;
664
665
666   /**
667    * Get a pointer to the root node.
668    */
669   SGPropertyNode * getRootNode ();
670
671
672   /**
673    * Get a const pointer to the root node.
674    */
675   const SGPropertyNode * getRootNode () const;
676
677
678   /**
679    * Get a pointer to another node by relative path.
680    */
681   SGPropertyNode * getNode (const string &relative_path, bool create = false);
682
683
684   /**
685    * Get a const pointer to another node by relative path.
686    */
687   const SGPropertyNode * getNode (const string &relative_path) const;
688
689
690   //
691   // Access Mode.
692   //
693
694   /**
695    * Check a single mode attribute for the property node.
696    */
697   bool getAttribute (Attribute attr) const { return (_attr & attr); }
698
699
700   /**
701    * Set a single mode attribute for the property node.
702    */
703   void setAttribute (Attribute attr, bool state) {
704     (state ? _attr |= attr : _attr &= ~attr);
705   }
706
707
708   /**
709    * Get all of the mode attributes for the property node.
710    */
711   int getAttributes () const { return _attr; }
712
713
714   /**
715    * Set all of the mode attributes for the property node.
716    */
717   void setAttributes (int attr) { _attr = attr; }
718   
719
720   //
721   // Leaf Value (primitive).
722   //
723
724
725   /**
726    * Get the type of leaf value, if any, for this node.
727    */
728   Type getType () const;
729
730
731   /**
732    * Get a bool value for this node.
733    */
734   bool getBoolValue () const;
735
736
737   /**
738    * Get an int value for this node.
739    */
740   int getIntValue () const;
741
742
743   /**
744    * Get a long int value for this node.
745    */
746   long getLongValue () const;
747
748
749   /**
750    * Get a float value for this node.
751    */
752   float getFloatValue () const;
753
754
755   /**
756    * Get a double value for this node.
757    */
758   double getDoubleValue () const;
759
760
761   /**
762    * Get a string value for this node.
763    */
764   string getStringValue () const;
765
766
767
768   /**
769    * Set a bool value for this node.
770    */
771   bool setBoolValue (bool value);
772
773
774   /**
775    * Set an int value for this node.
776    */
777   bool setIntValue (int value);
778
779
780   /**
781    * Set a long int value for this node.
782    */
783   bool setLongValue (long value);
784
785
786   /**
787    * Set a float value for this node.
788    */
789   bool setFloatValue (float value);
790
791
792   /**
793    * Set a double value for this node.
794    */
795   bool setDoubleValue (double value);
796
797
798   /**
799    * Set a string value for this node.
800    */
801   bool setStringValue (string value);
802
803
804   /**
805    * Set a value of unspecified type for this node.
806    */
807   bool setUnspecifiedValue (string value);
808
809
810   //
811   // Data binding.
812   //
813
814
815   /**
816    * Test whether this node is bound to an external data source.
817    */
818   bool isTied () const { return _tied; }
819
820
821   /**
822    * Bind this node to an external bool source.
823    */
824   bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
825
826
827   /**
828    * Bind this node to an external int source.
829    */
830   bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
831
832
833   /**
834    * Bind this node to an external long int source.
835    */
836   bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
837
838
839   /**
840    * Bind this node to an external float source.
841    */
842   bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
843
844
845   /**
846    * Bind this node to an external double source.
847    */
848   bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
849
850
851   /**
852    * Bind this node to an external string source.
853    */
854   bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
855
856
857   /**
858    * Unbind this node from any external data source.
859    */
860   bool untie ();
861
862
863   //
864   // Convenience methods using paths.
865   // TODO: add attribute methods
866   //
867
868
869   /**
870    * Get another node's type.
871    */
872   Type getType (const string &relative_path) const;
873
874
875   /**
876    * Test whether another node has a leaf value.
877    */
878   bool hasValue (const string &relative_path) const;
879
880
881   /**
882    * Get another node's value as a bool.
883    */
884   bool getBoolValue (const string &relative_path,
885                      bool defaultValue = false) const;
886
887
888   /**
889    * Get another node's value as an int.
890    */
891   int getIntValue (const string &relative_path,
892                    int defaultValue = 0) const;
893
894
895   /**
896    * Get another node's value as a long int.
897    */
898   long getLongValue (const string &relative_path,
899                      long defaultValue = 0L) const;
900
901
902   /**
903    * Get another node's value as a float.
904    */
905   float getFloatValue (const string &relative_path,
906                        float defaultValue = 0.0) const;
907
908
909   /**
910    * Get another node's value as a double.
911    */
912   double getDoubleValue (const string &relative_path,
913                          double defaultValue = 0.0L) const;
914
915
916   /**
917    * Get another node's value as a string.
918    */
919   string getStringValue (const string &relative_path,
920                          string defaultValue = "") const;
921
922
923   /**
924    * Set another node's value as a bool.
925    */
926   bool setBoolValue (const string &relative_path, bool value);
927
928
929   /**
930    * Set another node's value as an int.
931    */
932   bool setIntValue (const string &relative_path, int value);
933
934
935   /**
936    * Set another node's value as a long int.
937    */
938   bool setLongValue (const string &relative_path, long value);
939
940
941   /**
942    * Set another node's value as a float.
943    */
944   bool setFloatValue (const string &relative_path, float value);
945
946
947   /**
948    * Set another node's value as a double.
949    */
950   bool setDoubleValue (const string &relative_path, double value);
951
952
953   /**
954    * Set another node's value as a string.
955    */
956   bool setStringValue (const string &relative_path, string value);
957
958
959   /**
960    * Set another node's value with no specified type.
961    */
962   bool setUnspecifiedValue (const string &relative_path, string value);
963
964
965   /**
966    * Test whether another node is bound to an external data source.
967    */
968   bool isTied (const string &relative_path) const;
969
970
971   /**
972    * Bind another node to an external bool source.
973    */
974   bool tie (const string &relative_path, const SGRawValue<bool> &rawValue,
975             bool useDefault = true);
976
977
978   /**
979    * Bind another node to an external int source.
980    */
981   bool tie (const string &relative_path, const SGRawValue<int> &rawValue,
982             bool useDefault = true);
983
984
985   /**
986    * Bind another node to an external long int source.
987    */
988   bool tie (const string &relative_path, const SGRawValue<long> &rawValue,
989             bool useDefault = true);
990
991
992   /**
993    * Bind another node to an external float source.
994    */
995   bool tie (const string &relative_path, const SGRawValue<float> &rawValue,
996             bool useDefault = true);
997
998
999   /**
1000    * Bind another node to an external double source.
1001    */
1002   bool tie (const string &relative_path, const SGRawValue<double> &rawValue,
1003             bool useDefault = true);
1004
1005
1006   /**
1007    * Bind another node to an external string source.
1008    */
1009   bool tie (const string &relative_path, const SGRawValue<string> &rawValue,
1010             bool useDefault = true);
1011
1012
1013   /**
1014    * Unbind another node from any external data source.
1015    */
1016   bool untie (const string &relative_path);
1017
1018
1019 protected:
1020
1021
1022   /**
1023    * Protected constructor for making new nodes on demand.
1024    */
1025   SGPropertyNode (const string &name, int index, SGPropertyNode * parent);
1026
1027
1028 private:
1029
1030
1031   /**
1032    * Clear any existing value and set the type to NONE.
1033    */
1034   void clear_value ();
1035
1036   string _name;
1037   int _index;
1038   SGPropertyNode * _parent;
1039   vector<SGPropertyNode *> _children;
1040
1041
1042   Type _type;
1043   bool _tied;
1044   int _attr;
1045
1046                                 // The right kind of pointer...
1047   union {
1048     SGPropertyNode * alias;
1049     SGRawValue<bool> * bool_val;
1050     SGRawValue<int> * int_val;
1051     SGRawValue<long> * long_val;
1052     SGRawValue<float> * float_val;
1053     SGRawValue<double> * double_val;
1054     SGRawValue<string> * string_val;
1055   } _value;
1056
1057
1058 };
1059
1060
1061 \f
1062 ////////////////////////////////////////////////////////////////////////
1063 // I/O functions.
1064 ////////////////////////////////////////////////////////////////////////
1065
1066
1067 /**
1068  * Read properties from an XML input stream.
1069  */
1070 bool readProperties (istream &input, SGPropertyNode * start_node,
1071                      const string &base = "");
1072
1073
1074 /**
1075  * Read properties from an XML file.
1076  */
1077 bool readProperties (const string &file, SGPropertyNode * start_node);
1078
1079
1080 /**
1081  * Write properties to an XML output stream.
1082  */
1083 bool writeProperties (ostream &output, const SGPropertyNode * start_node);
1084
1085
1086 /**
1087  * Write properties to an XML file.
1088  */
1089 bool writeProperties (const string &file, const SGPropertyNode * start_node);
1090
1091
1092 /**
1093  * Copy properties from one node to another.
1094  */
1095 bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out);
1096
1097
1098 #endif // __PROPS_HXX
1099
1100 // end of props.hxx