Updated German translation
[dasher.git] / Src / DasherCore / AbstractXMLParser.cpp
blob1afc75eb81f17b59ef129dace43175c03f48a6b6
1 /*
2 * AbstractXMLParser.cpp
3 * Dasher
5 * Created by Alan Lawrence on 17/03/2011.
6 * Copyright 2011 Cavendish Laboratory. All rights reserved.
8 */
10 #include "AbstractXMLParser.h"
12 #include <fstream>
13 #include <stdio.h>
14 #include <cstring>
16 using namespace std;
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);
21 in.close();
22 return res;
25 AbstractXMLParser::AbstractXMLParser(CMessageDisplay *pMsgs) : AbstractParser(pMsgs) {
28 bool AbstractXMLParser::isUser() {
29 return m_bUser;
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;
38 m_bUser = bUser;
39 m_strDesc = 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);
49 bool bRes(true);
50 char Buffer[1024];
51 int Done;
52 do {
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) {
57 bRes=false;
58 if (m_pMsgs) {
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());
64 #ifdef DEBUG
65 std::cout << "Error in: " << string(Buffer,len) << std::endl;
66 #endif
68 break;
70 } while (!Done);
72 XML_ParserFree(Parser);
73 m_bUser = bOldUser; m_strDesc = strOldDesc;
74 return bRes;
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.
87 if(Input[i] == '&') {
88 Input.replace(i, 1, "&amp;");
89 continue;
91 if(Input[i] == '<') {
92 Input.replace(i, 1, "&lt;");
93 continue;
95 if(Input[i] == '>') {
96 Input.replace(i, 1, "&gt;");
97 continue;
99 // " and ' might need escaping inside attributes, I'll do them all.
100 if(Attribute == false)
101 continue;
103 if(Input[i] == '\'') {
104 Input.replace(i, 1, "&apos;");
105 continue;
107 if(Input[i] == '"') {
108 Input.replace(i, 1, "&quot;");
109 continue;
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);