Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
iksid *
iks_id_new (ikstack *s, const char *jid)
{
	iksid *id;
	char *src, *tmp;

/* FIXME: add jabber id validity checks to this function */
/* which characters are allowed in id parts? */

	if (!jid) return NULL;
	id = iks_stack_alloc (s, sizeof (iksid));
	if (!id) return NULL;
	memset (id, 0, sizeof (iksid));

	/* skip scheme */
	if (strncmp ("jabber:", jid, 7) == 0) jid += 7;

	id->full = iks_stack_strdup (s, jid, 0);
	src = id->full;

	/* split resource */
	tmp = strchr (src, '/');
	if (tmp) {
		id->partial = iks_stack_strdup (s, src, tmp - src);
		id->resource = tmp + 1;
		src = id->partial;
	} else {
		id->partial = src;
	}

	/* split user */
	tmp = strchr (src, '@');
	if (tmp) {
		id->user = iks_stack_strdup (s, src, tmp - src);
		src = ++tmp;
	}

	id->server = src;

	return id;
}
Пример #4
0
char *
iks_stack_strcat (ikstack *s, char *old, size_t old_len, const char *src, size_t src_len)
{
	char *ret;
	ikschunk *c;

	if (!old) {
		return iks_stack_strdup (s, src, src_len);
	}
	if (0 == old_len) old_len = strlen (old);
	if (0 == src_len) src_len = strlen (src);

	for (c = s->data; c; c = c->next) {
		if (c->data + c->last == old) break;
	}
	if (!c) {
		c = find_space (s, s->data, old_len + src_len + 1);
		if (!c) return NULL;
		ret = c->data + c->used;
		c->last = c->used;
		c->used += old_len + src_len + 1;
		memcpy (ret, old, old_len);
		memcpy (ret + old_len, src, src_len);
		ret[old_len + src_len] = '\0';
		return ret;
	}

	if (c->size - c->used > src_len) {
		ret = c->data + c->last;
		memcpy (ret + old_len, src, src_len);
		c->used += src_len;
		ret[old_len + src_len] = '\0';
	} else {
		/* FIXME: decrease c->used before moving string to new place */
		c = find_space (s, s->data, old_len + src_len + 1);
		if (!c) return NULL;
		c->last = c->used;
		ret = c->data + c->used;
		memcpy (ret, old, old_len);
		c->used += old_len;
		memcpy (c->data + c->used, src, src_len);
		c->used += src_len;
		c->data[c->used] = '\0';
		c->used++;
	}
	return ret;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
		void * Stack::strdupStack( Stack *stack, const string src, size_t len )
		{
			return iks_stack_strdup( stack->stack, src.c_str(), len );
		}
Пример #8
0
// Note that "s" may be NULL, in which case strings are not allocated
// from the stack, and in which case the caller is responsible for
// freeing any returned string.
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;
}