2 * AbstractXMLParser.cpp
5 * Created by Alan Lawrence on 17/03/2011.
6 * Copyright 2011 Cavendish Laboratory. All rights reserved.
10 #include "AbstractXMLParser.h"
18 bool AbstractParser::ParseFile(const string
&strPath
, bool bUser
) {
19 std::ifstream
in(strPath
.c_str(), ios::binary
);
20 bool res
=Parse("file://"+strPath
, in
, bUser
);
25 AbstractXMLParser::AbstractXMLParser(CMessageDisplay
*pMsgs
) : AbstractParser(pMsgs
) {
28 bool AbstractXMLParser::isUser() {
32 bool AbstractXMLParser::Parse(const std::string
&strDesc
, istream
&in
, bool bUser
) {
33 if (!in
.good()) return false;
35 //we'll be re-entrant (i.e. allow nested calls), as it's not difficult here...
36 const bool bOldUser
= m_bUser
;
37 const string strOldDesc
= m_strDesc
;
41 XML_Parser Parser
= XML_ParserCreate(NULL
);
43 // Members passed as callbacks must be static, so don't have a "this" pointer.
44 // We give them one through horrible casting so they can effect changes.
45 XML_SetUserData(Parser
, this);
47 XML_SetElementHandler(Parser
, XML_StartElement
, XML_EndElement
);
48 XML_SetCharacterDataHandler(Parser
, XML_CharacterData
);
53 in
.read(Buffer
, sizeof(Buffer
));
54 size_t len
= in
.gcount();
55 Done
= len
< sizeof(Buffer
);
56 if(XML_Parse(Parser
, Buffer
, len
, Done
) == XML_STATUS_ERROR
) {
59 const XML_LChar
*xmle
=XML_ErrorString(XML_GetErrorCode(Parser
)); //think XML_LChar==char, depends on preprocessor variables...
61 ///TRANSLATORS: the first string is the error message from the XML Parser;
62 /// the second is the URL of the file we're trying to read.
63 m_pMsgs
->FormatMessageWith2Strings(_("XML Error %s in file %s "), xmle
, m_strDesc
.c_str());
65 std::cout
<< "Error in: " << string(Buffer
,len
) << std::endl
;
72 XML_ParserFree(Parser
);
73 m_bUser
= bOldUser
; m_strDesc
= strOldDesc
;
77 void AbstractXMLParser::XmlCData(const XML_Char
*str
, int len
) {
81 void AbstractXMLParser::XML_Escape(std::string
&Input
, bool Attribute
) {
82 // The XML "W3C Recommendation" is here: http://www.w3.org/TR/REC-xml
84 for(unsigned int i
= 0; i
< Input
.size(); i
++) {
85 // & and < need escaping in XML. In one rare circumstance >
86 // needs escaping too. I'll always do it, as I'm allowed to.
88 Input
.replace(i
, 1, "&");
92 Input
.replace(i
, 1, "<");
96 Input
.replace(i
, 1, ">");
99 // " and ' might need escaping inside attributes, I'll do them all.
100 if(Attribute
== false)
103 if(Input
[i
] == '\'') {
104 Input
.replace(i
, 1, "'");
107 if(Input
[i
] == '"') {
108 Input
.replace(i
, 1, """);
115 //Actual callbacks for expat. void*, here we come!
116 void AbstractXMLParser::XML_StartElement(void *userData
, const XML_Char
* name
, const XML_Char
** atts
) {
117 static_cast<AbstractXMLParser
*>(userData
)->XmlStartHandler(name
, atts
);
120 void AbstractXMLParser::XML_EndElement(void *userData
, const XML_Char
* name
) {
121 static_cast<AbstractXMLParser
*>(userData
)->XmlEndHandler(name
);
124 void AbstractXMLParser::XML_CharacterData(void *userData
, const XML_Char
* s
, int len
) {
125 static_cast<AbstractXMLParser
*>(userData
)->XmlCData(s
,len
);