📄 xml.c
字号:
/*** iksemel (XML Parser for Jabber)** Copyright (C) 2000-2001 Gurer Ozen <palpa@jabber.org>**** This code is free software; you can redistribute it and/or** modify it under the terms of GNU Lesser General Public License.**** library API*/#include "common.h"/***** Memory Pools *****/ikspool *iks_pool_new(int pagesize){ ikspool *p; p = malloc(sizeof(ikspool)); if(!p) return(NULL); p->data = malloc(pagesize); if(!p->data) { free(p); return(NULL); } p->next = NULL; p->max = pagesize; p->len = 0; return p;}void *iks_pool_alloc(ikspool *p, int size){ void *mem; int i; i = size & 8; if(i) size += (8 - i); i = p->max; if(size > i) { while(p->next) p=p->next; p->next = iks_pool_new(size); p = p->next; if(!p) return(NULL); p->len = size; return p->data; } while(p) { if((p->max - p->len) >= size) { mem = p->data + p->len; p->len += size; return mem; } if(p->next) p = p->next; else p->next = iks_pool_new(i); } return NULL;}char *iks_pool_strdup(ikspool *p, const char *src){ char *dest; int len; if(!src) return(NULL); len = strlen(src); if(len == 0) return(NULL); dest = iks_pool_alloc(p, len + 1); if(!dest) return(NULL); memcpy(dest, src, len); dest[len] = '\0'; return dest;}void iks_pool_delete(ikspool *p){ ikspool *tmp; tmp = p; while(tmp) { tmp = p->next; free(p->data); free(p); p = tmp; }}/***** NULL-safe Functions *****/char *iks_strdup(const char *src){ if(src) return(strdup(src)); return NULL;}char *iks_strcat(char *dest, const char *src){ if(!src) return(dest); while(*src) *dest++ = *src++; *dest = '\0'; return dest;}int iks_strcmp(const char *a, const char *b){ if(!a || !b) return(-1); return strcmp(a, b);}int iks_strcasecmp(const char *a, const char *b){ if(!a || !b) return(-1); return strcasecmp(a, b);}int iks_strncmp(const char *a, const char *b, int n){ if(!a || !b) return(-1); return strncmp(a, b, n);}int iks_strncasecmp(const char *a, const char *b, int n){ if(!a || !b) return(-1); return strncasecmp(a, b, n);}int iks_strlen(const char *src){ if(!src) return(0); return (int)strlen(src);}/***** String Stuff *****/ikstr *iks_str_new(ikspool *p){ ikstr *s; int flag = 0; if(!p) { p = iks_pool_new(512); if(!p) return(NULL); flag = 1; } s = iks_pool_alloc(p, sizeof(ikstr)); if(!s) { if(flag) iks_pool_delete(p); return NULL; } s->p = p; s->flag = flag; s->len = 0; s->first = NULL; s->last = NULL; return s;}void iks_str_add(ikstr *s, char *src){ struct ikstrnode *sn; int len; if(!s || !src) return; len = strlen(src); if(len == 0) return; sn = iks_pool_alloc(s->p, sizeof(struct ikstrnode)); if(!sn) return; sn->data = iks_pool_alloc(s->p, len); if(!sn->data) return; memcpy(sn->data, src, len); sn->len = len; s->len += len; sn->next = NULL; if(!s->first) s->first = sn; if(s->last) s->last->next = sn; s->last = sn;}void iks_spool(ikstr *s, ...){ va_list ap; char *arg; va_start(ap, s); while(1) { arg = va_arg(ap, char *); if(((void *)arg) == ((void *)s)) break; iks_str_add(s, arg); } va_end(ap);}char *iks_str_print(ikstr *s){ char *ret, *tmp; struct ikstrnode *sn; if(!s || !s->first) return(NULL); ret = iks_pool_alloc(s->p, s->len + 1); sn = s->first; tmp = ret; while(sn) { memcpy(tmp, sn->data, sn->len); tmp += sn->len; sn = sn->next; } *tmp = '\0'; return ret;}void iks_str_delete(ikstr *s){ if(s->flag) iks_pool_delete(s->p);}/***** XML Escaping *****/char *iks_escape(ikspool *p, char *src, int len){ char *ret; int i, j, nlen; if(!src || !p) return(NULL); if(len == -1) len = strlen(src); nlen = len; for(i=0; i<len; i++) { switch(src[i]) { case '&': nlen += 4; break; case '<': nlen += 3; break; case '>': nlen += 3; break; case '\'': nlen += 5; break; case '"': nlen += 5; break; } } if(len == nlen) return(src); ret = iks_pool_alloc(p, nlen + 1); if(!ret) return(NULL); for(i=j=0; i<len; i++) { switch(src[i]) { case '&': memcpy(&ret[j], "&", 5); j += 5; break; case '\'': memcpy(&ret[j], "'", 6); j += 6; break; case '"': memcpy(&ret[j], """, 6); j += 6; break; case '<': memcpy(&ret[j], "<", 4); j += 4; break; case '>': memcpy(&ret[j], ">", 4); j += 4; break; default: ret[j++] = src[i]; } } ret[j] = '\0'; return ret;}char *iks_unescape(ikspool *p, char *src, int len){ int i,j; char *ret; if(!p || !src) return(NULL); if(!strchr(src, '&')) return(src); if(len == -1) len = strlen(src); ret = iks_pool_alloc(p, len + 1); if(!ret) return(NULL); for(i=j=0; i<len; i++) { if(src[i] == '&') { i++; if(strncmp(&src[i], "amp;", 4) == 0) { ret[j] = '&'; i += 3; } else if(strncmp(&src[i], "quot;", 5) == 0) { ret[j] = '"'; i += 4; } else if(strncmp(&src[i], "apos;", 5) == 0) { ret[j] = '\''; i += 4; } else if(strncmp(&src[i], "lt;", 3) == 0) { ret[j] = '<'; i += 2; } else if(strncmp(&src[i], "gt;", 3) == 0) { ret[j] = '>'; i += 2; } else { ret[j] = src[--i]; } } else { ret[j] = src[i]; } j++; } ret[j] = '\0'; return ret;}/***** Node Creating & Deleting *****/iks *iks_new(const char *name){ ikspool *p; iks *x; p = iks_pool_new(1024); if(!p) return(NULL); x = iks_new_pool(p, name); if(!x) { iks_pool_delete(p); return NULL; } return x;}iks *iks_new_pool(ikspool *p, const char *name){ iks *x; x = iks_pool_alloc(p, sizeof(iks)); if(!x) return(NULL); memset(x, 0, sizeof(iks)); x->p = p; x->type = IKS_TAG; if(name) { x->name = iks_pool_strdup(p, name); if(!x->name) return(NULL); } return x;}iks *iks_insert(iks *x, const char *name){ iks *y; if(!x) return(NULL); y = iks_new_pool(x->p, name); if(!y) return(NULL); y->parent = x; if(!x->children) x->children=y; if(x->lastchild) { x->lastchild->next = y; y->prev = x->lastchild; } x->lastchild = y; return y;}iks *iks_insert_cdata(iks *x, const char *data, int len){ iks *y; if(!x || !data) return(NULL); if(len == -1) len = strlen(data); y = x->lastchild; if(y && y->type == IKS_CDATA) { char *tmp; tmp = iks_pool_alloc(x->p, y->len + len + 1); if(!tmp) return(NULL); memcpy(tmp, y->cdata, y->len); memcpy(tmp + y->len, data, len); tmp[y->len + len] = '\0'; y->cdata = tmp; y->len += len; } else { y = iks_insert(x, NULL); if(!y) return(NULL); y->type = IKS_CDATA; y->cdata = iks_pool_alloc(x->p, len + 1); if(!y->cdata) return(NULL); memcpy(y->cdata, data, len); y->cdata[len] = '\0'; y->len = len; } return y;}iks *iks_insert_attrib(iks *x, const char *name, const char *value){ iks *y; int len; if(!x || !name || !value) return(NULL); y = iks_new_pool(x->p, name); if(!y) return(NULL); len = strlen(value); y->type = IKS_ATTRIBUTE; y->cdata = iks_pool_alloc(x->p, len + 1); if(!y->cdata) return(NULL); memcpy(y->cdata, value, len); *(y->cdata + len) = '\0'; y->len = len; y->parent = x; if(!x->attribs) x->attribs = y; if(x->lastattrib) { x->lastattrib->next = y; y->prev = x->lastattrib; } x->lastattrib = y; return y;}iks *iks_insert_node(iks *x, iks *y){ y->parent = x; if(!x->children) x->children=y; if(x->lastchild) { x->lastchild->next = y; y->prev = x->lastchild; } x->lastchild = y; return y;}void iks_hide(iks *x){ iks *y; if(!x) return; if(x->prev) x->prev->next = x->next; if(x->next) x->next->prev = x->prev; y = x->parent; if(y) { if(y->children == x) y->children = x->next; if(y->lastchild == x) y->lastchild = x->prev; }}void iks_delete(iks *x){ if(x) iks_pool_delete(x->p);}/***** Node Traversing *****/iks *iks_next(iks *x){ if(x) return(x->next); return NULL;}iks *iks_prev(iks *x){ if(x) return(x->prev); return NULL;}iks *iks_parent(iks *x){ if(x) return(x->parent); return NULL;}iks *iks_child(iks *x){ if(x) return(x->children); return NULL;}iks *iks_attrib(iks *x){ if(x) return(x->attribs); return NULL;}iks *iks_find(iks *x, const char *name){ iks *y; if(!x) return(NULL); /* FIX ME: for advanced searchs */ y = x->children; while(y) { if(y->name && strcmp(y->name, name) == 0) return(y); y = y->next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -