5 * Created by Alan Lawrence on 17/03/2011.
6 * Copyright 2011 Cavendish Laboratory. All rights reserved.
10 #ifndef __ABSTRACT_XML_PARSER_H__
11 #define __ABSTRACT_XML_PARSER_H__
13 #include "../Common/Common.h"
24 class AbstractParser
{
26 AbstractParser(CMessageDisplay
*pMsgs
) : m_pMsgs(pMsgs
) { }
27 ///Utility method: constructs an ifstream to read from the specified file,
28 /// then calls Parse(string&,istream&,bool) with the description 'file://strPath'
29 virtual bool ParseFile(const std::string
&strPath
, bool bUser
);
31 /// \param strDesc string to display to user to identify the source of this data,
32 /// if there is an error. (Suggest: use a url, e.g. file://...)
33 /// \param bUser if True, the file is from a user location (editable), false if from a
34 /// system one. (Some subclasses treat the data differently according to which of these
36 virtual bool Parse(const std::string
&strDesc
, std::istream
&in
, bool bUser
) = 0;
39 ///The MessageDisplay to use to inform the user. Subclasses should use this
40 /// too for any (e.g. semantic) errors they may detect.
41 CMessageDisplay
* const m_pMsgs
;
44 ///Basic wrapper over (Expat) XML Parser, handling file IO and wrapping C++
45 /// virtual methods over C callbacks. Subclasses must implement methods to
46 /// handle actual tags.
47 class AbstractXMLParser
: public AbstractParser
{
49 ///Parse (the whole) file - done in chunks to avoid loading the whole thing into memory.
50 /// Any errors _besides_ file-not-found, will be passed to m_pMsgs as modal messages.
51 virtual bool Parse(const std::string
&strDesc
, std::istream
&in
, bool bUser
);
53 ///Create an AbstractXMLParser which will use the specified MessageDisplay to
54 /// inform the user of any errors.
55 AbstractXMLParser(CMessageDisplay
*pMsgs
);
57 ///Subclasses may call to get the description of the current file
58 const std::string
&GetDesc() {return m_strDesc
;}
59 ///Subclasses may call to determine if the current file is from a user location
62 ///Subclass should override to handle a start tag
63 virtual void XmlStartHandler(const XML_Char
*name
, const XML_Char
**atts
)=0;
64 ///Subclass should override to handle an end tag
65 virtual void XmlEndHandler(const XML_Char
*name
)=0;
66 ///Subclass may override to handle character data; the default implementation does nothing.
67 ///\param str pointer to string data, note is NOT null-terminated
68 ///\param len number of bytes to read from pointer
69 virtual void XmlCData(const XML_Char
*str
, int len
);
71 ///Utility function provided for subclasses wishing to perform XML _output_.
72 // & to & < to < and > to > and if (Attribute) ' to ' and " to "
73 /// \param Input string to escape, will be updated in-place.
74 void XML_Escape(std::string
&Input
, bool Attribute
);
76 /// The actual callbacks passed to the expat library.
77 /// These just convert the void* we passed to the library back into
78 /// an instance pointer, to get a C++ class to work with a plain C library.
79 static void XML_StartElement(void *userData
, const XML_Char
* name
, const XML_Char
** atts
);
80 static void XML_EndElement(void *userData
, const XML_Char
* name
);
81 static void XML_CharacterData(void *userData
, const XML_Char
* s
, int len
);
83 std::string m_strDesc
;