1 /***************************************************************************
2                      expatwrap.h  -  c++ wrapper for expat
3                              -------------------
4     begin                : Sun May 20 2007
5     copyright            : (C) 2002-2007 by Ewald Arnold
6     email                : ulxmlrpcpp@ewald-arnold.de
7 
8     $Id: expatwrap.h 966 2007-07-08 17:23:21Z ewald-arnold $
9 
10  ***************************************************************************/
11 
12 /**************************************************************************
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Lesser General Public License as
16  * published by the Free Software Foundation; either version 2 of the License,
17  * or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  *
28  ***************************************************************************/
29 
30 #ifndef ULXR_EXPATWRAP_H
31 #define ULXR_EXPATWRAP_H
32 
33 #include <map>
34 
35 #include "xmlparse_base.h"
36 
37 
38 /** A wrapper for expat
39   */
40 class ExpatWrapper : public XmlParserBase
41 {
42  public:
43 
44    enum
45    {
46      NotWellformedError       = 1,
47      InvalidCharacterError    = 2,
48      UnsupportedEncodingError = 3
49    };
50 
51     class AttributeList;
52 
53   /** Constructs an expat  parser.
54     * @param createParser  create a new parser instance
55     */
56     ExpatWrapper(bool createParser=true);
57 
58   /** Destroys the parser.
59     */
60     virtual ~ExpatWrapper();
61 
62   /** Parse a pice of xml data.
63     * @param buffer   pointer start of next data chunk
64     * @param len      len of this chunk
65     * @param isFinal  true: last call to parser
66     * @return error condition, 0 = ok
67     */
68     virtual int parse(const char* buffer, int len, int isFinal);
69 
70   /** Gets the code for the current error.
71     * @return error code
72     */
73     virtual unsigned getErrorCode() const;
74 
75   /** Gets the description for an error code
76     * @param code  error code
77     * @return  pointer to description
78     */
79     virtual std::string getErrorString(unsigned code) const;
80 
81   /** Gets the line number in the xml data
82     * @return  line number
83     */
84     virtual int getCurrentLineNumber() const;
85 
86   /** Maps expat error codes to xml-rpc error codes.
87     * @param  xpatcode   error code from expat
88     * @return  the according xml-rpc error
89     */
90     virtual int mapToFaultCode(int xpatcode) const;
91 
92  protected:
93 
94   /** Gets the parser instance.
95     */
96     operator XML_Parser() const;
97 
98   /** C++ callback for an opening XML tag.
99     * Used ONLY internally as callback from expat.
100     * @param  name  the name of the current tag
101     * @param  atts  pointer to the current attributs (unused in XML-RPC)
102     */
103     virtual void startElement(const XML_Char* name, const XML_Char** atts);
104 
105   /** C++ callback for a closing XML tag.
106     * Used ONLY internally as callback from expat.
107     * @param  name  the name of the current tag
108     */
109     virtual void endElement(const XML_Char *name);
110 
111   /** C++ callback for regular text from expat.
112     * Used ONLY internally.
113     * @param  s        starting buffer with more data
114     * @param  len      lenth of buffer
115     */
116     virtual void charData(const XML_Char *s, int len);
117 
118   /** C-style callback for a closing XML tag from expat.
119     * Used ONLY internally.
120     * @param  userData pointer to the actual C++-object
121     * @param  name     the name of the current tag
122     * @param  atts     to the current attributs (unused in XML-RPC)
123     */
124     static void startElementCallback(void *userData, const XML_Char* name, const XML_Char** atts);
125 
126   /** C-style callback for an ending XML tag from expat.
127     * Used ONLY internally.
128     * @param  userData pointer to the actual C++-object
129     * @param  name     the name of the current tag
130     */
131     static void endElementCallback(void *userData, const XML_Char* name);
132 
133   /** C-style callback for regular text from expat.
134     * Used ONLY internally.
135     * @param  userData pointer to the actual C++-object
136     * @param  s        starting buffer with more data
137     * @param  len      lenth of buffer
138     */
139     static void charDataCallback(void *userData, const XML_Char* s, int len);
140 
141  private:
142 
143   /** Sets the callback handlers.
144     */
145     void setHandler();
146 
147   /** Resets the parser.
148     */
149     void reset();
150 
151  private:
152 
153     XML_Parser expatParser;
154 };
155 
156 
157 
158 class ExpatWrapper::AttributeList
159 {
160   public:
161 
162   /** Construct list from expat pointer
163     * @param  parser  pointer to current parser object
164     * @param  atts    pointer to the current attributs (unused in XML-RPC)
165     */
166     AttributeList(ExpatWrapper *parser, const XML_Char** atts);
167 
168   /** Tests if an attribute is available
169     * @param  name  name of attribute
170     * @return true: attribute is available
171     */
172     bool hasAttribute(const std::string &name) const;
173 
174   /** Get the content of an attribute
175     * @param  name  name of attribute
176     * @return content of attribute
177     * @return throw exception if attribute is not in list
178     */
179     std::string getAttribute(const std::string &name) const;
180 
181   private:
182 
183     std::map<std::string, std::string>  attributes;
184     ExpatWrapper                       *parser;
185 };
186 
187 
188 #endif // ULXR_EXPATWRAP_H
189 
190