![]() |
MAK RTIspy API Documentation for HLA Evolved
|
00001 /********************************************************************* 00002 ** Copyright (c) 2006 MaK Technologies, Inc. 00003 ** All rights reserved. 00004 *********************************************************************/ 00005 /******************************************************************************* 00006 ** $RCSfile: spyXmlBlockElements.h,v $ $Revision: 1.13 $ $State: Exp $ 00007 *******************************************************************************/ 00008 #ifndef DtSpyXmlBlockElements_H_ 00009 #define DtSpyXmlBlockElements_H_ 00010 00011 #include <rtiMsConfig.h> 00012 #include <mtl/env.h> 00013 #include <vlutil/vlExceptions.h> 00014 #include <vlutil/vlSmartPointers.h> 00015 #include <vlutil/vlString.h> 00016 #include <set> 00017 #include <sstream> 00018 #include <iomanip> 00019 00020 using namespace MAKRti; 00021 00022 00023 class DtSpyXmlBlock; 00024 class DtSpyXmlBlockElements; 00025 typedef DtBoost::shared_ptr<DtSpyXmlBlockElements> DtSpyXmlBlockElementsSP; 00026 typedef DtBoost::weak_ptr<DtSpyXmlBlockElements> DtSpyXmlBlockElementsWP; 00027 00028 // Since DtSpyXmlBlockElements are designed to be contained as members of 00029 // DtSpyXmlBlocks, this list uses standard pointers to avoid circular references 00030 // when parent has a shared pointer to child which contains an instance of 00031 // an Element 00032 typedef std::set< DtSpyXmlBlockElements* > DtSpyXmlBlockElementsSet; 00033 00034 // The xmlTagName parameter of DtSpyXmlBlockElement templates must point to 00035 // a global string with external linkage the DtDEFINE_SPY_XML_TAG(tagName) macro 00036 // is provided for convenience to declare valid tags 00037 #define DtDECLARE_SPY_XML_TAG(tagName) extern const char DT_DLL_WWW tagName[]; 00038 #define DtDEFINE_SPY_XML_TAG(tagName, tagString) const char tagName[] = tagString; 00039 00040 00041 // Provides converion from String to native types 00042 // Must be specialized for types with no built in conversion 00043 // TODO: should probably add a format specifier ( ie std::hex ) 00044 // to make this function truly generic 00045 #ifdef __solaris__ 00046 // Solaris cannot specialize templates differentiated solely by return type 00047 template<typename T> 00048 T DtConvertStringToValueType( const DtString& stringRep, T* dummy = 0 ); 00049 00050 // Specialize for strings -> no-op 00051 template<> 00052 DtString DtConvertStringToValueType<DtString>( const DtString& stringRep, DtString* dummy ); 00053 #else 00054 template<typename T> 00055 T DtConvertStringToValueType( const DtString& stringRep ); 00056 00057 // Specialize for strings -> no-op 00058 template<> 00059 DtString DtConvertStringToValueType<DtString>( const DtString& stringRep ); 00060 #endif // __solaris__ 00061 00062 00063 00064 // ABC used to handle pairs of DtSpyXmlBlock Member Data elements and pointers to their XML representation 00065 class DT_DLL_WWW DtSpyXmlBlockElements 00066 { 00067 public: 00068 00069 DtSpyXmlBlockElements( DtString xmlTag, bool isAttribute, DtSpyXmlBlock* parent ); 00070 virtual ~DtSpyXmlBlockElements(); 00071 inline DtEnvValueSP xmlNode() const; 00072 inline bool isAttribute() const; 00073 00074 // Output 00075 DtString type() const; 00076 DtString toString() const; 00077 00078 protected: 00079 00080 virtual void syncElementToValue() = 0; 00081 00082 // Copy and assignment unimplemented since they would have to be shallow copies 00083 DtSpyXmlBlockElements( const DtSpyXmlBlockElements& orig ); 00084 DtSpyXmlBlockElements& operator=( const DtSpyXmlBlockElements& orig ); 00085 00086 protected: 00087 00088 bool myIsXmlAttribute; 00089 DtEnvValueSP myXmlElement; 00090 DtSpyXmlBlock* myParent; 00091 }; 00092 00093 // Specific type for Member Data elements and pointers to their XML representation 00094 template< typename ValueType, bool isXmlAttribute = true > 00095 class DtSpyXmlBlockElement : public DtSpyXmlBlockElements 00096 { 00097 public: 00098 00099 DtSpyXmlBlockElement( const char* xmlTagName, DtSpyXmlBlock* parent ); 00100 DtSpyXmlBlockElement( const char* xmlTagName, ValueType value, DtSpyXmlBlock* parent ); 00101 virtual ~DtSpyXmlBlockElement(); 00102 00103 void setValue( ValueType value ); 00104 ValueType value() const; 00105 00106 operator ValueType() const; 00107 DtSpyXmlBlockElement& operator=( const ValueType& val ); 00108 00109 protected: 00110 00111 virtual void syncElementToValue(); 00112 00113 // Copy and assignment unimplemented since they would have to be shallow copies 00114 DtSpyXmlBlockElement( const DtSpyXmlBlockElement& orig ); 00115 DtSpyXmlBlockElement& operator=( const DtSpyXmlBlockElement& orig ); 00116 00117 protected: 00118 00119 ValueType myValue; 00120 }; 00121 00122 00123 DtEnvValueSP DtSpyXmlBlockElements::xmlNode() const { return myXmlElement; } 00124 bool DtSpyXmlBlockElements::isAttribute() const { return myIsXmlAttribute; } 00125 00126 template< typename ValueType, bool isXmlAttribute > 00127 DtSpyXmlBlockElement<ValueType, isXmlAttribute>::DtSpyXmlBlockElement( const char* xmlTagName, DtSpyXmlBlock* parent ) : 00128 DtSpyXmlBlockElements( xmlTagName, isXmlAttribute, parent ), 00129 #ifdef __solaris__ 00130 myValue( DtConvertStringToValueType<ValueType>( myXmlElement->value(), 0 )) {} 00131 #else 00132 myValue( DtConvertStringToValueType<ValueType>( myXmlElement->value() )) {} 00133 #endif //__solaris__ 00134 00135 template<typename ValueType, bool isXmlAttribute > 00136 DtSpyXmlBlockElement<ValueType, isXmlAttribute>::DtSpyXmlBlockElement( const char* xmlTagName, ValueType value, DtSpyXmlBlock* parent ) : 00137 DtSpyXmlBlockElements( xmlTagName, isXmlAttribute, parent ), 00138 myValue( value ) 00139 { 00140 myXmlElement->setValue( myValue ); 00141 } 00142 00143 00144 template<typename ValueType, bool isXmlAttribute > 00145 DtSpyXmlBlockElement<ValueType, isXmlAttribute>::~DtSpyXmlBlockElement() {} 00146 00147 template< typename ValueType, bool isXmlAttribute > 00148 void DtSpyXmlBlockElement<ValueType, isXmlAttribute>::syncElementToValue() { myXmlElement->setValue( myValue ); } 00149 00150 template< typename ValueType, bool isXmlAttribute > 00151 void DtSpyXmlBlockElement<ValueType, isXmlAttribute>::setValue( ValueType value ) 00152 { 00153 myValue = value; 00154 myXmlElement->setValue( myValue ); 00155 } 00156 00157 template< typename ValueType, bool isXmlAttribute > 00158 ValueType DtSpyXmlBlockElement<ValueType, isXmlAttribute>::value() const { return myValue; } 00159 00160 template< typename ValueType, bool isXmlAttribute > 00161 DtSpyXmlBlockElement<ValueType, isXmlAttribute>::operator ValueType() const 00162 { 00163 return myValue; 00164 } 00165 00166 template< typename ValueType, bool isXmlAttribute > 00167 DtSpyXmlBlockElement<ValueType, isXmlAttribute>& 00168 DtSpyXmlBlockElement<ValueType, isXmlAttribute>::operator=( const ValueType& val ) 00169 { 00170 setValue( val ); 00171 return *this; 00172 } 00173 00174 00175 #ifdef __solaris__ 00176 // Solaris cannot specialize templates differentiated solely by return type 00177 template<typename T> 00178 T DtConvertStringToValueType( const DtString& stringRep, T* dummy ) 00179 #else 00180 template<typename T> 00181 T DtConvertStringToValueType( const DtString& stringRep ) 00182 #endif // __solaris__ 00183 { 00184 T nativeRep; 00185 std::istringstream convert( stringRep.c_str() ); 00186 convert >> nativeRep; 00187 if ( convert.fail() ) 00188 { 00189 DtString error( "Conversion Failure - failed to convert: " ); 00190 DtTHROW_NEW( DtUnknownException, error + stringRep ); 00191 } 00192 return nativeRep; 00193 } 00194 00195 00196 #endif // DtSpyXmlBlockElements_H_ 00197