/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * saxparser.cc * * Tue Jul 22 16:26:22 CEST 2008 * Copyright 2008 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of DrumGizmo. * * DrumGizmo is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * DrumGizmo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "saxparser.h" #include #include #include SAXParser::SAXParser() { p = XML_ParserCreate(nullptr); if(!p) { ERR(sax, "Couldn't allocate memory for parser\n"); // throw Exception(...); TODO return; } XML_SetUserData(p, this); XML_UseParserAsHandlerArg(p); XML_SetElementHandler(p, start_hndl, end_hndl); XML_SetCharacterDataHandler(p, character_hndl); } SAXParser::~SAXParser() { XML_ParserFree(p); } int SAXParser::parse() { DEBUG(sax, "parse()\n"); std::string buf; int len; do { len = readData(buf, 32); if(len <= -1) { parseError("", 0, "Could not read data", 0); return 1; } if(!XML_Parse(p, (char*)buf.c_str(), len, len == 0)) { parseError(buf, len, XML_ErrorString(XML_GetErrorCode(p)), (int)XML_GetCurrentLineNumber(p)); return 1; } buf.clear(); } while(len); return 0; } int SAXParser::parse(const std::string& buffer) { DEBUG(sax, "parse(buffer %d bytes)\n", (int)buffer.length()); if(!XML_Parse(p, buffer.c_str(), buffer.length(), true)) { parseError(buffer, buffer.length(), XML_ErrorString(XML_GetErrorCode(p)), (int)XML_GetCurrentLineNumber(p)); return 1; } return 0; } void SAXParser::parseError(const std::string& buf, std::size_t len, const std::string& error, std::size_t lineno) { fprintf(stderr, "SAXParser error at line %d: %s\n", (int)lineno, error.c_str()); fprintf(stderr, "Buffer %u bytes: \n[\n", (int)len); fwrite((char*)buf.c_str(), len, 1, stderr); fprintf(stderr, "\n]\n"); fflush(stderr); } void SAXParser::character_hndl(void* p, const XML_Char* s, int len) { SAXParser* parser = (SAXParser*)XML_GetUserData(p); std::string chars(s, len); parser->characterData(chars); } void SAXParser::start_hndl(void* p, const char* el, const char** attr) { SAXParser* parser = (SAXParser*)XML_GetUserData(p); // Convert to comfy C++ values... attr_t attributes; while(*attr) { std::string at_name = *attr++; std::string at_value = *attr++; attributes.emplace(at_name, at_value); } parser->startTag(std::string(el), attributes); } void SAXParser::end_hndl(void* p, const char* el) { SAXParser* parser = (SAXParser*)XML_GetUserData(p); parser->endTag(std::string(el)); }