1: /* $Id: minixml.c,v 1.1.1.3 2013/07/22 00:32:35 misho Exp $ */
2: /* minixml.c : the minimum size a xml parser can be ! */
3: /* Project : miniupnp
4: * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
5: * Author : Thomas Bernard
6:
7: Copyright (c) 2005-2011, Thomas BERNARD
8: All rights reserved.
9:
10: Redistribution and use in source and binary forms, with or without
11: modification, are permitted provided that the following conditions are met:
12:
13: * Redistributions of source code must retain the above copyright notice,
14: this list of conditions and the following disclaimer.
15: * Redistributions in binary form must reproduce the above copyright notice,
16: this list of conditions and the following disclaimer in the documentation
17: and/or other materials provided with the distribution.
18: * The name of the author may not be used to endorse or promote products
19: derived from this software without specific prior written permission.
20:
21: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31: POSSIBILITY OF SUCH DAMAGE.
32: */
33: #include <string.h>
34: #include "minixml.h"
35:
36: /* parseatt : used to parse the argument list
37: * return 0 (false) in case of success and -1 (true) if the end
38: * of the xmlbuffer is reached. */
39: static int parseatt(struct xmlparser * p)
40: {
41: const char * attname;
42: int attnamelen;
43: const char * attvalue;
44: int attvaluelen;
45: while(p->xml < p->xmlend)
46: {
47: if(*p->xml=='/' || *p->xml=='>')
48: return 0;
49: if( !IS_WHITE_SPACE(*p->xml) )
50: {
51: char sep;
52: attname = p->xml;
53: attnamelen = 0;
54: while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) )
55: {
56: attnamelen++; p->xml++;
57: if(p->xml >= p->xmlend)
58: return -1;
59: }
60: while(*(p->xml++) != '=')
61: {
62: if(p->xml >= p->xmlend)
63: return -1;
64: }
65: while(IS_WHITE_SPACE(*p->xml))
66: {
67: p->xml++;
68: if(p->xml >= p->xmlend)
69: return -1;
70: }
71: sep = *p->xml;
72: if(sep=='\'' || sep=='\"')
73: {
74: p->xml++;
75: if(p->xml >= p->xmlend)
76: return -1;
77: attvalue = p->xml;
78: attvaluelen = 0;
79: while(*p->xml != sep)
80: {
81: attvaluelen++; p->xml++;
82: if(p->xml >= p->xmlend)
83: return -1;
84: }
85: }
86: else
87: {
88: attvalue = p->xml;
89: attvaluelen = 0;
90: while( !IS_WHITE_SPACE(*p->xml)
91: && *p->xml != '>' && *p->xml != '/')
92: {
93: attvaluelen++; p->xml++;
94: if(p->xml >= p->xmlend)
95: return -1;
96: }
97: }
98: /*printf("%.*s='%.*s'\n",
99: attnamelen, attname, attvaluelen, attvalue);*/
100: if(p->attfunc)
101: p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen);
102: }
103: p->xml++;
104: }
105: return -1;
106: }
107:
108: /* parseelt parse the xml stream and
109: * call the callback functions when needed... */
110: static void parseelt(struct xmlparser * p)
111: {
112: int i;
113: const char * elementname;
114: while(p->xml < (p->xmlend - 1))
115: {
116: if((p->xml)[0]=='<' && (p->xml)[1]!='?')
117: {
118: i = 0; elementname = ++p->xml;
119: while( !IS_WHITE_SPACE(*p->xml)
120: && (*p->xml!='>') && (*p->xml!='/')
121: )
122: {
123: i++; p->xml++;
124: if (p->xml >= p->xmlend)
125: return;
126: /* to ignore namespace : */
127: if(*p->xml==':')
128: {
129: i = 0;
130: elementname = ++p->xml;
131: }
132: }
133: if(i>0)
134: {
135: if(p->starteltfunc)
136: p->starteltfunc(p->data, elementname, i);
137: if(parseatt(p))
138: return;
139: if(*p->xml!='/')
140: {
141: const char * data;
142: i = 0; data = ++p->xml;
143: if (p->xml >= p->xmlend)
144: return;
145: while( IS_WHITE_SPACE(*p->xml) )
146: {
147: i++; p->xml++;
148: if (p->xml >= p->xmlend)
149: return;
150: }
151: if(memcmp(p->xml, "<![CDATA[", 9) == 0)
152: {
153: /* CDATA handling */
154: p->xml += 9;
155: data = p->xml;
156: i = 0;
157: while(memcmp(p->xml, "]]>", 3) != 0)
158: {
159: i++; p->xml++;
160: if ((p->xml + 3) >= p->xmlend)
161: return;
162: }
163: if(i>0 && p->datafunc)
164: p->datafunc(p->data, data, i);
165: while(*p->xml!='<')
166: {
167: p->xml++;
168: if (p->xml >= p->xmlend)
169: return;
170: }
171: }
172: else
173: {
174: while(*p->xml!='<')
175: {
176: i++; p->xml++;
177: if ((p->xml + 1) >= p->xmlend)
178: return;
179: }
180: if(i>0 && p->datafunc && *(p->xml + 1) == '/')
181: p->datafunc(p->data, data, i);
182: }
183: }
184: }
185: else if(*p->xml == '/')
186: {
187: i = 0; elementname = ++p->xml;
188: if (p->xml >= p->xmlend)
189: return;
190: while((*p->xml != '>'))
191: {
192: i++; p->xml++;
193: if (p->xml >= p->xmlend)
194: return;
195: }
196: if(p->endeltfunc)
197: p->endeltfunc(p->data, elementname, i);
198: p->xml++;
199: }
200: }
201: else
202: {
203: p->xml++;
204: }
205: }
206: }
207:
208: /* the parser must be initialized before calling this function */
209: void parsexml(struct xmlparser * parser)
210: {
211: parser->xml = parser->xmlstart;
212: parser->xmlend = parser->xmlstart + parser->xmlsize;
213: parseelt(parser);
214: }
215:
216:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>