mupnp 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|