23 #ifndef _EXPATMM_EXPATXMLPARSER_H 24 #define _EXPATMM_EXPATXMLPARSER_H 34 #define EXPATMM_SSIZE_T int 36 #define EXPATMM_SSIZE_T ssize_t 55 if(expat_parser != NULL) {
56 XML_ParserFree(expat_parser);
59 if(xml_buffer != NULL) {
70 virtual bool Parse(
void) {
75 EXPATMM_SSIZE_T bytes_read;
77 while((bytes_read = read_block()) >= 0) {
79 XML_Status local_status =
80 XML_Parse(expat_parser, getReadBuffer(), (
int)bytes_read,
83 if(local_status != XML_STATUS_OK) {
84 set_status(local_status);
89 if(getLastError() == XML_ERROR_FINISHED)
95 if((getStatus() == XML_STATUS_OK) ||
96 (getLastError() == XML_ERROR_FINISHED)) {
97 XML_Status local_status =
98 XML_Parse(expat_parser, getBuffer(), 0, XML_TRUE);
99 if(local_status != XML_STATUS_OK) {
100 set_status(local_status);
112 virtual bool Ready(
void)
const {
115 virtual XML_Error getLastError(
void)
const {
118 virtual XML_Status getStatus(
void)
const {
121 virtual XML_Size getLastErrorLine(
void)
const {
122 return last_error_line;
124 virtual XML_Size getLastErrorColumn(
void)
const {
125 return last_error_column;
127 virtual std::string getLastErrorMessage(
void)
const {
128 return last_error_message;
134 StackEl(
const char* nm) : name(nm) {}
136 XML_Size start_index;
137 std::map<std::string,std::string> attributes;
140 std::vector<StackEl> m_path;
142 virtual XML_Char *getBuffer(
void) {
145 virtual const char *getReadBuffer(
void) {
148 virtual size_t getBlockSize(
void) {
149 return xml_buffer_size;
178 virtual EXPATMM_SSIZE_T read_block(
void) {
179 last_error = XML_ERROR_NO_ELEMENTS;
180 status = XML_STATUS_ERROR;
184 virtual void setReadiness(
bool ready) {
185 valid_parser = ready;
187 virtual void setStatus(XML_Status new_status) {
190 virtual void setLastError(XML_Error new_last_error) {
191 last_error = new_last_error;
195 virtual void StartElement(
const XML_Char *,
const XML_Char **) {}
196 virtual void EndElement(
const XML_Char *) {}
197 virtual void CharacterData(
const XML_Char *,
int) {}
198 virtual void ProcessingInstruction(
const XML_Char *,
const XML_Char *) {}
199 virtual void CommentData(
const XML_Char *) {}
200 virtual void DefaultHandler(
const XML_Char *,
int) {}
201 virtual void CDataStart(
void) {}
202 virtual void CDataEnd(
void) {}
205 XML_Parser expat_parser;
210 XML_Char *xml_buffer;
211 size_t xml_buffer_size;
217 void set_status(XML_Status ls) {
219 last_error = XML_GetErrorCode(expat_parser);
220 last_error_line = XML_GetCurrentLineNumber(expat_parser);
221 last_error_column= XML_GetCurrentColumnNumber(expat_parser);
222 std::ostringstream oss;
223 oss << XML_ErrorString(last_error) <<
224 " at line " << last_error_line <<
" column " <<
226 last_error_message = oss.str();
230 XML_Error last_error;
231 XML_Size last_error_line{0};
232 XML_Size last_error_column{0};
233 std::string last_error_message;
240 static void _element_start_handler(
void *userData,
const XML_Char *name,
241 const XML_Char **atts) {
244 me->m_path.push_back(
StackEl(name));
245 StackEl& lastelt = me->m_path.back();
246 lastelt.start_index = XML_GetCurrentByteIndex(me->expat_parser);
247 for (
int i = 0; atts[i] != 0; i += 2) {
248 lastelt.attributes[atts[i]] = atts[i+1];
250 me->StartElement(name, atts);
253 static void _element_end_handler(
void *userData,
const XML_Char *name) {
256 me->EndElement(name);
257 me->m_path.pop_back();
260 static void _character_data_handler(
void *userData,
261 const XML_Char *s,
int len) {
263 if(me != NULL) me->CharacterData(s, len);
265 static void _processing_instr_handler(
void *userData,
266 const XML_Char *target,
267 const XML_Char *data) {
269 if(me != NULL) me->ProcessingInstruction(target, data);
271 static void _comment_handler(
void *userData,
const XML_Char *data) {
273 if(me != NULL) me->CommentData(data);
275 static void _default_handler(
void *userData,
const XML_Char *s,
int len) {
277 if(me != NULL) me->DefaultHandler(s, len);
279 static void _cdata_start_handler(
void *userData) {
281 if(me != NULL) me->CDataStart();
283 static void _cdata_end_handler(
void *userData) {
285 if(me != NULL) me->CDataEnd();
288 void register_default_handlers() {
289 XML_SetElementHandler(expat_parser, &_element_start_handler,
290 &_element_end_handler);
291 XML_SetCharacterDataHandler(expat_parser, &_character_data_handler);
292 XML_SetProcessingInstructionHandler(expat_parser,
293 &_processing_instr_handler);
294 XML_SetCommentHandler(expat_parser, &_comment_handler);
295 XML_SetCdataSectionHandler(expat_parser, &_cdata_start_handler,
296 &_cdata_end_handler);
297 XML_SetDefaultHandler(expat_parser, &_default_handler);
300 void init(
size_t chunk_size = 0) {
301 valid_parser =
false;
303 xml_buffer_size = chunk_size ? chunk_size : 10240;
304 xml_buffer =
new XML_Char[xml_buffer_size];
305 if(xml_buffer == NULL)
307 expat_parser = XML_ParserCreate(NULL);
309 if(expat_parser == NULL) {
310 delete [] xml_buffer;
314 status = XML_STATUS_OK;
315 last_error = XML_ERROR_NONE;
317 memset(xml_buffer, 0, chunk_size *
sizeof(XML_Char));
321 XML_SetUserData(expat_parser, (
void*)
this);
322 register_default_handlers();
338 EXPATMM_SSIZE_T read_block(
void) {
339 if (getLastError() == XML_ERROR_FINISHED) {
340 setStatus(XML_STATUS_OK);
343 setLastError(XML_ERROR_FINISHED);
344 return m_input.size();
346 const char *getReadBuffer() {
347 return m_input.c_str();
349 virtual size_t getBlockSize(
void) {
350 return m_input.size();
353 const std::string& m_input;
Definition: expatmm.hxx:39
Definition: expatmm.hxx:132