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 "MarshallInterface.hpp"
00060 #include <istream>
00061
00062 namespace RTT
00063 { namespace marsh {
00064
00065
00066 using std::cerr;
00067 using std::endl;
00068
00069 #ifdef XERCES_CPP_NAMESPACE
00070 using namespace XERCES_CPP_NAMESPACE;
00071 #endif
00072
00073 class RTT_API SAX2XMLRPCHandler : public DefaultHandler
00074 {
00075
00079 PropertyBag &bag;
00080 enum State { STATE_NAME, STATE_BOOLEAN, STATE_CHAR, STATE_INT, STATE_DOUBLE, STATE_STRING, STATE_PROPERTIES};
00081 std::stack<State> state_stack;
00082
00083 public:
00084
00085 SAX2XMLRPCHandler( PropertyBag &b ) : bag( b )
00086 {}
00087
00088 void endElement( const XMLCh* const uri,
00089 const XMLCh* const localname,
00090 const XMLCh* const qname )
00091 {
00092 char *ln = XMLString::transcode( localname );
00093 if ( !strcmp( ln, "xmlrpc" ) )
00094 {
00095 state_stack.pop();
00096 }
00097 else
00098 if ( !strcmp( ln, "boolean" ) )
00099 {
00100
00101 std::stringstream buffer;
00102 buffer << value.sv;
00103
00104 bag.add( new Property<bool>( name, "", true ) );
00105
00106 state_stack.pop();
00107 }
00108 else
00109 if ( !strcmp( ln, "char" ) )
00110 {
00111 bag.add( new Property<char>( name, "", 'Z' ) );
00112 state_stack.pop();
00113 }
00114 else
00115 if ( !strcmp( ln, "int" ) )
00116 {
00117 bag.add( new Property<int>( name, "", 1234 ) );
00118 state_stack.pop();
00119 }
00120 else
00121 if ( !strcmp( ln, "double" ) )
00122 {
00123 bag.add( new Property<double>( name, "", 6.789 ) );
00124 state_stack.pop();
00125 }
00126 else
00127 if ( !strcmp( ln, "string" ) )
00128 {
00129 bag.add( new Property<std::string>( name, "", value.sv ) );
00130 state_stack.pop();
00131 }
00132 else
00133 if ( !strcmp( ln, "name" ) )
00134 {
00135 state_stack.pop();
00136 }
00137 }
00138
00139 void startElement( const XMLCh* const uri,
00140 const XMLCh* const localname,
00141 const XMLCh* const qname,
00142 const Attributes& attributes )
00143 {
00144 char *ln = XMLString::transcode( localname );
00145 if ( !strcmp( ln, "boolean" ) )
00146 state_stack.push( STATE_BOOLEAN );
00147 else
00148 if ( !strcmp( ln, "char" ) )
00149 state_stack.push( STATE_CHAR );
00150 else
00151 if ( !strcmp( ln, "int" ) )
00152 state_stack.push( STATE_INT );
00153 else
00154 if ( !strcmp( ln, "double" ) )
00155 state_stack.push( STATE_DOUBLE );
00156 else
00157 if ( !strcmp( ln, "string" ) )
00158 state_stack.push( STATE_STRING );
00159 else
00160 if ( !strcmp( ln, "xmlrpc" ) )
00161 state_stack.push( STATE_PROPERTIES );
00162 else
00163 if ( !strcmp( ln, "name" ) )
00164 state_stack.push( STATE_NAME );
00165 }
00166 #if 0
00167 void warning( const SAXParseException& exception )
00168 {
00169 cerr << "\nWarning\n";
00170 }
00171 void error( const SAXParseException& exception )
00172 {
00173 cerr << "\nError\n";
00174 }
00175 void fatalError( const SAXParseException& exception )
00176 {
00177 cerr << "\nFatal error\n";
00178 }
00179 #endif
00180 void characters( const XMLCh* const chars, const unsigned int length )
00181 {
00182 char* string_value;
00183 switch ( state_stack.top() )
00184 {
00185 case STATE_NAME:
00186 name = XMLString::transcode( chars );
00187 break;
00188
00189 case STATE_STRING:
00190 value.sv = XMLString::transcode( chars );
00191 break;
00192
00193 case STATE_BOOLEAN:
00194 string_value = XMLString::transcode( chars );
00195
00196 break;
00197
00198 case STATE_INT:
00199 case STATE_CHAR:
00200 case STATE_DOUBLE:
00201 case STATE_PROPERTIES:
00202 break;
00203 }
00204 }
00205
00206
00210 char* name;
00211
00215 union {
00216 int iv;
00217 char *sv;
00218 } value;
00219
00220 };
00221
00222
00227 class RTT_API XMLRPCDemarshaller
00228 : public DemarshallInterface
00229 {
00230 typedef unsigned short XMLCh;
00231
00232 XMLCh* name;
00233 InputSource* fis;
00234
00235 public:
00236
00240 XMLRPCDemarshaller( const std::string filename ) : name(0), fis(0)
00241 {
00242 XMLPlatformUtils::Initialize();
00243 name = XMLString::transcode( filename.c_str() );
00244 fis = new LocalFileInputSource( name );
00245 delete[] name;
00246 }
00247
00248 ~XMLRPCDemarshaller()
00249 {
00250 delete fis;
00251 XMLPlatformUtils::Terminate();
00252 }
00253
00254 virtual bool deserialize( PropertyBag &v )
00255 {
00256 try
00257 {
00258 XMLPlatformUtils::Initialize();
00259 }
00260 catch ( const XMLException & toCatch )
00261 {
00262 cerr << "Error during initialization! :\n" << endl;
00263 }
00264 catch ( ... )
00265 {
00266 cerr << "other exception" << endl;
00267 }
00268
00269 SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
00270
00271 int errorCount = 0;
00272 try
00273 {
00274 SAX2XMLRPCHandler handler( v );
00275 parser->setContentHandler( &handler );
00276 parser->setErrorHandler( &handler );
00277
00278
00279
00280
00281
00282
00283
00284
00285 parser->parse( *fis );
00286 errorCount = parser->getErrorCount();
00287 }
00288 catch ( const XMLException & toCatch )
00289 {
00290 cerr << "\nAn XML parsing error occurred\n Error: " << endl;
00291 XMLPlatformUtils::Terminate();
00292 return false;
00293 }
00294 catch ( ... )
00295 {
00296 cerr << "General error" << endl;
00297 XMLPlatformUtils::Terminate();
00298 return false;
00299 }
00300 return true;
00301 }
00302
00303 };
00304 }}
00305 #endif