27 #ifndef _SAXPARSER_HPP_ 28 #define _SAXPARSER_HPP_ 33 #include "boost/iostreams/positioning.hpp" 82 memcpy(
data(),rhs.c_str(),rhs.length());
83 (*this)[rhs.length()] = 0;
87 if (strchr(
c_str(),
'&')) {
106 init(rhs ? strlen(rhs) : 0);
115 size_t oldsize =
length();
123 size_t rhslen = rhs?strlen(rhs):0;
125 size_t oldsize =
length();
127 strcpy(
data()+oldsize,rhs);
133 return c && !strcmp(c,
c_str());
137 return !strcmp(
c_str(),s.c_str());
148 size_t new_used = size +
_lead;
152 throw std::runtime_error(
"SAXParser: cannot allocate memory");
183 for (
const char *c=
c_str(); *c && strchr(
" \n\r\t",*c); c++) {
190 return !strncmp(
c_str(),txt,strlen(txt));
193 size_t len = strlen(txt);
227 template<
typename Target >
inline Target
textToValue(
const char *txt);
231 return (
float)
ATOF( txt ) ;
256 return (
unsigned int) strtoul( txt, NULL, 10 );
261 return strtoul( txt, NULL, 10 );
264 #if defined(BOOST_HAS_LONG_LONG) 266 template<>
inline long long textToValue(
const char *txt)
268 #if defined(BOOST_HAS_MS_INT64) 275 template<>
inline unsigned long long textToValue(
const char *txt)
277 #if defined(BOOST_HAS_MS_INT64) 278 return _strtoui64(txt,NULL,10);
280 return strtoull( txt, NULL, 10 );
284 #endif // has long long 288 return strcmp(t,
"0") && strcmp(t,
"false");
296 template<>
inline boost::logic::tribool
textToValue(
const char *txt)
300 return tribool(indeterminate);
310 return std::string( txt );
346 : flag(_flag), delegate(_delegate)
357 Attributes(
const char * _source_text,
size_t _source_text_len,
bool _autoUnescape) :
358 index(0),index_end(0),autoUnescape(_autoUnescape),firstread(true),attrs()
360 size=_source_text_len;
361 textbuff = (
char *)malloc(size+1);
363 memcpy(textbuff,_source_text,size);
369 index(0),index_end(0),autoUnescape(false),firstread(true),attrs()
377 index(0),index_end(0),autoUnescape(_autoUnescape),firstread(true),attrs()
379 textbuff = str.
data();
402 textbuff = (
char *)realloc(textbuff,size+1);
404 textbuff = (
char *)malloc(size+1);
406 memcpy(textbuff,rhs.
textbuff,size+1);
407 attrs.resize(rhs.
attrs.size());
409 for (
size_t n=attrs.size();n--;)
421 for (
size_t n=attrs.size();n--;)
423 assert(textbuff != NULL);
424 assert(attrs[n].name>textbuff);
425 assert(attrs[n].
value>attrs[n].name);
426 assert(attrs[n].
value<textbuff+size);
428 assert(attrs[n].name>attrs[n-1].
value);
436 return textbuff+(
'/'==*textbuff);
458 const char *c = textbuff;
459 while (*c && !strchr(
" \n\r\t/",*c)) c++;
460 size_t indexNameEnd = c-textbuff;
461 while (*c && strchr(
" \n\r\t",*c)) c++;
462 textbuff[indexNameEnd] = 0;
475 return !strcmp(test,name);
485 if (Unescape == NoXMLUnescape)
486 needsUnescape =
false;
487 else if (needsUnescape) {
489 needsUnescape =
false;
494 return std::string(getValuePtr(Unescape));
498 template<
typename T >
501 return textToValue<T>(getValuePtr(Unescape));
506 return (
size_t)strtoul(getValuePtr(Unescape),NULL,10);
514 void set(
const char *_name,
char *_value,
bool _needsUnescape)
518 needsUnescape = _needsUnescape;
527 attribute_list::const_iterator
begin()
const 530 return attrs.begin();
532 attribute_list::const_iterator
end()
const 537 attribute_list::const_iterator
find(
const std::string &name)
const 539 attribute_list::const_iterator it;
540 for (it = begin(); it != end() ; it++ )
542 if (it->matchName(name.c_str()))
549 PWIZ_API_DECL void parseAttributes(std::string::size_type& index)
const;
556 parseAttributes(index);
565 for (attribute_list::const_iterator it=attrs.begin();it!=attrs.end();it++)
567 if (it->matchName(name))
576 const attribute *attr = findAttributeByName(name);
586 const std::string& data,
587 stream_offset
position) {
return Status::Ok;}
591 stream_offset
position) {
return Status::Ok;}
594 stream_offset
position) {
return Status::Ok;}
597 stream_offset
position) {
return Status::Ok;}
599 Handler() : parseCharacters(false), autoUnescapeAttributes(true), autoUnescapeCharacters(true), version(0) {}
604 template <
typename T>
609 T defaultValue = T())
const 613 result = attr->
valueAs<T>(Unescape);
615 result = defaultValue;
622 const char * defaultValue = NULL)
const 632 template <
typename T>
639 result = attr->
valueAs<T>(XMLUnescapeDefault);
647 std::string& result)
const 658 template <
typename T>
660 const std::string &name,
662 T defaultValue = T())
const 666 result = attr->
valueAs<T>(XMLUnescapeDefault);
668 result = defaultValue;
728 #endif // _SAXPARSER_HPP_
virtual Status endElement(const std::string &name, stream_offset position)
const attribute * findAttributeByName(const char *name) const
PWIZ_API_DECL std::string xml_root_element_from_file(const std::string &filepath)
Returns the root element from an XML file; throws runtime_error if no element is found.
int version
contextual version available to control handler logic which support multiple versions of a schema; th...
Attributes(saxstring &str, bool _autoUnescape)
const char * c_str() const
saxstring & operator+=(const SAXParser::saxstring &rhs)
Target textToValue(const char *txt)
virtual Status processingInstruction(const std::string &name, const std::string &data, stream_offset position)
SAX event handler interface.
bool operator==(const char *c) const
char & operator[](size_t n)
const char * getTextBuffer() const
Status(Flag _flag=Ok, Handler *_delegate=0)
attribute_list::const_iterator end() const
const char * getAttribute(const Attributes &attributes, const char *name, XMLUnescapeBehavior_t Unescape, const char *defaultValue=NULL) const
virtual Status startElement(const std::string &name, const Attributes &attributes, stream_offset position)
PWIZ_API_DECL size_t count_trail_ws(const char *data, size_t len)
const char * getTagName() const
saxstring & operator=(const SAXParser::saxstring &rhs)
Attributes(const char *_source_text, size_t _source_text_len, bool _autoUnescape)
boost::iostreams::stream_offset stream_offset
PWIZ_API_DECL std::string xml_root_element(const std::string &fileheader)
Returns the root element from an XML buffer; throws runtime_error if no element is found...
void test_invariant() const
virtual Status characters(const SAXParser::saxstring &text, stream_offset position)
std::string & getAttribute(const Attributes &attributes, const char *name, std::string &result) const
const char * findValueByName(const char *name, XMLUnescapeBehavior_t Unescape=XMLUnescapeDefault) const
T & getAttribute(const Attributes &attributes, const char *name, T &result, XMLUnescapeBehavior_t Unescape, T defaultValue=T()) const
const char * getValuePtr(XMLUnescapeBehavior_t Unescape=XMLUnescapeDefault) const
Handler returns the Status struct as a means of changing the parser's behavior.
std::string getValue(XMLUnescapeBehavior_t Unescape=XMLUnescapeDefault) const
attribute_list::const_iterator begin() const
saxstring(const std::string &rhs)
bool parseCharacters
When false, no calls to characters() will be made.
PWIZ_API_DECL void unescapeXML(char *str)
const char * getName() const
T valueAs(XMLUnescapeBehavior_t Unescape) const
T & getAttribute(const Attributes &attributes, const char *name, T &result) const
size_t valueAs(XMLUnescapeBehavior_t Unescape) const
PWIZ_API_DECL Position position(CVID cvid=CVID_Unknown)
returns a Position corresponding to one of the following CVIDs: CVID_Unknown: Position::Anywhere MS_m...
Attributes(const Attributes &rhs)
std::vector< attribute > attribute_list
bool matchName(const char *test) const
PWIZ_API_DECL void parse(std::istream &is, Handler &handler)
Extract a single XML element from the istream, sending SAX events to the handler. ...
char * resize(size_t size)
bool ends_with(const char *txt) const
PWIZ_API_DECL std::string value(const std::string &id, const std::string &name)
convenience function to extract a named value from an id string
T & getAttribute(const Attributes &attributes, const std::string &name, T &result, T defaultValue=T()) const
PWIZ_API_DECL std::string & decode_xml_id(std::string &str)
Decodes any characters encoded with their hexadecimal value, e.g.
attribute_list::const_iterator find(const std::string &name) const
bool autoUnescapeCharacters
PWIZ_API_DECL std::string decode_xml_id_copy(const std::string &str)
Decodes any characters encoded with their hexadecimal value, e.g.
saxstring(const SAXParser::saxstring &rhs)
std::ostream & operator<<(std::ostream &os, const saxstring &s)
bool istrue(const char *t)
bool starts_with(const char *txt) const