1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
/*******************************************************************************
* Goggles Audio Player Library *
********************************************************************************
* Copyright (C) 2010-2021 by Sander Jansen. All Rights Reserved *
* --- *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see http://www.gnu.org/licenses. *
********************************************************************************/
#include "ap_defs.h"
#include "ap_utils.h"
#include "ap_xml_parser.h"
#include <expat.h>
namespace ap {
#define NUM_NODES 32
XmlParser::XmlParser() : nnodes(NUM_NODES),level(0) {
allocElms(nodes,nnodes);
nodes[0]=Elem_None;
}
XmlParser::~XmlParser() {
freeElms(nodes);
}
void XmlParser::element_start(const FXchar*element,const FXchar**attributes){
FXint n =0 ;
if (nodes[level])
n = begin(element,attributes);
level++;
if (level==nnodes){
nnodes+=NUM_NODES;
resizeElms(nodes,nnodes);
}
nodes[level] = n;
}
void XmlParser::element_end(const FXchar * element) {
if (nodes[level])
end(element);
level--;
}
void XmlParser::element_data(const FXchar * d,FXint len) {
if (nodes[level])
data(d,len);
}
static void element_start(void*ptr,const FXchar*element,const FXchar**attributes){
XmlParser * parser = static_cast<XmlParser*>(ptr);
parser->element_start((const FXchar*)element,(const FXchar**)attributes);
}
static void element_end(void*ptr,const FXchar * element) {
XmlParser * parser = static_cast<XmlParser*>(ptr);
parser->element_end((const FXchar*)element);
}
static void element_data(void*ptr,const FXchar * data,FXint len) {
XmlParser * parser = static_cast<XmlParser*>(ptr);
parser->element_data((const FXchar*)data,len);
}
static int unknown_encoding(void*,const XML_Char * name,XML_Encoding * info){
GM_DEBUG_PRINT("[xml] unknown_encoding \"%s\"\n",name);
const FXTextCodec * codec = ap_get_textcodec(name);
if (codec) {
/* Only works for single byte codecs */
FXwchar w;FXuchar c;
for (FXint i=0;i<256;i++) {
c=i;
codec->mb2wc(w,(const FXchar*)&c,1);
info->map[i] = w;
info->convert = nullptr;
info->release = nullptr;
}
return XML_STATUS_OK;
}
return XML_STATUS_ERROR;
}
FXbool XmlParser::parse(const FXString & buffer,const FXString & encoding) {
if (!encoding.empty())
GM_DEBUG_PRINT("[xml] parse with encoding %s\n",encoding.text());
XML_Parser parser;
if (encoding.empty())
parser = XML_ParserCreate(nullptr);
else
parser = XML_ParserCreate(encoding.text());
XML_SetUserData((XML_Parser)parser,this);
XML_SetElementHandler((XML_Parser)parser,ap::element_start,ap::element_end);
XML_SetCharacterDataHandler((XML_Parser)parser,ap::element_data);
XML_SetUnknownEncodingHandler((XML_Parser)parser,unknown_encoding,this);
XML_Status code = XML_Parse((XML_Parser)parser,buffer.text(),buffer.length(),1);
if (code==XML_STATUS_ERROR) {
XML_ParserFree(parser);
return false;
}
XML_ParserFree(parser);
return true;
}
}
|