SAX based XML parser

Dependents:   giken9_HTMLServer_Temp_Sample

Committer:
andrewbonney
Date:
Thu May 26 10:03:14 2011 +0000
Revision:
1:e96b2af301dd
Parent:
0:07919e3d6c56
Update to reduce buffer sizes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewbonney 0:07919e3d6c56 1 // expatpp
andrewbonney 0:07919e3d6c56 2 #ifndef H_EXPATPP
andrewbonney 0:07919e3d6c56 3 #define H_EXPATPP
andrewbonney 0:07919e3d6c56 4
andrewbonney 0:07919e3d6c56 5 #ifdef EXPATPP_COMPATIBLE_EXPAT12 // earlier versions of expat up to v1.2
andrewbonney 0:07919e3d6c56 6 #include "xmlparse.h"
andrewbonney 0:07919e3d6c56 7 #else
andrewbonney 0:07919e3d6c56 8 #include "expat.h" // since some version of expat moved to SourceForge
andrewbonney 0:07919e3d6c56 9 #endif
andrewbonney 0:07919e3d6c56 10 #include <stdio.h>
andrewbonney 0:07919e3d6c56 11 #include <assert.h>
andrewbonney 0:07919e3d6c56 12
andrewbonney 0:07919e3d6c56 13
andrewbonney 0:07919e3d6c56 14 /**
andrewbonney 0:07919e3d6c56 15 \file expatpp.h
andrewbonney 0:07919e3d6c56 16 Latest version 29-Dec-2002 compatible with expat 1.95.6
andrewbonney 0:07919e3d6c56 17 */
andrewbonney 0:07919e3d6c56 18
andrewbonney 0:07919e3d6c56 19 /**
andrewbonney 0:07919e3d6c56 20 expatpp follows a simple pattern for converting the semi-OOP callback design of
andrewbonney 0:07919e3d6c56 21 expat into a true class which allows you to override virtual methods to supply
andrewbonney 0:07919e3d6c56 22 callbacks.
andrewbonney 0:07919e3d6c56 23
andrewbonney 0:07919e3d6c56 24 \par USING expatpp
andrewbonney 0:07919e3d6c56 25 see testexpatpp.cpp for a detailed example
andrewbonney 0:07919e3d6c56 26
andrewbonney 0:07919e3d6c56 27 1) decide which callbacks you wish to use, eg: just startElement
andrewbonney 0:07919e3d6c56 28
andrewbonney 0:07919e3d6c56 29 2) declare a subclass of expatpp, eg:
andrewbonney 0:07919e3d6c56 30 class myExpat : public expatpp {
andrewbonney 0:07919e3d6c56 31 virtual void startElement(const XML_Char* name, const XML_Char** atts);
andrewbonney 0:07919e3d6c56 32 };
andrewbonney 0:07919e3d6c56 33
andrewbonney 0:07919e3d6c56 34 3) create an instance of your object and pass in a buffer to parse
andrewbonney 0:07919e3d6c56 35 myExpat parser;
andrewbonney 0:07919e3d6c56 36 parser.XML_Parse(buf, len, done)
andrewbonney 0:07919e3d6c56 37
andrewbonney 0:07919e3d6c56 38
andrewbonney 0:07919e3d6c56 39 \par HOW IT WORKS
andrewbonney 0:07919e3d6c56 40 The User Data which expat maintains is simply a pointer to an instance of your object.
andrewbonney 0:07919e3d6c56 41
andrewbonney 0:07919e3d6c56 42 Inline static functions are specified as the callbacks to expat.
andrewbonney 0:07919e3d6c56 43 These static functions take the user data parameter returned from expat and cast it
andrewbonney 0:07919e3d6c56 44 to a pointer to an expatpp object.
andrewbonney 0:07919e3d6c56 45
andrewbonney 0:07919e3d6c56 46 Using that typed pointer they then call the appropriate virtual method.
andrewbonney 0:07919e3d6c56 47
andrewbonney 0:07919e3d6c56 48 If you have overriden a given virtual method then your version will be called, otherwise
andrewbonney 0:07919e3d6c56 49 the (empty) method in the base expatpp class is called.
andrewbonney 0:07919e3d6c56 50
andrewbonney 0:07919e3d6c56 51 \par Possible Efficiency Tactic
andrewbonney 0:07919e3d6c56 52 For efficiency, you could provide your own constructor and set some of the callbacks
andrewbonney 0:07919e3d6c56 53 to 0, so expat doesn't call the static functions. (untested idea).
andrewbonney 0:07919e3d6c56 54
andrewbonney 0:07919e3d6c56 55 \par Naming Conventions
andrewbonney 0:07919e3d6c56 56 The virtual functions violate the usual AD Software convention of lowercase first letter
andrewbonney 0:07919e3d6c56 57 for public methods but this was a late change to protected and too much user code out there.
andrewbonney 0:07919e3d6c56 58
andrewbonney 0:07919e3d6c56 59
andrewbonney 0:07919e3d6c56 60 \todo Possibly implement some handling for XML_SetExternalEntityRefHandler which does NOT
andrewbonney 0:07919e3d6c56 61 receive user data, just the parser, so can't use normal pattern for invoking virtual methods
andrewbonney 0:07919e3d6c56 62
andrewbonney 0:07919e3d6c56 63 \todo Possibly implement handling for XML_UnknownEncodingHandler.
andrewbonney 0:07919e3d6c56 64
andrewbonney 0:07919e3d6c56 65 \todo review design for nested calls - not happy that it is the right thing that they don't see
andrewbonney 0:07919e3d6c56 66 their start and ending elements - makes it harder to unit test them in isolation.
andrewbonney 0:07919e3d6c56 67
andrewbonney 0:07919e3d6c56 68 \todo unit tests
andrewbonney 0:07919e3d6c56 69
andrewbonney 0:07919e3d6c56 70 \todo especially test abort mechanism
andrewbonney 0:07919e3d6c56 71
andrewbonney 0:07919e3d6c56 72 \todo reinstate copy constrution and assignment with child parser cleanup
andrewbonney 0:07919e3d6c56 73
andrewbonney 0:07919e3d6c56 74 \todo allow specification of encoding
andrewbonney 0:07919e3d6c56 75 */
andrewbonney 0:07919e3d6c56 76 class expatpp {
andrewbonney 0:07919e3d6c56 77 public:
andrewbonney 0:07919e3d6c56 78 expatpp(bool createParser=true);
andrewbonney 0:07919e3d6c56 79 virtual ~expatpp();
andrewbonney 0:07919e3d6c56 80
andrewbonney 0:07919e3d6c56 81 operator XML_Parser() const;
andrewbonney 0:07919e3d6c56 82
andrewbonney 0:07919e3d6c56 83 protected: // callback virtuals should only be invoked through our Callback static functions
andrewbonney 0:07919e3d6c56 84 bool emptyCharData(const XML_Char* s, int len); // utility often used in overridden charData
andrewbonney 0:07919e3d6c56 85
andrewbonney 0:07919e3d6c56 86 // overrideable callbacks
andrewbonney 0:07919e3d6c56 87 virtual void startElement(const XML_Char* name, const XML_Char** atts);
andrewbonney 0:07919e3d6c56 88 virtual void endElement(const XML_Char*);
andrewbonney 0:07919e3d6c56 89 virtual void charData(const XML_Char*, int len);
andrewbonney 0:07919e3d6c56 90 virtual void processingInstruction(const XML_Char* target, const XML_Char* data);
andrewbonney 0:07919e3d6c56 91 virtual void defaultHandler(const XML_Char*, int len);
andrewbonney 0:07919e3d6c56 92 virtual int notStandaloneHandler();
andrewbonney 0:07919e3d6c56 93 virtual void unparsedEntityDecl(const XML_Char* entityName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId, const XML_Char* notationName);
andrewbonney 0:07919e3d6c56 94 virtual void notationDecl(const XML_Char* notationName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId);
andrewbonney 0:07919e3d6c56 95 virtual void startNamespace(const XML_Char* prefix, const XML_Char* uri);
andrewbonney 0:07919e3d6c56 96 virtual void endNamespace(const XML_Char*);
andrewbonney 0:07919e3d6c56 97 /// \name Callbacks added to support expat 1.95.5
andrewbonney 0:07919e3d6c56 98 //@{
andrewbonney 0:07919e3d6c56 99 virtual void attlistDecl(
andrewbonney 0:07919e3d6c56 100 const XML_Char *elname,
andrewbonney 0:07919e3d6c56 101 const XML_Char *attname,
andrewbonney 0:07919e3d6c56 102 const XML_Char *att_type,
andrewbonney 0:07919e3d6c56 103 const XML_Char *dflt,
andrewbonney 0:07919e3d6c56 104 int isrequired);
andrewbonney 0:07919e3d6c56 105 virtual void endCdataSection();
andrewbonney 0:07919e3d6c56 106 virtual void endDoctypeDecl();
andrewbonney 0:07919e3d6c56 107 virtual void comment( const XML_Char *data);
andrewbonney 0:07919e3d6c56 108 virtual void elementDecl( const XML_Char *name, XML_Content *model);
andrewbonney 0:07919e3d6c56 109 virtual void entityDecl(
andrewbonney 0:07919e3d6c56 110 const XML_Char *entityName,
andrewbonney 0:07919e3d6c56 111 int is_parameter_entity,
andrewbonney 0:07919e3d6c56 112 const XML_Char *value,
andrewbonney 0:07919e3d6c56 113 int value_length,
andrewbonney 0:07919e3d6c56 114 const XML_Char *base,
andrewbonney 0:07919e3d6c56 115 const XML_Char *systemId,
andrewbonney 0:07919e3d6c56 116 const XML_Char *publicId,
andrewbonney 0:07919e3d6c56 117 const XML_Char *notationName);
andrewbonney 0:07919e3d6c56 118 virtual void skippedEntity(const XML_Char *entityName, int is_parameter_entity);
andrewbonney 0:07919e3d6c56 119 virtual void startCdataSection();
andrewbonney 0:07919e3d6c56 120 virtual void startDoctypeDecl(const XML_Char *doctypeName,
andrewbonney 0:07919e3d6c56 121 const XML_Char *sysid,
andrewbonney 0:07919e3d6c56 122 const XML_Char *pubid,
andrewbonney 0:07919e3d6c56 123 int has_internal_subset);
andrewbonney 0:07919e3d6c56 124 virtual void xmlDecl( const XML_Char *version,
andrewbonney 0:07919e3d6c56 125 const XML_Char *encoding,
andrewbonney 0:07919e3d6c56 126 int standalone);
andrewbonney 0:07919e3d6c56 127 //@}
andrewbonney 0:07919e3d6c56 128
andrewbonney 0:07919e3d6c56 129 public:
andrewbonney 0:07919e3d6c56 130 /// \name XML interfaces
andrewbonney 0:07919e3d6c56 131 //@{
andrewbonney 0:07919e3d6c56 132 XML_Status XML_Parse(const char* buffer, int len, int isFinal);
andrewbonney 0:07919e3d6c56 133 virtual XML_Status parseFile(FILE* inFile);
andrewbonney 0:07919e3d6c56 134 virtual XML_Status parseString(const char*);
andrewbonney 0:07919e3d6c56 135 XML_Error XML_GetErrorCode();
andrewbonney 0:07919e3d6c56 136 int XML_GetCurrentLineNumber();
andrewbonney 0:07919e3d6c56 137 int XML_GetCurrentColumnNumber();
andrewbonney 0:07919e3d6c56 138 //@}
andrewbonney 0:07919e3d6c56 139
andrewbonney 0:07919e3d6c56 140 protected:
andrewbonney 0:07919e3d6c56 141 XML_Parser mParser;
andrewbonney 0:07919e3d6c56 142 bool mHaveParsed;
andrewbonney 0:07919e3d6c56 143
andrewbonney 0:07919e3d6c56 144 /// \name overrideables to customise behaviour, must call parent
andrewbonney 0:07919e3d6c56 145 //@{
andrewbonney 0:07919e3d6c56 146 virtual void ReleaseParser();
andrewbonney 0:07919e3d6c56 147 virtual void ResetParser();
andrewbonney 0:07919e3d6c56 148 virtual void SetupHandlers();
andrewbonney 0:07919e3d6c56 149 //@}
andrewbonney 0:07919e3d6c56 150
andrewbonney 0:07919e3d6c56 151 /**
andrewbonney 0:07919e3d6c56 152 Override so subclass can react to an error causing exit from parse.
andrewbonney 0:07919e3d6c56 153 rather than leave it for application code to check status.
andrewbonney 0:07919e3d6c56 154 Useful point to insert logging to silently grab failed parses
andrewbonney 0:07919e3d6c56 155 */
andrewbonney 0:07919e3d6c56 156 virtual void CheckFinalStatus(XML_Status) {};
andrewbonney 0:07919e3d6c56 157
andrewbonney 0:07919e3d6c56 158 // static interface functions for callbacks
andrewbonney 0:07919e3d6c56 159 public:
andrewbonney 0:07919e3d6c56 160 static void startElementCallback(void *userData, const XML_Char* name, const XML_Char** atts);
andrewbonney 0:07919e3d6c56 161 static void endElementCallback(void *userData, const XML_Char* name);
andrewbonney 0:07919e3d6c56 162 static void startNamespaceCallback(void *userData, const XML_Char* prefix, const XML_Char* uri);
andrewbonney 0:07919e3d6c56 163 static void endNamespaceCallback(void *userData, const XML_Char* prefix);
andrewbonney 0:07919e3d6c56 164 static void charDataCallback(void *userData, const XML_Char* s, int len);
andrewbonney 0:07919e3d6c56 165 static void processingInstructionCallback(void *userData, const XML_Char* target, const XML_Char* data);
andrewbonney 0:07919e3d6c56 166 static void defaultHandlerCallback(void* userData, const XML_Char* s, int len);
andrewbonney 0:07919e3d6c56 167 static int notStandaloneHandlerCallback(void* userData);
andrewbonney 0:07919e3d6c56 168 static void unParsedEntityDeclCallback(void* userData, const XML_Char* entityName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId, const XML_Char* notationName);
andrewbonney 0:07919e3d6c56 169 static void notationDeclCallback(void *userData, const XML_Char* notationName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId);
andrewbonney 0:07919e3d6c56 170 /// \name Callback interfacess added to support expat 1.95.5
andrewbonney 0:07919e3d6c56 171 //@{
andrewbonney 0:07919e3d6c56 172 static void attlistDeclCallback(void *userData,
andrewbonney 0:07919e3d6c56 173 const XML_Char *elname,
andrewbonney 0:07919e3d6c56 174 const XML_Char *attname,
andrewbonney 0:07919e3d6c56 175 const XML_Char *att_type,
andrewbonney 0:07919e3d6c56 176 const XML_Char *dflt,
andrewbonney 0:07919e3d6c56 177 int isrequired);
andrewbonney 0:07919e3d6c56 178 static void commentCallback(void *userData, const XML_Char *data);
andrewbonney 0:07919e3d6c56 179 static void elementDeclCallback(void *userData, const XML_Char *name, XML_Content *model);
andrewbonney 0:07919e3d6c56 180 static void endCdataSectionCallback(void *userData);
andrewbonney 0:07919e3d6c56 181 static void endDoctypeDeclCallback(void *userData);
andrewbonney 0:07919e3d6c56 182 static void entityDeclCallback(void *userData,
andrewbonney 0:07919e3d6c56 183 const XML_Char *entityName,
andrewbonney 0:07919e3d6c56 184 int is_parameter_entity,
andrewbonney 0:07919e3d6c56 185 const XML_Char *value,
andrewbonney 0:07919e3d6c56 186 int value_length,
andrewbonney 0:07919e3d6c56 187 const XML_Char *base,
andrewbonney 0:07919e3d6c56 188 const XML_Char *systemId,
andrewbonney 0:07919e3d6c56 189 const XML_Char *publicId,
andrewbonney 0:07919e3d6c56 190 const XML_Char *notationName);
andrewbonney 0:07919e3d6c56 191 static void skippedEntityCallback(void *userData, const XML_Char *entityName, int is_parameter_entity);
andrewbonney 0:07919e3d6c56 192 static void startCdataSectionCallback(void *userData);
andrewbonney 0:07919e3d6c56 193 static void startDoctypeDeclCallback(void *userData,
andrewbonney 0:07919e3d6c56 194 const XML_Char *doctypeName,
andrewbonney 0:07919e3d6c56 195 const XML_Char *sysid,
andrewbonney 0:07919e3d6c56 196 const XML_Char *pubid,
andrewbonney 0:07919e3d6c56 197 int has_internal_subset);
andrewbonney 0:07919e3d6c56 198 static void xmlDeclCallback(void *userData, const XML_Char *version,
andrewbonney 0:07919e3d6c56 199 const XML_Char *encoding,
andrewbonney 0:07919e3d6c56 200 int standalone);
andrewbonney 0:07919e3d6c56 201 //@}
andrewbonney 0:07919e3d6c56 202
andrewbonney 0:07919e3d6c56 203
andrewbonney 0:07919e3d6c56 204 // utilities
andrewbonney 0:07919e3d6c56 205 static int skipWhiteSpace(const XML_Char*);
andrewbonney 0:07919e3d6c56 206 static const XML_Char* getAttribute(const XML_Char *matchingName, const XML_Char **atts);
andrewbonney 0:07919e3d6c56 207 static bool getIntegerAttribute(const XML_Char *matchingName, const XML_Char **atts, int& outAtt);
andrewbonney 0:07919e3d6c56 208 static bool getDoubleAttribute(const XML_Char *matchingName, const XML_Char **atts, double& outAtt);
andrewbonney 0:07919e3d6c56 209 };
andrewbonney 0:07919e3d6c56 210
andrewbonney 0:07919e3d6c56 211
andrewbonney 0:07919e3d6c56 212 /**
andrewbonney 0:07919e3d6c56 213 subclass to support a hierarchy of parsers, in a sort of recursion or
andrewbonney 0:07919e3d6c56 214 'nesting' approach, where a top-level parser might create sub-parsers
andrewbonney 0:07919e3d6c56 215 for part of a file.
andrewbonney 0:07919e3d6c56 216
andrewbonney 0:07919e3d6c56 217 The currently active child parser is owned (mOwnedChild) and is deleted
andrewbonney 0:07919e3d6c56 218 by DeleteChild (invoked from the dtor) so error handling can propagate
andrewbonney 0:07919e3d6c56 219 up the tree, closing parsers, without leaks.
andrewbonney 0:07919e3d6c56 220
andrewbonney 0:07919e3d6c56 221 \par Switching to sub-parsers
andrewbonney 0:07919e3d6c56 222 You can transfer to a sub-parser with
andrewbonney 0:07919e3d6c56 223 - new UserChildParser(this) // carries on using our parser, is self-deleting
andrewbonney 0:07919e3d6c56 224 - switchToNewSubParser( someVar = new UserChildParser(this) ) // if want to get values back after end parsing
andrewbonney 0:07919e3d6c56 225
andrewbonney 0:07919e3d6c56 226 \warning You can accidentally invoke a new parser without it doing anything
andrewbonney 0:07919e3d6c56 227 - new UserChildParser() // will be new top-level parser, nothing to do with our XML
andrewbonney 0:07919e3d6c56 228
andrewbonney 0:07919e3d6c56 229 \par Self-deletion
andrewbonney 0:07919e3d6c56 230 If you transfer control to a sub-parser with just new UserChildParser(this) then
andrewbonney 0:07919e3d6c56 231 it will be automatically self-deleting in its returnToParent method and
andrewbonney 0:07919e3d6c56 232 will invoke OwnedChildOrphansItself to clear our mOwnedChild.
andrewbonney 0:07919e3d6c56 233
andrewbonney 0:07919e3d6c56 234 The reason for self-deletion being governed by a somewhat complex chain of
andrewbonney 0:07919e3d6c56 235 calls rather than simply a boolean flag is because expatpp has been in use
andrewbonney 0:07919e3d6c56 236 worldwide for many years and it was deemed too unfriendly to break code in
andrewbonney 0:07919e3d6c56 237 a manner which could cause unwanted side effects - the current approach safely
andrewbonney 0:07919e3d6c56 238 preserves self-deletion but also allows for expatpp to have parent parsers
andrewbonney 0:07919e3d6c56 239 own and delete children, without compiling with different options.
andrewbonney 0:07919e3d6c56 240
andrewbonney 0:07919e3d6c56 241 \note
andrewbonney 0:07919e3d6c56 242 If you invoke a sub-parser with switchToNewSubParser( new UserChildParser() );
andrewbonney 0:07919e3d6c56 243 then the user child parser will start with a new XML parser instance
andrewbonney 0:07919e3d6c56 244 created by the expatpp ctor. This is safe but slightly wasteful of processing
andrewbonney 0:07919e3d6c56 245 as the new parser will be discarded by BeAdopted().
andrewbonney 0:07919e3d6c56 246
andrewbonney 0:07919e3d6c56 247 \par Switching to child and explicitly deleting
andrewbonney 0:07919e3d6c56 248 switchToNewSubParser( somevar = new UserChildParser(this) ) allows you to get values
andrewbonney 0:07919e3d6c56 249 back out of the child parser, in the context of the parent, eg:
andrewbonney 0:07919e3d6c56 250
andrewbonney 0:07919e3d6c56 251 \verbatim
andrewbonney 0:07919e3d6c56 252
andrewbonney 0:07919e3d6c56 253 void MultiFilterParser::startElement(const XML_Char* name, const XML_Char **atts)
andrewbonney 0:07919e3d6c56 254 {
andrewbonney 0:07919e3d6c56 255 if(strcmp(name,"FilterRequest")==0) {
andrewbonney 0:07919e3d6c56 256 switchToNewSubParser(
andrewbonney 0:07919e3d6c56 257 mCurrentFilterParser = new FilterRequestParser(this, atts)
andrewbonney 0:07919e3d6c56 258 ); // we own and will have to explicitly delete
andrewbonney 0:07919e3d6c56 259 ...
andrewbonney 0:07919e3d6c56 260 }
andrewbonney 0:07919e3d6c56 261
andrewbonney 0:07919e3d6c56 262 void MultiFilterParser::endElement(const XML_Char *name)
andrewbonney 0:07919e3d6c56 263 {
andrewbonney 0:07919e3d6c56 264 if(strcmp(name,"FilterRequest")==0) {
andrewbonney 0:07919e3d6c56 265 assert(mCurrentFilterParser);
andrewbonney 0:07919e3d6c56 266 FilterClause* newClause = mCurrentFilterParser->orphanBuiltClause(); // retrieve data built by sub-parser
andrewbonney 0:07919e3d6c56 267 ...
andrewbonney 0:07919e3d6c56 268 mCurrentFilterParser = 0;
andrewbonney 0:07919e3d6c56 269 DeleteChild();
andrewbonney 0:07919e3d6c56 270 }
andrewbonney 0:07919e3d6c56 271 }
andrewbonney 0:07919e3d6c56 272 \endverbatim
andrewbonney 0:07919e3d6c56 273 */
andrewbonney 0:07919e3d6c56 274 class expatppNesting : public expatpp {
andrewbonney 0:07919e3d6c56 275
andrewbonney 0:07919e3d6c56 276 public:
andrewbonney 0:07919e3d6c56 277 expatppNesting(expatppNesting* parent=0); ///< NOT a copy ctor!! this is a recursive situation
andrewbonney 0:07919e3d6c56 278 virtual ~expatppNesting();
andrewbonney 0:07919e3d6c56 279
andrewbonney 0:07919e3d6c56 280 void switchToNewSubParser( expatppNesting* pAdoptedChild );
andrewbonney 0:07919e3d6c56 281 expatppNesting* returnToParent();
andrewbonney 0:07919e3d6c56 282
andrewbonney 0:07919e3d6c56 283 protected:
andrewbonney 0:07919e3d6c56 284 void BeAdopted(expatppNesting* adoptingParent);
andrewbonney 0:07919e3d6c56 285 void OwnedChildOrphansItself(expatppNesting* callingChild);
andrewbonney 0:07919e3d6c56 286 void RegisterWithParentXMLParser();
andrewbonney 0:07919e3d6c56 287 virtual void AdoptChild(expatppNesting* adoptingChild);
andrewbonney 0:07919e3d6c56 288 virtual void DeleteChild();
andrewbonney 0:07919e3d6c56 289
andrewbonney 0:07919e3d6c56 290 int mDepth;
andrewbonney 0:07919e3d6c56 291 bool mSelfDeleting; ///< only valid if mParent not null
andrewbonney 0:07919e3d6c56 292 expatppNesting* mParent; ///< may be null the parent owns this object
andrewbonney 0:07919e3d6c56 293 expatppNesting* mOwnedChild; ///< owned, optional currently active child (auto_ptr not used to avoid STL dependency)
andrewbonney 0:07919e3d6c56 294
andrewbonney 0:07919e3d6c56 295 public:
andrewbonney 0:07919e3d6c56 296 /// \name interface functions for callbacks
andrewbonney 0:07919e3d6c56 297 //@{
andrewbonney 0:07919e3d6c56 298 static void nestedStartElementCallback(void* userData, const XML_Char* name, const XML_Char** atts);
andrewbonney 0:07919e3d6c56 299 static void nestedEndElementCallback(void* userData, const XML_Char* name);
andrewbonney 0:07919e3d6c56 300 //@}
andrewbonney 0:07919e3d6c56 301
andrewbonney 0:07919e3d6c56 302
andrewbonney 0:07919e3d6c56 303 /// \name overrideables to customise behaviour, must call parent
andrewbonney 0:07919e3d6c56 304 //@{
andrewbonney 0:07919e3d6c56 305 virtual void SetupHandlers();
andrewbonney 0:07919e3d6c56 306 //@}
andrewbonney 0:07919e3d6c56 307
andrewbonney 0:07919e3d6c56 308 private:
andrewbonney 0:07919e3d6c56 309 // Forbid copy-construction and assignment, to prevent double-deletion of mOwnedChild
andrewbonney 0:07919e3d6c56 310 expatppNesting( const expatppNesting & );
andrewbonney 0:07919e3d6c56 311 expatppNesting & operator=( const expatppNesting & );
andrewbonney 0:07919e3d6c56 312 };
andrewbonney 0:07919e3d6c56 313
andrewbonney 0:07919e3d6c56 314
andrewbonney 0:07919e3d6c56 315 // inlines
andrewbonney 0:07919e3d6c56 316
andrewbonney 0:07919e3d6c56 317 // -------------------------------------------------------
andrewbonney 0:07919e3d6c56 318 // e x p a t p p
andrewbonney 0:07919e3d6c56 319 // -------------------------------------------------------
andrewbonney 0:07919e3d6c56 320 inline
andrewbonney 0:07919e3d6c56 321 expatpp::operator XML_Parser() const
andrewbonney 0:07919e3d6c56 322 {
andrewbonney 0:07919e3d6c56 323 return mParser;
andrewbonney 0:07919e3d6c56 324 }
andrewbonney 0:07919e3d6c56 325
andrewbonney 0:07919e3d6c56 326
andrewbonney 0:07919e3d6c56 327 // -------------------------------------------------------
andrewbonney 0:07919e3d6c56 328 // e x p a t p p N e s t i n g
andrewbonney 0:07919e3d6c56 329 // -------------------------------------------------------
andrewbonney 0:07919e3d6c56 330 inline void
andrewbonney 0:07919e3d6c56 331 expatppNesting::OwnedChildOrphansItself(expatppNesting* callingChild)
andrewbonney 0:07919e3d6c56 332 {
andrewbonney 0:07919e3d6c56 333 assert(callingChild==mOwnedChild);
andrewbonney 0:07919e3d6c56 334 mOwnedChild = 0;
andrewbonney 0:07919e3d6c56 335 }
andrewbonney 0:07919e3d6c56 336
andrewbonney 0:07919e3d6c56 337
andrewbonney 0:07919e3d6c56 338
andrewbonney 0:07919e3d6c56 339 #endif // H_EXPATPP