1 /*
2 * Copyright 2005-2007 Gerald Schmidt.
3 *
4 * This file is part of Xml Copy Editor.
5 *
6 * Xml Copy Editor is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * Xml Copy Editor is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Xml Copy Editor; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <string>
22 #include <vector>
23 #include <stdexcept>
24 #include <expat.h>
25 #include <map>
26 #include <set>
27 #include <cstring>
28 #include "xmlfilterreader.h"
29
30 using namespace std;
31
XmlFilterReader()32 XmlFilterReader::XmlFilterReader() : fd ( new FilterData() )
33 {
34 fd->filterCount = 0;
35 fd->setState ( STATE_UNKNOWN );
36 XML_SetUserData ( p, fd.get() );
37 XML_SetElementHandler ( p, start, end );
38 XML_SetCharacterDataHandler ( p, characterdata );
39 }
40
~XmlFilterReader()41 XmlFilterReader::~XmlFilterReader()
42 {}
43
getFilterCount()44 int XmlFilterReader::getFilterCount()
45 {
46 return fd->filterCount;
47 }
48
getExcludeVector(vector<string> & v)49 void XmlFilterReader::getExcludeVector ( vector<string> &v )
50 {
51 v = fd->excludeVector;
52 }
53
getIncludeVector(vector<string> & v)54 void XmlFilterReader::getIncludeVector ( vector<string> &v )
55 {
56 v = fd->includeVector;
57 }
58
getFilterMap(map<string,map<string,set<string>>> & m)59 void XmlFilterReader::getFilterMap (
60 map<string, map<string, set<string> > > &m
61 )
62 {
63 m = fd->filterMap;
64 }
65
start(void * data,const XML_Char * el,const XML_Char ** attr)66 void XMLCALL XmlFilterReader::start ( void *data,
67 const XML_Char *el,
68 const XML_Char **attr )
69 {
70 FilterData *fd;
71 fd = ( FilterData * ) data;
72
73 if ( !strcmp ( el, "element" ) )
74 fd->setState ( STATE_IN_ELEMENT );
75 else if ( !strcmp ( el, "attribute" ) )
76 fd->setState ( STATE_IN_ATTRIBUTE );
77 else if ( !strcmp ( el, "key" ) )
78 fd->setState ( STATE_IN_ATTRIBUTE_KEY );
79 else if ( !strcmp ( el, "value" ) )
80 fd->setState ( STATE_IN_ATTRIBUTE_VALUE );
81 else if ( !strcmp ( el, "exclude" ) )
82 fd->setState ( STATE_IN_EXCLUDE );
83 else if ( !strcmp ( el, "include" ) )
84 fd->setState ( STATE_IN_INCLUDE );
85 else
86 fd->setState ( STATE_UNKNOWN );
87 }
88
end(void * data,const XML_Char * el)89 void XMLCALL XmlFilterReader::end ( void *data, const XML_Char *el )
90 {
91 FilterData *fd;
92 fd = ( FilterData * ) data;
93
94 if ( !strcmp ( el, "element" ) )
95 {
96 fd->filterMap.insert ( make_pair ( fd->elementString, fd->attributeMap ) );
97 ( fd->filterCount ) ++;
98
99 fd->elementString = "";
100 fd->attributeKeyString = "";
101 fd->attributeValueString = "";
102 fd->attributeMap.clear();
103 fd->setState ( STATE_UNKNOWN );
104 }
105
106 else if ( !strcmp ( el, "attribute" ) )
107 {
108 fd->attributeMap.insert (
109 make_pair ( fd->attributeKeyString, fd->attributeValueSet )
110 );
111 fd->setState ( STATE_UNKNOWN );
112 }
113 else if ( !strcmp ( el, "key" ) )
114 fd->setState ( STATE_UNKNOWN );
115 else if ( !strcmp ( el, "value" ) )
116 {
117 fd->attributeValueSet.insert ( fd->attributeValueString );
118 fd->setState ( STATE_UNKNOWN );
119 fd->attributeValueString = "";
120 }
121
122 // handle excludes/includes
123 else if ( !strcmp ( el, "exclude" ) )
124 {
125 fd->excludeVector.push_back ( fd->excludeString );
126 fd->excludeString = "";
127 fd->setState ( STATE_UNKNOWN );
128 }
129 else if ( !strcmp ( el, "include" ) )
130 {
131 fd->includeVector.push_back ( fd->includeString );
132 fd->includeString = "";
133 fd->setState ( STATE_UNKNOWN );
134 }
135 }
136
characterdata(void * data,const XML_Char * s,int len)137 void XMLCALL XmlFilterReader::characterdata (
138 void *data,
139 const XML_Char *s,
140 int len )
141 {
142 FilterData *fd;
143 fd = ( FilterData * ) data;
144
145 switch ( fd->getState() )
146 {
147 case STATE_IN_ELEMENT:
148 fd->elementString.append ( s, len );
149 break;
150 case STATE_IN_ATTRIBUTE_KEY:
151 fd->attributeKeyString.append ( s, len );
152 break;
153 case STATE_IN_ATTRIBUTE_VALUE:
154 fd->attributeValueString.append ( s, len );
155 break;
156 case STATE_IN_EXCLUDE:
157 fd->excludeString.append ( s, len );
158 break;
159 case STATE_IN_INCLUDE:
160 fd->includeString.append ( s, len );
161 break;
162 default:
163 break;
164 }
165 }
166