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 ==
"llong")
194 if ( sscanf(value_string.c_str(),
"%lld", &v) == 1)
195 bag_stack.top().first->ownProperty(
new Property<long long>( name, description, v ) );
197 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
198 " Value should contain an integer value, got '"+ value_string +
"'.").c_str());
200 else if ( type ==
"ullong")
202 unsigned long long v;
203 if ( sscanf(value_string.c_str(),
"%llu", &v) == 1)
204 bag_stack.top().first->ownProperty(
new Property<unsigned long long>( name, description, v ) );
206 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
207 " Value should contain an integer value, got '"+ value_string +
"'.").c_str());
209 else if ( type ==
"double")
212 if ( sscanf(value_string.c_str(),
"%lf", &v) == 1 )
213 bag_stack.top().first->ownProperty
214 (
new Property<double>( name, description, v ) );
216 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
217 " Value should contain a double value, got '"+ value_string +
"'.").c_str());
219 else if ( type ==
"float")
222 if ( sscanf(value_string.c_str(),
"%f", &v) == 1 )
223 bag_stack.top().first->ownProperty
224 (
new Property<float>( name, description, v ) );
226 throw SAXException(std::string(
"Wrong value for property '"+type+
"'." \
227 " Value should contain a float value, got '"+ value_string +
"'.").c_str());
229 else if ( type ==
"string")
230 bag_stack.top().first->ownProperty
231 (
new Property<std::string>( name, description, value_string ) );
233 value_string.clear();
241 Property<PropertyBag>* prop = bag_stack.top().second;
243 bag_stack.top().first->ownProperty( prop );
253 case TAG_DESCRIPTION:
255 if ( tag_stack.top() == TAG_STRUCT ) {
257 bag_stack.top().second->setDescription(description);
271 void startElement(
const XMLCh*
const uri,
272 const XMLCh*
const localname,
273 const XMLCh*
const qname,
274 const Attributes& attributes )
277 XMLChToStdString( localname, ln );
279 if ( ln ==
"properties" )
280 tag_stack.push( TAG_PROPERTIES );
282 if ( ln ==
"simple" )
286 tag_stack.push( TAG_SIMPLE );
287 for (
unsigned int ac = 0; ac < attributes.getLength(); ++ac)
290 XMLChToStdString( attributes.getLocalName(ac), an );
293 XMLChToStdString( attributes.getValue(ac), name);
295 else if ( an ==
"type")
297 XMLChToStdString( attributes.getValue(ac), type);
302 if ( ln ==
"struct" || ln ==
"sequence")
307 for (
unsigned int ac = 0; ac < attributes.getLength(); ++ac)
310 XMLChToStdString( attributes.getLocalName(ac), an );
313 XMLChToStdString( attributes.getValue(ac), name);
315 else if ( an ==
"type")
317 XMLChToStdString( attributes.getValue(ac), type);
321 if ( ln ==
"struct" )
322 tag_stack.push( TAG_STRUCT );
324 tag_stack.push( TAG_SEQUENCE );
328 Property<PropertyBag> *prop;
329 prop =
new Property<PropertyBag>(name,
"",PropertyBag(type));
332 bag_stack.push(std::make_pair( &(prop->value()), prop));
335 if ( ln ==
"description")
336 tag_stack.push( TAG_DESCRIPTION );
339 tag_stack.push( TAG_VALUE );
341 log(
Warning) <<
"Unrecognised XML tag :"<< ln <<
": ignoring." << endlog();
342 tag_stack.push( TAG_UNKNOWN );
346 void warning(
const SAXParseException& exception )
349 XMLChToStdString( exception.getMessage(), warn);
351 if ( exception.getPublicId() )
353 XMLChToStdString( exception.getPublicId(), warn);
356 Logger::log() <<
" Column "<< exception.getColumnNumber()<<
" Line " <<exception.getLineNumber()<<
Logger::endl;
360 void error(
const SAXParseException& exception )
364 void fatalError(
const SAXParseException& exception )
368 #if XERCES_VERSION_MAJOR < 3 369 void characters(
const XMLCh*
const chars,
const unsigned int length )
371 void characters(
const XMLCh*
const chars,
const XMLSize_t length )
375 switch ( tag_stack.top() )
377 case TAG_DESCRIPTION:
378 XMLChToStdString( chars, description);
382 XMLChToStdString( chars, value_string);
396 CPFDemarshaller::CPFDemarshaller(
const std::string& filename )
399 Logger::In
in(
"CPFDemarshaller");
402 XMLPlatformUtils::Initialize();
404 catch (
const XMLException & toCatch )
407 XMLChToStdString(toCatch.getMessage(), error);
417 name = XMLString::transcode( filename.c_str() );
418 fis =
new LocalFileInputSource( name );
420 catch ( XMLException& xe )
431 XMLString::release( &name );
434 CPFDemarshaller::~CPFDemarshaller()
437 XMLPlatformUtils::Terminate();
440 bool CPFDemarshaller::deserialize( PropertyBag &v )
445 SAX2XMLReader* parser = 0;
447 XMLPlatformUtils::Initialize();
448 parser = XMLReaderFactory::createXMLReader();
453 XMLPlatformUtils::Terminate();
458 Logger::In
in(
"CPFDemarshaller");
462 SAX2CPFHandler handler( v );
463 parser->setContentHandler( &handler );
464 parser->setErrorHandler( &handler );
465 parser->setFeature( XMLUni::fgSAX2CoreValidation,
false );
466 parser->setFeature( XMLUni::fgXercesValidationErrorAsFatal,
false );
467 parser->setFeature( XMLUni::fgXercesContinueAfterFatalError,
false );
469 parser->setFeature( XMLUni::fgXercesSchemaFullChecking,
false );
470 parser->setFeature( XMLUni::fgXercesDynamic,
true );
471 parser->setFeature( XMLUni::fgSAX2CoreNameSpaces,
true );
472 parser->setFeature( XMLUni::fgSAX2CoreNameSpacePrefixes,
true );
473 parser->setFeature( XMLUni::fgXercesSchema,
false );
477 using namespace detail;
478 parser->setFeature( XMLUni::fgXercesLoadExternalDTD,
false );
480 int length = XMLString::stringLen(
cpf_dtd);
481 XMLByte* buffer =
new XMLByte[length];
482 memcpy( buffer,
cpf_dtd, length );
483 MemBufInputSource dtd(buffer, length,
"internal_cpf.dtd");
484 parser->loadGrammar( dtd, Grammar::DTDGrammarType );
487 parser->parse( *fis );
488 parser->getErrorCount();
490 XMLPlatformUtils::Terminate();
492 catch (
const XMLException & toCatch )
495 if ( toCatch.getSrcFile() ) {
498 Logger::log() << XMLgetString(toCatch.getMessage()) <<Logger::endl;
500 XMLPlatformUtils::Terminate();
503 catch (
const SAXParseException & toCatch )
506 Logger::log() << XMLgetString(toCatch.getMessage()) <<Logger::endl;
507 if ( toCatch.getPublicId() )
509 Logger::log() <<
" At entity "<< XMLgetString(toCatch.getPublicId()) <<Logger::nl;
513 XMLPlatformUtils::Terminate();
516 catch (
const SAXException & toCatch )
519 Logger::log() << XMLgetString(toCatch.getMessage()) <<Logger::endl;
521 XMLPlatformUtils::Terminate();
528 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.