2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
* Copyright (C) 2003 - The Authors
18
* Author : Richard GAYRAUD - 04 Nov 2003
19
* From Hewlett Packard Company.
25
* WARNING 1: Only supports printable
26
* ASCII characters in xml files. '\0'
27
* is not a valid character. Returned string are
30
* WARNING 2: Does not supports multithreading. Works
31
* with static buffer, no memory allocation.
34
/******************* Include files *********************/
40
#include <xp_parser.h>
42
/************* Constants and Global variables ***********/
44
#define XP_MAX_NAME_LEN 256
45
#define XP_MAX_FILE_LEN 65536
46
#define XP_MAX_STACK_LEN 256
48
char xp_file [XP_MAX_FILE_LEN + 1];
49
char * xp_position [XP_MAX_STACK_LEN];
52
/****************** Internal routines ********************/
53
int xp_replace(char *source, char *dest, char *search, char *replace)
59
if (!source || !dest || !search || !replace) {
64
occurances = strstr(position, search);
66
strncat(dest, position, occurances - position);
67
strcat(dest, replace);
68
position = occurances + strlen(search);
69
occurances = strstr(position, search);
72
strcat(dest, position);
76
char * xp_find_local_end()
78
char * ptr = xp_position[xp_stack];
83
if ((*(ptr+1) == '!') &&
85
(strstr(ptr,"<![CDATA[") == ptr)) {
86
char * cdata_end = strstr(ptr, "]]>");
87
if(!cdata_end) return NULL;
89
} else if ((*(ptr+1) == '!') &&
91
(strstr(ptr,"<!--") == ptr)) {
92
char * comment_end = strstr(ptr, "-->");
93
if(!comment_end) return NULL;
94
ptr = comment_end + 3;
95
} else if(*(ptr+1) == '/') {
97
if(level < 0) return ptr;
101
} else if((*ptr == '/') && (*(ptr+1) == '>')) {
103
if(level < 0) return ptr;
110
/********************* Interface routines ********************/
112
int xp_set_xml_buffer_from_string(char * str)
114
size_t len = strlen(str);
116
if(len > XP_MAX_FILE_LEN) {
120
strcpy(xp_file, str);
122
xp_position[xp_stack] = xp_file;
124
if(strstr(xp_position[xp_stack], "<?xml") != xp_position[xp_stack]) return 0;
125
if(!strstr(xp_position[xp_stack], "?>")) return 0;
126
xp_position[xp_stack] = xp_position[xp_stack] + 2;
131
int xp_set_xml_buffer_from_file(char * filename)
133
FILE * f = fopen(filename, "rb");
139
while((c = fgetc(f)) != EOF) {
140
if(c == '\r') continue;
141
xp_file[index++] = c;
142
if(index >= XP_MAX_FILE_LEN) {
143
xp_file[index++] = 0;
145
xp_position[xp_stack] = xp_file;
149
xp_file[index++] = 0;
153
xp_position[xp_stack] = xp_file;
155
if(strstr(xp_position[xp_stack], "<?xml") != xp_position[xp_stack]) return 0;
156
if(!strstr(xp_position[xp_stack], "?>")) return 0;
157
xp_position[xp_stack] = xp_position[xp_stack] + 2;
162
char * xp_open_element(int index)
164
char * ptr = xp_position[xp_stack];
166
static char name[XP_MAX_NAME_LEN];
170
if ((*(ptr+1) == '!') &&
172
(strstr(ptr,"<![CDATA[") == ptr)) {
173
char * cdata_end = strstr(ptr, "]]>");
174
if(!cdata_end) return NULL;
176
} else if ((*(ptr+1) == '!') &&
178
(strstr(ptr,"<!--") == ptr)) {
179
char * comment_end = strstr(ptr, "-->");
180
if(!comment_end) return NULL;
181
ptr = comment_end + 3;
182
} else if (strstr(ptr,"<!DOCTYPE") == ptr) {
183
char * doctype_end = strstr(ptr, ">");
184
if(!doctype_end) return NULL;
185
ptr = doctype_end + 3;
186
} else if(*(ptr+1) == '/') {
188
if(level < 0) return NULL;
194
char * end = strchr(ptr, '>');
196
if(!end) return NULL;
198
p = strchr(ptr, ' ');
199
if(p && (p < end)) { end = p; }
200
p = strchr(ptr, '\t');
201
if(p && (p < end)) { end = p; }
202
p = strchr(ptr, '\r');
203
if(p && (p < end)) { end = p; }
204
p = strchr(ptr, '\n');
205
if(p && (p < end)) { end = p; }
206
p = strchr(ptr, '/');
207
if(p && (p < end)) { end = p; }
209
memcpy(name, ptr + 1, end-ptr-1);
212
xp_position[++xp_stack] = end;
218
} else if((*ptr == '/') && (*(ptr+1) == '>')) {
220
if(level < 0) return NULL;
227
void xp_close_element()
239
char * xp_get_value(char * name)
242
static char buffer[XP_MAX_FILE_LEN + 1];
243
char * ptr, *end, *check;
245
end = strchr(xp_position[xp_stack], '>');
246
if(!end) return NULL;
248
ptr = xp_position[xp_stack];
251
ptr = strstr(ptr, name);
253
if(!ptr) return NULL;
254
if(ptr > end) return NULL;
255
// FIXME: potential BUG in parser: we must retrieve full word,
256
// so the use of strstr as it is is not enough.
257
// we should check that the retrieved word is not a piece of another one.
259
if(check >= xp_position[xp_stack])
261
if((*check != '\r') &&
264
(*check != ' ' )) { return NULL; }
270
while((*ptr == '\r') ||
273
(*ptr == ' ' ) ) { ptr ++; }
274
if(*ptr != '=') continue;
276
while((*ptr == '\r') ||
279
(*ptr == ' ') ) { ptr ++; }
282
while((*ptr) && ((*ptr!='"') || (*(ptr-1)=='\\'))) {
283
buffer[index++] = *ptr++;
284
if(index > XP_MAX_FILE_LEN) return NULL;
293
char * xp_get_cdata()
295
static char buffer[XP_MAX_FILE_LEN + 1];
296
char * end = xp_find_local_end();
299
ptr = strstr(xp_position[xp_stack],"<![CDATA[");
300
if(!ptr) { return NULL; }
302
if(ptr > end) return NULL;
303
end = strstr(ptr, "]]>");
304
if(!end) { return NULL; }
305
if((end -ptr) > XP_MAX_FILE_LEN) return NULL;
306
memcpy(buffer, ptr, (end-ptr));
311
int xp_get_content_length(char * P_buffer)
314
int L_content_length = -1 ;
316
L_ctl_hdr = strstr(P_buffer, "Content-Length:");
317
if(!L_ctl_hdr) L_ctl_hdr = strstr(P_buffer, "Content-length:");
318
if(!L_ctl_hdr) L_ctl_hdr = strstr(P_buffer, "content-Length:");
319
if(!L_ctl_hdr) L_ctl_hdr = strstr(P_buffer, "content-length:");
320
if(!L_ctl_hdr) L_ctl_hdr = strstr(P_buffer, "CONTENT-LENGTH:");
324
while(isspace(*L_ctl_hdr)) L_ctl_hdr++;
325
sscanf(L_ctl_hdr, "%d", &L_content_length);
327
// L_content_length = -1 the message does not contain content-length
328
return (L_content_length);