2009-04-18 21:25:23 +00:00
|
|
|
/* Copyright (c) 2007-2009 by Adalin B.V.
|
|
|
|
* Copyright (c) 2007-2009 by Erik Hofman
|
2008-06-29 13:08:24 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* * Neither the name of (any of) the copyrightholder(s) nor the
|
|
|
|
* names of its contributors may be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
|
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
|
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
|
|
* THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef WIN32
|
2009-04-18 21:25:23 +00:00
|
|
|
# include <io.h>
|
2008-06-29 13:08:24 +00:00
|
|
|
|
|
|
|
#else /* !WIN32 */
|
|
|
|
# include <sys/mman.h>
|
2009-04-18 14:13:13 +00:00
|
|
|
# include <unistd.h>
|
2008-06-29 13:08:24 +00:00
|
|
|
#endif
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
# include <stdio.h>
|
|
|
|
#endif
|
2009-04-20 19:56:09 +00:00
|
|
|
#include <stdlib.h> /* free, malloc */
|
2009-05-06 14:29:12 +00:00
|
|
|
#include <malloc.h>
|
2009-05-05 12:50:00 +00:00
|
|
|
#include <string.h> /* memcmp */
|
2009-04-27 16:54:46 +00:00
|
|
|
#ifndef _MSC_VER
|
|
|
|
#include <strings.h> /* strncasecmp */
|
|
|
|
#else
|
|
|
|
# define strncasecmp strnicmp
|
|
|
|
#endif
|
2009-04-20 19:56:09 +00:00
|
|
|
#include <fcntl.h>
|
2008-06-29 13:08:24 +00:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
2008-07-19 12:18:05 +00:00
|
|
|
#include <assert.h>
|
2008-06-29 13:08:24 +00:00
|
|
|
#include <ctype.h>
|
2009-04-18 21:25:23 +00:00
|
|
|
|
2009-04-20 16:46:39 +00:00
|
|
|
#include "xml.h"
|
|
|
|
|
2009-05-11 08:46:03 +00:00
|
|
|
#ifndef XML_NONVALIDATING
|
2009-04-18 21:25:23 +00:00
|
|
|
static const char *__xml_error_str[XML_MAX_ERROR];
|
|
|
|
|
|
|
|
static void __xmlErrorSet(const void *, const char *, unsigned int);
|
|
|
|
# define xmlErrorSet(a, b, c) __xmlErrorSet(a, b, c)
|
2009-05-05 12:50:00 +00:00
|
|
|
|
|
|
|
# ifndef NDEBUG
|
|
|
|
# define PRINT_INFO(a) \
|
|
|
|
assert((a) < XML_MAX_ERROR); \
|
|
|
|
printf("at line %i: %s\n", __LINE__, __xml_error_str[(a)])
|
|
|
|
# else
|
|
|
|
# define PRINT_INFO(a)
|
|
|
|
# endif
|
|
|
|
|
|
|
|
# define SET_ERROR_AND_RETURN(a, b) \
|
|
|
|
{ *rlen = 0; *name = (a); *len = (b); PRINT_INFO(b); return 0; }
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
#else /* !XML_NONVALIDATING */
|
|
|
|
# define xmlErrorSet(a, b, c)
|
2009-05-05 12:50:00 +00:00
|
|
|
# define SET_ERROR_AND_RETURN(a, b) return 0;
|
2009-04-16 19:03:22 +00:00
|
|
|
#endif
|
2009-03-31 08:06:17 +00:00
|
|
|
|
2009-05-24 14:09:46 +00:00
|
|
|
static char *__xmlNodeGetPath(void **, const char *, size_t *, char **, size_t *);
|
|
|
|
static char *__xmlNodeGet(void *, const char *, size_t *, char **, size_t *, size_t *);
|
2009-04-30 19:26:57 +00:00
|
|
|
static char *__xmlProcessCDATA(char **, size_t *);
|
2009-04-16 19:03:22 +00:00
|
|
|
static char *__xmlCommentSkip(const char *, size_t);
|
2009-04-18 21:25:23 +00:00
|
|
|
static char *__xmlInfoProcess(const char *, size_t);
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
static void *__xml_memncasecmp(const char *, size_t *, char **, size_t *);
|
2009-05-05 12:50:00 +00:00
|
|
|
static void __xmlPrepareData(char **, size_t *);
|
2008-07-06 11:34:50 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
/*
|
|
|
|
* map 'filename' and return a pointer to it.
|
|
|
|
*/
|
|
|
|
static void *simple_mmap(int, size_t, SIMPLE_UNMMAP *);
|
|
|
|
static void simple_unmmap(SIMPLE_UNMMAP *);
|
|
|
|
|
|
|
|
# define mmap(a,b,c,d,e,f) simple_mmap((e), (b), &rid->un)
|
|
|
|
# define munmap(a,b) simple_unmmap(&rid->un)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
# define PRINT(a, b, c) { \
|
2009-05-24 14:09:46 +00:00
|
|
|
size_t l1 = (b), l2 = (c); \
|
|
|
|
char *s = (a); \
|
|
|
|
if (s) { \
|
|
|
|
size_t q, len = l2; \
|
|
|
|
if (l1 < l2) len = l1; \
|
2008-07-19 12:18:05 +00:00
|
|
|
if (len < 50000) { \
|
|
|
|
printf("(%i) '", len); \
|
2009-05-24 14:09:46 +00:00
|
|
|
for (q=0; q<len; q++) printf("%c", s[q]); \
|
2008-07-19 12:18:05 +00:00
|
|
|
printf("'\n"); \
|
|
|
|
} else printf("Length (%u) seems too large at line %i\n",len, __LINE__); \
|
2008-07-06 11:34:50 +00:00
|
|
|
} else printf("NULL pointer at line %i\n", __LINE__); \
|
|
|
|
}
|
2009-04-18 21:25:23 +00:00
|
|
|
#endif
|
2008-06-29 13:08:24 +00:00
|
|
|
|
|
|
|
void *
|
2009-03-31 08:06:17 +00:00
|
|
|
xmlOpen(const char *filename)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _root_id *rid = 0;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
if (filename)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
int fd = open(filename, O_RDONLY);
|
2009-05-05 12:50:00 +00:00
|
|
|
if (fd >= 0)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
struct stat statbuf;
|
|
|
|
void *mm;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-05-05 12:50:00 +00:00
|
|
|
fstat(fd, &statbuf);
|
|
|
|
mm = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0L);
|
|
|
|
if (mm != (void *)-1)
|
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
rid = calloc(1, sizeof(struct _root_id));
|
2009-05-05 12:50:00 +00:00
|
|
|
if (rid)
|
2009-04-25 09:54:28 +00:00
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
size_t blen = statbuf.st_size;
|
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
size_t num = 0, nlen = 1;
|
|
|
|
char *n = "*";
|
|
|
|
|
|
|
|
rid->node = cacheInit();
|
|
|
|
__xmlNodeGet(rid->node, mm, &blen, &n, &nlen, &num);
|
|
|
|
#endif
|
2009-04-25 09:54:28 +00:00
|
|
|
rid->fd = fd;
|
|
|
|
rid->start = mm;
|
2009-05-24 14:09:46 +00:00
|
|
|
rid->len = blen;
|
2009-04-25 09:54:28 +00:00
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
return (void *)rid;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-04-27 16:54:46 +00:00
|
|
|
void *
|
|
|
|
xmlInitBuffer(const char *buffer, size_t size)
|
|
|
|
{
|
|
|
|
struct _root_id *rid = 0;
|
|
|
|
|
2009-04-27 19:27:29 +00:00
|
|
|
if (buffer && (size > 0))
|
2009-04-27 16:54:46 +00:00
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
rid = calloc(1, sizeof(struct _root_id));
|
2009-04-27 19:27:29 +00:00
|
|
|
if (rid)
|
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
size_t num = 0, nlen = 1;
|
|
|
|
size_t blen = size;
|
|
|
|
char *n = "*";
|
|
|
|
|
|
|
|
rid->node = cacheInit();
|
|
|
|
__xmlNodeGet(rid->node, buffer, &blen, &n, &nlen, &num);
|
|
|
|
#endif
|
|
|
|
rid->fd = -1;
|
2009-04-27 19:27:29 +00:00
|
|
|
rid->start = (char *)buffer;
|
|
|
|
rid->len = size;
|
|
|
|
}
|
2009-04-27 16:54:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (void *)rid;
|
|
|
|
}
|
|
|
|
|
2008-06-29 13:08:24 +00:00
|
|
|
void
|
|
|
|
xmlClose(void *id)
|
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _root_id *rid = (struct _root_id *)id;
|
2008-07-20 09:38:53 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(rid != 0);
|
|
|
|
assert(rid->name == 0);
|
|
|
|
|
2009-04-27 19:27:29 +00:00
|
|
|
if (rid->fd != -1)
|
2009-04-27 16:54:46 +00:00
|
|
|
{
|
|
|
|
munmap(rid->start, rid->len);
|
|
|
|
close(rid->fd);
|
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
if (rid->node) cacheFree(rid->node);
|
|
|
|
#endif
|
2009-05-11 08:46:03 +00:00
|
|
|
#ifndef XML_NONVALIDATING
|
2009-04-20 16:46:39 +00:00
|
|
|
if (rid->info) free(rid->info);
|
2009-05-11 08:46:03 +00:00
|
|
|
#endif
|
2009-04-20 16:46:39 +00:00
|
|
|
free(rid);
|
2009-04-18 21:25:23 +00:00
|
|
|
id = 0;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlNodeGet(const void *id, const char *path)
|
2009-03-31 08:06:17 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
struct _xml_id *xsid = 0;
|
|
|
|
size_t len, slen;
|
|
|
|
char *ptr, *node;
|
2009-05-24 14:09:46 +00:00
|
|
|
void *nc, *nnc;
|
2009-03-31 08:06:17 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(id != 0);
|
|
|
|
assert(path != 0);
|
|
|
|
|
|
|
|
node = (char *)path;
|
|
|
|
len = xid->len;
|
|
|
|
slen = strlen(path);
|
2009-05-24 14:09:46 +00:00
|
|
|
|
|
|
|
nnc = nc = cacheNodeGet(xid);
|
|
|
|
ptr = __xmlNodeGetPath(&nnc, xid->start, &len, &node, &slen);
|
2009-04-18 21:25:23 +00:00
|
|
|
if (ptr)
|
|
|
|
{
|
|
|
|
xsid = malloc(sizeof(struct _xml_id));
|
|
|
|
if (xsid)
|
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
xsid->name = node;
|
2009-05-24 14:09:46 +00:00
|
|
|
xsid->name_len = slen;
|
|
|
|
xsid->start = ptr;
|
|
|
|
xsid->len = len;
|
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
xsid->node = nnc;
|
|
|
|
#endif
|
2009-04-18 21:25:23 +00:00
|
|
|
#ifndef XML_NONVALIDATING
|
|
|
|
if (xid->name)
|
|
|
|
xsid->root = xid->root;
|
|
|
|
else
|
|
|
|
xsid->root = (struct _root_id *)xid;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (slen == 0)
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, node, len);
|
2009-04-18 21:25:23 +00:00
|
|
|
}
|
2009-03-31 08:06:17 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
return (void *)xsid;
|
2009-03-31 08:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlNodeCopy(const void *id, const char *path)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
2008-06-29 13:08:24 +00:00
|
|
|
struct _xml_id *xsid = 0;
|
2009-04-18 21:25:23 +00:00
|
|
|
char *ptr, *node, *p;
|
|
|
|
size_t slen, len;
|
2009-05-24 14:09:46 +00:00
|
|
|
void *nc, *nnc;
|
2009-04-18 21:25:23 +00:00
|
|
|
|
|
|
|
node = (char *)path;
|
|
|
|
len = xid->len;
|
|
|
|
slen = strlen(path);
|
2009-05-24 14:09:46 +00:00
|
|
|
|
|
|
|
nnc = nc = cacheNodeGet(xid);
|
|
|
|
ptr = __xmlNodeGetPath(&nnc, xid->start, &len, &node, &slen);
|
2009-04-18 21:25:23 +00:00
|
|
|
if (ptr)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
xsid = malloc(sizeof(struct _xml_id) + len);
|
|
|
|
if (xsid)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
p = (char *)xsid + sizeof(struct _xml_id);
|
|
|
|
|
|
|
|
xsid->len = len;
|
|
|
|
xsid->start = p;
|
|
|
|
xsid->name_len = slen;
|
|
|
|
xsid->name = node;
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
xsid->node = nc;
|
|
|
|
#endif
|
2009-04-18 21:25:23 +00:00
|
|
|
#ifndef XML_NONVALIDATING
|
|
|
|
if (xid->name)
|
|
|
|
xsid->root = xid->root;
|
|
|
|
else
|
|
|
|
xsid->root = (struct _root_id *)xid;
|
|
|
|
#endif
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
memcpy(xsid->start, ptr, len);
|
|
|
|
}
|
|
|
|
else
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (slen == 0)
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, node, len);
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
|
|
|
return (void *)xsid;
|
|
|
|
}
|
|
|
|
|
2008-07-20 09:38:53 +00:00
|
|
|
char *
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlNodeGetName(const void *id)
|
2008-07-20 09:38:53 +00:00
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
2008-07-21 12:32:22 +00:00
|
|
|
size_t len;
|
2008-07-20 09:38:53 +00:00
|
|
|
char *ret;
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
|
|
|
|
len = xid->name_len;
|
2008-07-21 12:32:22 +00:00
|
|
|
ret = malloc(len+1);
|
2008-07-20 09:38:53 +00:00
|
|
|
if (ret)
|
|
|
|
{
|
2008-07-21 12:32:22 +00:00
|
|
|
memcpy(ret, xid->name, len);
|
|
|
|
*(ret + len) = 0;
|
2008-07-20 09:38:53 +00:00
|
|
|
}
|
2009-04-18 21:25:23 +00:00
|
|
|
else
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
2008-07-20 09:38:53 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
2009-04-18 21:25:23 +00:00
|
|
|
xmlNodeCopyName(const void *id, char *buf, size_t buflen)
|
2008-07-20 09:38:53 +00:00
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
size_t slen = 0;
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(buf != 0);
|
|
|
|
assert(buflen > 0);
|
|
|
|
|
2009-04-20 19:56:09 +00:00
|
|
|
slen = xid->name_len;
|
|
|
|
if (slen >= buflen)
|
2009-04-20 17:05:03 +00:00
|
|
|
{
|
2009-04-20 19:56:09 +00:00
|
|
|
slen = buflen-1;
|
2009-04-18 21:25:23 +00:00
|
|
|
xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
|
2008-07-20 09:38:53 +00:00
|
|
|
}
|
2009-04-18 21:25:23 +00:00
|
|
|
memcpy(buf, xid->name, slen);
|
|
|
|
*(buf + slen) = 0;
|
2008-07-21 12:32:22 +00:00
|
|
|
|
|
|
|
return slen;
|
2008-07-20 09:38:53 +00:00
|
|
|
}
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
unsigned int
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlNodeGetNum(const void *id, const char *path)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
size_t num = 0;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(path != 0);
|
|
|
|
|
|
|
|
if (xid->len)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
char *nodename, *pathname;
|
2008-07-19 12:18:05 +00:00
|
|
|
size_t len, slen;
|
2009-05-24 14:09:46 +00:00
|
|
|
void *nc;
|
2009-03-31 08:06:17 +00:00
|
|
|
char *p;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
nodename = (char *)path;
|
|
|
|
if (*path == '/') nodename++;
|
|
|
|
slen = strlen(nodename);
|
2008-07-01 12:15:46 +00:00
|
|
|
|
2009-05-24 14:09:46 +00:00
|
|
|
nc = cacheNodeGet(xid);
|
2009-03-31 08:06:17 +00:00
|
|
|
pathname = strchr(nodename, '/');
|
|
|
|
if (pathname)
|
|
|
|
{
|
|
|
|
char *node;
|
2008-07-01 12:15:46 +00:00
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
len = xid->len;
|
|
|
|
pathname++;
|
|
|
|
slen -= pathname-nodename;
|
|
|
|
node = pathname;
|
2009-05-24 14:09:46 +00:00
|
|
|
p = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
|
2009-04-20 16:46:39 +00:00
|
|
|
if (p == 0 && slen == 0)
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, node, len);
|
|
|
|
}
|
2009-03-31 08:06:17 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p = xid->start;
|
|
|
|
len = xid->len;
|
|
|
|
}
|
2008-07-01 12:15:46 +00:00
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
if (p)
|
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
char *ret, *node = nodename;
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifndef XML_USE_NODECACHE
|
|
|
|
ret = __xmlNodeGet(nc, p, &len, &node, &slen, &num);
|
|
|
|
#else
|
|
|
|
ret = __xmlNodeGetFromCache(&nc, p, &len, &node, &slen, &num);
|
|
|
|
#endif
|
2009-04-20 16:46:39 +00:00
|
|
|
if (ret == 0 && slen == 0)
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, node, len);
|
|
|
|
num = 0;
|
|
|
|
}
|
2009-03-31 08:06:17 +00:00
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
return num;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
void *
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlNodeGetPos(const void *pid, void *id, const char *element, size_t num)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _xml_id *xpid = (struct _xml_id *)pid;
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
size_t len, slen;
|
|
|
|
char *ptr, *node;
|
2009-03-31 08:06:17 +00:00
|
|
|
void *ret = 0;
|
2009-05-24 14:09:46 +00:00
|
|
|
void *nc;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xpid != 0);
|
|
|
|
assert(xid != 0);
|
|
|
|
assert(element != 0);
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
len = xpid->len;
|
|
|
|
slen = strlen(element);
|
|
|
|
node = (char *)element;
|
2009-05-24 14:09:46 +00:00
|
|
|
nc = cacheNodeGet(xpid);
|
|
|
|
#ifndef XML_USE_NODECACHE
|
|
|
|
ptr = __xmlNodeGet(nc, xpid->start, &len, &node, &slen, &num);
|
|
|
|
#else
|
|
|
|
ptr = __xmlNodeGetFromCache(&nc, xpid->start, &len, &node, &slen, &num);
|
|
|
|
#endif
|
2009-04-18 21:25:23 +00:00
|
|
|
if (ptr)
|
|
|
|
{
|
|
|
|
xid->len = len;
|
|
|
|
xid->start = ptr;
|
|
|
|
xid->name = node;
|
|
|
|
xid->name_len = slen;
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
/* unused for the cache but tested at the start of this function */
|
|
|
|
if (len == 0) xid->len = 1;
|
|
|
|
xid->node = nc;
|
|
|
|
#endif
|
2009-04-18 21:25:23 +00:00
|
|
|
ret = xid;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else if (slen == 0)
|
|
|
|
{
|
|
|
|
xmlErrorSet(xpid, node, len);
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
2008-07-21 12:32:22 +00:00
|
|
|
xmlGetString(const void *id)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
char *str = 0;
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
|
|
|
|
if (xid->len)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
size_t len;
|
|
|
|
char *ps;
|
2008-07-20 09:38:53 +00:00
|
|
|
|
|
|
|
ps = xid->start;
|
2009-05-24 14:09:46 +00:00
|
|
|
len = xid->len;
|
2009-05-05 12:50:00 +00:00
|
|
|
__xmlPrepareData(&ps, &len);
|
|
|
|
if (len)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
str = malloc(len+1);
|
2008-07-20 09:38:53 +00:00
|
|
|
if (str)
|
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
memcpy(str, ps, len);
|
|
|
|
*(str+len) = 0;
|
2008-07-20 09:38:53 +00:00
|
|
|
}
|
2009-04-18 21:25:23 +00:00
|
|
|
else
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
2008-07-20 09:38:53 +00:00
|
|
|
}
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2008-07-20 09:38:53 +00:00
|
|
|
return str;
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2008-07-20 09:38:53 +00:00
|
|
|
size_t
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlCopyString(const void *id, char *buffer, size_t buflen)
|
2008-07-20 09:38:53 +00:00
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
2009-04-16 19:03:22 +00:00
|
|
|
size_t ret = 0;
|
2009-04-18 21:25:23 +00:00
|
|
|
|
|
|
|
assert(xid != 0);
|
|
|
|
assert(buffer != 0);
|
|
|
|
assert(buflen > 0);
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-05-06 14:29:12 +00:00
|
|
|
*buffer = '\0';
|
2009-04-18 21:25:23 +00:00
|
|
|
if (xid->len)
|
2008-07-20 09:38:53 +00:00
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
size_t len;
|
2009-05-24 14:09:46 +00:00
|
|
|
char *ps;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-05-24 14:09:46 +00:00
|
|
|
ps = xid->start;
|
|
|
|
len = xid->len;
|
|
|
|
__xmlPrepareData(&ps, &len);
|
2009-05-05 12:50:00 +00:00
|
|
|
if (len)
|
2008-07-20 09:38:53 +00:00
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
if (len >= buflen)
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
len = buflen-1;
|
2009-04-18 21:25:23 +00:00
|
|
|
xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
|
|
|
|
}
|
2009-05-24 14:09:46 +00:00
|
|
|
memcpy(buffer, ps, len);
|
2009-05-05 12:50:00 +00:00
|
|
|
*(buffer+len) = 0;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
2009-05-06 14:29:12 +00:00
|
|
|
ret = len;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-04-16 19:03:22 +00:00
|
|
|
return ret;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
int
|
|
|
|
xmlCompareString(const void *id, const char *s)
|
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
int ret = -1;
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(s != 0);
|
|
|
|
|
|
|
|
if (xid->len && (strlen(s) > 0))
|
2009-03-31 08:06:17 +00:00
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
size_t len;
|
|
|
|
char *ps;
|
2009-03-31 08:06:17 +00:00
|
|
|
|
|
|
|
ps = xid->start;
|
2009-05-24 14:09:46 +00:00
|
|
|
len = xid->len;
|
2009-05-05 12:50:00 +00:00
|
|
|
__xmlPrepareData(&ps, &len);
|
2009-05-24 14:09:46 +00:00
|
|
|
ret = strncasecmp(ps, s, len);
|
2009-03-31 08:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlNodeGetString(const void *id, const char *path)
|
2009-03-31 08:06:17 +00:00
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
char *str = 0;
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(path != 0);
|
|
|
|
|
|
|
|
if (xid->len)
|
2009-03-31 08:06:17 +00:00
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
char *ptr, *node = (char *)path;
|
2009-05-06 14:29:12 +00:00
|
|
|
size_t slen = strlen(node);
|
2009-04-20 16:46:39 +00:00
|
|
|
size_t len = xid->len;
|
2009-05-24 14:09:46 +00:00
|
|
|
void *nc;
|
2009-04-20 16:46:39 +00:00
|
|
|
|
2009-05-24 14:09:46 +00:00
|
|
|
nc = cacheNodeGet(xid);
|
|
|
|
ptr = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
|
|
|
|
if (ptr && len)
|
2009-03-31 08:06:17 +00:00
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
__xmlPrepareData(&ptr, &len);
|
2009-05-06 14:29:12 +00:00
|
|
|
str = malloc(len+1);
|
|
|
|
if (str)
|
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
memcpy(str, ptr, len);
|
2009-05-06 14:29:12 +00:00
|
|
|
*(str+len) = '\0';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
|
|
|
}
|
2009-03-31 08:06:17 +00:00
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, node, len);
|
|
|
|
}
|
2009-03-31 08:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2008-07-20 09:38:53 +00:00
|
|
|
size_t
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlNodeCopyString(const void *id, const char *path, char *buffer, size_t buflen)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
2009-04-16 19:03:22 +00:00
|
|
|
size_t ret = 0;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(path != 0);
|
|
|
|
assert(buffer != 0);
|
|
|
|
assert(buflen > 0);
|
|
|
|
|
2009-05-06 14:29:12 +00:00
|
|
|
*buffer = '\0';
|
2009-04-18 21:25:23 +00:00
|
|
|
if (xid->len)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-05-06 14:29:12 +00:00
|
|
|
char *p, *node = (char *)path;
|
|
|
|
size_t slen = strlen(node);
|
|
|
|
size_t len = xid->len;
|
2009-05-24 14:09:46 +00:00
|
|
|
void *nc;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-05-24 14:09:46 +00:00
|
|
|
nc = cacheNodeGet(xid);
|
|
|
|
p = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
|
2009-05-06 14:29:12 +00:00
|
|
|
if (p)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-05-06 14:29:12 +00:00
|
|
|
__xmlPrepareData(&p, &len);
|
|
|
|
if (len)
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
2009-05-06 14:29:12 +00:00
|
|
|
if (len >= buflen)
|
|
|
|
{
|
|
|
|
len = buflen-1;
|
|
|
|
xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-05-06 14:29:12 +00:00
|
|
|
memcpy(buffer, p, len);
|
|
|
|
*(buffer+len) = '\0';
|
|
|
|
}
|
|
|
|
ret = 0;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else if (slen == 0)
|
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
xmlErrorSet(xid, node, len);
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-04-16 19:03:22 +00:00
|
|
|
return ret;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
int
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlNodeCompareString(const void *id, const char *path, const char *s)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
2009-03-31 08:06:17 +00:00
|
|
|
int ret = -1;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(path != 0);
|
|
|
|
assert(s != 0);
|
|
|
|
|
|
|
|
if (xid->len && (strlen(s) > 0))
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
char *node, *str, *ps, *pe;
|
2009-04-16 19:03:22 +00:00
|
|
|
size_t len, slen;
|
2009-05-24 14:09:46 +00:00
|
|
|
void *nc;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2008-07-19 12:18:05 +00:00
|
|
|
len = xid->len;
|
|
|
|
slen = strlen(path);
|
2008-07-20 09:38:53 +00:00
|
|
|
node = (char *)path;
|
2009-05-24 14:09:46 +00:00
|
|
|
nc = cacheNodeGet(xid);
|
|
|
|
str = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
|
2008-07-19 12:18:05 +00:00
|
|
|
if (str)
|
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
ps = str;
|
2009-05-05 12:50:00 +00:00
|
|
|
__xmlPrepareData(&ps, &len);
|
|
|
|
ret = strncasecmp(ps, s, len);
|
2008-07-19 12:18:05 +00:00
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else if (slen == 0)
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, node, len);
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
return ret;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
long int
|
2008-07-21 12:32:22 +00:00
|
|
|
xmlGetInt(const void *id)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
long int li = 0;
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
|
|
|
|
if (xid->len)
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
|
|
|
char *end = xid->start + xid->len;
|
|
|
|
li = strtol(xid->start, &end, 10);
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
|
|
|
return li;
|
|
|
|
}
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
long int
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlNodeGetInt(const void *id, const char *path)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
long int li = 0;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(path != 0);
|
|
|
|
|
|
|
|
if (xid->len)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2008-07-19 12:18:05 +00:00
|
|
|
size_t len, slen;
|
2008-07-20 09:38:53 +00:00
|
|
|
char *str, *node;
|
2009-05-24 14:09:46 +00:00
|
|
|
void *nc;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2008-07-19 12:18:05 +00:00
|
|
|
len = xid->len;
|
|
|
|
slen = strlen(path);
|
2008-07-20 09:38:53 +00:00
|
|
|
node = (char *)path;
|
2009-05-24 14:09:46 +00:00
|
|
|
nc = cacheNodeGet(xid);
|
|
|
|
str = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
|
2008-07-19 12:18:05 +00:00
|
|
|
if (str)
|
|
|
|
{
|
|
|
|
char *end = str+len;
|
2009-03-31 08:06:17 +00:00
|
|
|
li = strtol(str, &end, 10);
|
2008-07-19 12:18:05 +00:00
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else if (slen == 0)
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, node, len);
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
return li;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
double
|
2008-07-21 12:32:22 +00:00
|
|
|
xmlGetDouble(const void *id)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
double d = 0.0;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
|
|
|
|
if (xid->len)
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
|
|
|
char *end = xid->start + xid->len;
|
|
|
|
d = strtod(xid->start, &end);
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
double
|
2009-04-16 19:03:22 +00:00
|
|
|
xmlNodeGetDouble(const void *id, const char *path)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
2009-03-31 08:06:17 +00:00
|
|
|
double d = 0.0;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(path != 0);
|
|
|
|
|
|
|
|
if (xid->len)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2008-07-19 12:18:05 +00:00
|
|
|
size_t len, slen;
|
2009-03-31 08:06:17 +00:00
|
|
|
char *str, *node;
|
2009-05-24 14:09:46 +00:00
|
|
|
void *nc;
|
2008-07-20 09:38:53 +00:00
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
len = xid->len;
|
|
|
|
slen = strlen(path);
|
|
|
|
node = (char *)path;
|
2009-05-24 14:09:46 +00:00
|
|
|
nc = cacheNodeGet(xid);
|
|
|
|
str = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
|
2009-03-31 08:06:17 +00:00
|
|
|
if (str)
|
2008-07-20 09:38:53 +00:00
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
char *end = str+len;
|
|
|
|
d = strtod(str, &end);
|
2008-07-20 09:38:53 +00:00
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else if (slen == 0)
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, node, len);
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
return d;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
2008-07-21 12:32:22 +00:00
|
|
|
xmlMarkId(const void *id)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _xml_id *xmid = 0;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(id != 0);
|
|
|
|
|
|
|
|
xmid = malloc(sizeof(struct _xml_id));
|
|
|
|
if (xmid)
|
|
|
|
{
|
|
|
|
struct _root_id *xrid = (struct _root_id *)id;
|
|
|
|
if (xrid->name == 0)
|
|
|
|
{
|
|
|
|
xmid->name = "";
|
2009-05-24 14:09:46 +00:00
|
|
|
xmid->name_len = 0;
|
2009-04-18 21:25:23 +00:00
|
|
|
xmid->start = xrid->start;
|
|
|
|
xmid->len = xrid->len;
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
xmid->node = xrid->node;
|
|
|
|
#endif
|
2009-04-18 21:25:23 +00:00
|
|
|
#ifndef XML_NONVALIDATING
|
|
|
|
xmid->root = xrid;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
memcpy(xmid, id, sizeof(struct _xml_id));
|
2009-04-18 21:25:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
xmlErrorSet(id, 0, XML_OUT_OF_MEMORY);
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
return (void *)xmid;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-04-16 19:03:22 +00:00
|
|
|
double
|
|
|
|
xmlAttributeGetDouble(const void *id, const char *name)
|
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
double ret = 0.0;
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(name != 0);
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
if (xid->name_len)
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
size_t slen = strlen(name);
|
2009-04-18 21:25:23 +00:00
|
|
|
char *ps, *pe;
|
|
|
|
|
|
|
|
assert(xid->start > xid->name);
|
|
|
|
|
|
|
|
ps = xid->name + xid->name_len + 1;
|
|
|
|
pe = xid->start - 1;
|
|
|
|
while (ps<pe)
|
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
while ((ps<pe) && isspace(*ps)) ps++;
|
|
|
|
if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
|
|
|
ps += slen;
|
|
|
|
if ((ps<pe) && (*ps == '='))
|
|
|
|
{
|
|
|
|
char *start;
|
|
|
|
|
|
|
|
ps++;
|
|
|
|
if (*ps == '"' || *ps == '\'') ps++;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = ps;
|
|
|
|
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
|
|
|
|
if (ps<pe)
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
ret = strtod(start, &ps);
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
2009-04-18 21:25:23 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
while ((ps<pe) && !isspace(*ps)) ps++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((ps<pe) && !isspace(*ps)) ps++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2009-04-16 19:03:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
long int
|
|
|
|
xmlAttributeGetInt(const void *id, const char *name)
|
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
long int ret = 0;
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(name != 0);
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
if (xid->name_len)
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
size_t slen = strlen(name);
|
2009-04-18 21:25:23 +00:00
|
|
|
char *ps, *pe;
|
|
|
|
|
|
|
|
assert(xid->start > xid->name);
|
|
|
|
|
|
|
|
ps = xid->name + xid->name_len + 1;
|
|
|
|
pe = xid->start - 1;
|
|
|
|
while (ps<pe)
|
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
while ((ps<pe) && isspace(*ps)) ps++;
|
|
|
|
if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
|
|
|
ps += slen;
|
|
|
|
if ((ps<pe) && (*ps == '='))
|
|
|
|
{
|
|
|
|
char *start;
|
|
|
|
|
|
|
|
ps++;
|
|
|
|
if (*ps == '"' || *ps == '\'') ps++;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = ps;
|
|
|
|
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
|
|
|
|
if (ps<pe)
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
ret = strtol(start, &ps, 10);
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
2009-04-18 21:25:23 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
while ((ps<pe) && isspace(*ps)) ps++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((ps<pe) && !isspace(*ps)) ps++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2009-04-16 19:03:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
xmlAttributeGetString(const void *id, const char *name)
|
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
char *ret = 0;
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(name != 0);
|
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
if (xid->name_len)
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
size_t slen = strlen(name);
|
2009-04-18 21:25:23 +00:00
|
|
|
char *ps, *pe;
|
|
|
|
|
|
|
|
assert(xid->start > xid->name);
|
|
|
|
|
|
|
|
ps = xid->name + xid->name_len + 1;
|
|
|
|
pe = xid->start - 1;
|
|
|
|
while (ps<pe)
|
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
while ((ps<pe) && isspace(*ps)) ps++;
|
|
|
|
if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
|
2009-04-16 19:03:22 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
ps += slen;
|
|
|
|
if ((ps<pe) && (*ps == '='))
|
|
|
|
{
|
|
|
|
char *start;
|
|
|
|
|
|
|
|
ps++;
|
|
|
|
if (*ps == '"' || *ps == '\'') ps++;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = ps;
|
|
|
|
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
|
|
|
|
if (ps<pe)
|
|
|
|
{
|
|
|
|
ret = malloc(ps-start);
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
memcpy(ret, start, (ps-start));
|
|
|
|
*(ret+(ps-start)) = '\0';
|
|
|
|
}
|
|
|
|
else
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
2009-04-18 21:25:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
while ((ps<pe) && !isspace(*ps)) ps++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
break;
|
2009-04-16 19:03:22 +00:00
|
|
|
}
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
while ((ps<pe) && !isspace(*ps)) ps++;
|
|
|
|
}
|
|
|
|
}
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
return ret;
|
2009-04-16 19:03:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
xmlAttributeCopyString(const void *id, const char *name,
|
|
|
|
char *buffer, size_t buflen)
|
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
size_t ret = 0;
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid != 0);
|
|
|
|
assert(name != 0);
|
|
|
|
assert(buffer != 0);
|
|
|
|
assert(buflen > 0);
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
if (xid->name_len)
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
size_t slen = strlen(name);
|
2009-04-18 21:25:23 +00:00
|
|
|
char *ps, *pe;
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid->start > xid->name);
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
*buffer = '\0';
|
|
|
|
ps = xid->name + xid->name_len + 1;
|
|
|
|
pe = xid->start - 1;
|
|
|
|
while (ps<pe)
|
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
while ((ps<pe) && isspace(*ps)) ps++;
|
|
|
|
if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
|
|
|
ps += slen;
|
|
|
|
if ((ps<pe) && (*ps == '='))
|
2009-04-16 19:03:22 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
char *start;
|
|
|
|
|
|
|
|
ps++;
|
|
|
|
if (*ps == '"' || *ps == '\'') ps++;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = ps;
|
|
|
|
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
|
|
|
|
if (ps<pe)
|
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
size_t restlen = ps-start;
|
2009-04-18 21:25:23 +00:00
|
|
|
if (restlen >= buflen)
|
|
|
|
{
|
|
|
|
restlen = buflen-1;
|
|
|
|
xmlErrorSet(xid, ps, XML_TRUNCATE_RESULT);
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(buffer, start, restlen);
|
|
|
|
*(buffer+restlen) = 0;
|
|
|
|
ret = restlen;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
|
|
|
|
return 0;
|
|
|
|
}
|
2009-04-16 19:03:22 +00:00
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
while ((ps<pe) && isspace(*ps)) ps++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
while ((ps<pe) && !isspace(*ps)) ps++;
|
|
|
|
}
|
|
|
|
}
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
return ret;
|
2009-04-16 19:03:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
xmlAttributeCompareString(const void *id, const char *name, const char *s)
|
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
assert(xid != 0);
|
|
|
|
assert(name != 0);
|
|
|
|
assert(s != 0);
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
if (xid->name_len && strlen(s))
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
size_t slen = strlen(name);
|
2009-04-18 21:25:23 +00:00
|
|
|
char *ps, *pe;
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
assert(xid->start > xid->name);
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
ps = xid->name + xid->name_len + 1;
|
|
|
|
pe = xid->start - 1;
|
|
|
|
while (ps<pe)
|
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
while ((ps<pe) && isspace(*ps)) ps++;
|
|
|
|
if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
|
|
|
ps += slen;
|
|
|
|
if ((ps<pe) && (*ps == '='))
|
2009-04-16 19:03:22 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
char *start;
|
|
|
|
|
|
|
|
ps++;
|
|
|
|
if (*ps == '"' || *ps == '\'') ps++;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = ps;
|
|
|
|
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
|
|
|
|
if (ps<pe)
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
ret = strncasecmp(start, s, ps-start);
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
2009-04-18 21:25:23 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
|
|
|
|
return 0;
|
|
|
|
}
|
2009-04-16 19:03:22 +00:00
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
while ((ps<pe) && !isspace(*ps)) ps++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
while ((ps<pe) && !isspace(*ps)) ps++;
|
|
|
|
}
|
|
|
|
}
|
2009-04-16 19:03:22 +00:00
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
return ret;
|
2009-04-16 19:03:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
#ifndef XML_NONVALIDATING
|
|
|
|
int
|
2009-04-20 16:46:39 +00:00
|
|
|
xmlErrorGetNo(const void *id, int clear)
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (id)
|
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
struct _root_id *rid;
|
|
|
|
|
|
|
|
if (xid->name) rid = xid->root;
|
|
|
|
else rid = (struct _root_id *)xid;
|
|
|
|
|
|
|
|
assert(rid != 0);
|
|
|
|
|
|
|
|
if (rid->info)
|
|
|
|
{
|
|
|
|
struct _xml_error *err = rid->info;
|
|
|
|
|
2009-04-18 22:20:50 +00:00
|
|
|
ret = err->err_no;
|
2009-04-20 16:46:39 +00:00
|
|
|
if (clear) err->err_no = 0;
|
2009-04-18 21:25:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
2009-04-20 16:46:39 +00:00
|
|
|
xmlErrorGetLineNo(const void *id, int clear)
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
|
|
|
size_t ret = 0;
|
|
|
|
|
|
|
|
if (id)
|
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
struct _root_id *rid;
|
|
|
|
|
|
|
|
if (xid->name) rid = xid->root;
|
|
|
|
else rid = (struct _root_id *)xid;
|
|
|
|
|
|
|
|
assert(rid != 0);
|
|
|
|
|
|
|
|
if (rid->info)
|
|
|
|
{
|
|
|
|
struct _xml_error *err = rid->info;
|
|
|
|
char *ps = rid->start;
|
|
|
|
char *pe = err->pos;
|
|
|
|
char *new;
|
|
|
|
|
2009-04-20 16:46:39 +00:00
|
|
|
ret++;
|
2009-04-18 21:25:23 +00:00
|
|
|
while (ps<pe)
|
|
|
|
{
|
|
|
|
new = memchr(ps, '\n', pe-ps);
|
2009-04-27 16:54:46 +00:00
|
|
|
if (new) ret++;
|
|
|
|
else break;
|
|
|
|
ps = new+1;
|
2009-04-18 21:25:23 +00:00
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
|
|
|
|
if (clear) err->err_no = 0;
|
2009-04-18 21:25:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-04-27 16:54:46 +00:00
|
|
|
size_t
|
|
|
|
xmlErrorGetColumnNo(const void *id, int clear)
|
|
|
|
{
|
|
|
|
size_t ret = 0;
|
|
|
|
|
|
|
|
if (id)
|
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
struct _root_id *rid;
|
|
|
|
|
|
|
|
if (xid->name) rid = xid->root;
|
|
|
|
else rid = (struct _root_id *)xid;
|
|
|
|
|
|
|
|
assert(rid != 0);
|
|
|
|
|
|
|
|
if (rid->info)
|
|
|
|
{
|
|
|
|
struct _xml_error *err = rid->info;
|
|
|
|
char *ps = rid->start;
|
|
|
|
char *pe = err->pos;
|
|
|
|
char *new;
|
|
|
|
|
|
|
|
while (ps<pe)
|
|
|
|
{
|
|
|
|
new = memchr(ps, '\n', pe-ps);
|
|
|
|
new = memchr(ps, '\n', pe-ps);
|
|
|
|
if (new) ret++;
|
|
|
|
else break;
|
|
|
|
ps = new+1;
|
|
|
|
}
|
|
|
|
ret = pe-ps;
|
|
|
|
|
|
|
|
if (clear) err->err_no = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
const char *
|
2009-04-20 16:46:39 +00:00
|
|
|
xmlErrorGetString(const void *id, int clear)
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
|
|
|
char *ret = 0;
|
|
|
|
|
|
|
|
if (id)
|
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
struct _root_id *rid;
|
|
|
|
|
|
|
|
if (xid->name) rid = xid->root;
|
|
|
|
else rid = (struct _root_id *)xid;
|
|
|
|
|
|
|
|
assert(rid != 0);
|
|
|
|
|
|
|
|
if (rid->info)
|
|
|
|
{
|
|
|
|
struct _xml_error *err = rid->info;
|
2009-04-18 22:20:50 +00:00
|
|
|
if (XML_NO_ERROR <= err->err_no && err->err_no < XML_MAX_ERROR)
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 22:20:50 +00:00
|
|
|
ret = (char *)__xml_error_str[err->err_no];
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
2009-04-18 21:25:23 +00:00
|
|
|
else
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
ret = "incorrect error number.";
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (clear) err->err_no = 0;
|
2009-04-18 21:25:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2009-05-11 08:46:03 +00:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
int
|
|
|
|
xmlErrorGetNo(const void *id, int clear)
|
|
|
|
{
|
|
|
|
return XML_NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
xmlErrorGetLineNo(const void *id, int clear)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
xmlErrorGetColumnNo(const void *id, int clear)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
xmlErrorGetString(const void *id, int clear)
|
|
|
|
{
|
|
|
|
return "error detection was not enabled at compile time: no error.";
|
|
|
|
}
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
#endif
|
|
|
|
|
2008-06-29 13:08:24 +00:00
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
2009-04-20 16:46:39 +00:00
|
|
|
#ifndef XML_NONVALIDATING
|
2009-04-18 21:25:23 +00:00
|
|
|
static const char *__xml_error_str[XML_MAX_ERROR] =
|
|
|
|
{
|
|
|
|
"no error.",
|
|
|
|
"unable to allocate enough memory.",
|
|
|
|
"unable to open file for reading.",
|
2009-05-01 08:00:17 +00:00
|
|
|
"requested node name is invalid.",
|
|
|
|
"unexpected end of section.",
|
2009-04-20 17:05:03 +00:00
|
|
|
"buffer too small to hold all data, truncating.",
|
2009-04-20 16:46:39 +00:00
|
|
|
"incorrect comment section.",
|
|
|
|
"bad information block.",
|
2009-04-18 21:25:23 +00:00
|
|
|
"incompatible opening tag for element.",
|
|
|
|
"missing or invalid closing tag for element.",
|
|
|
|
"missing or invalid opening quote for attribute.",
|
|
|
|
"missing or invalid closing quote for attribute."
|
|
|
|
};
|
2009-04-20 16:46:39 +00:00
|
|
|
#endif
|
2009-04-18 21:25:23 +00:00
|
|
|
|
2008-06-29 13:08:24 +00:00
|
|
|
char *
|
2009-05-24 14:09:46 +00:00
|
|
|
__xmlNodeGetPath(void **nc, const char *start, size_t *len, char **name, size_t *nlen)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-05-06 14:29:12 +00:00
|
|
|
char *path;
|
2008-06-29 13:08:24 +00:00
|
|
|
char *ret = 0;
|
|
|
|
|
2009-04-20 16:46:39 +00:00
|
|
|
assert(start != 0);
|
|
|
|
assert(len != 0);
|
2009-04-20 19:56:09 +00:00
|
|
|
assert(*len != 0);
|
2009-04-20 16:46:39 +00:00
|
|
|
assert(name != 0);
|
|
|
|
assert(*name != 0);
|
2009-05-05 12:50:00 +00:00
|
|
|
assert(nlen != 0);
|
|
|
|
assert(*nlen != 0);
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-05-05 12:50:00 +00:00
|
|
|
if (*nlen > *len) return 0;
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-05-06 14:29:12 +00:00
|
|
|
path = *name;
|
|
|
|
if (*path == '/') path++;
|
|
|
|
if (*path != '\0')
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-05-06 14:29:12 +00:00
|
|
|
size_t num, blocklen, pathlen, nodelen;
|
|
|
|
char *node;
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-05-06 14:29:12 +00:00
|
|
|
node = path;
|
|
|
|
pathlen = strlen(path);
|
2008-07-19 12:18:05 +00:00
|
|
|
path = strchr(node, '/');
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-05-06 14:29:12 +00:00
|
|
|
if (!path) nodelen = pathlen;
|
|
|
|
else nodelen = path++ - node;
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-04-20 19:56:09 +00:00
|
|
|
num = 0;
|
2009-05-06 14:29:12 +00:00
|
|
|
blocklen = *len;
|
2009-05-24 14:09:46 +00:00
|
|
|
|
|
|
|
#ifndef XML_USE_NODECACHE
|
|
|
|
ret = __xmlNodeGet(nc, start, &blocklen, &node, &nodelen, &num);
|
|
|
|
#else
|
|
|
|
ret = __xmlNodeGetFromCache(nc, start, &blocklen, &node, &nodelen, &num);
|
|
|
|
#endif
|
2009-05-05 12:50:00 +00:00
|
|
|
if (ret)
|
2008-07-01 12:15:46 +00:00
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
if (path)
|
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
ret = __xmlNodeGetPath(nc, ret, &blocklen, &path, &pathlen);
|
2009-05-05 12:50:00 +00:00
|
|
|
*name = path;
|
2009-05-06 14:29:12 +00:00
|
|
|
*len = blocklen;
|
|
|
|
*nlen = pathlen;
|
2009-05-05 12:50:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*name = node;
|
2009-05-06 14:29:12 +00:00
|
|
|
*nlen = nodelen;
|
|
|
|
*len = blocklen;
|
2009-05-05 12:50:00 +00:00
|
|
|
}
|
2009-04-20 19:56:09 +00:00
|
|
|
}
|
2009-05-05 12:50:00 +00:00
|
|
|
else
|
2009-04-20 19:56:09 +00:00
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
*len = 0;
|
|
|
|
*nlen = 0;
|
2008-07-01 12:15:46 +00:00
|
|
|
}
|
2008-07-19 12:18:05 +00:00
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2008-07-19 12:18:05 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
2009-05-24 14:09:46 +00:00
|
|
|
__xmlNodeGet(void *nc, const char *start, size_t *len, char **name, size_t *rlen, size_t *nodenum)
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
2009-05-01 08:00:17 +00:00
|
|
|
char *cdata, *open_element = *name;
|
2009-04-28 13:59:26 +00:00
|
|
|
char *element, *start_tag=0;
|
2008-07-19 12:18:05 +00:00
|
|
|
char *new, *cur, *ne, *ret = 0;
|
|
|
|
size_t restlen, elementlen;
|
2009-04-28 13:59:26 +00:00
|
|
|
size_t open_len = *rlen;
|
2009-04-25 09:54:28 +00:00
|
|
|
size_t return_len = 0;
|
2009-05-01 08:00:17 +00:00
|
|
|
int found, num;
|
2009-05-24 14:09:46 +00:00
|
|
|
void *nnc = 0;
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-04-20 16:46:39 +00:00
|
|
|
assert(start != 0);
|
|
|
|
assert(len != 0);
|
|
|
|
assert(name != 0);
|
|
|
|
assert(rlen != 0);
|
|
|
|
assert(nodenum != 0);
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-05-01 08:00:17 +00:00
|
|
|
if (open_len == 0 || *name == 0)
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN((char *)start, XML_INVALID_NODE_NAME);
|
2009-05-01 08:00:17 +00:00
|
|
|
|
|
|
|
cdata = (char *)start;
|
2009-04-20 16:46:39 +00:00
|
|
|
if (*rlen > *len)
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN((char *)start, XML_UNEXPECTED_EOF);
|
2008-07-19 12:18:05 +00:00
|
|
|
|
|
|
|
found = 0;
|
|
|
|
num = *nodenum;
|
|
|
|
restlen = *len;
|
|
|
|
cur = (char *)start;
|
|
|
|
ne = cur + restlen;
|
|
|
|
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
cacheInitLevel(nc);
|
|
|
|
#endif
|
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
/* search for an opening tag */
|
2008-07-19 12:18:05 +00:00
|
|
|
while ((new = memchr(cur, '<', restlen)) != 0)
|
|
|
|
{
|
2009-04-25 09:54:28 +00:00
|
|
|
size_t len_remaining;
|
|
|
|
char *rptr;
|
|
|
|
|
|
|
|
if (*(new+1) == '/') /* end of section */
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
*len -= restlen;
|
2008-07-19 12:18:05 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
new++;
|
|
|
|
restlen -= new-cur;
|
|
|
|
cur = new;
|
|
|
|
|
2009-05-01 08:00:17 +00:00
|
|
|
if (*cur == '!') /* comment */
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
2009-04-30 19:26:57 +00:00
|
|
|
char *start = cur;
|
2009-05-05 12:50:00 +00:00
|
|
|
size_t blocklen = restlen;
|
|
|
|
new = __xmlProcessCDATA(&start, &blocklen);
|
|
|
|
if (!new && start && open_len) /* CDATA */
|
|
|
|
SET_ERROR_AND_RETURN(cur, XML_INVALID_COMMENT);
|
|
|
|
|
2008-07-19 12:18:05 +00:00
|
|
|
restlen -= new-cur;
|
|
|
|
cur = new;
|
|
|
|
continue;
|
|
|
|
}
|
2009-04-25 09:54:28 +00:00
|
|
|
else if (*cur == '?') /* info block */
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
new = __xmlInfoProcess(cur, restlen);
|
2009-04-20 16:46:39 +00:00
|
|
|
if (!new)
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(cur, XML_INVALID_INFO_BLOCK);
|
2008-07-19 12:18:05 +00:00
|
|
|
|
|
|
|
restlen -= new-cur;
|
|
|
|
cur = new;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
/*
|
|
|
|
* get element name and a pointer to after the opening tag
|
|
|
|
*/
|
2009-03-31 08:06:17 +00:00
|
|
|
element = *name;
|
2008-07-19 12:18:05 +00:00
|
|
|
elementlen = *rlen;
|
2009-04-25 09:54:28 +00:00
|
|
|
len_remaining = restlen;
|
2009-05-24 14:09:46 +00:00
|
|
|
rptr = __xml_memncasecmp(cur, &restlen, &element, &elementlen);
|
2009-04-25 09:54:28 +00:00
|
|
|
if (rptr) /* requested element was found */
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
new = rptr;
|
2009-04-25 09:54:28 +00:00
|
|
|
return_len = elementlen;
|
2009-04-20 16:46:39 +00:00
|
|
|
if (found == num)
|
2009-04-16 19:03:22 +00:00
|
|
|
{
|
2009-04-25 09:54:28 +00:00
|
|
|
ret = new;
|
2009-04-28 13:59:26 +00:00
|
|
|
open_len = elementlen;
|
2009-04-20 16:46:39 +00:00
|
|
|
start_tag = element;
|
2009-04-16 19:03:22 +00:00
|
|
|
}
|
|
|
|
else start_tag = 0;
|
2008-07-01 12:15:46 +00:00
|
|
|
}
|
2009-04-25 09:54:28 +00:00
|
|
|
else /* different element name was foud */
|
2008-07-01 12:15:46 +00:00
|
|
|
{
|
2009-04-25 09:54:28 +00:00
|
|
|
new = cur + (len_remaining - restlen);
|
2009-04-20 16:46:39 +00:00
|
|
|
if (new >= ne)
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(cur, XML_UNEXPECTED_EOF);
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
element = *name;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
nnc = cacheNodeNew(nc);
|
|
|
|
#endif
|
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
if (*(new-2) == '/') /* e.g. <test/> */
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-25 09:54:28 +00:00
|
|
|
cur = new;
|
|
|
|
if (rptr)
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
cacheDataSet(nnc, element, elementlen, rptr, 0);
|
|
|
|
#endif
|
2009-04-25 09:54:28 +00:00
|
|
|
if (found == num)
|
|
|
|
{
|
2009-04-28 13:59:26 +00:00
|
|
|
open_element = start_tag;
|
2009-04-25 09:54:28 +00:00
|
|
|
*len = 0;
|
|
|
|
}
|
|
|
|
found++;
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
/*
|
|
|
|
* get the next xml tag
|
|
|
|
*/
|
2008-07-19 12:18:05 +00:00
|
|
|
/* restlen -= new-cur; not necessary because of __xml_memncasecmp */
|
|
|
|
cur = new;
|
|
|
|
new = memchr(cur, '<', restlen);
|
2009-04-20 16:46:39 +00:00
|
|
|
if (!new)
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(cur, XML_ELEMENT_NO_CLOSING_TAG);
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-04-26 09:05:22 +00:00
|
|
|
new++;
|
2008-07-19 12:18:05 +00:00
|
|
|
restlen -= new-cur;
|
|
|
|
cur = new;
|
2009-04-30 19:26:57 +00:00
|
|
|
if (*cur == '!') /* comment, CDATA */
|
2009-04-26 09:05:22 +00:00
|
|
|
{
|
2009-04-30 19:26:57 +00:00
|
|
|
char *start = cur;
|
2009-05-05 12:50:00 +00:00
|
|
|
size_t blocklen = restlen;
|
2009-04-30 19:26:57 +00:00
|
|
|
new = __xmlProcessCDATA(&start, &blocklen);
|
2009-05-01 08:00:17 +00:00
|
|
|
if (new && start && open_len) /* CDATA */
|
2009-04-30 19:26:57 +00:00
|
|
|
{
|
2009-05-01 08:00:17 +00:00
|
|
|
cdata = ret;
|
2009-04-30 19:26:57 +00:00
|
|
|
}
|
|
|
|
else if (!new)
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(cur, XML_INVALID_COMMENT);
|
|
|
|
|
2009-04-26 09:05:22 +00:00
|
|
|
restlen -= new-cur;
|
|
|
|
cur = new;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* look for the closing tag of the cascading block
|
|
|
|
*/
|
|
|
|
new = memchr(cur, '<', restlen);
|
|
|
|
if (!new)
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(cur, XML_ELEMENT_NO_CLOSING_TAG);
|
|
|
|
|
2009-04-26 09:05:22 +00:00
|
|
|
new++;
|
|
|
|
restlen -= new-cur;
|
|
|
|
cur = new;
|
|
|
|
}
|
2009-05-05 12:50:00 +00:00
|
|
|
|
2009-05-08 09:10:56 +00:00
|
|
|
if (*cur == '/') /* closing tag of leaf node found */
|
|
|
|
{
|
|
|
|
if (!strncasecmp(new+1, element, elementlen))
|
|
|
|
{
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
cacheDataSet(nnc, element, elementlen, rptr, new-rptr-1);
|
|
|
|
#endif
|
2009-05-08 09:10:56 +00:00
|
|
|
if (*(new+elementlen+1) != '>')
|
|
|
|
SET_ERROR_AND_RETURN(new+1, XML_ELEMENT_NO_CLOSING_TAG);
|
|
|
|
|
|
|
|
if (found == num)
|
|
|
|
{
|
|
|
|
if (start_tag)
|
|
|
|
{
|
|
|
|
*len = new-ret-1;
|
|
|
|
open_element = start_tag;
|
|
|
|
cdata = (char *)start;
|
|
|
|
start_tag = 0;
|
|
|
|
}
|
|
|
|
else /* report error */
|
|
|
|
SET_ERROR_AND_RETURN(new, XML_ELEMENT_NO_OPENING_TAG);
|
|
|
|
}
|
|
|
|
found++;
|
|
|
|
}
|
|
|
|
|
|
|
|
new = memchr(cur, '>', restlen);
|
|
|
|
if (!new)
|
|
|
|
SET_ERROR_AND_RETURN(cur, XML_ELEMENT_NO_CLOSING_TAG);
|
|
|
|
|
|
|
|
restlen -= new-cur;
|
|
|
|
cur = new;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* no leaf node, continue */
|
2009-04-26 09:05:22 +00:00
|
|
|
if (*cur != '/') /* cascading tag found */
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2008-07-20 09:38:53 +00:00
|
|
|
char *node = "*";
|
2009-04-30 13:56:50 +00:00
|
|
|
size_t slen = restlen+1; /* due to cur-1 below*/
|
2008-07-19 12:18:05 +00:00
|
|
|
size_t nlen = 1;
|
2009-03-31 08:06:17 +00:00
|
|
|
size_t pos = -1;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
/*
|
|
|
|
* recursively walk the xml tree from here
|
|
|
|
*/
|
2009-05-24 14:09:46 +00:00
|
|
|
new = __xmlNodeGet(nnc, cur-1, &slen, &node, &nlen, &pos);
|
2008-07-19 12:18:05 +00:00
|
|
|
if (!new)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-04-27 16:54:46 +00:00
|
|
|
if (nlen == 0) /* error upstream */
|
|
|
|
{
|
|
|
|
*rlen = nlen;
|
|
|
|
*name = node;
|
|
|
|
*len = slen;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-04-20 16:46:39 +00:00
|
|
|
if (slen == restlen)
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(cur, XML_UNEXPECTED_EOF);
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2009-04-30 13:56:50 +00:00
|
|
|
slen--;
|
|
|
|
new = cur + slen;
|
|
|
|
restlen -= slen;
|
|
|
|
}
|
|
|
|
else restlen -= slen;
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
/*
|
|
|
|
* look for the closing tag of the cascading block
|
|
|
|
*/
|
2009-04-30 13:56:50 +00:00
|
|
|
cur = new;
|
2008-07-19 12:18:05 +00:00
|
|
|
new = memchr(cur, '<', restlen);
|
2009-04-20 16:46:39 +00:00
|
|
|
if (!new)
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(cur, XML_ELEMENT_NO_CLOSING_TAG);
|
|
|
|
|
2009-04-26 09:05:22 +00:00
|
|
|
new++;
|
2008-07-19 12:18:05 +00:00
|
|
|
restlen -= new-cur;
|
|
|
|
cur = new;
|
|
|
|
}
|
|
|
|
|
2009-04-26 09:05:22 +00:00
|
|
|
if (*cur == '/') /* closing tag found */
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
2009-04-26 09:05:22 +00:00
|
|
|
if (!strncasecmp(new+1, element, elementlen))
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-04-27 09:45:59 +00:00
|
|
|
if (*(new+elementlen+1) != '>')
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(new+1, XML_ELEMENT_NO_CLOSING_TAG);
|
2009-04-27 09:45:59 +00:00
|
|
|
|
2009-05-24 14:09:46 +00:00
|
|
|
#ifdef XML_USE_NODECACHE
|
|
|
|
cacheDataSet(nnc, element, elementlen, rptr, new-rptr-1);
|
|
|
|
#endif
|
2009-04-20 16:46:39 +00:00
|
|
|
if (found == num)
|
2009-04-16 19:03:22 +00:00
|
|
|
{
|
2009-04-27 16:54:46 +00:00
|
|
|
if (start_tag)
|
|
|
|
{
|
|
|
|
*len = new-ret-1;
|
2009-04-28 13:59:26 +00:00
|
|
|
open_element = start_tag;
|
2009-05-01 08:00:17 +00:00
|
|
|
cdata = (char *)start;
|
|
|
|
start_tag = 0;
|
2009-04-27 16:54:46 +00:00
|
|
|
}
|
|
|
|
else /* report error */
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(new, XML_ELEMENT_NO_OPENING_TAG);
|
2009-04-16 19:03:22 +00:00
|
|
|
}
|
2008-07-19 12:18:05 +00:00
|
|
|
found++;
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
2008-07-19 12:18:05 +00:00
|
|
|
new = memchr(cur, '>', restlen);
|
2009-04-20 16:46:39 +00:00
|
|
|
if (!new)
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(cur, XML_ELEMENT_NO_CLOSING_TAG);
|
2008-07-19 12:18:05 +00:00
|
|
|
|
|
|
|
restlen -= new-cur;
|
|
|
|
cur = new;
|
|
|
|
}
|
2009-04-20 16:46:39 +00:00
|
|
|
else
|
2009-05-05 12:50:00 +00:00
|
|
|
SET_ERROR_AND_RETURN(cur, XML_ELEMENT_NO_CLOSING_TAG);
|
|
|
|
|
2009-04-30 13:56:50 +00:00
|
|
|
} /* while */
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
if (found == 0)
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
|
|
|
ret = 0;
|
|
|
|
*rlen = 0;
|
|
|
|
*name = start_tag;
|
2009-04-25 09:54:28 +00:00
|
|
|
*len = XML_NO_ERROR; /* element not found, no real error */
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-04-28 13:59:26 +00:00
|
|
|
*rlen = open_len;
|
|
|
|
*name = open_element;
|
2009-04-20 16:46:39 +00:00
|
|
|
*nodenum = found;
|
|
|
|
}
|
2008-07-19 12:18:05 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-04-30 19:26:57 +00:00
|
|
|
char *
|
|
|
|
__xmlProcessCDATA(char **start, size_t *len)
|
|
|
|
{
|
|
|
|
char *cur, *new;
|
|
|
|
size_t restlen = *len;
|
|
|
|
|
|
|
|
cur = *start;
|
2009-05-05 12:50:00 +00:00
|
|
|
if ((restlen > 6) && (*(cur+1) == '-')) /* comment */
|
2009-04-30 19:26:57 +00:00
|
|
|
{
|
|
|
|
new = __xmlCommentSkip(cur, restlen);
|
2009-05-05 12:50:00 +00:00
|
|
|
if (new)
|
|
|
|
{
|
2009-05-08 09:10:56 +00:00
|
|
|
*start = new;
|
|
|
|
*len = 0;
|
2009-05-05 12:50:00 +00:00
|
|
|
}
|
2009-04-30 19:26:57 +00:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2009-05-05 12:50:00 +00:00
|
|
|
if (restlen < 12) return 0; /* ![CDATA[ ]]> */
|
2009-04-30 19:26:57 +00:00
|
|
|
|
|
|
|
cur = *start;
|
|
|
|
new = 0;
|
|
|
|
|
|
|
|
if (memcmp(cur, "![CDATA[", 8) == 0)
|
|
|
|
{
|
2009-05-05 12:50:00 +00:00
|
|
|
*start = cur+8;
|
2009-04-30 19:26:57 +00:00
|
|
|
cur += 8;
|
|
|
|
restlen -= 8;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
new = memchr(cur, ']', restlen);
|
|
|
|
if (new)
|
|
|
|
{
|
|
|
|
if ((restlen > 3) && (memcmp(new, "]]>", 3) == 0))
|
|
|
|
{
|
2009-05-08 09:10:56 +00:00
|
|
|
*len = new-1 - *start;
|
2009-04-30 19:26:57 +00:00
|
|
|
restlen -= 3;
|
2009-05-01 08:00:17 +00:00
|
|
|
new += 3;
|
2009-04-30 19:26:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
cur = new+1;
|
|
|
|
}
|
2009-05-01 08:00:17 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
*len = 0;
|
|
|
|
break;
|
|
|
|
}
|
2009-04-30 19:26:57 +00:00
|
|
|
}
|
|
|
|
while (new && (restlen > 2));
|
|
|
|
}
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2008-07-19 12:18:05 +00:00
|
|
|
char *
|
2009-04-16 19:03:22 +00:00
|
|
|
__xmlCommentSkip(const char *start, size_t len)
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
|
|
|
char *cur, *new;
|
|
|
|
|
2009-04-30 19:26:57 +00:00
|
|
|
if (len < 7) return 0; /* !-- --> */
|
|
|
|
|
2008-07-19 12:18:05 +00:00
|
|
|
cur = (char *)start;
|
|
|
|
new = 0;
|
|
|
|
|
|
|
|
if (memcmp(cur, "!--", 3) == 0)
|
|
|
|
{
|
|
|
|
cur += 3;
|
|
|
|
len -= 3;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
new = memchr(cur, '-', len);
|
|
|
|
if (new)
|
|
|
|
{
|
2009-05-08 09:10:56 +00:00
|
|
|
len -= new-cur;
|
2009-05-05 12:50:00 +00:00
|
|
|
if ((len >= 3) && (memcmp(new, "-->", 3) == 0))
|
2008-06-30 12:00:40 +00:00
|
|
|
{
|
2008-07-19 12:18:05 +00:00
|
|
|
new += 3;
|
2009-05-08 09:10:56 +00:00
|
|
|
/* len -= 3; */
|
2008-07-19 12:18:05 +00:00
|
|
|
break;
|
2008-06-30 12:00:40 +00:00
|
|
|
}
|
2008-07-19 12:18:05 +00:00
|
|
|
cur = new+1;
|
2009-05-08 09:10:56 +00:00
|
|
|
len -= cur-new;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
2008-07-20 09:38:53 +00:00
|
|
|
else break;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
2008-07-19 12:18:05 +00:00
|
|
|
while (new && (len > 2));
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2008-07-19 12:18:05 +00:00
|
|
|
return new;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2008-07-19 12:18:05 +00:00
|
|
|
char *
|
2009-04-18 21:25:23 +00:00
|
|
|
__xmlInfoProcess(const char *start, size_t len)
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
|
|
|
char *cur, *new;
|
|
|
|
|
|
|
|
cur = (char *)start;
|
|
|
|
new = 0;
|
|
|
|
|
|
|
|
if (*cur == '?')
|
|
|
|
{
|
2009-04-20 16:46:39 +00:00
|
|
|
if (len < 3) return 0; /* <? ?> */
|
2008-07-19 12:18:05 +00:00
|
|
|
|
|
|
|
cur++;
|
|
|
|
len--;
|
|
|
|
new = memchr(cur, '?', len);
|
|
|
|
if (!new || *(new+1) != '>') return 0;
|
|
|
|
|
|
|
|
new += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
2008-06-29 13:08:24 +00:00
|
|
|
|
|
|
|
|
2009-05-07 12:23:30 +00:00
|
|
|
static void
|
|
|
|
__xmlPrepareData(char **start, size_t *blocklen)
|
2009-05-05 12:50:00 +00:00
|
|
|
{
|
|
|
|
size_t len = *blocklen;
|
|
|
|
char *pe, *ps = *start;
|
|
|
|
|
2009-05-24 14:09:46 +00:00
|
|
|
if (len > 1)
|
|
|
|
{
|
|
|
|
pe = ps + len-1;
|
|
|
|
while ((ps<pe) && isspace(*ps)) ps++;
|
|
|
|
while ((pe>ps) && isspace(*pe)) pe--;
|
|
|
|
len = (pe-ps)+1;
|
|
|
|
}
|
|
|
|
else if (isspace(*(ps+1))) len--;
|
2009-05-05 12:50:00 +00:00
|
|
|
|
|
|
|
/* CDATA or comment */
|
|
|
|
if ((len >= 2) && !strncmp(ps, "<!", 2))
|
|
|
|
{
|
|
|
|
char *start = ps+1;
|
|
|
|
size_t blocklen = len-1;
|
|
|
|
if (blocklen >= 6) /* !-- --> */
|
|
|
|
{
|
2009-05-08 09:10:56 +00:00
|
|
|
char *new = __xmlProcessCDATA(&start, &len);
|
2009-05-05 12:50:00 +00:00
|
|
|
if (new)
|
|
|
|
{
|
|
|
|
ps = start;
|
|
|
|
pe = ps + len;
|
|
|
|
|
|
|
|
while ((ps<pe) && isspace(*ps)) ps++;
|
|
|
|
while ((pe>ps) && isspace(*pe)) pe--;
|
|
|
|
len = (pe-ps);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*start = ps;
|
|
|
|
*blocklen = len;
|
|
|
|
}
|
|
|
|
|
2008-07-19 12:18:05 +00:00
|
|
|
#define NOCASECMP(a,b) ( ((a)^(b)) & 0xdf )
|
2008-07-06 11:34:50 +00:00
|
|
|
void *
|
2009-03-31 08:06:17 +00:00
|
|
|
__xml_memncasecmp(const char *haystack, size_t *haystacklen,
|
|
|
|
char **needle, size_t *needlelen)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-04-25 09:54:28 +00:00
|
|
|
char *rptr = 0;
|
2008-07-06 11:34:50 +00:00
|
|
|
|
|
|
|
if (haystack && needle && needlelen && (*needlelen > 0)
|
2008-07-19 12:18:05 +00:00
|
|
|
&& (*haystacklen >= *needlelen))
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
char *hs = (char *)haystack;
|
2008-07-19 12:18:05 +00:00
|
|
|
char *ns;
|
2008-07-06 11:34:50 +00:00
|
|
|
size_t i;
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
ns = *needle;
|
2008-07-06 11:34:50 +00:00
|
|
|
|
|
|
|
/* search for everything */
|
|
|
|
if ((*ns == '*') && (*needlelen == 1))
|
|
|
|
{
|
2009-04-29 07:05:22 +00:00
|
|
|
char *he = hs + *haystacklen;
|
2008-07-06 11:34:50 +00:00
|
|
|
|
2009-04-20 16:46:39 +00:00
|
|
|
while ((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
|
2009-04-25 09:54:28 +00:00
|
|
|
if (*(hs-1) == '/') hs--;
|
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
*needle = (char *)haystack;
|
|
|
|
*needlelen = hs - haystack;
|
2009-04-25 09:54:28 +00:00
|
|
|
|
2009-04-29 07:05:22 +00:00
|
|
|
ns = memchr(hs, '>', he-hs);
|
|
|
|
if (ns) hs = ns+1;
|
|
|
|
else hs = he;
|
2009-04-25 09:54:28 +00:00
|
|
|
|
2008-07-06 11:34:50 +00:00
|
|
|
rptr = hs;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_t nlen = *needlelen;
|
2008-07-19 12:18:05 +00:00
|
|
|
char *he = hs + *haystacklen;
|
2008-07-06 11:34:50 +00:00
|
|
|
|
|
|
|
for (i=0; i<nlen; i++)
|
|
|
|
{
|
2008-07-19 12:18:05 +00:00
|
|
|
if (NOCASECMP(*hs,*ns) && (*ns != '?')) break;
|
2009-04-25 09:54:28 +00:00
|
|
|
if (isspace(*hs) || (*hs == '/') || (*hs == '>')) break;
|
2008-07-06 11:34:50 +00:00
|
|
|
hs++;
|
|
|
|
ns++;
|
|
|
|
}
|
|
|
|
|
2009-04-25 09:54:28 +00:00
|
|
|
if (i == nlen)
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
2009-03-31 08:06:17 +00:00
|
|
|
*needle = (char *)haystack;
|
|
|
|
*needlelen = hs - haystack;
|
2009-04-25 09:54:28 +00:00
|
|
|
|
2009-04-29 07:05:22 +00:00
|
|
|
ns = memchr(hs, '>', he-hs);
|
|
|
|
if (ns) hs = ns+1;
|
|
|
|
else hs = he;
|
2009-04-25 09:54:28 +00:00
|
|
|
|
|
|
|
rptr = hs;
|
2008-07-19 12:18:05 +00:00
|
|
|
}
|
2009-04-25 09:54:28 +00:00
|
|
|
else /* not found */
|
2008-07-19 12:18:05 +00:00
|
|
|
{
|
2009-04-25 09:54:28 +00:00
|
|
|
while((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
|
|
|
|
if (*(hs-1) == '/') hs--;
|
2009-04-20 16:46:39 +00:00
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
*needle = (char *)haystack;
|
|
|
|
*needlelen = hs - haystack;
|
2009-04-20 16:46:39 +00:00
|
|
|
|
2009-04-29 07:05:22 +00:00
|
|
|
ns = memchr(hs, '>', he-hs);
|
|
|
|
if (ns) hs = ns+1;
|
|
|
|
else hs = he;
|
2008-07-19 12:18:05 +00:00
|
|
|
}
|
2008-07-06 11:34:50 +00:00
|
|
|
}
|
2008-07-19 12:18:05 +00:00
|
|
|
|
2009-03-31 08:06:17 +00:00
|
|
|
*haystacklen -= hs - haystack;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
2008-07-06 11:34:50 +00:00
|
|
|
|
|
|
|
return rptr;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
2009-04-18 21:25:23 +00:00
|
|
|
#ifndef XML_NONVALIDATING
|
|
|
|
void
|
2009-04-18 22:20:50 +00:00
|
|
|
__xmlErrorSet(const void *id, const char *pos, unsigned int err_no)
|
2009-04-18 21:25:23 +00:00
|
|
|
{
|
|
|
|
struct _xml_id *xid = (struct _xml_id *)id;
|
|
|
|
struct _root_id *rid;
|
|
|
|
|
|
|
|
assert(xid != 0);
|
|
|
|
|
|
|
|
if (xid->name) rid = xid->root;
|
|
|
|
else rid = (struct _root_id *)xid;
|
|
|
|
|
|
|
|
assert(rid != 0);
|
|
|
|
if (rid->info == 0)
|
2009-04-20 16:46:39 +00:00
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
rid->info = malloc(sizeof(struct _xml_error));
|
2009-04-20 16:46:39 +00:00
|
|
|
}
|
2009-04-18 21:25:23 +00:00
|
|
|
|
|
|
|
if (rid->info)
|
|
|
|
{
|
|
|
|
struct _xml_error *err = rid->info;
|
|
|
|
|
|
|
|
err->pos = (char *)pos;
|
2009-04-18 22:20:50 +00:00
|
|
|
err->err_no = err_no;
|
2009-04-18 21:25:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-06-29 13:08:24 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
/* Source:
|
|
|
|
* https://mollyrocket.com/forums/viewtopic.php?p=2529
|
|
|
|
*/
|
|
|
|
|
|
|
|
void *
|
2009-04-16 19:03:22 +00:00
|
|
|
simple_mmap(int fd, size_t length, SIMPLE_UNMMAP *un)
|
2008-06-29 13:08:24 +00:00
|
|
|
{
|
|
|
|
HANDLE f;
|
|
|
|
HANDLE m;
|
|
|
|
void *p;
|
|
|
|
|
|
|
|
f = (HANDLE)_get_osfhandle(fd);
|
2009-04-29 07:05:22 +00:00
|
|
|
if (!f) return (void *)-1;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
|
|
|
m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL);
|
2009-04-29 07:05:22 +00:00
|
|
|
if (!m) return (void *)-1;
|
2008-06-29 13:08:24 +00:00
|
|
|
|
|
|
|
p = MapViewOfFile(m, FILE_MAP_READ, 0,0,0);
|
|
|
|
if (!p)
|
|
|
|
{
|
|
|
|
CloseHandle(m);
|
2009-04-29 07:05:22 +00:00
|
|
|
return (void *)-1;
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (un)
|
|
|
|
{
|
|
|
|
un->m = m;
|
|
|
|
un->p = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
simple_unmmap(SIMPLE_UNMMAP *un)
|
|
|
|
{
|
2009-04-18 21:25:23 +00:00
|
|
|
UnmapViewOfFile(un->p);
|
|
|
|
CloseHandle(un->m);
|
2008-06-29 13:08:24 +00:00
|
|
|
}
|
|
|
|
#endif
|