Changeset 122
- Timestamp:
- 06/19/08 22:20:11 (17 years ago)
- Files:
-
- 4 modified
Legend:
- Unmodified
- Added
- Removed
-
bdm/userinfo.cpp
r90 r122 11 11 // 12 12 13 #include <itpp/itbase.h>14 13 #include "userinfo.h" 14 15 GlobalXercesConnector::GlobalXercesConnector() 16 { 17 // initialize the XML library 18 XMLPlatformUtils::Initialize(); 19 20 // get a serializer, an instance of DOMWriter (the "LS" stands for load-save). 21 pImplementation = DOMImplementationRegistry::getDOMImplementation(L"LS"); 22 23 pSerializer = ( (DOMImplementationLS*)pImplementation )->createDOMWriter(); 24 // set user specified end of line sequence and output encoding 25 pSerializer->setNewLine( L"\n" ); 26 // optionally, set the format-pretty-print feature 27 if (pSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true)) 28 pSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true); 29 30 pParser = new XercesDOMParser; 31 pParser->setValidationScheme(XercesDOMParser::Val_Auto); 32 pParser->setDoNamespaces(false); 33 pParser->setDoSchema(false); 34 } 35 36 GlobalXercesConnector::~GlobalXercesConnector() 37 { 38 delete pParser; 39 delete pSerializer; 40 41 // terminate the XML library 42 XMLPlatformUtils::Terminate(); 43 } 44 45 string GlobalXercesConnector::XMLCh2str( const XMLCh* const XMLCh_str ) 46 { 47 char *local = XMLString::transcode( XMLCh_str ); 48 string res = local; 49 XMLString::release( &local ); 50 return res; 51 } 52 53 bool GlobalXercesConnector::Comparator::operator()( const XMLCh* const a , const XMLCh* const b) const 54 { 55 return ( XMLString::compareString(a,b) > 0); 56 } 57 58 const GlobalXercesConnector XMLConnector; 59 60 ////////////////////// 61 62 Attribute::Attribute( const string name ) 63 : transcodedName ( XMLString::transcode( name.c_str() ) ) 64 { 65 XMLString::lowerCase( transcodedName ); 66 } 67 68 Attribute::~Attribute() 69 { 70 XMLString::release( (XMLCh**)&transcodedName ); 71 } 72 73 void Attribute::Attach( MappedAttributes &externalAttributes) 74 { 75 pair<const XMLCh* const, Attribute* const> newPair( transcodedName, this ); 76 externalAttributes.insert(newPair); 77 } 78 79 void Attribute::FillAttribute(DOMElement &element) 80 { 81 DOMDocument* pDoc = element.getOwnerDocument(); 82 DOMAttr* pAttribute = pDoc->createAttribute( transcodedName ); 83 84 const string attributeValue = Get(); 85 XMLCh* transcodedValue = XMLString::transcode( attributeValue.c_str() ); 86 pAttribute->setValue( transcodedValue ); 87 XMLString::release( &transcodedValue ); 88 89 element.setAttributeNode(pAttribute); 90 } 91 92 DoubleAttribute::DoubleAttribute( const string name) 93 : Attribute( name ) 94 { 95 value = 0; 96 } 97 98 void DoubleAttribute::Set( const string str ) 99 { 100 value = atof( str.c_str() ); 101 } 102 103 const string DoubleAttribute::Get() 104 { 105 char buffer[50]; 106 sprintf( buffer, "%f", value ); 107 return string( buffer ); 108 } 109 110 111 /*! 112 @brief User Info base class 113 114 This class is used to store information about parameters of an object. It support loading and saving of the information and, potentially, interaction with the user. 115 */ 116 IntAttribute::IntAttribute( const string name ) 117 : Attribute( name ) 118 { 119 value = 0; 120 } 121 122 void IntAttribute::Set( const string str ) 123 { 124 value = atoi( str.c_str() ); 125 } 126 127 const string IntAttribute::Get() 128 { 129 char buffer[50]; 130 sprintf( buffer, "%d", value ); 131 return string( buffer ); 132 } 133 134 135 /*! 136 @brief User Info base class 137 138 This class is used to store information about parameters of an object. It support loading and saving of the information and, potentially, interaction with the user. 139 */ 140 StringAttribute::StringAttribute( const string name ) 141 : Attribute( name ), 142 value("") 143 { 144 } 145 146 void StringAttribute::Set( const string str ) 147 { 148 value = str.c_str(); 149 } 150 151 const string StringAttribute::Get() 152 { 153 return value; 154 } 155 156 -
bdm/userinfo.h
r98 r122 1 // 2 // C++ Interface: userinfo 3 // 4 // Description: 5 // 6 // 7 // Author: smidl <smidl@utia.cas.cz>, (C) 2008 8 // 9 // Copyright: See COPYING file that comes with this distribution 10 // 11 // 12 #include <itpp/itbase.h> 13 #include <itpp/base/mat.h> 14 15 using std::cout; 16 using std::endl; 1 #ifndef UI_H 2 #define UI_H 3 4 #include <sstream> 5 #include <iostream> 6 #include <stdio.h> 7 #include <string> 8 #include <map> 9 #include <utility> 10 #include <xercesc/dom/DOM.hpp> 11 #include <xercesc/util/PlatformUtils.hpp> 12 #include <xercesc/util/XMLString.hpp> 13 #include <iostream> 14 #include <xercesc/framework/LocalFileFormatTarget.hpp> 15 #include <xercesc/framework/LocalFileInputSource.hpp> 16 #include <xercesc/dom/DOMWriter.hpp> 17 #include <xercesc/parsers/XercesDOMParser.hpp> 18 19 #ifdef XERCES_CPP_NAMESPACE_USE 20 XERCES_CPP_NAMESPACE_USE 21 #endif 22 17 23 using std::string; 24 using namespace std; 25 26 27 /*! 28 @brief Xerces interface class 29 30 This class is used to interact with the Xerces library. 31 */ 32 class GlobalXercesConnector 33 { 34 public: 35 //! DOMImplementation is a base class for the all DOM oparations 36 DOMImplementation *pImplementation; 37 //! This DOMWriter is used to export internal data into xml files 38 DOMWriter *pSerializer; 39 //! This DOMWriter is used to import external data from xml files 40 XercesDOMParser *pParser; 41 42 43 //!default constructor 44 GlobalXercesConnector(); 45 //!destructor 46 ~GlobalXercesConnector(); 47 48 49 //! function transcodes Xerces' XMLCh-based strings into C++ strings 50 static string XMLCh2str( const XMLCh* const XMLCh_str ); 51 52 class Comparator 53 { 54 public: 55 //! operator compares two XMLCh strings and wheather the first is alphabethically higher 56 bool operator()( const XMLCh* const a , const XMLCh* const b) const; 57 }; 58 }; 59 60 //! The only global instance of the GlobalXercesConnector class 61 extern const GlobalXercesConnector XMLConnector; 62 18 63 19 64 /*! … … 22 67 This class is used to store information about parameters of an object. It support loading and saving of the information and, potentially, interaction with the user. 23 68 */ 24 class uibase { 69 70 class Attribute 71 { 72 private: 73 //! Name which identifies the attribute among others related to the same XML-tag, 74 //! must be unique within its context! 75 XMLCh* const transcodedName; 76 77 public: 78 //! Type definition of mapping which transforms names to the related attributes 79 typedef map<const XMLCh* const, Attribute* const, GlobalXercesConnector::Comparator> MappedAttributes; 80 81 //! The only constructor which fills the transcodedName attribute 82 Attribute( const string name ); 83 //! Destructor 84 ~Attribute(); 85 86 //! Set accessor to this attribute converting input string into a properly-typed value 87 virtual void Set( const string str ) = 0; 88 //! Get accessor converting stored value into a string 89 virtual const string Get() = 0; 90 //! This method is the key method to connect the attribute to the related UI element 91 void Attach( MappedAttributes &externalAttributes); 92 //! This method add and DOMAttribute node to the DOMElement passed as an argument 93 void FillAttribute(DOMElement &element); 94 }; 95 96 /*! 97 @brief Class encapsulating all the necessary stuff to work with the double attribute 98 */ 99 class DoubleAttribute: public Attribute 100 { 101 public: 102 double value; 103 DoubleAttribute( const string name); 104 void Set( const string str ); 105 const string Get(); 106 }; 107 108 109 /*! 110 @brief Class encapsulating all the necessary stuff to work with an int attribute 111 */ 112 class IntAttribute : public Attribute 113 { 114 public: 115 int value; 116 IntAttribute( const string name ); 117 void Set( const string str ); 118 const string Get(); 119 }; 120 121 /*! 122 @brief Class encapsulating all the necessary stuff to work with a string attribute 123 */ 124 class StringAttribute : public Attribute 125 { 126 public: 127 string value; 128 StringAttribute( const string name ); 129 void Set( const string str ); 130 const string Get(); 131 }; 132 133 /*! 134 @brief UserInfoCore class is for internal purposes only. Use UserInfo<T> instead. 135 136 The raison d'etre of this class is to allow pointers to (the main part of) 137 UserInfo<T> objects even for different generic types. 138 */ 139 class UserInfoCore 140 { 141 public: 142 //! Fills internal attributes and descendant elements according DOMElement 143 virtual void ParseElement(DOMElement *element) = 0; 144 145 //! Fills DOMElement according internal attributes and descendant elements 146 virtual void FillElement(DOMElement &element) = 0; 147 }; 148 149 /*! 150 @brief The main user info template class 151 152 You should derive this class whenever you need new UserInfo. 153 */ 154 template<typename T> class UserInfo : public UserInfoCore 155 { 156 private: 157 //! Name which identifies the element among others related to the same XML-tag, 158 //! must be unique within its context! 159 XMLCh* transcodedName; 160 161 //! Type definition of mapping which transforms names to the related elements 162 typedef map<const XMLCh* const, UserInfoCore* const, GlobalXercesConnector::Comparator> MappedElements; 163 25 164 protected: 26 //! String identifier of a field 27 string name; 28 //! Explanation for a user what the field means 29 string help; 30 //! Possible parent of the userinfo 31 uibase* parent; 32 //! Indentation level, i.e. number of parents 33 int ilevel; 34 public: 35 //!Default constructor 36 uibase ( string com = "Abstract class, please ignore!", uibase* par=NULL ) :name ( com ),help ( "" ),parent ( par ) { 37 if ( parent!=NULL ) {ilevel=parent->get_level() +1;} 38 else {ilevel =0;} 39 } 40 41 //! returns a summary of its contents (used in dialogs) 42 virtual void getsummary ( std::string &S ) {}; 43 44 //! interaction with the user 45 virtual void askuser() {}; 46 47 //! test if the info is valid 48 virtual bool isvalid() {return true;} 49 //! for future use 50 virtual ~uibase() {}; 51 //! Save to file 52 virtual void save ( std::ostream &os ) { 53 os.width(ilevel); 54 os.fill(' '); 55 os<<"#"<<help<<endl; 56 os.width(ilevel); 57 os.fill(' '); 58 os<<name<<" = "; 165 //! MappiLength of the output vector 166 MappedElements elements; 167 //! Length of the output vector 168 Attribute::MappedAttributes attributes; 169 170 public: 171 //! Explanation for an user is the only obligatory attribute 172 StringAttribute help; 173 174 //! The only constructor which fills both the transcodedName and the help attribute 175 UserInfo<T>( 176 const string name, 177 const string help_msg = "" ) 178 : help("help"), 179 transcodedName( XMLString::transcode( name.c_str() ) ) 180 { 181 XMLString::upperCase( transcodedName ); 182 help.Attach( attributes ); 183 help.value = help_msg; 59 184 }; 60 //! load from file 61 virtual void load ( std::istream &is ) { 62 char tmp[200]; 63 is.ignore ( ilevel+1,'#' ); // +1 is for # 64 is.getline ( tmp,200 );help=tmp; 65 is.ignore ( ilevel,'\0' ); 66 is.getline ( tmp,200,'=' ); name=tmp; 67 }; 185 //! Destructor 186 ~UserInfo<T>() 187 { 188 XMLString::release( (XMLCh**)&transcodedName ); 189 } 190 191 //! returns object of templated type filled with data stored in this UserInfo instance 192 virtual T* build(void) = 0; 193 194 //! Save UserInfo to the file (typically with an XML extension) 195 void Save ( char* fileName ) 196 { 197 XMLCh* transcodedFileName = XMLString::transcode( fileName ); 198 LocalFileFormatTarget outputTarget( transcodedFileName ); 199 XMLString::release( &transcodedFileName ); 200 201 DOMDocument* pDoc = XMLConnector.pImplementation->createDocument( L"M3K USER INFO", L"ROOT", NULL ); 202 DOMElement *pRoot = pDoc->getDocumentElement(); 203 204 FillElement( *pRoot ); 205 206 XMLConnector.pSerializer->writeNode( &outputTarget, *pDoc); 207 delete pDoc; 208 } 209 //! Load UserInfo from the file (typically with an XML extension) 210 void Load ( char* fileName ) 211 { 212 bool bFailed = false; 213 214 try 215 { 216 XMLCh* transcodedFileName = XMLString::transcode( fileName ) ; 217 const LocalFileInputSource inputSource( transcodedFileName ); 218 XMLString::release( &transcodedFileName ); 219 220 XMLConnector.pParser->parse( inputSource ); 221 bFailed = ( XMLConnector.pParser->getErrorCount() != 0 ); 222 } 223 catch (...) 224 { 225 bFailed = true; 226 } 227 228 if( !bFailed) 229 { 230 DOMDocument *pDoc = XMLConnector.pParser->getDocument(); 231 DOMElement *pRoot = pDoc->getDocumentElement(); 232 bFailed = true; 233 for( DOMNode* node = pRoot->getFirstChild(); node != NULL; node = node->getNextSibling() ) 234 if( node->getNodeType() == DOMNode::ELEMENT_NODE ) 235 { 236 ParseElement( (DOMElement*) node ); 237 bFailed = false; 238 break; 239 } 240 } 241 242 if( bFailed ) 243 { 244 // exception?! 245 } 246 } 247 //! This method is the key method to connect the element to its parent UI element 248 void Attach( MappedElements &externalElements) 249 { 250 pair<const XMLCh* const, UserInfoCore* const> newPair( transcodedName, this ); 251 externalElements.insert(newPair); 252 } 68 253 69 //!access function 70 int get_level(){return ilevel;} 71 }; 72 73 //! User info for scalars 74 template<class T> 75 class uiscalar : public uibase { 76 protected: 77 //! Value 78 T N; 79 public: 80 //!Default constructor 81 uiscalar ( std::string com, uibase* par =NULL) :uibase ( com,par ) {N=T ( 0 );}; 82 83 void getsummary ( std::string &S ) {S="Scalar";}; 84 85 void askuser () {}; 86 87 void save ( std::ostream &os ) {uibase::save ( os );os<<N<<endl;} 88 void load ( std::istream &is ) {uibase::load ( is );is>>N;} 89 //! for future use 90 ~uiscalar() {}; 91 92 //! access function 93 void set_value ( T N0 ) {N=N0;} 94 }; 95 96 //! User info for strings 97 class uistring : public uibase { 98 protected: 99 //! Values 100 std::string S; 101 public: 102 void getsummary ( std::string &S ) {S="String";}; 103 104 //!Default constructor 105 uistring ( std::string com , uibase* par=NULL) :uibase ( com,par ) {} 106 107 void askuser () {}; 108 109 void save ( std::ostream &os ) {uibase::save ( os );os<<S<<endl;} 110 void load ( std::istream &is ) {uibase::load ( is );is>>S;} 111 112 ~uistring() {}; 113 //! access function 114 void set_value ( std::string S0 ) {S=S0;} 115 }; 116 117 //! User info for vectors 118 template<class T> 119 class uivector : public uibase { 120 protected: 121 //! Value 122 itpp::Vec<T> V; 123 public: 124 void getsummary ( std::string &S ) { S="Vector of length "+ V.length();}; 125 126 //!Default constructor 127 uivector ( std::string com, uibase* par=NULL ) :uibase ( com,par ) {}; 128 129 void askuser () {}; 130 131 void save ( std::ostream &os ) {uibase::save ( os );os<<V<<endl;;} 132 void load ( std::istream &is ) {uibase::load ( is );is>>V;} 133 134 //! access function 135 void set_value ( itpp::Vec<T> V0 ) {V=V0;} 136 137 }; 138 139 //! User info for matrices 140 template<class T> 141 class uimatrix : public uibase { 142 protected: 143 //! Value 144 itpp::Mat<T> M; 145 146 public: 147 //!Default constructor 148 uimatrix ( std::string com, uibase* par=NULL ) :uibase ( com,par ) {} 149 150 void getsummary ( std::string &S ) { S="Matrix ";}; 151 152 void askuser () {}; 153 154 void save ( std::ostream &os ) {uibase::save ( os );os<<M<<endl;} 155 void load ( std::istream &is ) {uibase::load ( is );is>>M;} 156 157 //! access function 158 void set_value ( itpp::Mat<T> M0 ) {M=M0;} 159 }; 160 161 162 typedef uimatrix<double> uimat; 163 typedef uimatrix<int> uiimat; 164 165 typedef uivector<double> uivec; 166 typedef uivector<int> uiivec; 167 254 void ParseElement(DOMElement *element) 255 { 256 DOMNodeList* nodeList = element->getChildNodes(); 257 if( nodeList ) 258 for( int i = 0; i < nodeList->getLength(); i++ ) 259 { 260 DOMNode* node = nodeList->item(i); 261 if( node->getNodeType() == DOMNode::ELEMENT_NODE ) 262 { 263 DOMElement* childElement = (DOMElement*) node; 264 MappedElements::const_iterator iter = elements.find( childElement->getTagName() ); 265 266 if( iter != elements.end()) 267 iter->second->ParseElement( childElement ); 268 } 269 } 270 271 DOMNamedNodeMap* nodeMap = element->getAttributes(); 272 if( nodeMap ) 273 for( int i = 0; i < nodeMap->getLength(); i++ ) 274 { 275 DOMNode* node = nodeMap->item(i); 276 if( node->getNodeType() == DOMNode::ATTRIBUTE_NODE ) 277 { 278 DOMAttr* attribute = (DOMAttr*) node; 279 Attribute::MappedAttributes::const_iterator iter = attributes.find( attribute->getName() ); 280 281 if( iter != attributes.end()) 282 { 283 string attributeValue = GlobalXercesConnector::XMLCh2str( attribute->getValue() ); 284 iter->second->Set( attributeValue ); 285 } 286 } 287 } 288 } 289 290 void FillElement(DOMElement &element) 291 { 292 DOMDocument* pDoc = element.getOwnerDocument(); 293 294 DOMElement* pHead = pDoc->createElement( transcodedName ); 295 element.appendChild( pHead ); 296 297 for( MappedElements::const_iterator iter = elements.begin(); iter != elements.end(); iter++) 298 iter->second->FillElement( *pHead ); 299 300 for( Attribute::MappedAttributes::iterator iter = attributes.begin(); iter != attributes.end(); iter++) 301 iter->second->FillAttribute( *pHead ); 302 } 303 }; 304 305 #endif // #ifndef UI_H -
tests/CMakeLists.txt
r113 r122 50 50 target_link_libraries (testKF_QR ${BdmLibs}) 51 51 target_link_libraries (testKF_QRexh ${BdmLibs}) 52 target_link_libraries (testUI ${BdmLibs} )52 target_link_libraries (testUI ${BdmLibs} ${XERCES_LIBRARIES}) 53 53 54 54 -
tests/testUI.cpp
r90 r122 1 #include <itpp/itbase.h>2 #include <fstream>3 1 #include "userinfo.h" 4 2 5 //These lines are needed for use of cout and endl 6 using namespace std; 3 class Engine 4 { 5 public: 6 string producer; 7 double consumption; 8 9 Engine( string producer, double consumption ) 10 : producer( producer ), 11 consumption( consumption ) 12 { 13 } 14 }; 15 16 //! User info for strings 17 class EngineUI : public UserInfo<Engine> 18 { 19 public: 20 StringAttribute producer; 21 DoubleAttribute consumption; 22 23 EngineUI() 24 : UserInfo( "engine", "type of engine" ), 25 producer( "producer"), 26 consumption( "consumption") 27 { 28 producer.Attach( attributes ); 29 consumption.Attach( attributes ); 30 } 31 32 Engine* build() 33 { 34 return new Engine( producer.value, consumption.value ); 35 } 36 }; 37 38 39 class Car 40 { 41 public: 42 string color; 43 int year; 44 Engine engine; 45 46 Car( string color, int year, Engine engine) 47 : color( color ), 48 year( year ), 49 engine( engine ) 50 { 51 } 52 }; 53 54 //! User info for strings 55 class CarUI : public UserInfo<Car> 56 { 57 public: 58 EngineUI engine; 59 60 StringAttribute color; 61 IntAttribute year; 62 63 CarUI() 64 : UserInfo("car", "type of a car"), 65 color( "color"), 66 year( "year" ) 67 { 68 engine.Attach( elements ); 69 70 color.Attach( attributes ); 71 year.Attach( attributes ); 72 } 73 74 Car* build() 75 { 76 Engine* pEng = engine.build(); 77 return new Car(color.value, year.value,*pEng); 78 } 79 }; 80 7 81 8 82 int main() 9 83 { 10 uiscalar<double> uisc("Sc"); 11 uiscalar<double> uisc2(""); 12 uivec uiv("VEc"); 13 uivec uiv2("V"); 14 uistring uist("Str"); 15 uistring uist2("S"); 16 uimat uim("Mat"); 17 uimat uim2("M"); 18 19 //SET values 20 21 uisc.set_value(0.5); 22 uiv.set_value(itpp::vec_2(1.3,1.7)); 23 uist.set_value("Wow this is cool!"); 24 uim.set_value(itpp::mat_2x2(1.1,1.2,1.3,1.4)); 25 26 ofstream OF; 27 OF.open("testUI.exb"); 28 uisc.save(OF); 29 uiv.save(OF); 30 uist.save(OF); 31 uim.save(OF); 32 OF.close(); 33 34 ifstream IF; 35 IF.open("testUI.exb"); 36 uisc2.load(IF); 37 uiv2.load(IF); 38 uist2.load(IF); 39 uim2.load(IF); 40 IF.close(); 41 42 //Exit program: 84 CarUI car; 85 86 car.Save( "car.xml" ); 87 88 /* 89 car.Load( "car.xml" ); 90 Car *pDefaultCar = car.build(); 91 cout << "our car has " << pDefaultCar->color << " color"; 92 delete pDefaultCar; 93 // */ 94 95 getchar(); 43 96 return 0; 97 } 44 98 45 }