/** create a new elem on the list */ int nad_append_elem(nad_t nad, int ns, const char *name, int depth) { int elem; _nad_ptr_check(__func__, nad); /* make sure there's mem for us */ NAD_SAFE(nad->elems, (nad->ecur + 1) * sizeof(struct nad_elem_st), nad->elen); elem = nad->ecur; nad->ecur++; nad->elems[elem].lname = strlen(name); nad->elems[elem].iname = _nad_cdata(nad,name,nad->elems[elem].lname); nad->elems[elem].icdata = nad->elems[elem].lcdata = 0; nad->elems[elem].itail = nad->elems[elem].ltail = 0; nad->elems[elem].attr = -1; nad->elems[elem].ns = nad->scope; nad->scope = -1; nad->elems[elem].depth = depth; nad->elems[elem].my_ns = ns; /* make sure there's mem in the depth array, then track us */ NAD_SAFE(nad->depths, (depth + 1) * sizeof(int), nad->dlen); nad->depths[depth] = elem; /* our parent is the previous guy in the depth array */ if(depth <= 0) nad->elems[elem].parent = -1; else nad->elems[elem].parent = nad->depths[depth - 1]; return elem; }
nad_t nad_copy(nad_t nad) { nad_t copy; _nad_ptr_check(__func__, nad); if(nad == NULL) return NULL; copy = nad_new(); /* if it's not large enough, make bigger */ NAD_SAFE(copy->elems, nad->elen, copy->elen); NAD_SAFE(copy->attrs, nad->alen, copy->alen); NAD_SAFE(copy->nss, nad->nlen, copy->nlen); NAD_SAFE(copy->cdata, nad->clen, copy->clen); /* copy all data */ memcpy(copy->elems, nad->elems, nad->elen); memcpy(copy->attrs, nad->attrs, nad->alen); memcpy(copy->nss, nad->nss, nad->nlen); memcpy(copy->cdata, nad->cdata, nad->clen); /* sync data */ copy->ecur = nad->ecur; copy->acur = nad->acur; copy->ncur = nad->ncur; copy->ccur = nad->ccur; copy->scope = nad->scope; return copy; }
/** declare a namespace on an already-existing element */ int nad_append_namespace(nad_t nad, int elem, const char *uri, const char *prefix) { int ns; _nad_ptr_check(__func__, nad); /* see if its already scoped on this element */ ns = nad_find_namespace(nad, elem, uri, NULL); if(ns >= 0) return ns; /* make some room */ NAD_SAFE(nad->nss, (nad->ncur + 1) * sizeof(struct nad_ns_st), nad->nlen); ns = nad->ncur; nad->ncur++; nad->nss[ns].next = nad->elems[elem].ns; nad->elems[elem].ns = ns; nad->nss[ns].luri = strlen(uri); nad->nss[ns].iuri = _nad_cdata(nad, uri, nad->nss[ns].luri); if(prefix != NULL) { nad->nss[ns].lprefix = strlen(prefix); nad->nss[ns].iprefix = _nad_cdata(nad, prefix, nad->nss[ns].lprefix); } else nad->nss[ns].iprefix = -1; return ns; }
/** bring a new namespace into scope */ int nad_add_namespace(nad_t nad, const char *uri, const char *prefix) { int ns; _nad_ptr_check(__func__, nad); /* only add it if its not already in scope */ ns = nad_find_scoped_namespace(nad, uri, NULL); if(ns >= 0) return ns; /* make sure there's mem for us */ NAD_SAFE(nad->nss, (nad->ncur + 1) * sizeof(struct nad_ns_st), nad->nlen); ns = nad->ncur; nad->ncur++; nad->nss[ns].next = nad->scope; nad->scope = ns; nad->nss[ns].luri = strlen(uri); nad->nss[ns].iuri = _nad_cdata(nad, uri, nad->nss[ns].luri); if(prefix != NULL) { nad->nss[ns].lprefix = strlen(prefix); nad->nss[ns].iprefix = _nad_cdata(nad, prefix, nad->nss[ns].lprefix); } else nad->nss[ns].iprefix = -1; return ns; }
/** wrap an element with another element */ void nad_wrap_elem(nad_t nad, int elem, int ns, const char *name) { int cur; _nad_ptr_check(__func__, nad); if(elem >= nad->ecur) return; NAD_SAFE(nad->elems, (nad->ecur + 1) * sizeof(struct nad_elem_st), nad->elen); /* relocate all the rest of the elems after us */ memmove(&nad->elems[elem + 1], &nad->elems[elem], (nad->ecur - elem) * sizeof(struct nad_elem_st)); nad->ecur++; /* relink parents on moved elements */ for(cur = elem + 1; cur < nad->ecur; cur++) if(nad->elems[cur].parent > elem + 1) nad->elems[cur].parent++; /* set up req'd parts of new elem */ nad->elems[elem].lname = strlen(name); nad->elems[elem].iname = _nad_cdata(nad,name,nad->elems[elem].lname); nad->elems[elem].attr = -1; nad->elems[elem].ns = nad->scope; nad->scope = -1; nad->elems[elem].itail = nad->elems[elem].ltail = 0; nad->elems[elem].icdata = nad->elems[elem].lcdata = 0; nad->elems[elem].my_ns = ns; /* raise the bar on all the children */ nad->elems[elem+1].depth++; for(cur = elem + 2; cur < nad->ecur && nad->elems[cur].depth > nad->elems[elem].depth; cur++) nad->elems[cur].depth++; /* hook up the parent */ nad->elems[elem].parent = nad->elems[elem + 1].parent; }
/** internal: append some cdata and return the index to it */ static int _nad_cdata(nad_t nad, const char *cdata, int len) { NAD_SAFE(nad->cdata, nad->ccur + len, nad->clen); memcpy(nad->cdata + nad->ccur, cdata, len); nad->ccur += len; return nad->ccur - len; }
/** shove in a new child elem after the given one */ int nad_insert_elem(nad_t nad, int parent, int ns, const char *name, const char *cdata) { int elem; if (parent >= nad->ecur) { if (nad->ecur > 0) parent = nad->ecur -1; else parent = 0; } elem = parent + 1; _nad_ptr_check(__func__, nad); NAD_SAFE(nad->elems, (nad->ecur + 1) * sizeof(struct nad_elem_st), nad->elen); /* relocate all the rest of the elems (unless we're at the end already) */ if(nad->ecur != elem) memmove(&nad->elems[elem + 1], &nad->elems[elem], (nad->ecur - elem) * sizeof(struct nad_elem_st)); nad->ecur++; /* set up req'd parts of new elem */ nad->elems[elem].parent = parent; nad->elems[elem].lname = strlen(name); nad->elems[elem].iname = _nad_cdata(nad,name,nad->elems[elem].lname); nad->elems[elem].attr = -1; nad->elems[elem].ns = nad->scope; nad->scope = -1; nad->elems[elem].itail = nad->elems[elem].ltail = 0; nad->elems[elem].my_ns = ns; /* add cdata if given */ if(cdata != NULL) { nad->elems[elem].lcdata = strlen(cdata); nad->elems[elem].icdata = _nad_cdata(nad,cdata,nad->elems[elem].lcdata); } else { nad->elems[elem].icdata = nad->elems[elem].lcdata = 0; } /* parent/child */ nad->elems[elem].depth = nad->elems[parent].depth + 1; return elem; }
/** internal: create a new attr on any given elem */ static int _nad_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen) { int attr; /* make sure there's mem for us */ NAD_SAFE(nad->attrs, (nad->acur + 1) * sizeof(struct nad_attr_st), nad->alen); attr = nad->acur; nad->acur++; nad->attrs[attr].next = nad->elems[elem].attr; nad->elems[elem].attr = attr; nad->attrs[attr].lname = strlen(name); nad->attrs[attr].iname = _nad_cdata(nad,name,nad->attrs[attr].lname); if(vallen > 0) nad->attrs[attr].lval = vallen; else nad->attrs[attr].lval = strlen(val); nad->attrs[attr].ival = _nad_cdata(nad,val,nad->attrs[attr].lval); nad->attrs[attr].my_ns = ns; return attr; }
/** internal recursive printing function */ static int _nad_lp0(nad_t nad, int elem) { int attr; int ndepth; int ns; int elem_ns; /* there's a lot of code in here, but don't let that scare you, it's just duplication in order to be a bit more efficient cpu-wise */ /* this whole thing is in a big loop for processing siblings */ while(elem != nad->ecur) { /* make enough space for the opening element */ ns = nad->elems[elem].my_ns; if(ns >= 0 && nad->nss[ns].iprefix >= 0) { NAD_SAFE(nad->cdata, nad->ccur + nad->elems[elem].lname + nad->nss[ns].lprefix + 2, nad->clen); } else { NAD_SAFE(nad->cdata, nad->ccur + nad->elems[elem].lname + 1, nad->clen); } /* opening tag */ *(nad->cdata + nad->ccur++) = '<'; /* add the prefix if necessary */ if(ns >= 0 && nad->nss[ns].iprefix >= 0) { memcpy(nad->cdata + nad->ccur, nad->cdata + nad->nss[ns].iprefix, nad->nss[ns].lprefix); nad->ccur += nad->nss[ns].lprefix; *(nad->cdata + nad->ccur++) = ':'; } /* copy in the name */ memcpy(nad->cdata + nad->ccur, nad->cdata + nad->elems[elem].iname, nad->elems[elem].lname); nad->ccur += nad->elems[elem].lname; /* add element prefix namespace */ ns = nad->elems[elem].my_ns; if(ns >= 0 && nad->nss[ns].iprefix >= 0) { /* make space */ if(nad->nss[ns].iprefix >= 0) { NAD_SAFE(nad->cdata, nad->ccur + nad->nss[ns].luri + nad->nss[ns].lprefix + 10, nad->clen); } else { NAD_SAFE(nad->cdata, nad->ccur + nad->nss[ns].luri + 9, nad->clen); } /* start */ memcpy(nad->cdata + nad->ccur, " xmlns", 6); nad->ccur += 6; /* prefix if necessary */ if(nad->nss[ns].iprefix >= 0) { *(nad->cdata + nad->ccur++) = ':'; memcpy(nad->cdata + nad->ccur, nad->cdata + nad->nss[ns].iprefix, nad->nss[ns].lprefix); nad->ccur += nad->nss[ns].lprefix; } *(nad->cdata + nad->ccur++) = '='; *(nad->cdata + nad->ccur++) = '\''; /* uri */ memcpy(nad->cdata + nad->ccur, nad->cdata + nad->nss[ns].iuri, nad->nss[ns].luri); nad->ccur += nad->nss[ns].luri; *(nad->cdata + nad->ccur++) = '\''; elem_ns = ns; }else{ elem_ns = -1; } /* add the namespaces */ for(ns = nad->elems[elem].ns; ns >= 0; ns = nad->nss[ns].next) { /* never explicitly declare the implicit xml namespace */ if(nad->nss[ns].luri == strlen(uri_XML) && strncmp(uri_XML, nad->cdata + nad->nss[ns].iuri, nad->nss[ns].luri) == 0) continue; /* do not redeclare element namespace */ if(ns == elem_ns) continue; /* make space */ if(nad->nss[ns].iprefix >= 0) { NAD_SAFE(nad->cdata, nad->ccur + nad->nss[ns].luri + nad->nss[ns].lprefix + 10, nad->clen); } else { NAD_SAFE(nad->cdata, nad->ccur + nad->nss[ns].luri + 9, nad->clen); } /* start */ memcpy(nad->cdata + nad->ccur, " xmlns", 6); nad->ccur += 6; /* prefix if necessary */ if(nad->nss[ns].iprefix >= 0) { *(nad->cdata + nad->ccur++) = ':'; memcpy(nad->cdata + nad->ccur, nad->cdata + nad->nss[ns].iprefix, nad->nss[ns].lprefix); nad->ccur += nad->nss[ns].lprefix; } *(nad->cdata + nad->ccur++) = '='; *(nad->cdata + nad->ccur++) = '\''; /* uri */ memcpy(nad->cdata + nad->ccur, nad->cdata + nad->nss[ns].iuri, nad->nss[ns].luri); nad->ccur += nad->nss[ns].luri; *(nad->cdata + nad->ccur++) = '\''; } for(attr = nad->elems[elem].attr; attr >= 0; attr = nad->attrs[attr].next) { if(nad->attrs[attr].lname <= 0) continue; /* make enough space for the wrapper part */ ns = nad->attrs[attr].my_ns; if(ns >= 0 && nad->nss[ns].iprefix >= 0) { NAD_SAFE(nad->cdata, nad->ccur + nad->attrs[attr].lname + nad->nss[ns].lprefix + 4, nad->clen); } else { NAD_SAFE(nad->cdata, nad->ccur + nad->attrs[attr].lname + 3, nad->clen); } *(nad->cdata + nad->ccur++) = ' '; /* add the prefix if necessary */ if(ns >= 0 && nad->nss[ns].iprefix >= 0) { memcpy(nad->cdata + nad->ccur, nad->cdata + nad->nss[ns].iprefix, nad->nss[ns].lprefix); nad->ccur += nad->nss[ns].lprefix; *(nad->cdata + nad->ccur++) = ':'; } /* copy in the name parts */ memcpy(nad->cdata + nad->ccur, nad->cdata + nad->attrs[attr].iname, nad->attrs[attr].lname); nad->ccur += nad->attrs[attr].lname; *(nad->cdata + nad->ccur++) = '='; *(nad->cdata + nad->ccur++) = '\''; /* copy in the escaped value */ _nad_escape(nad, nad->attrs[attr].ival, nad->attrs[attr].lval, 4); /* make enough space for the closing quote and add it */ NAD_SAFE(nad->cdata, nad->ccur + 1, nad->clen); *(nad->cdata + nad->ccur++) = '\''; } /* figure out what's next */ if(elem+1 == nad->ecur) ndepth = -1; else ndepth = nad->elems[elem+1].depth; /* handle based on if there are children, update nelem after done */ if(ndepth <= nad->elems[elem].depth) { /* make sure there's enough for what we could need */ NAD_SAFE(nad->cdata, nad->ccur + 2, nad->clen); if(nad->elems[elem].lcdata == 0) { memcpy(nad->cdata + nad->ccur, "/>", 2); nad->ccur += 2; }else{ *(nad->cdata + nad->ccur++) = '>'; /* copy in escaped cdata */ _nad_escape(nad, nad->elems[elem].icdata, nad->elems[elem].lcdata,4); /* make room */ ns = nad->elems[elem].my_ns; if(ns >= 0 && nad->nss[ns].iprefix >= 0) { NAD_SAFE(nad->cdata, nad->ccur + 4 + nad->elems[elem].lname + nad->nss[ns].lprefix, nad->clen); } else { NAD_SAFE(nad->cdata, nad->ccur + 3 + nad->elems[elem].lname, nad->clen); } /* close tag */ memcpy(nad->cdata + nad->ccur, "</", 2); nad->ccur += 2; /* add the prefix if necessary */ if(ns >= 0 && nad->nss[ns].iprefix >= 0) { memcpy(nad->cdata + nad->ccur, nad->cdata + nad->nss[ns].iprefix, nad->nss[ns].lprefix); nad->ccur += nad->nss[ns].lprefix; *(nad->cdata + nad->ccur++) = ':'; } memcpy(nad->cdata + nad->ccur, nad->cdata + nad->elems[elem].iname, nad->elems[elem].lname); nad->ccur += nad->elems[elem].lname; *(nad->cdata + nad->ccur++) = '>'; } /* always try to append the tail */ _nad_escape(nad, nad->elems[elem].itail, nad->elems[elem].ltail,4); /* if no siblings either, bail */ if(ndepth < nad->elems[elem].depth) return elem+1; /* next sibling */ elem++; }else{ int nelem; /* process any children */ /* close ourself and append any cdata first */ NAD_SAFE(nad->cdata, nad->ccur + 1, nad->clen); *(nad->cdata + nad->ccur++) = '>'; _nad_escape(nad, nad->elems[elem].icdata, nad->elems[elem].lcdata, 4); /* process children */ nelem = _nad_lp0(nad, elem+1); /* close and tail up */ ns = nad->elems[elem].my_ns; if(ns >= 0 && nad->nss[ns].iprefix >= 0) { NAD_SAFE(nad->cdata, nad->ccur + 4 + nad->elems[elem].lname + nad->nss[ns].lprefix, nad->clen); } else { NAD_SAFE(nad->cdata, nad->ccur + 3 + nad->elems[elem].lname, nad->clen); } memcpy(nad->cdata + nad->ccur, "</", 2); nad->ccur += 2; if(ns >= 0 && nad->nss[ns].iprefix >= 0) { memcpy(nad->cdata + nad->ccur, nad->cdata + nad->nss[ns].iprefix, nad->nss[ns].lprefix); nad->ccur += nad->nss[ns].lprefix; *(nad->cdata + nad->ccur++) = ':'; } memcpy(nad->cdata + nad->ccur, nad->cdata + nad->elems[elem].iname, nad->elems[elem].lname); nad->ccur += nad->elems[elem].lname; *(nad->cdata + nad->ccur++) = '>'; _nad_escape(nad, nad->elems[elem].itail, nad->elems[elem].ltail,4); /* if the next element is not our sibling, we're done */ if(nelem < nad->ecur && nad->elems[nelem].depth < nad->elems[elem].depth) return nelem; /* for next sibling in while loop */ elem = nelem; } /* here's the end of that big while loop */ } return elem; }
static void _nad_escape(nad_t nad, int data, int len, int flag) { char *c; int ic; if(len <= 0) return; /* first, if told, find and escape " */ while(flag >= 4 && (c = memchr(nad->cdata + data,'"',len)) != NULL) { /* get offset */ ic = c - nad->cdata; /* cute, eh? handle other data before this normally */ _nad_escape(nad, data, ic - data, 3); /* ensure enough space, and add our escaped " */ NAD_SAFE(nad->cdata, nad->ccur + 6, nad->clen); memcpy(nad->cdata + nad->ccur, """, 6); nad->ccur += 6; /* just update and loop for more */ len -= (ic+1) - data; data = ic+1; } /* next, find and escape ' */ while(flag >= 3 && (c = memchr(nad->cdata + data,'\'',len)) != NULL) { ic = c - nad->cdata; _nad_escape(nad, data, ic - data, 2); /* ensure enough space, and add our escaped ' */ NAD_SAFE(nad->cdata, nad->ccur + 6, nad->clen); memcpy(nad->cdata + nad->ccur, "'", 6); nad->ccur += 6; /* just update and loop for more */ len -= (ic+1) - data; data = ic+1; } /* next look for < */ while(flag >= 2 && (c = memchr(nad->cdata + data,'<',len)) != NULL) { ic = c - nad->cdata; _nad_escape(nad, data, ic - data, 1); /* ensure enough space, and add our escaped < */ NAD_SAFE(nad->cdata, nad->ccur + 4, nad->clen); memcpy(nad->cdata + nad->ccur, "<", 4); nad->ccur += 4; /* just update and loop for more */ len -= (ic+1) - data; data = ic+1; } /* next look for > */ while(flag >= 1 && (c = memchr(nad->cdata + data, '>', len)) != NULL) { ic = c - nad->cdata; _nad_escape(nad, data, ic - data, 0); /* ensure enough space, and add our escaped > */ NAD_SAFE(nad->cdata, nad->ccur + 4, nad->clen); memcpy(nad->cdata + nad->ccur, ">", 4); nad->ccur += 4; /* just update and loop for more */ len -= (ic+1) - data; data = ic+1; } /* if & is found, escape it */ while((c = memchr(nad->cdata + data,'&',len)) != NULL) { ic = c - nad->cdata; /* ensure enough space */ NAD_SAFE(nad->cdata, nad->ccur + 5 + (ic - data), nad->clen); /* handle normal data */ memcpy(nad->cdata + nad->ccur, nad->cdata + data, (ic - data)); nad->ccur += (ic - data); /* append escaped & */ memcpy(nad->cdata + nad->ccur, "&", 5); nad->ccur += 5; /* just update and loop for more */ len -= (ic+1) - data; data = ic+1; } /* nothing exciting, just append normal cdata */ if(len > 0) { NAD_SAFE(nad->cdata, nad->ccur + len, nad->clen); memcpy(nad->cdata + nad->ccur, nad->cdata + data, len); nad->ccur += len; } }
/** insert part of a nad into another nad */ int nad_insert_nad(nad_t dest, int delem, nad_t src, int selem) { int nelem, first, i, j, ns, nattr, attr; char buri[256], *uri = buri, bprefix[256], *prefix = bprefix; _nad_ptr_check(__func__, dest); _nad_ptr_check(__func__, src); /* can't do anything if these aren't real elems */ if(src->ecur <= selem || dest->ecur <= delem) return -1; /* figure out how many elements to copy */ nelem = 1; while(selem + nelem < src->ecur && src->elems[selem + nelem].depth > src->elems[selem].depth) nelem++; /* make room */ NAD_SAFE(dest->elems, (dest->ecur + nelem) * sizeof(struct nad_elem_st), dest->elen); /* relocate all the elems after us */ memmove(&dest->elems[delem + nelem + 1], &dest->elems[delem + 1], (dest->ecur - delem - 1) * sizeof(struct nad_elem_st)); dest->ecur += nelem; /* relink parents on moved elements */ for(i = delem + nelem; i < dest->ecur; i++) if(dest->elems[i].parent > delem) dest->elems[i].parent += nelem; first = delem + 1; /* copy them in, one at a time */ for(i = 0; i < nelem; i++) { /* link the parent */ dest->elems[first + i].parent = delem + (src->elems[selem + i].parent - src->elems[selem].parent); /* depth */ dest->elems[first + i].depth = dest->elems[delem].depth + (src->elems[selem + i].depth - src->elems[selem].depth) + 1; /* name */ dest->elems[first + i].lname = src->elems[selem + i].lname; dest->elems[first + i].iname = _nad_cdata(dest, src->cdata + src->elems[selem + i].iname, src->elems[selem + i].lname); /* cdata */ dest->elems[first + i].lcdata = src->elems[selem + i].lcdata; dest->elems[first + i].icdata = _nad_cdata(dest, src->cdata + src->elems[selem + i].icdata, src->elems[selem + i].lcdata); dest->elems[first + i].ltail = src->elems[selem + i].ltail; dest->elems[first + i].itail = _nad_cdata(dest, src->cdata + src->elems[selem + i].itail, src->elems[selem + i].ltail); /* namespaces */ dest->elems[first + i].my_ns = dest->elems[first + i].ns = dest->scope = -1; /* first, the element namespace */ ns = src->elems[selem + i].my_ns; if(ns >= 0) { for(j = 0; j < dest->ncur; j++) if(NAD_NURI_L(src, ns) == NAD_NURI_L(dest, j) && strncmp(NAD_NURI(src, ns), NAD_NURI(dest, j), NAD_NURI_L(src, ns)) == 0) { dest->elems[first + i].my_ns = j; break; } /* not found, gotta add it */ if(j == dest->ncur) { /* make room */ /* !!! this can go once we have _ex() functions */ if(NAD_NURI_L(src, ns) > 255) uri = (char *) malloc(sizeof(char) * (NAD_NURI_L(src, ns) + 1)); if(NAD_NPREFIX_L(src, ns) > 255) prefix = (char *) malloc(sizeof(char) * (NAD_NURI_L(src, ns) + 1)); sprintf(uri, "%.*s", NAD_NURI_L(src, ns), NAD_NURI(src, ns)); if(NAD_NPREFIX_L(src, ns) > 0) { sprintf(prefix, "%.*s", NAD_NPREFIX_L(src, ns), NAD_NPREFIX(src, ns)); dest->elems[first + i].my_ns = nad_add_namespace(dest, uri, prefix); } else dest->elems[first + i].my_ns = nad_add_namespace(dest, uri, NULL); if(uri != buri) free(uri); if(prefix != bprefix) free(prefix); } } /* then, any declared namespaces */ for(ns = src->elems[selem + i].ns; ns >= 0; ns = src->nss[ns].next) { for(j = 0; j < dest->ncur; j++) if(NAD_NURI_L(src, ns) == NAD_NURI_L(dest, j) && strncmp(NAD_NURI(src, ns), NAD_NURI(dest, j), NAD_NURI_L(src, ns)) == 0) break; /* not found, gotta add it */ if(j == dest->ncur) { /* make room */ /* !!! this can go once we have _ex() functions */ if(NAD_NURI_L(src, ns) > 255) uri = (char *) malloc(sizeof(char) * (NAD_NURI_L(src, ns) + 1)); if(NAD_NPREFIX_L(src, ns) > 255) prefix = (char *) malloc(sizeof(char) * (NAD_NURI_L(src, ns) + 1)); sprintf(uri, "%.*s", NAD_NURI_L(src, ns), NAD_NURI(src, ns)); if(NAD_NPREFIX_L(src, ns) > 0) { sprintf(prefix, "%.*s", NAD_NPREFIX_L(src, ns), NAD_NPREFIX(src, ns)); nad_add_namespace(dest, uri, prefix); } else nad_add_namespace(dest, uri, NULL); if(uri != buri) free(uri); if(prefix != bprefix) free(prefix); } } /* scope any new namespaces onto this element */ dest->elems[first + i].ns = dest->scope; dest->scope = -1; /* attributes */ dest->elems[first + i].attr = -1; if(src->acur > 0) { nattr = 0; for(attr = src->elems[selem + i].attr; attr >= 0; attr = src->attrs[attr].next) nattr++; /* make room */ NAD_SAFE(dest->attrs, (dest->acur + nattr) * sizeof(struct nad_attr_st), dest->alen); /* kopy ker-azy! */ for(attr = src->elems[selem + i].attr; attr >= 0; attr = src->attrs[attr].next) { /* name */ dest->attrs[dest->acur].lname = src->attrs[attr].lname; dest->attrs[dest->acur].iname = _nad_cdata(dest, src->cdata + src->attrs[attr].iname, src->attrs[attr].lname); /* val */ dest->attrs[dest->acur].lval = src->attrs[attr].lval; dest->attrs[dest->acur].ival = _nad_cdata(dest, src->cdata + src->attrs[attr].ival, src->attrs[attr].lval); /* namespace */ dest->attrs[dest->acur].my_ns = -1; ns = src->attrs[attr].my_ns; if(ns >= 0) for(j = 0; j < dest->ncur; j++) if(NAD_NURI_L(src, ns) == NAD_NURI_L(dest, j) && strncmp(NAD_NURI(src, ns), NAD_NURI(dest, j), NAD_NURI_L(src, ns)) == 0) { dest->attrs[dest->acur].my_ns = j; break; } /* link it up */ dest->attrs[dest->acur].next = dest->elems[first + i].attr; dest->elems[first + i].attr = dest->acur; dest->acur++; } } } return first; }