⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml.c

📁 avi player 使用Linux下 GDK,GTK
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	return NULL;}char *iks_find_cdata(iks *x, const char *name){	iks *y;	y = iks_find(x, name);	if(!y) return(NULL);	y = y->children;	if(!y) return(NULL);	return y->cdata;}char *iks_find_attrib(iks *x, const char *name){	iks *y;	if(!x) return(NULL);	y = x->attribs;	while(y)	{		if(iks_strcmp(y->name, name) == 0) return(y->cdata);		y = y->next;	}	return NULL;}/*****  Node Information  *****/ikspool *iks_pool(iks *x){	if(x) return(x->p);	return NULL;}enum ikstype iks_type(iks *x){	if(x) return(x->type);	return IKS_NONE;}char *iks_name(iks *x){	if(x) return(x->name);	return NULL;}char *iks_cdata(iks *x){	if(x) return(x->cdata);	return NULL;}int iks_cdata_size(iks *x){	if(x) return(x->len);	return 0;}int iks_has_children(iks *x){	if(x && x->children) return(1);	return 0;}int iks_has_attribs(iks *x){	if(x && x->attribs) return(1);	return 0;}/*****  Special  *****/ikstr *iks_string(ikspool *p, iks *x){	ikstr *s;	int level=0, dir=0;	iks *y;	if(!x || x->type != IKS_TAG) return(NULL);	s = iks_str_new(p);	if(!s) return(NULL);	p = s->p;	while(1)	{		if(dir==0)		{			if(x->type == IKS_TAG)			{				iks *y;				iks_str_add(s, "<");				iks_str_add(s, x->name);				y = x->attribs;				while(y)				{					iks_spool(s, " ", y->name, "='", iks_escape(p, y->cdata, y->len), "'", s);					y = y->next;				}				if(x->children)				{					iks_str_add(s, ">");					x = x->children;					level++;					continue;				}				else					iks_str_add(s, "/>");			}			else				iks_str_add(s, iks_escape(p, x->cdata, x->len));		}		y = x->next;		if(!y)		{			x = x->parent;			level--;			if(level >= 0)			iks_spool(s, "</", x->name, ">", s);			if(level < 1) break;			dir = 1;		}		else		{			x = y;			dir = 0;		}	}	return s;}/*****  dom parsers  *****/static void dom_tstart(iksparser *prs, char *tag, char **atts);static void dom_tend(iksparser *prs, char *tag);static void hook_cdata(iksparser *prs, char *data, int len);iksparser *iks_sax_new(void *udata, iksTagStart *ts, iksTagEnd *te, iksCharData *cd){	iksparser *prs;	prs = malloc(sizeof(iksparser));	if(!prs) return(NULL);	memset(prs, 0, sizeof(iksparser));#ifdef USE_EXPAT	prs->expat = XML_ParserCreate(NULL);	if(!prs->expat)	{		free(prs);		return NULL;	}	XML_SetUserData(prs->expat, (void *)prs);	XML_SetElementHandler(prs->expat, (XML_StartElementHandler)ts, (XML_EndElementHandler)te);	XML_SetCharacterDataHandler(prs->expat, (XML_CharacterDataHandler)cd);#endif	prs->udata = udata;	prs->udata2 = udata;	prs->tagStart = ts;	prs->tagEnd = te;	prs->charData = cd;	return prs;}iksparser *iks_dom_new(iks **iksptr){	iksparser *prs;	prs = iks_sax_new(NULL, (iksTagStart *)dom_tstart, (iksTagEnd *)dom_tend, (iksCharData *)hook_cdata);	if(!prs) return(NULL);	prs->udata = prs;	prs->iksptr = iksptr;	return prs;}#ifdef USE_EXPATint iks_parse(iksparser *prs, char *data, int len, int finish){	if(XML_Parse(prs->expat, data, len, 0))		return IKS_RET_OK;	return IKS_RET_BADXML;}#endifvoid iks_parser_delete(iksparser *prs){#ifdef USE_EXPAT	XML_ParserFree(prs->expat);#endif	free(prs);}/*****  Internal Hooks  *****/static void insert_attribs(iksparser* p, iks *x, char **atts){	int i=0;	if(!x || !atts) return;	while(atts[i])	{		iks_insert_attrib(x, atts[i], atts[i+1]);		i += 2;	}}static void dom_tstart(iksparser *prs, char *tag, char **atts){	iks *x;	/* FIX ME: handle PIs in parser */	if(tag[0] == '?') return;	if(prs->current)		x = iks_insert(prs->current, tag);	else		x = iks_new(tag);	insert_attribs(prs, x, atts);	prs->current = x;}static void dom_tend(iksparser *prs, char *tag){	iks *x;	x = iks_parent(prs->current);	if(x)		prs->current = x;	else		*(prs->iksptr) = prs->current;}static void hook_cdata(iksparser *prs, char *data, int len){	if(prs->current)		iks_insert_cdata(prs->current, data, len);}/*****  sax parser  *****/enum contexts{	C_CDATA = 0,	C_TAG,	C_ATTRIBUTE,	C_VALUE,	C_WHITESPACE,	C_ENTITY,	C_COMMENT,	C_MARKUP,	C_PI};static int parse_xml(iksparser *prs, char *buf, int len);/* following function sucks, it is lame,** but as long as it works, i don't care** -madcat (ode to lazy coder) */int iks_parse(iksparser *prs, char *data, int len, int finish){	char *buf;	int diff;	if(!data || len == 0) return(IKS_RET_OK);	if(len == -1) len = strlen(data);	if(prs->buffer)	{		buf = malloc(prs->buflen + len);		if(!buf) return(IKS_RET_NOMEM);		memcpy(buf, prs->buffer, prs->buflen);		memcpy(buf + prs->buflen, data, len);		diff = (int)buf - (int)prs->buffer;		if(prs->tagname) prs->tagname += diff;		if(prs->atts)		{			int i = 0;			while(i < (prs->attmax * 2))			{				if(prs->atts[i]) prs->atts[i] += diff;				i++;			}		}		free(prs->buffer);		prs->buffer = buf;		buf += prs->buflen;		prs->buflen += len;	}	else	{		buf = malloc(len);		if(!buf) return(IKS_RET_NOMEM);		memcpy(buf, data, len);		prs->buffer = buf;		prs->buflen = len;	}	parse_xml(prs, buf, len);	return IKS_RET_OK;}static int parse_xml(iksparser *prs, char *buf, int len){	int pos = 0, old = 0;	while(pos < len)	{		switch(prs->context)		{		case C_CDATA:			if(buf[pos] == '&')			{				prs->context = C_ENTITY;				buf[pos] = '\0';				if(prs->charData) (prs->charData)(prs->udata, &buf[old], pos - old);				prs->entpos = 0;			}			if(buf[pos] == '<')			{				if(old < pos)				{					buf[pos] = '\0';					if(prs->charData) (prs->charData)(prs->udata, &buf[old], pos - old);					old = pos + 1;				}				prs->minpos = pos;				prs->oldcontext = C_CDATA;				prs->context = C_TAG;			}			break;		case C_TAG:			if(!prs->tagname)			{				prs->tagname = buf + pos;				if(buf[pos] == '/')				{					prs->tagflag = 2;					prs->tagname++;					break;				}			}			if(buf[pos] == ' ' || buf[pos] == '\t' || buf[pos] == '\r' || buf[pos] == '\n')			{				buf[pos] = '\0';				prs->oldcontext = C_ATTRIBUTE;				prs->context = C_WHITESPACE;				break;			}			if(buf[pos] == '/')			{				buf[pos] = '\0';				prs->tagflag = 1;			}			if(buf[pos] == '>')			{				buf[pos] = '\0';				if(prs->tagStart && prs->tagflag != 2) (prs->tagStart)(prs->udata, prs->tagname, NULL);				if(prs->tagEnd && prs->tagflag) (prs->tagEnd)(prs->udata, prs->tagname);				prs->tagname = NULL;				prs->tagflag = 0;				prs->context = C_CDATA;				old = pos + 1;				prs->minpos = -1;			}			break;		case C_ATTRIBUTE:			if(!prs->atts)			{				prs->attmax = 6;				prs->atts = malloc(sizeof(char *) * 2 * 6);				if(!prs->atts) return(0);				memset(prs->atts, 0, sizeof(char *) * 2 * 6);				prs->attcur = 0;			}			else			{				if(prs->attcur >= (prs->attmax * 2))				{					void *tmp;					prs->attmax += 4;					tmp = malloc(sizeof(char *) * 2 * prs->attmax);					if(!tmp) return(0);					memset(tmp, 0, sizeof(char *) * 2 * prs->attmax);					memcpy(tmp, prs->atts, sizeof(char *) * (prs->attcur - 1));					free(prs->atts);					prs->atts = tmp;				}			}			if(!prs->atts[prs->attcur])			{				prs->atts[prs->attcur] = buf + pos;			}			if(buf[pos] == '=')			{				buf[pos] = '\0';				prs->context = C_VALUE;				break;			}			if(buf[pos] == '/') prs->tagflag = 1;			if(buf[pos] == '>')			{				buf[pos] = '\0';				if(prs->atts) prs->atts[prs->attcur] = NULL;				if(prs->tagStart) (prs->tagStart)(prs->udata, prs->tagname, prs->atts);				free(prs->atts);				prs->atts = NULL;				prs->attcur = 0;				if(prs->tagEnd && prs->tagflag) (prs->tagEnd)(prs->udata, prs->tagname);				prs->tagname = NULL;				prs->tagflag = 0;				prs->context = C_CDATA;				old = pos + 1;			}			break;		case C_VALUE:			if(buf[pos] == '\'' || buf[pos] == '"')			{				buf[pos] = '\0';				if(prs->valflag)				{					prs->valflag = 0;					prs->oldcontext = C_ATTRIBUTE;					prs->context = C_WHITESPACE;					prs->attcur += 2;					break;				}				prs->valflag = 1;				prs->atts[prs->attcur + 1] = buf + pos + 1;			}			break;		case C_WHITESPACE:			if(buf[pos] != ' ' && buf[pos] != '\t' && buf[pos] != '\r' && buf[pos] != '\n')			{				prs->context = prs->oldcontext;				pos--;			}			break;		case C_ENTITY:			if(buf[pos] != ';')			{				prs->entity[prs->entpos++] = buf[pos];			}			else			{				char t = '?';				prs->entity[prs->entpos] = '\0';				if(strcmp(prs->entity, "amp") == 0)					t = '&';				else if(strcmp(prs->entity, "quot") == 0)					t = '"';				else if(strcmp(prs->entity, "apos") == 0)					t = '\'';				else if(strcmp(prs->entity, "lt") == 0)					t = '<';				else if(strcmp(prs->entity, "gt") == 0)					t = '>';				buf[pos] = t;				old = pos;				prs->context = C_CDATA;			}			break;		case C_COMMENT:		case C_MARKUP:		case C_PI:			break;		}		pos++;	}	if(prs->charData && prs->context == C_CDATA && old < pos)	{		(prs->charData)(prs->udata, &buf[old], pos - old);	}	return 1;}/*****  load&save  *****/iks *iks_load(char *fname){	iksparser *prs;	iks *x = NULL;	char *buf;	FILE *f;	int len, done = 0;	if(!fname) return(NULL);	buf = malloc(2048);	if(buf)	{		prs = iks_dom_new(&x);		if(prs)		{			f = fopen(fname, "r");			if(f)			{				while(!done)				{					len = fread(buf, 1, 2048, f);					if(len < 2048) done = 1;					iks_parse(prs, buf, len, done);				}				fclose(f);			}			iks_parser_delete(prs);		}		free(buf);	}	return x;}int iks_save(char *fname, iks *x){	FILE *f;	ikstr *s;	char *data;	int ret;	s = iks_string(NULL, x);	data = iks_str_print(s);	if(!data) return(0);	f = fopen(fname, "w");	if(!f)	{		iks_str_delete(s);		return 0;	}	ret = fputs(data, f);	iks_str_delete(s);	fclose(f);	if(ret < 0) return(0);	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -