XMLRPCDemarshaller.hpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef PI_PROPERTIES_XMLRPCDESERIALIZER
00039 #define PI_PROPERTIES_XMLRPCDESERIALIZER
00040
00041 #include <xercesc/util/PlatformUtils.hpp>
00042 #include <xercesc/util/TransService.hpp>
00043 #include <xercesc/sax2/SAX2XMLReader.hpp>
00044 #include <xercesc/sax2/XMLReaderFactory.hpp>
00045 #include <xercesc/sax2/DefaultHandler.hpp>
00046 #include <xercesc/sax2/Attributes.hpp>
00047 #include <xercesc/util/XMLUniDefs.hpp>
00048 #include <xercesc/framework/LocalFileInputSource.hpp>
00049 #include <iostream>
00050 #include <fstream>
00051
00052 #include <sstream>
00053 #include <vector>
00054 #include <stack>
00055 #include <map>
00056 #include <string>
00057 #include "../Property.hpp"
00058 #include "StreamProcessor.hpp"
00059 #include "../Marshaller.hpp"
00060 #include <istream>
00061
00062 namespace RTT
00063 {
00064
00065 using std::cerr;
00066 using std::endl;
00067
00068 #ifdef XERCES_CPP_NAMESPACE
00069 using namespace XERCES_CPP_NAMESPACE;
00070 #endif
00071
00072 class RTT_API SAX2XMLRPCHandler : public DefaultHandler
00073 {
00074
00078 PropertyBag &bag;
00079 enum State { STATE_NAME, STATE_BOOLEAN, STATE_CHAR, STATE_INT, STATE_DOUBLE, STATE_STRING, STATE_PROPERTIES};
00080 std::stack<State> state_stack;
00081
00082 public:
00083
00084 SAX2XMLRPCHandler( PropertyBag &b ) : bag( b )
00085 {}
00086
00087 void endElement( const XMLCh* const uri,
00088 const XMLCh* const localname,
00089 const XMLCh* const qname )
00090 {
00091 char *ln = XMLString::transcode( localname );
00092 if ( !strcmp( ln, "xmlrpc" ) )
00093 {
00094 state_stack.pop();
00095 }
00096 else
00097 if ( !strcmp( ln, "boolean" ) )
00098 {
00099
00100 std::stringstream buffer;
00101 buffer << value.sv;
00102
00103 bag.add( new Property<bool>( name, "", true ) );
00104
00105 state_stack.pop();
00106 }
00107 else
00108 if ( !strcmp( ln, "char" ) )
00109 {
00110 bag.add( new Property<char>( name, "", 'Z' ) );
00111 state_stack.pop();
00112 }
00113 else
00114 if ( !strcmp( ln, "int" ) )
00115 {
00116 bag.add( new Property<int>( name, "", 1234 ) );
00117 state_stack.pop();
00118 }
00119 else
00120 if ( !strcmp( ln, "double" ) )
00121 {
00122 bag.add( new Property<double>( name, "", 6.789 ) );
00123 state_stack.pop();
00124 }
00125 else
00126 if ( !strcmp( ln, "string" ) )
00127 {
00128 bag.add( new Property<std::string>( name, "", value.sv ) );
00129 state_stack.pop();
00130 }
00131 else
00132 if ( !strcmp( ln, "name" ) )
00133 {
00134 state_stack.pop();
00135 }
00136 }
00137
00138 void startElement( const XMLCh* const uri,
00139 const XMLCh* const localname,
00140 const XMLCh* const qname,
00141 const Attributes& attributes )
00142 {
00143 char *ln = XMLString::transcode( localname );
00144 if ( !strcmp( ln, "boolean" ) )
00145 state_stack.push( STATE_BOOLEAN );
00146 else
00147 if ( !strcmp( ln, "char" ) )
00148 state_stack.push( STATE_CHAR );
00149 else
00150 if ( !strcmp( ln, "int" ) )
00151 state_stack.push( STATE_INT );
00152 else
00153 if ( !strcmp( ln, "double" ) )
00154 state_stack.push( STATE_DOUBLE );
00155 else
00156 if ( !strcmp( ln, "string" ) )
00157 state_stack.push( STATE_STRING );
00158 else
00159 if ( !strcmp( ln, "xmlrpc" ) )
00160 state_stack.push( STATE_PROPERTIES );
00161 else
00162 if ( !strcmp( ln, "name" ) )
00163 state_stack.push( STATE_NAME );
00164 }
00165 #if 0
00166 void warning( const SAXParseException& exception )
00167 {
00168 cerr << "\nWarning\n";
00169 }
00170 void error( const SAXParseException& exception )
00171 {
00172 cerr << "\nError\n";
00173 }
00174 void fatalError( const SAXParseException& exception )
00175 {
00176 cerr << "\nFatal error\n";
00177 }
00178 #endif
00179 void characters( const XMLCh* const chars, const unsigned int length )
00180 {
00181 char* string_value;
00182 switch ( state_stack.top() )
00183 {
00184 case STATE_NAME:
00185 name = XMLString::transcode( chars );
00186 break;
00187
00188 case STATE_STRING:
00189 value.sv = XMLString::transcode( chars );
00190 break;
00191
00192 case STATE_BOOLEAN:
00193 string_value = XMLString::transcode( chars );
00194
00195 break;
00196
00197 case STATE_INT:
00198 case STATE_CHAR:
00199 case STATE_DOUBLE:
00200 case STATE_PROPERTIES:
00201 break;
00202 }
00203 }
00204
00205
00209 char* name;
00210
00214 union {
00215 int iv;
00216 char *sv;
00217 } value;
00218
00219 };
00220
00221
00226 class RTT_API XMLRPCDemarshaller
00227 : public Demarshaller
00228 {
00229 typedef unsigned short XMLCh;
00230
00231 XMLCh* name;
00232 InputSource* fis;
00233
00234 public:
00235
00239 XMLRPCDemarshaller( const std::string filename ) : name(0), fis(0)
00240 {
00241 XMLPlatformUtils::Initialize();
00242 name = XMLString::transcode( filename.c_str() );
00243 fis = new LocalFileInputSource( name );
00244 delete[] name;
00245 }
00246
00247 ~XMLRPCDemarshaller()
00248 {
00249 delete fis;
00250 XMLPlatformUtils::Terminate();
00251 }
00252
00253 virtual bool deserialize( PropertyBag &v )
00254 {
00255 try
00256 {
00257 XMLPlatformUtils::Initialize();
00258 }
00259 catch ( const XMLException & toCatch )
00260 {
00261 cerr << "Error during initialization! :\n" << endl;
00262 }
00263 catch ( ... )
00264 {
00265 cerr << "other exception" << endl;
00266 }
00267
00268 SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
00269
00270 int errorCount = 0;
00271 try
00272 {
00273 SAX2XMLRPCHandler handler( v );
00274 parser->setContentHandler( &handler );
00275 parser->setErrorHandler( &handler );
00276
00277
00278
00279
00280
00281
00282
00283
00284 parser->parse( *fis );
00285 errorCount = parser->getErrorCount();
00286 }
00287 catch ( const XMLException & toCatch )
00288 {
00289 cerr << "\nAn XML parsing error occurred\n Error: " << endl;
00290 XMLPlatformUtils::Terminate();
00291 return false;
00292 }
00293 catch ( ... )
00294 {
00295 cerr << "General error" << endl;
00296 XMLPlatformUtils::Terminate();
00297 return false;
00298 }
00299 return true;
00300 }
00301
00302 };
00303 }
00304 #endif