43 #ifdef OROPKG_SUPPORT_XERCES_C 44 #include <xercesc/util/PlatformUtils.hpp> 45 #include <xercesc/util/TransService.hpp> 46 #include <xercesc/sax2/SAX2XMLReader.hpp> 47 #include <xercesc/sax2/XMLReaderFactory.hpp> 48 #include <xercesc/sax2/DefaultHandler.hpp> 49 #include <xercesc/sax2/Attributes.hpp> 50 #include <xercesc/util/XMLUniDefs.hpp> 51 #include <xercesc/util/BinMemInputStream.hpp> 52 #include <xercesc/framework/LocalFileInputSource.hpp> 53 #include <xercesc/framework/MemBufInputSource.hpp> 54 #include <xercesc/validators/common/Grammar.hpp> 64 #include "../base/PropertyIntrospection.hpp" 69 #ifdef XERCES_CPP_NAMESPACE 70 using namespace XERCES_CPP_NAMESPACE;
72 using namespace marsh;
75 inline bool XMLChToStdString(
const XMLCh*
const c, std::string& res)
78 chholder = XMLString::transcode( c );
81 XMLString::release( &chholder );
84 log(
Error) <<
"Could not transcode XMLCh* !" <<endlog();
88 inline std::string XMLgetString(
const XMLCh*
const c)
92 chholder = XMLString::transcode( c );
95 XMLString::release( &chholder );
98 log(
Error) <<
"Could not transcode XMLCh* !" <<endlog();
102 class SAX2CPFHandler :
public DefaultHandler
109 std::stack< std::pair<PropertyBag*, Property<PropertyBag>*> > bag_stack;
111 enum Tag { TAG_STRUCT, TAG_SIMPLE, TAG_SEQUENCE, TAG_PROPERTIES, TAG_DESCRIPTION, TAG_VALUE, TAG_UNKNOWN};
112 std::stack<Tag> tag_stack;
118 std::string description;
120 std::string value_string;
124 SAX2CPFHandler( PropertyBag &b ) : bag( b )
126 Property<PropertyBag>* dummy = 0;
127 bag_stack.push(std::make_pair(&bag, dummy));
130 void endElement(
const XMLCh*
const uri,
131 const XMLCh*
const localname,
132 const XMLCh*
const qname )
140 switch ( tag_stack.top() )
143 if ( type ==
"boolean" )
145 if ( value_string ==
"1" || value_string ==
"true")
146 bag_stack.top().first->ownProperty
147 (
new Property<bool>( name, description,
true ) );
148 else if ( value_string ==
"0" || value_string ==
"false" )
149 bag_stack.top().first->ownProperty
150 (
new Property<bool>( name, description,
false ) );
152 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
153 " Value should contain '0' or '1', got '"+ value_string +
"'.").c_str());
155 else if ( type ==
"char" ) {
156 if ( value_string.empty() )
157 bag_stack.top().first->ownProperty(
new Property<char>( name, description,
'\0' ) );
159 if ( value_string.length() != 1 )
160 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
161 " Value should contain a single character, got '"+ value_string +
"'.").c_str());
163 bag_stack.top().first->ownProperty(
new Property<char>( name, description, value_string[0] ) );
165 else if ( type ==
"uchar" || type ==
"octet" ) {
166 if ( value_string.length() != 1 )
167 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
168 " Value should contain a single unsigned character, got '"+ value_string +
"'.").c_str());
170 bag_stack.top().first->ownProperty
171 (
new Property<unsigned char>( name, description, value_string[0] ) );
173 else if ( type ==
"long" || type ==
"short")
176 if ( sscanf(value_string.c_str(),
"%d", &v) == 1)
177 bag_stack.top().first->ownProperty(
new Property<int>( name, description, v ) );
179 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
180 " Value should contain an integer value, got '"+ value_string +
"'.").c_str());
182 else if ( type ==
"ulong" || type ==
"ushort")
185 if ( sscanf(value_string.c_str(),
"%u", &v) == 1)
186 bag_stack.top().first->ownProperty(
new Property<unsigned int>( name, description, v ) );
188 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
189 " Value should contain an integer value, got '"+ value_string +
"'.").c_str());
191 else if ( type ==
"double")
194 if ( sscanf(value_string.c_str(),
"%lf", &v) == 1 )
195 bag_stack.top().first->ownProperty
196 (
new Property<double>( name, description, v ) );
198 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
199 " Value should contain a double value, got '"+ value_string +
"'.").c_str());
201 else if ( type ==
"float")
204 if ( sscanf(value_string.c_str(),
"%f", &v) == 1 )
205 bag_stack.top().first->ownProperty
206 (
new Property<float>( name, description, v ) );
208 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
209 " Value should contain a float value, got '"+ value_string +
"'.").c_str());
211 else if ( type ==
"string")
212 bag_stack.top().first->ownProperty
213 (
new Property<std::string>( name, description, value_string ) );
215 value_string.clear();
223 Property<PropertyBag>* prop = bag_stack.top().second;
225 bag_stack.top().first->ownProperty( prop );
235 case TAG_DESCRIPTION:
237 if ( tag_stack.top() == TAG_STRUCT ) {
239 bag_stack.top().second->setDescription(description);
253 void startElement(
const XMLCh*
const uri,
254 const XMLCh*
const localname,
255 const XMLCh*
const qname,
256 const Attributes& attributes )
259 XMLChToStdString( localname, ln );
261 if ( ln ==
"properties" )
262 tag_stack.push( TAG_PROPERTIES );
264 if ( ln ==
"simple" )
268 tag_stack.push( TAG_SIMPLE );
269 for (
unsigned int ac = 0; ac < attributes.getLength(); ++ac)
272 XMLChToStdString( attributes.getLocalName(ac), an );
275 XMLChToStdString( attributes.getValue(ac), name);
277 else if ( an ==
"type")
279 XMLChToStdString( attributes.getValue(ac), type);
284 if ( ln ==
"struct" || ln ==
"sequence")
289 for (
unsigned int ac = 0; ac < attributes.getLength(); ++ac)
292 XMLChToStdString( attributes.getLocalName(ac), an );
295 XMLChToStdString( attributes.getValue(ac), name);
297 else if ( an ==
"type")
299 XMLChToStdString( attributes.getValue(ac), type);
303 if ( ln ==
"struct" )
304 tag_stack.push( TAG_STRUCT );
306 tag_stack.push( TAG_SEQUENCE );
310 Property<PropertyBag> *prop;
311 prop =
new Property<PropertyBag>(name,
"",PropertyBag(type));
314 bag_stack.push(std::make_pair( &(prop->value()), prop));
317 if ( ln ==
"description")
318 tag_stack.push( TAG_DESCRIPTION );
321 tag_stack.push( TAG_VALUE );
323 log(
Warning) <<
"Unrecognised XML tag :"<< ln <<
": ignoring." << endlog();
324 tag_stack.push( TAG_UNKNOWN );
328 void warning(
const SAXParseException& exception )
331 XMLChToStdString( exception.getMessage(), warn);
333 if ( exception.getPublicId() )
335 XMLChToStdString( exception.getPublicId(), warn);
338 Logger::log() <<
" Column "<< exception.getColumnNumber()<<
" Line " <<exception.getLineNumber()<<
Logger::endl;
342 void error(
const SAXParseException& exception )
346 void fatalError(
const SAXParseException& exception )
350 #if XERCES_VERSION_MAJOR < 3 351 void characters(
const XMLCh*
const chars,
const unsigned int length )
353 void characters(
const XMLCh*
const chars,
const XMLSize_t length )
357 switch ( tag_stack.top() )
359 case TAG_DESCRIPTION:
360 XMLChToStdString( chars, description);
364 XMLChToStdString( chars, value_string);
378 CPFDemarshaller::CPFDemarshaller(
const std::string& filename )
381 Logger::In
in(
"CPFDemarshaller");
384 XMLPlatformUtils::Initialize();
386 catch (
const XMLException & toCatch )
389 XMLChToStdString(toCatch.getMessage(), error);
399 name = XMLString::transcode( filename.c_str() );
400 fis =
new LocalFileInputSource( name );
402 catch ( XMLException& xe )
413 XMLString::release( &name );
416 CPFDemarshaller::~CPFDemarshaller()
419 XMLPlatformUtils::Terminate();
422 bool CPFDemarshaller::deserialize( PropertyBag &v )
427 SAX2XMLReader* parser = 0;
429 XMLPlatformUtils::Initialize();
430 parser = XMLReaderFactory::createXMLReader();
435 XMLPlatformUtils::Terminate();
440 Logger::In
in(
"CPFDemarshaller");
444 SAX2CPFHandler handler( v );
445 parser->setContentHandler( &handler );
446 parser->setErrorHandler( &handler );
447 parser->setFeature( XMLUni::fgSAX2CoreValidation,
false );
448 parser->setFeature( XMLUni::fgXercesValidationErrorAsFatal,
false );
449 parser->setFeature( XMLUni::fgXercesContinueAfterFatalError,
false );
451 parser->setFeature( XMLUni::fgXercesSchemaFullChecking,
false );
452 parser->setFeature( XMLUni::fgXercesDynamic,
true );
453 parser->setFeature( XMLUni::fgSAX2CoreNameSpaces,
true );
454 parser->setFeature( XMLUni::fgSAX2CoreNameSpacePrefixes,
true );
455 parser->setFeature( XMLUni::fgXercesSchema,
false );
459 using namespace detail;
460 parser->setFeature( XMLUni::fgXercesLoadExternalDTD,
false );
462 int length = XMLString::stringLen(
cpf_dtd);
463 XMLByte* buffer =
new XMLByte[length];
464 memcpy( buffer,
cpf_dtd, length );
465 MemBufInputSource dtd(buffer, length,
"internal_cpf.dtd");
466 parser->loadGrammar( dtd, Grammar::DTDGrammarType );
469 parser->parse( *fis );
470 parser->getErrorCount();
472 XMLPlatformUtils::Terminate();
474 catch (
const XMLException & toCatch )
477 if ( toCatch.getSrcFile() ) {
480 Logger::log() << XMLgetString(toCatch.getMessage()) <<Logger::endl;
482 XMLPlatformUtils::Terminate();
485 catch (
const SAXParseException & toCatch )
488 Logger::log() << XMLgetString(toCatch.getMessage()) <<Logger::endl;
489 if ( toCatch.getPublicId() )
491 Logger::log() <<
" At entity "<< XMLgetString(toCatch.getPublicId()) <<Logger::nl;
495 XMLPlatformUtils::Terminate();
498 catch (
const SAXException & toCatch )
501 Logger::log() << XMLgetString(toCatch.getMessage()) <<Logger::endl;
503 XMLPlatformUtils::Terminate();
510 XMLPlatformUtils::Terminate();
static std::ostream & nl(std::ostream &__os)
Insert a newline ' ' in the ostream.
static std::ostream & endl(std::ostream &__os)
static Logger & log()
As Instance(), but more userfriendly.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Logger & in(const std::string &modname)
Inform the Logger of the entry of a module.