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));
136 snprintf(loc,
sizeof(loc),
"%x", (
int) nad);
151 if(nad == NULL)
return NULL;
180 if(nad == NULL)
return;
186 snprintf(loc,
sizeof(loc),
"%x", (
int) nad);
212 if(elem >= nad->
ecur)
return -1;
216 if(name != NULL) lname = strlen(name);
219 for(elem++;elem < nad->
ecur;elem++)
243 if(elem >= nad->
ecur || name == NULL)
return -1;
246 lname = strlen(name);
247 if(val != NULL) lval = strlen(val);
253 (lval <= 0 || (lval == nad->
attrs[attr].
lval && strncmp(val,nad->
cdata + nad->
attrs[attr].
ival, lval) == 0)) &&
269 if(elem >= nad->
ecur || uri == NULL)
return -1;
279 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)))
299 for(ns = 0; ns < nad->
ncur; ns++)
319 char *str, *slash, *qmark, *equals;
324 if(elem >= nad->
ecur || name == NULL)
return -1;
327 if(strstr(name,
"/") == NULL && strstr(name,
"?") == NULL)
331 slash = strstr(str,
"/");
332 qmark = strstr(str,
"?");
333 equals = strstr(str,
"=");
336 if(qmark != NULL && (slash == NULL || qmark < slash))
349 if(strcmp(qmark,
"xmlns") == 0) {
386 _nad_attr(nad, elem, ns, name, val, vallen);
409 if (parent >= nad->
ecur) {
411 parent = nad->
ecur -1;
423 if(nad->
ecur != elem)
457 if(elem >= nad->
ecur)
return;
466 nad->
ecur -= next - elem;
469 for(cur = elem; cur < nad->
ecur; cur++)
481 if(elem >= nad->
ecur)
return;
490 for(cur = elem + 1; cur < nad->
ecur; cur++)
513 int nelem, first, i, j, ns, nattr, attr;
514 char buri[256], *uri = buri, bprefix[256], *prefix = bprefix;
520 if(src->
ecur <= selem || dest->
ecur <= delem)
525 while(selem + nelem < src->ecur && src->
elems[selem + nelem].
depth > src->
elems[selem].
depth) nelem++;
531 memmove(&dest->
elems[delem + nelem + 1], &dest->
elems[delem + 1], (dest->
ecur - delem - 1) *
sizeof(
struct nad_elem_st));
535 for(i = delem + nelem; i < dest->
ecur; i++)
542 for(i = 0; i < nelem; i++) {
565 for(j = 0; j < dest->
ncur; j++)
572 if(j == dest->
ncur) {
576 uri = (
char *) malloc(
sizeof(
char) * (
NAD_NURI_L(src, ns) + 1));
578 prefix = (
char *) malloc(
sizeof(
char) * (
NAD_NURI_L(src, ns) + 1));
588 if(uri != buri) free(uri);
589 if(prefix != bprefix) free(prefix);
594 for(ns = src->
elems[selem + i].
ns; ns >= 0; ns = src->
nss[ns].
next) {
595 for(j = 0; j < dest->
ncur; j++)
600 if(j == dest->
ncur) {
604 uri = (
char *) malloc(
sizeof(
char) * (
NAD_NURI_L(src, ns) + 1));
606 prefix = (
char *) malloc(
sizeof(
char) * (
NAD_NURI_L(src, ns) + 1));
616 if(uri != buri) free(uri);
617 if(prefix != bprefix) free(prefix);
628 for(attr = src->
elems[selem + i].
attr; attr >= 0; attr = src->
attrs[attr].
next) nattr++;
648 for(j = 0; j < dest->
ncur; j++)
689 nad->
depths[depth] = elem;
711 int elem = nad->
ecur - 1;
726 elem = nad->
depths[depth];
753 nad->
nss[ns].
luri = strlen(uri);
785 nad->
nss[ns].
luri = strlen(uri);
806 while(flag >= 4 && (c = memchr(nad->
cdata + data,
'"',len)) != NULL)
816 memcpy(nad->
cdata + nad->
ccur,
""", 6);
820 len -= (ic+1) - data;
825 while(flag >= 3 && (c = memchr(nad->
cdata + data,
'\'',len)) != NULL)
832 memcpy(nad->
cdata + nad->
ccur,
"'", 6);
836 len -= (ic+1) - data;
841 while(flag >= 2 && (c = memchr(nad->
cdata + data,
'<',len)) != NULL)
848 memcpy(nad->
cdata + nad->
ccur,
"<", 4);
852 len -= (ic+1) - data;
857 while(flag >= 1 && (c = memchr(nad->
cdata + data,
'>', len)) != NULL)
864 memcpy(nad->
cdata + nad->
ccur,
">", 4);
868 len -= (ic+1) - data;
873 while((c = memchr(nad->
cdata + data,
'&',len)) != NULL)
882 nad->
ccur += (ic - data);
885 memcpy(nad->
cdata + nad->
ccur,
"&", 5);
889 len -= (ic+1) - data;
912 while(elem != nad->
ecur)
952 memcpy(nad->
cdata + nad->
ccur,
" xmlns", 6);
997 memcpy(nad->
cdata + nad->
ccur,
" xmlns", 6);
1056 if(elem+1 == nad->
ecur)
1062 if(ndepth <= nad->elems[elem].depth)
1068 memcpy(nad->
cdata + nad->
ccur,
"/>", 2);
1086 memcpy(nad->
cdata + nad->
ccur,
"</", 2);
1106 if(ndepth < nad->elems[elem].depth)
1131 memcpy(nad->
cdata + nad->
ccur,
"</", 2);
1160 int ixml = nad->
ccur;
1165 *len = nad->
ccur - ixml;
1166 *xml = nad->
cdata + ixml;
1191 *len =
sizeof(int) * 5 +
1195 sizeof(char) * nad->
ccur;
1197 *buf = (
char *) malloc(*len);
1200 * (
int *) pos = *len; pos +=
sizeof(int);
1201 * (
int *) pos = nad->
ecur; pos +=
sizeof(
int);
1202 * (
int *) pos = nad->
acur; pos +=
sizeof(
int);
1203 * (
int *) pos = nad->
ncur; pos +=
sizeof(
int);
1204 * (
int *) pos = nad->
ccur; pos +=
sizeof(
int);
1209 memcpy(pos, nad->
cdata,
sizeof(
char) * nad->
ccur);
1214 const char *pos = buf +
sizeof(int);
1218 nad->
ecur = * (
int *) pos; pos +=
sizeof(int);
1219 nad->
acur = * (
int *) pos; pos +=
sizeof(int);
1220 nad->
ncur = * (
int *) pos; pos +=
sizeof(int);
1221 nad->
ccur = * (
int *) pos; pos +=
sizeof(int);
1250 nad->
cdata = (
char *) malloc(
sizeof(
char) * nad->
ccur);
1251 memcpy(nad->
cdata, pos,
sizeof(
char) * nad->
ccur);
1269 char *uri, *elem, *prefix;
1274 strncpy(buf, name, 1024);
1285 elem = strchr(uri,
'|');
1289 prefix = strchr(elem,
'|');
1290 if(prefix != NULL) {
1308 while(attr[0] != NULL) {
1311 strncpy(buf, attr[0], 1024);
1316 elem = strchr(uri,
'|');
1320 prefix = strchr(elem,
'|');
1321 if(prefix != NULL) {
1366 #ifdef HAVE_XML_STOPPARSER
1368 static void _nad_parse_entity_declaration(
void *arg,
const char *entityName,
1369 int is_parameter_entity,
const char *value,
1370 int value_length,
const char *base,
1371 const char *systemId,
const char *publicId,
1372 const char *notationName)
1376 XML_StopParser(bd->
p, XML_FALSE);
1387 p = XML_ParserCreateNS(NULL,
'|');
1392 XML_SetReturnNSTriplet(p, 1);
1398 #ifdef HAVE_XML_STOPPARSER
1399 XML_SetEntityDeclHandler(p, (
void *) _nad_parse_entity_declaration);
1401 XML_SetDefaultHandler(p, NULL);
1407 XML_SetUserData(p, (
void *) &bd);
1412 if(!XML_Parse(p, buf, len, 1)) {
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
int nad_insert_elem(nad_t nad, int parent, int ns, const char *name, const char *cdata)
shove in a new child elem after the given one
#define NAD_SAFE(blocks, size, len)
this is the safety check used to make sure there's always enough mem
int nad_find_elem(nad_t nad, int elem, int ns, const char *name, int depth)
locate the next elem at a given depth with an optional matching name
void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth)
append new cdata to the last elem
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
static int _nad_realloc(void **oblocks, int len)
Reallocate the given buffer to make it larger.
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
void nad_wrap_elem(nad_t nad, int elem, int ns, const char *name)
wrap an element with another element
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:
void nad_set_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen)
create, update, or zap any matching attr on this elem
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_insert_nad(nad_t dest, int delem, nad_t src, int selem)
insert part of a nad into another nad
int nad_find_namespace(nad_t nad, int elem, const char *uri, const char *prefix)
get a matching ns on this elem, both uri and optional prefix
#define NAD_NPREFIX(N, NS)
void nad_drop_elem(nad_t nad, int elem)
remove an element (and its subelements)
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)
int nad_find_attr(nad_t nad, int elem, int ns, const char *name, const char *val)
get a matching attr on this elem, both name and optional val
int nad_append_namespace(nad_t nad, int elem, const char *uri, const char *prefix)
declare a namespace on an already-existing element
int nad_find_elem_path(nad_t nad, 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 c...
static void _nad_parse_namespace_start(void *arg, const char *prefix, const char *uri)
static int _nad_lp0(nad_t nad, int elem)
internal recursive printing function
void nad_print(nad_t nad, int elem, const char **xml, int *len)
create a string representation of the given element (and children), point references to it ...
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