41 static xht _nad_alloc_tracked = NULL;
42 static xht _nad_free_tracked = NULL;
46 snprintf(loc,
sizeof(loc),
"%x", (
int) nad);
48 if(
xhash_get(_nad_alloc_tracked, loc) == NULL) {
49 fprintf(stderr,
">>> NAD OP %s: 0x%x not allocated!\n", func, (
int) nad);
53 if(
xhash_get(_nad_free_tracked, loc) != NULL) {
54 fprintf(stderr,
">>> NAD OP %s: 0x%x previously freed!\n", func, (
int) nad);
58 fprintf(stderr,
">>> NAD OP %s: 0x%x\n", func, (
int) nad);
61 #define _nad_ptr_check(func,nad) 84 *oblocks = realloc(*oblocks, nlen);
89 #define NAD_SAFE(blocks, size, len) if((size) > len) len = _nad_realloc((void**)&(blocks),(size)); 96 memcpy(nad->
cdata + nad->
ccur, cdata, len);
98 return nad->
ccur - len;
102 static int _nad_attr(
nad_t nad,
int elem,
int ns,
const char *name,
const char *val,
int vallen)
129 nad = calloc(1,
sizeof(
struct nad_st));
134 if(_nad_alloc_tracked == NULL) _nad_alloc_tracked =
xhash_new(501);
135 if(_nad_free_tracked == NULL) _nad_free_tracked =
xhash_new(501);
138 snprintf(loc,
sizeof(loc),
"%x", (
int) nad);
153 if(nad == NULL)
return NULL;
182 if(nad == NULL)
return;
188 snprintf(loc,
sizeof(loc),
"%x", (
int) nad);
214 if(elem >= nad->
ecur)
return -1;
218 if(name != NULL) lname = strlen(name);
221 for(elem++;elem < nad->
ecur;elem++)
245 if(elem >= nad->
ecur || name == NULL)
return -1;
248 lname = strlen(name);
249 if(val != NULL) lval = strlen(val);
255 (lval <= 0 || (lval == nad->
attrs[attr].
lval && strncmp(val,nad->
cdata + nad->
attrs[attr].
ival, lval) == 0)) &&
271 if(elem >= nad->
ecur || uri == NULL)
return -1;
281 if(strlen(uri) ==
NAD_NURI_L(nad, ns) && strncmp(uri,
NAD_NURI(nad, ns),
NAD_NURI_L(nad, ns)) == 0 && (prefix == NULL || (nad->
nss[ns].
iprefix >= 0 && strlen(prefix) ==
NAD_NPREFIX_L(nad, ns) && strncmp(prefix,
NAD_NPREFIX(nad, ns),
NAD_NPREFIX_L(nad, ns)) == 0)))
301 for(ns = 0; ns < nad->
ncur; ns++)
323 char *str, *slash, *qmark, *excl, *equals;
329 if(elem >= nad->
ecur || name == NULL)
return -1;
332 if(strstr(name,
"/") == NULL && strstr(name,
"?") == NULL && strstr(name,
"!") == NULL)
337 slash = strstr(str,
"/");
338 qmark = strstr(str,
"?");
339 excl = strstr(str,
"!");
340 equals = strstr(str,
"=");
343 if(qmark != NULL && (slash == NULL || qmark < slash))
356 if(strcmp(qmark,
"xmlns") == 0) {
368 if(excl != NULL && (slash == NULL || excl < slash))
381 if(strcmp(excl,
"xmlns") == 0) {
407 void nad_set_attr(
nad_t nad,
unsigned int elem,
int ns,
const char *name,
const char *val,
int vallen)
418 _nad_attr(nad, elem, ns, name, val, vallen);
441 if (parent >= nad->
ecur) {
443 parent = nad->
ecur -1;
455 if(nad->
ecur != elem)
489 if(elem >= nad->
ecur)
return;
498 nad->
ecur -= next - elem;
501 for(cur = elem; cur < nad->
ecur; cur++)
513 if(elem >= nad->
ecur)
return;
533 for(cur = elem + 1; cur < nad->
ecur; cur++)
545 int nelem, first, i, j, ns, nattr, attr;
546 char buri[256], *uri = buri, bprefix[256], *prefix = bprefix;
552 if(src->
ecur <= selem || dest->
ecur <= delem)
557 while(selem + nelem < src->ecur && src->
elems[selem + nelem].
depth > src->
elems[selem].
depth) nelem++;
563 memmove(&dest->
elems[delem + nelem + 1], &dest->
elems[delem + 1], (dest->
ecur - delem - 1) *
sizeof(
struct nad_elem_st));
567 for(i = delem + nelem; i < dest->
ecur; i++)
574 for(i = 0; i < nelem; i++) {
597 for(j = 0; j < dest->
ncur; j++)
604 if(j == dest->
ncur) {
608 uri = (
char *) malloc(
sizeof(
char) * (
NAD_NURI_L(src, ns) + 1));
610 prefix = (
char *) malloc(
sizeof(
char) * (
NAD_NURI_L(src, ns) + 1));
624 if(prefix != bprefix) {
632 for(ns = src->
elems[selem + i].
ns; ns >= 0; ns = src->
nss[ns].
next) {
633 for(j = 0; j < dest->
ncur; j++)
638 if(j == dest->
ncur) {
642 uri = (
char *) malloc(
sizeof(
char) * (
NAD_NURI_L(src, ns) + 1));
644 prefix = (
char *) malloc(
sizeof(
char) * (
NAD_NURI_L(src, ns) + 1));
658 if(prefix != bprefix) {
672 for(attr = src->
elems[selem + i].
attr; attr >= 0; attr = src->
attrs[attr].
next) nattr++;
692 for(j = 0; j < dest->
ncur; j++)
733 nad->
depths[depth] = elem;
755 int elem = nad->
ecur - 1;
770 elem = nad->
depths[depth];
797 nad->
nss[ns].
luri = strlen(uri);
832 nad->
nss[ns].
luri = strlen(uri);
856 while(flag >= 4 && (c = memchr(nad->
cdata + data,
'"',len)) != NULL)
866 memcpy(nad->
cdata + nad->
ccur,
""", 6);
870 len -= (ic+1) - data;
875 while(flag >= 3 && (c = memchr(nad->
cdata + data,
'\'',len)) != NULL)
882 memcpy(nad->
cdata + nad->
ccur,
"'", 6);
886 len -= (ic+1) - data;
891 while(flag >= 2 && (c = memchr(nad->
cdata + data,
'<',len)) != NULL)
898 memcpy(nad->
cdata + nad->
ccur,
"<", 4);
902 len -= (ic+1) - data;
907 while(flag >= 1 && (c = memchr(nad->
cdata + data,
'>', len)) != NULL)
914 memcpy(nad->
cdata + nad->
ccur,
">", 4);
918 len -= (ic+1) - data;
923 while((c = memchr(nad->
cdata + data,
'&',len)) != NULL)
932 nad->
ccur += (ic - data);
935 memcpy(nad->
cdata + nad->
ccur,
"&", 5);
939 len -= (ic+1) - data;
962 while(elem != nad->
ecur)
1002 memcpy(nad->
cdata + nad->
ccur,
" xmlns", 6);
1047 memcpy(nad->
cdata + nad->
ccur,
" xmlns", 6);
1106 if(elem+1 == nad->
ecur)
1112 if(ndepth <= nad->elems[elem].depth)
1118 memcpy(nad->
cdata + nad->
ccur,
"/>", 2);
1136 memcpy(nad->
cdata + nad->
ccur,
"</", 2);
1156 if(ndepth < nad->elems[elem].depth)
1181 memcpy(nad->
cdata + nad->
ccur,
"</", 2);
1210 int ixml = nad->
ccur;
1215 *len = nad->
ccur - ixml;
1216 *xml = nad->
cdata + ixml;
1241 *len =
sizeof(int) * 5 +
1245 sizeof(char) * nad->
ccur;
1247 *buf = (
char *) malloc(*len);
1250 * (
int *) pos = *len; pos +=
sizeof(int);
1251 * (
int *) pos = nad->
ecur; pos +=
sizeof(
int);
1252 * (
int *) pos = nad->
acur; pos +=
sizeof(
int);
1253 * (
int *) pos = nad->
ncur; pos +=
sizeof(
int);
1254 * (
int *) pos = nad->
ccur; pos +=
sizeof(
int);
1259 memcpy(pos, nad->
cdata,
sizeof(
char) * nad->
ccur);
1264 const char *pos = buf +
sizeof(int);
1268 nad->
ecur = * (
int *) pos; pos +=
sizeof(int);
1269 nad->
acur = * (
int *) pos; pos +=
sizeof(int);
1270 nad->
ncur = * (
int *) pos; pos +=
sizeof(int);
1271 nad->
ccur = * (
int *) pos; pos +=
sizeof(int);
1300 nad->
cdata = (
char *) malloc(
sizeof(
char) * nad->
ccur);
1301 memcpy(nad->
cdata, pos,
sizeof(
char) * nad->
ccur);
1319 char *uri, *elem, *prefix;
1324 strncpy(buf, name, 1024);
1335 elem = strchr(uri,
'|');
1339 prefix = strchr(elem,
'|');
1340 if(prefix != NULL) {
1358 while(attr[0] != NULL) {
1361 strncpy(buf, attr[0], 1024);
1366 elem = strchr(uri,
'|');
1370 prefix = strchr(elem,
'|');
1371 if(prefix != NULL) {
1416 #ifdef HAVE_XML_STOPPARSER 1418 static void _nad_parse_entity_declaration(
void *arg,
const char *entityName,
1419 int is_parameter_entity,
const char *value,
1420 int value_length,
const char *base,
1421 const char *systemId,
const char *publicId,
1422 const char *notationName)
1426 XML_StopParser(bd->
p, XML_FALSE);
1437 p = XML_ParserCreateNS(NULL,
'|');
1442 XML_SetReturnNSTriplet(p, 1);
1448 #ifdef HAVE_XML_STOPPARSER 1449 XML_SetEntityDeclHandler(p, (
void *) _nad_parse_entity_declaration);
1451 XML_SetDefaultHandler(p, NULL);
1457 XML_SetUserData(p, (
void *) &bd);
1462 if(!XML_Parse(p, buf, len, 1)) {
void nad_wrap_elem(nad_t nad, unsigned int elem, int ns, const char *name)
wrap an element with another element
struct nad_elem_st * elems
#define _nad_ptr_check(func, nad)
!!! Things to do (after 2.0)
nad_t nad_new(void)
create a new nad
int nad_append_attr(nad_t nad, int ns, const char *name, const char *val)
attach new attr to the last elem
#define NAD_SAFE(blocks, size, len)
this is the safety check used to make sure there's always enough mem
int nad_find_attr(nad_t nad, unsigned int elem, int ns, const char *name, const char *val)
get a matching attr on this elem, both name and optional val
void nad_set_attr(nad_t nad, unsigned int elem, int ns, const char *name, const char *val, int vallen)
create, update, or zap any matching attr on this elem
void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth)
append new cdata to the last elem
void nad_drop_elem(nad_t nad, unsigned int elem)
remove an element (and its subelements)
static void _nad_parse_element_end(void *arg, const char *name)
struct nad_attr_st * attrs
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix)
bring a new namespace into scope
void nad_print(nad_t nad, unsigned int elem, const char **xml, int *len)
create a string representation of the given element (and children), point references to it ...
static int _nad_realloc(void **oblocks, int len)
Reallocate the given buffer to make it larger.
int nad_insert_elem(nad_t nad, unsigned int parent, int ns, const char *name, const char *cdata)
shove in a new child elem after the given one
int nad_append_elem(nad_t nad, int ns, const char *name, int depth)
create a new elem on the list
void nad_free(nad_t nad)
free that nad
static int _nad_cdata(nad_t nad, const char *cdata, int len)
internal: append some cdata and return the index to it
nad_t nad_copy(nad_t nad)
copy a nad
nad_t nad_deserialize(const char *buf)
#define NAD_NPREFIX_L(N, NS)
void nad_serialize(nad_t nad, char **buf, int *len)
nads serialize to a buffer of this form:
int nad_find_namespace(nad_t nad, unsigned int elem, const char *uri, const char *prefix)
get a matching ns on this elem, both uri and optional prefix
static void _nad_escape(nad_t nad, int data, int len, int flag)
nad_t nad_parse(const char *buf, int len)
create a nad from raw xml
#define NAD_NURI_L(N, NS)
void xhash_put(xht h, const char *key, void *val)
static void _nad_parse_element_start(void *arg, const char *name, const char **atts)
static int _nad_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen)
internal: create a new attr on any given elem
void xhash_zap(xht h, const char *key)
static void _nad_parse_cdata(void *arg, const char *str, int len)
int nad_find_elem(nad_t nad, unsigned int elem, int ns, const char *name, int depth)
locate the next elem at a given depth with an optional matching name
int nad_insert_nad(nad_t dest, int delem, nad_t src, int selem)
insert part of a nad into another nad
#define NAD_NPREFIX(N, NS)
pool_t xhash_pool(xht h)
get our pool
char * pstrdup(pool_t p, const char *src)
XXX efficient: move this to const char * and then loop throug the existing heaps to see if src is wit...
void * xhash_get(xht h, const char *key)
static int _nad_lp0(nad_t nad, unsigned int elem)
internal recursive printing function
static void _nad_parse_namespace_start(void *arg, const char *prefix, const char *uri)
int nad_append_namespace(nad_t nad, unsigned int elem, const char *uri, const char *prefix)
declare a namespace on an already-existing element
int nad_find_elem_path(nad_t nad, unsigned int elem, int ns, const char *name)
find elem using XPath like query name – "name" for the child tag of that name "name/name" for a sub ...
parse a buffer into a nad
int nad_find_scoped_namespace(nad_t nad, const char *uri, const char *prefix)
find a namespace in scope