mupnp 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +13 -0
- data/Rakefile +80 -0
- data/ext/Changelog.txt +188 -0
- data/ext/LICENSE +27 -0
- data/ext/README +53 -0
- data/ext/declspec.h +15 -0
- data/ext/extconf.rb +5 -0
- data/ext/igd_desc_parse.c +115 -0
- data/ext/igd_desc_parse.h +38 -0
- data/ext/minisoap.c +112 -0
- data/ext/minisoap.h +15 -0
- data/ext/minissdpc.c +107 -0
- data/ext/minissdpc.h +15 -0
- data/ext/miniupnpc.c +751 -0
- data/ext/miniupnpc.h +108 -0
- data/ext/miniwget.c +219 -0
- data/ext/miniwget.h +28 -0
- data/ext/minixml.c +191 -0
- data/ext/minixml.h +37 -0
- data/ext/upnp.i +13 -0
- data/ext/upnp_wrap.c +5207 -0
- data/ext/upnpcommands.c +569 -0
- data/ext/upnpcommands.h +179 -0
- data/ext/upnperrors.c +55 -0
- data/ext/upnperrors.h +16 -0
- data/ext/upnpreplyparse.c +127 -0
- data/ext/upnpreplyparse.h +62 -0
- data/lib/UPnP.rb +400 -0
- data/test/UPnP/tc_upnp.rb +20 -0
- metadata +83 -0
data/ext/miniupnpc.h
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
/* $Id: miniupnpc.h,v 1.17 2007/12/19 14:58:54 nanard Exp $ */
|
2
|
+
/* Project: miniupnp
|
3
|
+
* http://miniupnp.free.fr/
|
4
|
+
* Author: Thomas Bernard
|
5
|
+
* Copyright (c) 2005-2006 Thomas Bernard
|
6
|
+
* This software is subjects to the conditions detailed
|
7
|
+
* in the LICENCE file provided within this distribution */
|
8
|
+
#ifndef __MINIUPNPC_H__
|
9
|
+
#define __MINIUPNPC_H__
|
10
|
+
|
11
|
+
#include "declspec.h"
|
12
|
+
#include "igd_desc_parse.h"
|
13
|
+
|
14
|
+
#ifdef __cplusplus
|
15
|
+
extern "C" {
|
16
|
+
#endif
|
17
|
+
|
18
|
+
/* Structures definitions : */
|
19
|
+
struct UPNParg { char * elt; char * val; };
|
20
|
+
|
21
|
+
int simpleUPnPcommand(int, const char *, const char *,
|
22
|
+
const char *, struct UPNParg *,
|
23
|
+
char *, int *);
|
24
|
+
|
25
|
+
struct UPNPDev {
|
26
|
+
struct UPNPDev * pNext;
|
27
|
+
char * descURL;
|
28
|
+
char * st;
|
29
|
+
char buffer[2];
|
30
|
+
};
|
31
|
+
|
32
|
+
/* upnpDiscover()
|
33
|
+
* discover UPnP devices on the network.
|
34
|
+
* The discovered devices are returned as a chained list.
|
35
|
+
* It is up to the caller to free the list with freeUPNPDevlist().
|
36
|
+
* delay (in millisecond) is the maximum time for waiting any device
|
37
|
+
* response.
|
38
|
+
* If available, device list will be obtained from MiniSSDPd.
|
39
|
+
* Default path for minissdpd socket will be used if minissdpdsock argument
|
40
|
+
* is NULL.
|
41
|
+
* If multicastif is not NULL, it will be used instead of the default
|
42
|
+
* multicast interface for sending SSDP discover packets. */
|
43
|
+
LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
44
|
+
const char * minissdpdsock);
|
45
|
+
/* freeUPNPDevlist()
|
46
|
+
* free list returned by upnpDiscover() */
|
47
|
+
LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
|
48
|
+
|
49
|
+
/* parserootdesc() :
|
50
|
+
* parse root XML description of a UPnP device and fill the IGDdatas
|
51
|
+
* structure. */
|
52
|
+
LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
|
53
|
+
|
54
|
+
/* structure used to get fast access to urls
|
55
|
+
* controlURL: controlURL of the WANIPConnection
|
56
|
+
* ipcondescURL: url of the description of the WANIPConnection
|
57
|
+
* controlURL_CIF: controlURL of the WANCommonInterfaceConfig
|
58
|
+
*/
|
59
|
+
struct UPNPUrls {
|
60
|
+
char * controlURL;
|
61
|
+
char * ipcondescURL;
|
62
|
+
char * controlURL_CIF;
|
63
|
+
};
|
64
|
+
|
65
|
+
/* UPNP_GetValidIGD() :
|
66
|
+
* return values :
|
67
|
+
* 0 = NO IGD found
|
68
|
+
* 1 = A valid connected IGD has been found
|
69
|
+
* 2 = A valid IGD has been found but it reported as
|
70
|
+
* not connected
|
71
|
+
* 3 = an UPnP device has been found but was not recognized as an IGD
|
72
|
+
*
|
73
|
+
* In any non zero return case, the urls and data structures
|
74
|
+
* passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
|
75
|
+
* free allocated memory.
|
76
|
+
*/
|
77
|
+
LIBSPEC int
|
78
|
+
UPNP_GetValidIGD(struct UPNPDev * devlist,
|
79
|
+
struct UPNPUrls * urls,
|
80
|
+
struct IGDdatas * data,
|
81
|
+
char * lanaddr, int lanaddrlen);
|
82
|
+
|
83
|
+
/* UPNP_GetIGDFromUrl()
|
84
|
+
* Used when skipping the discovery process.
|
85
|
+
* return value :
|
86
|
+
* 0 - Not ok
|
87
|
+
* 1 - OK */
|
88
|
+
LIBSPEC int
|
89
|
+
UPNP_GetIGDFromUrl(const char * rootdescurl,
|
90
|
+
struct UPNPUrls * urls,
|
91
|
+
struct IGDdatas * data,
|
92
|
+
char * lanaddr, int lanaddrlen);
|
93
|
+
|
94
|
+
LIBSPEC void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *);
|
95
|
+
|
96
|
+
LIBSPEC void FreeUPNPUrls(struct UPNPUrls *);
|
97
|
+
|
98
|
+
/* Reads data from the specified socket.
|
99
|
+
* Returns the number of bytes read if successful, zero if no bytes were
|
100
|
+
* read or if we timed out. Returns negative if there was an error. */
|
101
|
+
int ReceiveData(int socket, char * data, int length, int timeout);
|
102
|
+
|
103
|
+
#ifdef __cplusplus
|
104
|
+
}
|
105
|
+
#endif
|
106
|
+
|
107
|
+
#endif
|
108
|
+
|
data/ext/miniwget.c
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
/* $Id: miniwget.c,v 1.19 2007/11/02 14:16:19 nanard Exp $ */
|
2
|
+
/* Project : miniupnp
|
3
|
+
* Author : Thomas Bernard
|
4
|
+
* Copyright (c) 2005 Thomas Bernard
|
5
|
+
* This software is subject to the conditions detailed in the
|
6
|
+
* LICENCE file provided in this distribution.
|
7
|
+
* */
|
8
|
+
#include <stdio.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <string.h>
|
11
|
+
#include "miniupnpc.h"
|
12
|
+
#ifdef WIN32
|
13
|
+
#include <winsock2.h>
|
14
|
+
#include <io.h>
|
15
|
+
#define MAXHOSTNAMELEN 64
|
16
|
+
#define MIN(x,y) (((x)<(y))?(x):(y))
|
17
|
+
#define snprintf _snprintf
|
18
|
+
#define herror
|
19
|
+
#define socklen_t int
|
20
|
+
#else
|
21
|
+
#include <unistd.h>
|
22
|
+
#include <sys/param.h>
|
23
|
+
#include <sys/socket.h>
|
24
|
+
#include <netdb.h>
|
25
|
+
#include <netinet/in.h>
|
26
|
+
#include <arpa/inet.h>
|
27
|
+
#define closesocket close
|
28
|
+
#endif
|
29
|
+
/* for MIN() macro : */
|
30
|
+
#if defined(__sun) || defined(sun)
|
31
|
+
#include <utility.h>
|
32
|
+
#endif
|
33
|
+
|
34
|
+
/* miniwget2() :
|
35
|
+
* */
|
36
|
+
static void *
|
37
|
+
miniwget2(const char * url, const char * host,
|
38
|
+
unsigned short port, const char * path,
|
39
|
+
int * size, char * addr_str, int addr_str_len)
|
40
|
+
{
|
41
|
+
char buf[2048];
|
42
|
+
int s;
|
43
|
+
struct sockaddr_in dest;
|
44
|
+
struct hostent *hp;
|
45
|
+
*size = 0;
|
46
|
+
hp = gethostbyname(host);
|
47
|
+
if(hp==NULL)
|
48
|
+
{
|
49
|
+
herror(host);
|
50
|
+
return NULL;
|
51
|
+
}
|
52
|
+
/* memcpy((char *)&dest.sin_addr, hp->h_addr, hp->h_length); */
|
53
|
+
memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
|
54
|
+
memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
|
55
|
+
s = socket(PF_INET, SOCK_STREAM, 0);
|
56
|
+
if(s < 0)
|
57
|
+
{
|
58
|
+
perror("socket");
|
59
|
+
return NULL;
|
60
|
+
}
|
61
|
+
dest.sin_family = AF_INET;
|
62
|
+
dest.sin_port = htons(port);
|
63
|
+
if(connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in))<0)
|
64
|
+
{
|
65
|
+
perror("connect");
|
66
|
+
closesocket(s);
|
67
|
+
return NULL;
|
68
|
+
}
|
69
|
+
|
70
|
+
/* get address for caller ! */
|
71
|
+
if(addr_str)
|
72
|
+
{
|
73
|
+
struct sockaddr_in saddr;
|
74
|
+
socklen_t len;
|
75
|
+
|
76
|
+
len = sizeof(saddr);
|
77
|
+
getsockname(s, (struct sockaddr *)&saddr, &len);
|
78
|
+
#ifndef WIN32
|
79
|
+
inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);
|
80
|
+
#else
|
81
|
+
/* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
|
82
|
+
* But his function make a string with the port : nn.nn.nn.nn:port */
|
83
|
+
/* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
|
84
|
+
NULL, addr_str, (DWORD *)&addr_str_len))
|
85
|
+
{
|
86
|
+
printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
|
87
|
+
}*/
|
88
|
+
strncpy(addr_str, inet_ntoa(saddr.sin_addr), addr_str_len);
|
89
|
+
#endif
|
90
|
+
#ifdef DEBUG
|
91
|
+
printf("address miniwget : %s\n", addr_str);
|
92
|
+
#endif
|
93
|
+
}
|
94
|
+
|
95
|
+
snprintf(buf, sizeof(buf),
|
96
|
+
"GET %s HTTP/1.1\r\n"
|
97
|
+
"Host: %s:%d\r\n"
|
98
|
+
"Connection: Close\r\n"
|
99
|
+
"\r\n",
|
100
|
+
path, host, port);
|
101
|
+
/*write(s, buf, strlen(buf));*/
|
102
|
+
send(s, buf, strlen(buf), 0);
|
103
|
+
{
|
104
|
+
int n, headers=1;
|
105
|
+
char * respbuffer = NULL;
|
106
|
+
int allreadyread = 0;
|
107
|
+
/*while((n = recv(s, buf, 2048, 0)) > 0)*/
|
108
|
+
while((n = ReceiveData(s, buf, 2048, 5000)) > 0)
|
109
|
+
{
|
110
|
+
if(headers)
|
111
|
+
{
|
112
|
+
int i=0;
|
113
|
+
while(i<n-3)
|
114
|
+
{
|
115
|
+
if(buf[i]=='\r' && buf[i+1]=='\n'
|
116
|
+
&& buf[i+2]=='\r' && buf[i+3]=='\n')
|
117
|
+
{
|
118
|
+
headers = 0; /* end */
|
119
|
+
if(i<n-4)
|
120
|
+
{
|
121
|
+
respbuffer = (char *)realloc((void *)respbuffer,
|
122
|
+
allreadyread+(n-i-4));
|
123
|
+
memcpy(respbuffer+allreadyread, buf + i + 4, n-i-4);
|
124
|
+
allreadyread += (n-i-4);
|
125
|
+
}
|
126
|
+
break;
|
127
|
+
}
|
128
|
+
i++;
|
129
|
+
}
|
130
|
+
}
|
131
|
+
else
|
132
|
+
{
|
133
|
+
respbuffer = (char *)realloc((void *)respbuffer,
|
134
|
+
allreadyread+n);
|
135
|
+
memcpy(respbuffer+allreadyread, buf, n);
|
136
|
+
allreadyread += n;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
*size = allreadyread;
|
140
|
+
#ifndef NDEBUG
|
141
|
+
printf("%d bytes read\n", *size);
|
142
|
+
#endif
|
143
|
+
closesocket(s);
|
144
|
+
return respbuffer;
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
/* parseURL()
|
149
|
+
* arguments :
|
150
|
+
* url : source string not modified
|
151
|
+
* hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
|
152
|
+
* port : port (destination)
|
153
|
+
* path : pointer to the path part of the URL
|
154
|
+
*
|
155
|
+
* Return values :
|
156
|
+
* 0 - Failure
|
157
|
+
* 1 - Success */
|
158
|
+
int parseURL(const char * url, char * hostname, unsigned short * port, char * * path)
|
159
|
+
{
|
160
|
+
char * p1, *p2, *p3;
|
161
|
+
p1 = strstr(url, "://");
|
162
|
+
if(!p1)
|
163
|
+
return 0;
|
164
|
+
p1 += 3;
|
165
|
+
if( (url[0]!='h') || (url[1]!='t')
|
166
|
+
||(url[2]!='t') || (url[3]!='p'))
|
167
|
+
return 0;
|
168
|
+
p2 = strchr(p1, ':');
|
169
|
+
p3 = strchr(p1, '/');
|
170
|
+
if(!p3)
|
171
|
+
return 0;
|
172
|
+
memset(hostname, 0, MAXHOSTNAMELEN + 1);
|
173
|
+
if(!p2 || (p2>p3))
|
174
|
+
{
|
175
|
+
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
|
176
|
+
*port = 80;
|
177
|
+
}
|
178
|
+
else
|
179
|
+
{
|
180
|
+
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
|
181
|
+
*port = 0;
|
182
|
+
p2++;
|
183
|
+
while( (*p2 >= '0') && (*p2 <= '9'))
|
184
|
+
{
|
185
|
+
*port *= 10;
|
186
|
+
*port += (unsigned short)(*p2 - '0');
|
187
|
+
p2++;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
*path = p3;
|
191
|
+
return 1;
|
192
|
+
}
|
193
|
+
|
194
|
+
void * miniwget(const char * url, int * size)
|
195
|
+
{
|
196
|
+
unsigned short port;
|
197
|
+
char * path;
|
198
|
+
/* protocol://host:port/chemin */
|
199
|
+
char hostname[MAXHOSTNAMELEN+1];
|
200
|
+
*size = 0;
|
201
|
+
if(!parseURL(url, hostname, &port, &path))
|
202
|
+
return NULL;
|
203
|
+
return miniwget2(url, hostname, port, path, size, 0, 0);
|
204
|
+
}
|
205
|
+
|
206
|
+
void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)
|
207
|
+
{
|
208
|
+
unsigned short port;
|
209
|
+
char * path;
|
210
|
+
/* protocol://host:port/chemin */
|
211
|
+
char hostname[MAXHOSTNAMELEN+1];
|
212
|
+
*size = 0;
|
213
|
+
if(addr)
|
214
|
+
addr[0] = '\0';
|
215
|
+
if(!parseURL(url, hostname, &port, &path))
|
216
|
+
return NULL;
|
217
|
+
return miniwget2(url, hostname, port, path, size, addr, addrlen);
|
218
|
+
}
|
219
|
+
|
data/ext/miniwget.h
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
/* $Id: miniwget.h,v 1.5 2007/01/29 20:27:23 nanard Exp $ */
|
2
|
+
/* Project : miniupnp
|
3
|
+
* Author : Thomas Bernard
|
4
|
+
* Copyright (c) 2005 Thomas Bernard
|
5
|
+
* This software is subject to the conditions detailed in the
|
6
|
+
* LICENCE file provided in this distribution.
|
7
|
+
* */
|
8
|
+
#ifndef __MINIWGET_H__
|
9
|
+
#define __MINIWGET_H__
|
10
|
+
|
11
|
+
#include "declspec.h"
|
12
|
+
|
13
|
+
#ifdef __cplusplus
|
14
|
+
extern "C" {
|
15
|
+
#endif
|
16
|
+
|
17
|
+
LIBSPEC void * miniwget(const char *, int *);
|
18
|
+
|
19
|
+
LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int);
|
20
|
+
|
21
|
+
int parseURL(const char *, char *, unsigned short *, char * *);
|
22
|
+
|
23
|
+
#ifdef __cplusplus
|
24
|
+
}
|
25
|
+
#endif
|
26
|
+
|
27
|
+
#endif
|
28
|
+
|
data/ext/minixml.c
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
/* $Id: minixml.c,v 1.6 2007/05/15 18:14:08 nanard 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-2007, 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 "minixml.h"
|
34
|
+
|
35
|
+
/* parseatt : used to parse the argument list
|
36
|
+
* return 0 (false) in case of success and -1 (true) if the end
|
37
|
+
* of the xmlbuffer is reached. */
|
38
|
+
int parseatt(struct xmlparser * p)
|
39
|
+
{
|
40
|
+
const char * attname;
|
41
|
+
int attnamelen;
|
42
|
+
const char * attvalue;
|
43
|
+
int attvaluelen;
|
44
|
+
while(p->xml < p->xmlend)
|
45
|
+
{
|
46
|
+
if(*p->xml=='/' || *p->xml=='>')
|
47
|
+
return 0;
|
48
|
+
if( !IS_WHITE_SPACE(*p->xml) )
|
49
|
+
{
|
50
|
+
char sep;
|
51
|
+
attname = p->xml;
|
52
|
+
attnamelen = 0;
|
53
|
+
while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) )
|
54
|
+
{
|
55
|
+
attnamelen++; p->xml++;
|
56
|
+
if(p->xml >= p->xmlend)
|
57
|
+
return -1;
|
58
|
+
}
|
59
|
+
while(*(p->xml++) != '=')
|
60
|
+
{
|
61
|
+
if(p->xml >= p->xmlend)
|
62
|
+
return -1;
|
63
|
+
}
|
64
|
+
while(IS_WHITE_SPACE(*p->xml))
|
65
|
+
{
|
66
|
+
p->xml++;
|
67
|
+
if(p->xml >= p->xmlend)
|
68
|
+
return -1;
|
69
|
+
}
|
70
|
+
sep = *p->xml;
|
71
|
+
if(sep=='\'' || sep=='\"')
|
72
|
+
{
|
73
|
+
p->xml++;
|
74
|
+
if(p->xml >= p->xmlend)
|
75
|
+
return -1;
|
76
|
+
attvalue = p->xml;
|
77
|
+
attvaluelen = 0;
|
78
|
+
while(*p->xml != sep)
|
79
|
+
{
|
80
|
+
attvaluelen++; p->xml++;
|
81
|
+
if(p->xml >= p->xmlend)
|
82
|
+
return -1;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
else
|
86
|
+
{
|
87
|
+
attvalue = p->xml;
|
88
|
+
attvaluelen = 0;
|
89
|
+
while( !IS_WHITE_SPACE(*p->xml)
|
90
|
+
&& *p->xml != '>' && *p->xml != '/')
|
91
|
+
{
|
92
|
+
attvaluelen++; p->xml++;
|
93
|
+
if(p->xml >= p->xmlend)
|
94
|
+
return -1;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
/*printf("%.*s='%.*s'\n",
|
98
|
+
attnamelen, attname, attvaluelen, attvalue);*/
|
99
|
+
if(p->attfunc)
|
100
|
+
p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen);
|
101
|
+
}
|
102
|
+
p->xml++;
|
103
|
+
}
|
104
|
+
return -1;
|
105
|
+
}
|
106
|
+
|
107
|
+
/* parseelt parse the xml stream and
|
108
|
+
* call the callback functions when needed... */
|
109
|
+
void parseelt(struct xmlparser * p)
|
110
|
+
{
|
111
|
+
int i;
|
112
|
+
const char * elementname;
|
113
|
+
while(p->xml < (p->xmlend - 1))
|
114
|
+
{
|
115
|
+
if((p->xml)[0]=='<' && (p->xml)[1]!='?')
|
116
|
+
{
|
117
|
+
i = 0; elementname = ++p->xml;
|
118
|
+
while( !IS_WHITE_SPACE(*p->xml)
|
119
|
+
&& (*p->xml!='>') && (*p->xml!='/')
|
120
|
+
)
|
121
|
+
{
|
122
|
+
i++; p->xml++;
|
123
|
+
if (p->xml >= p->xmlend)
|
124
|
+
return;
|
125
|
+
/* to ignore namespace : */
|
126
|
+
if(*p->xml==':')
|
127
|
+
{
|
128
|
+
i = 0;
|
129
|
+
elementname = ++p->xml;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
if(i>0)
|
133
|
+
{
|
134
|
+
if(p->starteltfunc)
|
135
|
+
p->starteltfunc(p->data, elementname, i);
|
136
|
+
if(parseatt(p))
|
137
|
+
return;
|
138
|
+
if(*p->xml!='/')
|
139
|
+
{
|
140
|
+
const char * data;
|
141
|
+
i = 0; data = ++p->xml;
|
142
|
+
if (p->xml >= p->xmlend)
|
143
|
+
return;
|
144
|
+
while( IS_WHITE_SPACE(*p->xml) )
|
145
|
+
{
|
146
|
+
p->xml++;
|
147
|
+
if (p->xml >= p->xmlend)
|
148
|
+
return;
|
149
|
+
}
|
150
|
+
while(*p->xml!='<')
|
151
|
+
{
|
152
|
+
i++; p->xml++;
|
153
|
+
if (p->xml >= p->xmlend)
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
if(i>0 && p->datafunc)
|
157
|
+
p->datafunc(p->data, data, i);
|
158
|
+
}
|
159
|
+
}
|
160
|
+
else if(*p->xml == '/')
|
161
|
+
{
|
162
|
+
i = 0; elementname = ++p->xml;
|
163
|
+
if (p->xml >= p->xmlend)
|
164
|
+
return;
|
165
|
+
while((*p->xml != '>'))
|
166
|
+
{
|
167
|
+
i++; p->xml++;
|
168
|
+
if (p->xml >= p->xmlend)
|
169
|
+
return;
|
170
|
+
}
|
171
|
+
if(p->endeltfunc)
|
172
|
+
p->endeltfunc(p->data, elementname, i);
|
173
|
+
p->xml++;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
else
|
177
|
+
{
|
178
|
+
p->xml++;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
/* the parser must be initialized before calling this function */
|
184
|
+
void parsexml(struct xmlparser * parser)
|
185
|
+
{
|
186
|
+
parser->xml = parser->xmlstart;
|
187
|
+
parser->xmlend = parser->xmlstart + parser->xmlsize;
|
188
|
+
parseelt(parser);
|
189
|
+
}
|
190
|
+
|
191
|
+
|