📄 nad.c
字号:
}else{ 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); }}/** 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 = 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;}/** 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++; /* 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++; /* relink the parents */ nad->elems[elem].parent = nad->elems[elem + 1].parent; nad->elems[elem + 1].parent = elem;}/** 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;}/** attach new attr to the last elem */int nad_append_attr(nad_t nad, int ns, const char *name, const char *val){ _nad_ptr_check(__func__, nad); return _nad_attr(nad, nad->ecur - 1, ns, name, val, 0);}/** append new cdata to the last elem */void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth){ int elem = nad->ecur - 1; _nad_ptr_check(__func__, nad); /* make sure this cdata is the child of the last elem to append */ if(nad->elems[elem].depth == depth - 1) { if(nad->elems[elem].icdata == 0) nad->elems[elem].icdata = nad->ccur; _nad_cdata(nad,cdata,len); nad->elems[elem].lcdata += len; return; } /* otherwise, pin the cdata on the tail of the last element at this depth */ elem = nad->depths[depth]; if(nad->elems[elem].itail == 0) nad->elems[elem].itail = nad->ccur; _nad_cdata(nad,cdata,len); nad->elems[elem].ltail += len;}/** 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;}/** 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;}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 >= 3 && (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, 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; } /* check for ]]>, we need to escape the > */ while(flag >= 1 && (c = memchr(nad->cdata + data, '>', len)) != NULL) { /* check for the sequence */ if(c >= nad->cdata + 2 && c[-1] == ']' && c[-2] == ']') { 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; } /* otherwise, just plug the > in as-is */ else { ic = c - nad->cdata; _nad_escape(nad, data, ic - data, 0); NAD_SAFE(nad->cdata, nad->ccur + 1, nad->clen); *(nad->cdata + nad->ccur) = '>'; nad->ccur++; } /* 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 */ NAD_SAFE(nad->cdata, nad->ccur + len, nad->clen); memcpy(nad->cdata + nad->ccur, nad->cdata + data, len); nad->ccur += len;}/** internal recursive printing function */int _nad_lp0(nad_t nad, int elem){ int attr; int ndepth; int 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 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; /* 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++) = '\''; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -