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

📄 iks.c

📁 linux平台或者windwos平台通用xml 解析器
💻 C
字号:
/* iksemel (XML parser for Jabber)** Copyright (C) 2000-2007 Gurer Ozen <madcat@e-kolay.net>** This code is free software; you can redistribute it and/or** modify it under the terms of GNU Lesser General Public License.*/#include "common.h"#include "iksemel.h"#define IKS_COMMON \	struct iks_struct *next, *prev; \	struct iks_struct *parent; \	enum ikstype type; \	ikstack *sstruct iks_struct {	IKS_COMMON;};struct iks_tag {	IKS_COMMON;	struct iks_struct *children, *last_child;	struct iks_struct *attribs, *last_attrib;	char *name;};#define IKS_TAG_NAME(x) ((struct iks_tag *) (x) )->name#define IKS_TAG_CHILDREN(x) ((struct iks_tag *) (x) )->children#define IKS_TAG_LAST_CHILD(x) ((struct iks_tag *) (x) )->last_child#define IKS_TAG_ATTRIBS(x) ((struct iks_tag *) (x) )->attribs#define IKS_TAG_LAST_ATTRIB(x) ((struct iks_tag *) (x) )->last_attribstruct iks_cdata {	IKS_COMMON;	char *cdata;	size_t len;};#define IKS_CDATA_CDATA(x) ((struct iks_cdata *) (x) )->cdata#define IKS_CDATA_LEN(x) ((struct iks_cdata *) (x) )->lenstruct iks_attrib {	IKS_COMMON;	char *name;	char *value;};#define IKS_ATTRIB_NAME(x) ((struct iks_attrib *) (x) )->name#define IKS_ATTRIB_VALUE(x) ((struct iks_attrib *) (x) )->value/*****  Node Creating & Deleting  *****/iks *iks_new (const char *name){	ikstack *s;	iks *x;	s = iks_stack_new (sizeof (struct iks_tag) * 6, 256);	if (!s) return NULL;	x = iks_new_within (name, s);	if (!x) {		iks_stack_delete (s);		return NULL;	}	return x;}iks *iks_new_within (const char *name, ikstack *s){	iks *x;	size_t len;	if (name) len = sizeof (struct iks_tag); else len = sizeof (struct iks_cdata);	x = iks_stack_alloc (s, len);	if (!x) return NULL;	memset (x, 0, len);	x->s = s;	x->type = IKS_TAG;	if (name) {		IKS_TAG_NAME (x) = iks_stack_strdup (s, name, 0);		if (!IKS_TAG_NAME (x)) return NULL;	}	return x;}iks *iks_insert (iks *x, const char *name){	iks *y;	if (!x) return NULL;	y = iks_new_within (name, x->s);	if (!y) return NULL;	y->parent = x;	if (!IKS_TAG_CHILDREN (x)) IKS_TAG_CHILDREN (x) = y;	if (IKS_TAG_LAST_CHILD (x)) {		IKS_TAG_LAST_CHILD (x)->next = y;		y->prev = IKS_TAG_LAST_CHILD (x);	}	IKS_TAG_LAST_CHILD (x) = y;	return y;}iks *iks_insert_cdata (iks *x, const char *data, size_t len){	iks *y;	if(!x || !data) return NULL;	if(len == 0) len = strlen (data);	y = IKS_TAG_LAST_CHILD (x);	if (y && y->type == IKS_CDATA) {		IKS_CDATA_CDATA (y) = iks_stack_strcat (x->s, IKS_CDATA_CDATA (y), IKS_CDATA_LEN (y), data, len);		IKS_CDATA_LEN (y) += len;	} else {		y = iks_insert (x, NULL);		if (!y) return NULL;		y->type = IKS_CDATA;		IKS_CDATA_CDATA (y) = iks_stack_strdup (x->s, data, len);		if (!IKS_CDATA_CDATA (y)) return NULL;		IKS_CDATA_LEN (y) = len;	}	return y;}iks *iks_insert_attrib (iks *x, const char *name, const char *value){	iks *y;	if (!x) return NULL;	y = IKS_TAG_ATTRIBS (x);	while (y) {		if (strcmp (name, IKS_ATTRIB_NAME (y)) == 0) break;		y = y->next;	}	if (NULL == y) {		if (!value) return NULL;		y = iks_stack_alloc (x->s, sizeof (struct iks_attrib));		if (!y) return NULL;		memset (y, 0, sizeof (struct iks_attrib));		y->type = IKS_ATTRIBUTE;		y->s = x->s;		IKS_ATTRIB_NAME (y) = iks_stack_strdup (x->s, name, 0);		if (!IKS_ATTRIB_NAME (y)) return NULL;		y->parent = x;		if (!IKS_TAG_ATTRIBS (x)) IKS_TAG_ATTRIBS (x) = y;		if (IKS_TAG_LAST_ATTRIB (x)) {			IKS_TAG_LAST_ATTRIB (x)->next = y;			y->prev = IKS_TAG_LAST_ATTRIB (x);		}		IKS_TAG_LAST_ATTRIB (x) = y;	}	if (value) {		IKS_ATTRIB_VALUE (y) = iks_stack_strdup (x->s, value, 0);		if (!IKS_ATTRIB_VALUE (y)) return NULL;	} else {		if (y->next) y->next->prev = y->prev;		if (y->prev) y->prev->next = y->next;		if (IKS_TAG_ATTRIBS (x) == y) IKS_TAG_ATTRIBS (x) = y->next;		if (IKS_TAG_LAST_ATTRIB (x) == y) IKS_TAG_LAST_ATTRIB (x) = y->prev;	}	return y;}iks *iks_insert_node (iks *x, iks *y){	y->parent = x;	if (!IKS_TAG_CHILDREN (x)) IKS_TAG_CHILDREN (x) = y;	if (IKS_TAG_LAST_CHILD (x)) {		IKS_TAG_LAST_CHILD (x)->next = y;		y->prev = IKS_TAG_LAST_CHILD (x);	}	IKS_TAG_LAST_CHILD (x) = y;	return y;}iks *iks_append (iks *x, const char *name){	iks *y;	if (!x) return NULL;	y = iks_new_within (name, x->s);	if (!y) return NULL;	if (x->next) {		x->next->prev = y;	} else {		IKS_TAG_LAST_CHILD (x->parent) = y;	}	y->next = x->next;	x->next = y;	y->parent = x->parent;	y->prev = x;	return y;}iks *iks_prepend (iks *x, const char *name){	iks *y;	if (!x) return NULL;	y = iks_new_within (name, x->s);	if (!y) return NULL;	if (x->prev) {		x->prev->next = y;	} else {		IKS_TAG_CHILDREN (x->parent) = y;	}	y->prev = x->prev;	x->prev = y;	y->parent = x->parent;	y->next = x;	return y;}iks *iks_append_cdata (iks *x, const char *data, size_t len){	iks *y;	if (!x || !data) return NULL;	if (len == 0) len = strlen (data);	y = iks_new_within (NULL, x->s);	if (!y) return NULL;	y->type = IKS_CDATA;	IKS_CDATA_CDATA (y) = iks_stack_strdup (x->s, data, len);	if (!IKS_CDATA_CDATA (y)) return NULL;	IKS_CDATA_LEN (y) = len;	if (x->next) {		x->next->prev = y;	} else {		IKS_TAG_LAST_CHILD (x->parent) = y;	}	y->next = x->next;	x->next = y;	y->parent = x->parent;	y->prev = x;	return y;}iks *iks_prepend_cdata (iks *x, const char *data, size_t len){	iks *y;	if (!x || !data) return NULL;	if (len == 0) len = strlen (data);	y = iks_new_within (NULL, x->s);	if (!y) return NULL;	y->type = IKS_CDATA;	IKS_CDATA_CDATA(y) = iks_stack_strdup (x->s, data, len);	if (!IKS_CDATA_CDATA (y)) return NULL;	IKS_CDATA_LEN (y) = len;	if (x->prev) {		x->prev->next = y;	} else {		IKS_TAG_CHILDREN (x->parent) = y;	}	y->prev = x->prev;	x->prev = y;	y->parent = x->parent;	y->next = x;	return y;}voidiks_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 (IKS_TAG_CHILDREN (y) == x) IKS_TAG_CHILDREN (y) = x->next;		if (IKS_TAG_LAST_CHILD (y) == x) IKS_TAG_LAST_CHILD (y) = x->prev;	}}voidiks_delete (iks *x){	if (x) iks_stack_delete (x->s);}/*****  Node Traversing  *****/iks *iks_next (iks *x){	if (x) return x->next;	return NULL;}iks *iks_next_tag (iks *x){	if (x) {		while (1) {			x = x->next;			if (NULL == x) break;			if (IKS_TAG == x->type) return x;		}	}	return NULL;}iks *iks_prev (iks *x){	if (x) return x->prev;	return NULL;}iks *iks_prev_tag (iks *x){	if (x) {		while (1) {			x = x->prev;			if (NULL == x) break;			if (IKS_TAG == x->type) return x;		}	}	return NULL;}iks *iks_parent (iks *x){	if (x) return x->parent;	return NULL;}iks *iks_root (iks *x){	if (x) {		while (x->parent)			x = x->parent;	}	return x;}iks *iks_child (iks *x){	if (x && IKS_TAG == x->type) return IKS_TAG_CHILDREN (x);	return NULL;}iks *iks_first_tag (iks *x){	if (x) {		x = IKS_TAG_CHILDREN (x);		while (x) {			if (IKS_TAG == x->type) return x;			x = x->next;		}	}	return NULL;}iks *iks_attrib (iks *x){	if (x) return IKS_TAG_ATTRIBS (x);	return NULL;}iks *iks_find (iks *x, const char *name){	iks *y;	if (!x) return NULL;	y = IKS_TAG_CHILDREN (x);	while (y) {		if (IKS_TAG == y->type && IKS_TAG_NAME (y) && strcmp (IKS_TAG_NAME (y), name) == 0) return y;		y = y->next;	}	return NULL;}char *iks_find_cdata (iks *x, const char *name){	iks *y;	y = iks_find (x, name);	if (!y) return NULL;	y = IKS_TAG_CHILDREN (y);	if (!y || IKS_CDATA != y->type) return NULL;	return IKS_CDATA_CDATA (y);}char *iks_find_attrib (iks *x, const char *name){	iks *y;	if (!x) return NULL;	y = IKS_TAG_ATTRIBS (x);	while (y) {		if (IKS_ATTRIB_NAME (y) && strcmp (IKS_ATTRIB_NAME (y), name) == 0)			return IKS_ATTRIB_VALUE (y);		y = y->next;	}	return NULL;}iks *iks_find_with_attrib (iks *x, const char *tagname, const char *attrname, const char *value){	iks *y;	if (NULL == x) return NULL;	if (tagname) {		for (y = IKS_TAG_CHILDREN (x); y; y = y->next) {			if (IKS_TAG == y->type				&& strcmp (IKS_TAG_NAME (y), tagname) == 0				&& iks_strcmp (iks_find_attrib (y, attrname), value) == 0) {					return y;			}		}	} else {		for (y = IKS_TAG_CHILDREN (x); y; y = y->next) {			if (IKS_TAG == y->type				&& iks_strcmp (iks_find_attrib (y, attrname), value) == 0) {					return y;			}		}	}	return NULL;}/*****  Node Information  *****/ikstack *iks_stack (iks *x){	if (x) return x->s;	return NULL;}enum ikstypeiks_type (iks *x){	if (x) return x->type;	return IKS_NONE;}char *iks_name (iks *x){	if (x) {		if (IKS_TAG == x->type)			return IKS_TAG_NAME (x);		else			return IKS_ATTRIB_NAME (x);	}	return NULL;}char *iks_cdata (iks *x){	if (x) {		if (IKS_CDATA == x->type)			return IKS_CDATA_CDATA (x);		else			return IKS_ATTRIB_VALUE (x);	}	return NULL;}size_tiks_cdata_size (iks *x){	if (x) return IKS_CDATA_LEN (x);	return 0;}intiks_has_children (iks *x){	if (x && IKS_TAG == x->type && IKS_TAG_CHILDREN (x)) return 1;	return 0;}intiks_has_attribs (iks *x){	if (x && IKS_TAG == x->type && IKS_TAG_ATTRIBS (x)) return 1;	return 0;}/*****  Serializing  *****/static size_tescape_size (char *src, size_t len){	size_t sz;	char c;	int i;	sz = 0;	for (i = 0; i < len; i++) {		c = src[i];		switch (c) {			case '&': sz += 5; break;			case '\'': sz += 6; break;			case '"': sz += 6; break;			case '<': sz += 4; break;			case '>': sz += 4; break;			default: sz++; break;		}	}	return sz;}static char *my_strcat (char *dest, char *src, size_t len){	if (0 == len) len = strlen (src);	memcpy (dest, src, len);	return dest + len;}static char *escape (char *dest, char *src, size_t len){	char c;	int i;	int j = 0;	for (i = 0; i < len; i++) {		c = src[i];		if ('&' == c || '<' == c || '>' == c || '\'' == c || '"' == c) {			if (i - j > 0) dest = my_strcat (dest, src + j, i - j);			j = i + 1;			switch (c) {			case '&': dest = my_strcat (dest, "&amp;", 5); break;			case '\'': dest = my_strcat (dest, "&apos;", 6); break;			case '"': dest = my_strcat (dest, "&quot;", 6); break;			case '<': dest = my_strcat (dest, "&lt;", 4); break;			case '>': dest = my_strcat (dest, "&gt;", 4); break;			}		}	}	if (i - j > 0) dest = my_strcat (dest, src + j, i - j);	return dest;}char *iks_string (ikstack *s, iks *x){	size_t size;	int level, dir;	iks *y, *z;	char *ret, *t;	if (!x) return NULL;	if (x->type == IKS_CDATA) {		if (s) {			return iks_stack_strdup (s, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x));		} else {			ret = iks_malloc (IKS_CDATA_LEN (x));			memcpy (ret, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x));			return ret;		}	}	size = 0;	level = 0;	dir = 0;	y = x;	while (1) {		if (dir==0) {			if (y->type == IKS_TAG) {				size++;				size += strlen (IKS_TAG_NAME (y));				for (z = IKS_TAG_ATTRIBS (y); z; z = z->next) {					size += 4 + strlen (IKS_ATTRIB_NAME (z))						+ escape_size (IKS_ATTRIB_VALUE (z), strlen (IKS_ATTRIB_VALUE (z)));				}				if (IKS_TAG_CHILDREN (y)) {					size++;					y = IKS_TAG_CHILDREN (y);					level++;					continue;				} else {					size += 2;				}			} else {				size += escape_size (IKS_CDATA_CDATA (y), IKS_CDATA_LEN (y));			}		}		z = y->next;		if (z) {			if (0 == level) {				if (IKS_TAG_CHILDREN (y)) size += 3 + strlen (IKS_TAG_NAME (y));				break;			}			y = z;			dir = 0;		} else {			y = y->parent;			level--;			if (level >= 0) size += 3 + strlen (IKS_TAG_NAME (y));			if (level < 1) break;			dir = 1;		}	}	if (s) ret = iks_stack_alloc (s, size + 1);	else ret = iks_malloc (size + 1);	if (!ret) return NULL;	t = ret;	level = 0;	dir = 0;	while (1) {		if (dir==0) {			if (x->type == IKS_TAG) {				*t++ = '<';				t = my_strcat (t, IKS_TAG_NAME (x), 0);				y = IKS_TAG_ATTRIBS (x);				while (y) {					*t++ = ' ';					t = my_strcat (t, IKS_ATTRIB_NAME (y), 0);					*t++ = '=';					*t++ = '\'';					t = escape (t, IKS_ATTRIB_VALUE (y), strlen (IKS_ATTRIB_VALUE (y)));					*t++ = '\'';					y = y->next;				}				if (IKS_TAG_CHILDREN (x)) {					*t++ = '>';					x = IKS_TAG_CHILDREN (x);					level++;					continue;				} else {					*t++ = '/';					*t++ = '>';				}			} else {				t = escape (t, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x));			}		}		y = x->next;		if (y) {			if (0 == level) {				if (IKS_TAG_CHILDREN (x)) {					*t++ = '<';					*t++ = '/';					t = my_strcat (t, IKS_TAG_NAME (x), 0);					*t++ = '>';				}				break;			}			x = y;			dir = 0;		} else {			x = x->parent;			level--;			if (level >= 0) {					*t++ = '<';					*t++ = '/';					t = my_strcat (t, IKS_TAG_NAME (x), 0);					*t++ = '>';				}			if (level < 1) break;			dir = 1;		}	}	*t = '\0';	return ret;}/*****  Copying  *****/iks *iks_copy_within (iks *x, ikstack *s){	int level=0, dir=0;	iks *copy = NULL;	iks *cur = NULL;	iks *y;	while (1) {		if (dir == 0) {			if (x->type == IKS_TAG) {				if (copy == NULL) {					copy = iks_new_within (IKS_TAG_NAME (x), s);					cur = copy;				} else {					cur = iks_insert (cur, IKS_TAG_NAME (x));				}				for (y = IKS_TAG_ATTRIBS (x); y; y = y->next) {					iks_insert_attrib (cur, IKS_ATTRIB_NAME (y), IKS_ATTRIB_VALUE (y));				}				if (IKS_TAG_CHILDREN (x)) {					x = IKS_TAG_CHILDREN (x);					level++;					continue;				} else {					cur = cur->parent;				}			} else {				iks_insert_cdata (cur, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x));			}		}		y = x->next;		if (y) {			if (0 == level) break;			x = y;			dir = 0;		} else {			if (level < 2) break;			level--;			x = x->parent;			cur = cur->parent;			dir = 1;		}	}	return copy;}iks *iks_copy (iks *x){	return iks_copy_within (x, iks_stack_new (sizeof (struct iks_tag) * 6, 256));}

⌨️ 快捷键说明

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