Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/impress/iksemel.c
diff options
context:
space:
mode:
Diffstat (limited to 'impress/iksemel.c')
-rw-r--r--impress/iksemel.c1881
1 files changed, 0 insertions, 1881 deletions
diff --git a/impress/iksemel.c b/impress/iksemel.c
deleted file mode 100644
index 6d24d43..0000000
--- a/impress/iksemel.c
+++ /dev/null
@@ -1,1881 +0,0 @@
-/* iksemel (XML parser for Jabber)
-** Copyright (C) 2000-2003 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.
-*/
-
-/* minimum sax buffer size */
-#define SAX_BUFFER_MIN_SIZE 128
-
-/* sax parser structure plus extra data of dom parser */
-#define DEFAULT_DOM_CHUNK_SIZE 256
-
-/* sax parser structure plus extra data of stream parser */
-#define DEFAULT_STREAM_CHUNK_SIZE 256
-
-/* iks structure, its data, child iks structures, for stream parsing */
-#define DEFAULT_IKS_CHUNK_SIZE 1024
-
-/* iks structure, its data, child iks structures, for file parsing */
-#define DEFAULT_DOM_IKS_CHUNK_SIZE 2048
-
-/* rule structure and from/to/id/ns strings */
-#define DEFAULT_RULE_CHUNK_SIZE 128
-
-/* file is read by blocks with this size */
-#define FILE_IO_BUF_SIZE 4096
-
-/* network receive buffer */
-#define NET_IO_BUF_SIZE 4096
-/* iksemel (XML parser for Jabber)
-** Copyright (C) 2000-2003 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 <errno.h>
-
-#include "common.h"
-#include "iksemel.h"
-
-/***** malloc wrapper *****/
-
-static void *(*my_malloc_func)(size_t size);
-static void (*my_free_func)(void *ptr);
-
-void *
-iks_malloc (size_t size)
-{
- if (my_malloc_func)
- return my_malloc_func (size);
- else
- return malloc (size);
-}
-
-void
-iks_free (void *ptr)
-{
- if (my_free_func)
- my_free_func (ptr);
- else
- free (ptr);
-}
-
-void
-iks_set_mem_funcs (void *(*malloc_func)(size_t size), void (*free_func)(void *ptr))
-{
- my_malloc_func = malloc_func;
- my_free_func = free_func;
-}
-
-/***** NULL-safe Functions *****/
-
-char *
-iks_strdup (const char *src)
-{
- if (src) return strdup(src);
- return NULL;
-}
-
-char *
-iks_strcat (char *dest, const char *src)
-{
- size_t len;
-
- if (!src) return dest;
-
- len = strlen (src);
- memcpy (dest, src, len);
- dest[len] = '\0';
- return dest + len;
-}
-
-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, size_t n)
-{
- if (!a || !b) return -1;
- return strncmp (a, b, n);
-}
-
-int
-iks_strncasecmp (const char *a, const char *b, size_t n)
-{
- if (!a || !b) return -1;
- return strncasecmp (a, b, n);
-}
-
-size_t
-iks_strlen (const char *src)
-{
- if (!src) return 0;
- return strlen (src);
-}
-
-/***** XML Escaping *****/
-
-char *
-iks_escape (ikstack *s, char *src, size_t len)
-{
- char *ret;
- int i, j, nlen;
-
- if (!src || !s) 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_stack_alloc (s, nlen + 1);
- if (!ret) return NULL;
-
- for (i=j=0; i<len; i++) {
- switch (src[i]) {
- case '&': memcpy (&ret[j], "&amp;", 5); j += 5; break;
- case '\'': memcpy (&ret[j], "&apos;", 6); j += 6; break;
- case '"': memcpy (&ret[j], "&quot;", 6); j += 6; break;
- case '<': memcpy (&ret[j], "&lt;", 4); j += 4; break;
- case '>': memcpy (&ret[j], "&gt;", 4); j += 4; break;
- default: ret[j++] = src[i];
- }
- }
- ret[j] = '\0';
-
- return ret;
-}
-
-char *
-iks_unescape (ikstack *s, char *src, size_t len)
-{
- int i,j;
- char *ret;
-
- if (!s || !src) return NULL;
- if (!strchr (src, '&')) return src;
- if (len == -1) len = strlen (src);
-
- ret = iks_stack_alloc (s, 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;
-}
-/* iksemel (XML parser for Jabber)
-** Copyright (C) 2000-2004 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"
-
-struct align_test { char a; double b; };
-#define DEFAULT_ALIGNMENT ((size_t) ((char *) &((struct align_test *) 0)->b - (char *) 0))
-#define ALIGN_MASK ( DEFAULT_ALIGNMENT - 1 )
-#define MIN_CHUNK_SIZE ( DEFAULT_ALIGNMENT * 8 )
-#define MIN_ALLOC_SIZE DEFAULT_ALIGNMENT
-#define ALIGN(x) ( (x) + (DEFAULT_ALIGNMENT - ( (x) & ALIGN_MASK)) )
-
-typedef struct ikschunk_struct {
- struct ikschunk_struct *next;
- size_t size;
- size_t used;
- size_t last;
- char data[4];
-} ikschunk;
-
-struct ikstack_struct {
- size_t allocated;
- ikschunk *meta;
- ikschunk *data;
-};
-
-static ikschunk *
-find_space (ikstack *s, ikschunk *c, size_t size)
-{
- /* FIXME: dont use *2 after over allocated chunks */
- while (1) {
- if (c->size - c->used >= size) return c;
- if (!c->next) {
- if ((c->size * 2) > size) size = c->size * 2;
- c->next = iks_malloc (sizeof (ikschunk) + size);
- if (!c->next) return NULL;
- s->allocated += sizeof (ikschunk) + size;
- c = c->next;
- c->next = NULL;
- c->size = size;
- c->used = 0;
- c->last = (size_t) -1;
- return c;
- }
- c = c->next;
- }
- return NULL;
-}
-
-ikstack *
-iks_stack_new (size_t meta_chunk, size_t data_chunk)
-{
- ikstack *s;
- size_t len;
-
- if (meta_chunk < MIN_CHUNK_SIZE) meta_chunk = MIN_CHUNK_SIZE;
- if (meta_chunk & ALIGN_MASK) meta_chunk = ALIGN (meta_chunk);
- if (data_chunk < MIN_CHUNK_SIZE) data_chunk = MIN_CHUNK_SIZE;
- if (data_chunk & ALIGN_MASK) data_chunk = ALIGN (data_chunk);
-
- len = sizeof (ikstack) + meta_chunk + data_chunk + (sizeof (ikschunk) * 2);
- s = iks_malloc (len);
- if (!s) return NULL;
- s->allocated = len;
- s->meta = (ikschunk *) ((char *) s + sizeof (ikstack));
- s->meta->next = NULL;
- s->meta->size = meta_chunk;
- s->meta->used = 0;
- s->meta->last = (size_t) -1;
- s->data = (ikschunk *) ((char *) s + sizeof (ikstack) + sizeof (ikschunk) + meta_chunk);
- s->data->next = NULL;
- s->data->size = data_chunk;
- s->data->used = 0;
- s->data->last = (size_t) -1;
- return s;
-}
-
-void *
-iks_stack_alloc (ikstack *s, size_t size)
-{
- ikschunk *c;
- void *mem;
-
- if (size < MIN_ALLOC_SIZE) size = MIN_ALLOC_SIZE;
- if (size & ALIGN_MASK) size = ALIGN (size);
-
- c = find_space (s, s->meta, size);
- if (!c) return NULL;
- mem = c->data + c->used;
- c->used += size;
- return mem;
-}
-
-char *
-iks_stack_strdup (ikstack *s, const char *src, size_t len)
-{
- ikschunk *c;
- char *dest;
-
- if (!src) return NULL;
- if (0 == len) len = strlen (src);
-
- c = find_space (s, s->data, len + 1);
- if (!c) return NULL;
- dest = c->data + c->used;
- c->last = c->used;
- c->used += len + 1;
- memcpy (dest, src, len);
- dest[len] = '\0';
- return dest;
-}
-
-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;
-}
-
-void
-iks_stack_stat (ikstack *s, size_t *allocated, size_t *used)
-{
- ikschunk *c;
-
- if (allocated) {
- *allocated = s->allocated;
- }
- if (used) {
- *used = 0;
- for (c = s->meta; c; c = c->next) {
- (*used) += c->used;
- }
- for (c = s->data; c; c = c->next) {
- (*used) += c->used;
- }
- }
-}
-
-void
-iks_stack_delete (ikstack *s)
-{
- ikschunk *c, *tmp;
-
- c = s->meta->next;
- while (c) {
- tmp = c->next;
- iks_free (c);
- c = tmp;
- }
- c = s->data->next;
- while (c) {
- tmp = c->next;
- iks_free (c);
- c = tmp;
- }
- iks_free (s);
-}
-/* iksemel (XML parser for Jabber)
-** Copyright (C) 2000-2004 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"
-
-enum cons_e {
- C_CDATA = 0,
- C_TAG_START,
- C_TAG,
- C_TAG_END,
- C_ATTRIBUTE,
- C_ATTRIBUTE_1,
- C_ATTRIBUTE_2,
- C_VALUE,
- C_VALUE_APOS,
- C_VALUE_QUOT,
- C_WHITESPACE,
- C_ENTITY,
- C_COMMENT,
- C_COMMENT_1,
- C_COMMENT_2,
- C_COMMENT_3,
- C_MARKUP,
- C_MARKUP_1,
- C_SECT,
- C_SECT_CDATA,
- C_SECT_CDATA_1,
- C_SECT_CDATA_2,
- C_SECT_CDATA_3,
- C_SECT_CDATA_4,
- C_SECT_CDATA_C,
- C_SECT_CDATA_E,
- C_SECT_CDATA_E2,
- C_PI
-};
-
-/* if you add a variable here, dont forget changing iks_parser_reset */
-struct iksparser_struct {
- ikstack *s;
- void *user_data;
- iksTagHook *tagHook;
- iksCDataHook *cdataHook;
- iksDeleteHook *deleteHook;
- /* parser context */
- char *stack;
- size_t stack_pos;
- size_t stack_max;
-
- enum cons_e context;
- enum cons_e oldcontext;
-
- char *tag_name;
- enum ikstagtype tagtype;
-
- unsigned int attmax;
- unsigned int attcur;
- int attflag;
- char **atts;
- int valflag;
-
- unsigned int entpos;
- char entity[8];
-
- unsigned long nr_bytes;
- unsigned long nr_lines;
-
- int uni_max;
- int uni_len;
-};
-
-iksparser *
-iks_sax_new (void *user_data, iksTagHook *tagHook, iksCDataHook *cdataHook)
-{
- iksparser *prs;
-
- prs = iks_malloc (sizeof (iksparser));
- if (NULL == prs) return NULL;
- memset (prs, 0, sizeof (iksparser));
- prs->user_data = user_data;
- prs->tagHook = tagHook;
- prs->cdataHook = cdataHook;
- return prs;
-}
-
-iksparser *
-iks_sax_extend (ikstack *s, void *user_data, iksTagHook *tagHook, iksCDataHook *cdataHook, iksDeleteHook *deleteHook)
-{
- iksparser *prs;
-
- prs = iks_stack_alloc (s, sizeof (iksparser));
- if (NULL == prs) return NULL;
- memset (prs, 0, sizeof (iksparser));
- prs->s = s;
- prs->user_data = user_data;
- prs->tagHook = tagHook;
- prs->cdataHook = cdataHook;
- prs->deleteHook = deleteHook;
- return prs;
-}
-
-ikstack *
-iks_parser_stack (iksparser *prs)
-{
- return prs->s;
-}
-
-void *
-iks_user_data (iksparser *prs)
-{
- return prs->user_data;
-}
-
-unsigned long
-iks_nr_bytes (iksparser *prs)
-{
- return prs->nr_bytes;
-}
-
-unsigned long
-iks_nr_lines (iksparser *prs)
-{
- return prs->nr_lines;
-}
-
-#define IS_WHITESPACE(x) ' ' == (x) || '\t' == (x) || '\r' == (x) || '\n' == (x)
-#define NOT_WHITESPACE(x) ' ' != (x) && '\t' != (x) && '\r' != (x) && '\n' != (x)
-
-static int
-stack_init (iksparser *prs)
-{
- prs->stack = iks_malloc (128);
- if (!prs->stack) return 0;
- prs->stack_max = 128;
- prs->stack_pos = 0;
- return 1;
-}
-
-static int
-stack_expand (iksparser *prs, int len)
-{
- size_t need;
- off_t diff;
- char *tmp;
- need = len - (prs->stack_max - prs->stack_pos);
- if (need < prs->stack_max) {
- need = prs->stack_max * 2;
- } else {
- need = prs->stack_max + (need * 1.2);
- }
- tmp = iks_malloc (need);
- if (!tmp) return 0;
- diff = tmp - prs->stack;
- memcpy (tmp, prs->stack, prs->stack_max);
- iks_free (prs->stack);
- prs->stack = tmp;
- prs->stack_max = need;
- prs->tag_name += diff;
- if (prs->attflag != 0) {
- int i = 0;
- while (i < (prs->attmax * 2)) {
- if (prs->atts[i]) prs->atts[i] += diff;
- i++;
- }
- }
- return 1;
-}
-
-#define STACK_INIT \
- if (NULL == prs->stack && 0 == stack_init (prs)) return IKS_NOMEM
-
-#define STACK_PUSH_START (prs->stack + prs->stack_pos)
-
-#define STACK_PUSH(buf,len) \
-{ \
- char *sbuf = (buf); \
- size_t slen = (len); \
- if (prs->stack_max - prs->stack_pos <= slen) { \
- if (0 == stack_expand (prs, slen)) return IKS_NOMEM; \
- } \
- memcpy (prs->stack + prs->stack_pos, sbuf, slen); \
- prs->stack_pos += slen; \
-}
-
-#define STACK_PUSH_END \
-{ \
- if (prs->stack_pos >= prs->stack_max) { \
- if (0 == stack_expand (prs, 1)) return IKS_NOMEM; \
- } \
- prs->stack[prs->stack_pos] = '\0'; \
- prs->stack_pos++; \
-}
-
-static enum ikserror
-sax_core (iksparser *prs, char *buf, int len)
-{
- enum ikserror err;
- int pos = 0, old = 0, re, stack_old = -1;
- unsigned char c;
-
- while (pos < len) {
- re = 0;
- c = buf[pos];
- if (0 == c || 0xFE == c || 0xFF == c) return IKS_BADXML;
- if (prs->uni_max) {
- if ((c & 0xC0) != 0x80) return IKS_BADXML;
- prs->uni_len++;
- if (prs->uni_len == prs->uni_max) prs->uni_max = 0;
- goto cont;
- } else {
- if (c & 0x80) {
- unsigned char mask;
- if ((c & 0x60) == 0x40) {
- prs->uni_max = 2;
- mask = 0x1F;
- } else if ((c & 0x70) == 0x60) {
- prs->uni_max = 3;
- mask = 0x0F;
- } else if ((c & 0x78) == 0x70) {
- prs->uni_max = 4;
- mask = 0x07;
- } else if ((c & 0x7C) == 0x78) {
- prs->uni_max = 5;
- mask = 0x03;
- } else if ((c & 0x7E) == 0x7C) {
- prs->uni_max = 6;
- mask = 0x01;
- } else {
- return IKS_BADXML;
- }
- if ((c & mask) == 0) return IKS_BADXML;
- prs->uni_len = 1;
- if (stack_old == -1) stack_old = pos;
- goto cont;
- }
- }
-
- switch (prs->context) {
- case C_CDATA:
- if ('&' == c) {
- if (old < pos && prs->cdataHook) {
- err = prs->cdataHook (prs->user_data, &buf[old], pos - old);
- if (IKS_OK != err) return err;
- }
- prs->context = C_ENTITY;
- prs->entpos = 0;
- break;
- }
- if ('<' == c) {
- if (old < pos && prs->cdataHook) {
- err = prs->cdataHook (prs->user_data, &buf[old], pos - old);
- if (IKS_OK != err) return err;
- }
- STACK_INIT;
- prs->tag_name = STACK_PUSH_START;
- if (!prs->tag_name) return IKS_NOMEM;
- prs->context = C_TAG_START;
- }
- break;
-
- case C_TAG_START:
- prs->context = C_TAG;
- if ('/' == c) {
- prs->tagtype = IKS_CLOSE;
- break;
- }
- if ('?' == c) {
- prs->context = C_PI;
- break;
- }
- if ('!' == c) {
- prs->context = C_MARKUP;
- break;
- }
- prs->tagtype = IKS_OPEN;
- stack_old = pos;
- break;
-
- case C_TAG:
- if (IS_WHITESPACE(c)) {
- if (IKS_CLOSE == prs->tagtype)
- prs->oldcontext = C_TAG_END;
- else
- prs->oldcontext = C_ATTRIBUTE;
- prs->context = C_WHITESPACE;
- if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
- stack_old = -1;
- STACK_PUSH_END;
- break;
- }
- if ('/' == c) {
- if (IKS_CLOSE == prs->tagtype) return IKS_BADXML;
- prs->tagtype = IKS_SINGLE;
- prs->context = C_TAG_END;
- if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
- stack_old = -1;
- STACK_PUSH_END;
- break;
- }
- if ('>' == c) {
- prs->context = C_TAG_END;
- if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
- stack_old = -1;
- STACK_PUSH_END;
- re = 1;
- }
- if (stack_old == -1) stack_old = pos;
- break;
-
- case C_TAG_END:
- if (c != '>') return IKS_BADXML;
- if (prs->tagHook) {
- char **tmp;
- if (prs->attcur == 0) tmp = NULL; else tmp = prs->atts;
- err = prs->tagHook (prs->user_data, prs->tag_name, tmp, prs->tagtype);
- if (IKS_OK != err) return err;
- }
- prs->stack_pos = 0;
- stack_old = -1;
- prs->attcur = 0;
- prs->attflag = 0;
- prs->context = C_CDATA;
- old = pos + 1;
- break;
-
- case C_ATTRIBUTE:
- if ('/' == c) {
- prs->tagtype = IKS_SINGLE;
- prs->context = C_TAG_END;
- break;
- }
- if ('>' == c) {
- prs->context = C_TAG_END;
- re = 1;
- break;
- }
- if (!prs->atts) {
- prs->attmax = 12;
- prs->atts = iks_malloc (sizeof(char *) * 2 * 12);
- if (!prs->atts) return IKS_NOMEM;
- memset (prs->atts, 0, sizeof(char *) * 2 * 12);
- prs->attcur = 0;
- } else {
- if (prs->attcur >= (prs->attmax * 2)) {
- void *tmp;
- prs->attmax += 12;
- tmp = iks_malloc (sizeof(char *) * 2 * prs->attmax);
- if (!tmp) return IKS_NOMEM;
- memset (tmp, 0, sizeof(char *) * 2 * prs->attmax);
- memcpy (tmp, prs->atts, sizeof(char *) * prs->attcur);
- free (prs->atts);
- prs->atts = tmp;
- }
- }
- prs->attflag = 1;
- prs->atts[prs->attcur] = STACK_PUSH_START;
- stack_old = pos;
- prs->context = C_ATTRIBUTE_1;
- break;
-
- case C_ATTRIBUTE_1:
- if ('=' == c) {
- if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
- stack_old = -1;
- STACK_PUSH_END;
- prs->context = C_VALUE;
- break;
- }
- if (stack_old == -1) stack_old = pos;
- break;
-
- case C_ATTRIBUTE_2:
- if ('/' == c) {
- prs->tagtype = IKS_SINGLE;
- prs->atts[prs->attcur] = NULL;
- prs->context = C_TAG_END;
- break;
- }
- if ('>' == c) {
- prs->atts[prs->attcur] = NULL;
- prs->context = C_TAG_END;
- re = 1;
- break;
- }
- prs->context = C_ATTRIBUTE;
- re = 1;
- break;
-
- case C_VALUE:
- prs->atts[prs->attcur + 1] = STACK_PUSH_START;
- if ('\'' == c) {
- prs->context = C_VALUE_APOS;
- break;
- }
- if ('"' == c) {
- prs->context = C_VALUE_QUOT;
- break;
- }
- return IKS_BADXML;
-
- case C_VALUE_APOS:
- if ('\'' == c) {
- if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
- stack_old = -1;
- STACK_PUSH_END;
- prs->oldcontext = C_ATTRIBUTE_2;
- prs->context = C_WHITESPACE;
- prs->attcur += 2;
- }
- if (stack_old == -1) stack_old = pos;
- break;
-
- case C_VALUE_QUOT:
- if ('"' == c) {
- if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
- stack_old = -1;
- STACK_PUSH_END;
- prs->oldcontext = C_ATTRIBUTE_2;
- prs->context = C_WHITESPACE;
- prs->attcur += 2;
- }
- if (stack_old == -1) stack_old = pos;
- break;
-
- case C_WHITESPACE:
- if (NOT_WHITESPACE(c)) {
- prs->context = prs->oldcontext;
- re = 1;
- }
- break;
-
- case C_ENTITY:
- if (';' == c) {
- char hede[2];
- 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 = '>';
- old = pos + 1;
- hede[0] = t;
- if (prs->cdataHook) {
- err = prs->cdataHook (prs->user_data, &hede[0], 1);
- if (IKS_OK != err) return err;
- }
- prs->context = C_CDATA;
- } else {
- prs->entity[prs->entpos++] = buf[pos];
- if (prs->entpos > 7) return IKS_BADXML;
- }
- break;
-
- case C_COMMENT:
- if ('-' != c) return IKS_BADXML;
- prs->context = C_COMMENT_1;
- break;
-
- case C_COMMENT_1:
- if ('-' == c) prs->context = C_COMMENT_2;
- break;
-
- case C_COMMENT_2:
- if ('-' == c)
- prs->context = C_COMMENT_3;
- else
- prs->context = C_COMMENT_1;
- break;
-
- case C_COMMENT_3:
- if ('>' != c) return IKS_BADXML;
- prs->context = C_CDATA;
- old = pos + 1;
- break;
-
- case C_MARKUP:
- if ('[' == c) {
- prs->context = C_SECT;
- break;
- }
- if ('-' == c) {
- prs->context = C_COMMENT;
- break;
- }
- prs->context = C_MARKUP_1;
-
- case C_MARKUP_1:
- if ('>' == c) {
- old = pos + 1;
- prs->context = C_CDATA;
- }
- break;
-
- case C_SECT:
- if ('C' == c) {
- prs->context = C_SECT_CDATA;
- break;
- }
- return IKS_BADXML;
-
- case C_SECT_CDATA:
- if ('D' != c) return IKS_BADXML;
- prs->context = C_SECT_CDATA_1;
- break;
-
- case C_SECT_CDATA_1:
- if ('A' != c) return IKS_BADXML;
- prs->context = C_SECT_CDATA_2;
- break;
-
- case C_SECT_CDATA_2:
- if ('T' != c) return IKS_BADXML;
- prs->context = C_SECT_CDATA_3;
- break;
-
- case C_SECT_CDATA_3:
- if ('A' != c) return IKS_BADXML;
- prs->context = C_SECT_CDATA_4;
- break;
-
- case C_SECT_CDATA_4:
- if ('[' != c) return IKS_BADXML;
- old = pos + 1;
- prs->context = C_SECT_CDATA_C;
- break;
-
- case C_SECT_CDATA_C:
- if (']' == c) {
- prs->context = C_SECT_CDATA_E;
- if (prs->cdataHook && old < pos) {
- err = prs->cdataHook (prs->user_data, &buf[old], pos - old);
- if (IKS_OK != err) return err;
- }
- }
- break;
-
- case C_SECT_CDATA_E:
- if (']' == c) {
- prs->context = C_SECT_CDATA_E2;
- } else {
- if (prs->cdataHook) {
- err = prs->cdataHook (prs->user_data, "]", 1);
- if (IKS_OK != err) return err;
- }
- old = pos;
- prs->context = C_SECT_CDATA_C;
- }
- break;
-
- case C_SECT_CDATA_E2:
- if ('>' == c) {
- old = pos + 1;
- prs->context = C_CDATA;
- } else {
- if (prs->cdataHook) {
- err = prs->cdataHook (prs->user_data, "]]", 2);
- if (IKS_OK != err) return err;
- }
- old = pos;
- prs->context = C_SECT_CDATA_C;
- }
- break;
-
- case C_PI:
- old = pos + 1;
- if ('>' == c) prs->context = C_CDATA;
- break;
- }
-cont:
- if (0 == re) {
- pos++;
- prs->nr_bytes++;
- if ('\n' == c) prs->nr_lines++;
- }
- }
-
- if (stack_old != -1)
- STACK_PUSH (buf + stack_old, pos - stack_old);
-
- err = IKS_OK;
- if (prs->cdataHook && (prs->context == C_CDATA || prs->context == C_SECT_CDATA_C) && old < pos)
- err = prs->cdataHook (prs->user_data, &buf[old], pos - old);
- return err;
-}
-
-int
-iks_parse (iksparser *prs, const char *data, size_t len, int finish)
-{
- if (!data) return IKS_OK;
- if (len == 0) len = strlen (data);
- return sax_core (prs, (char *) data, len);
-}
-
-void
-iks_parser_reset (iksparser *prs)
-{
- if (prs->deleteHook) prs->deleteHook (prs->user_data);
- prs->stack_pos = 0;
- prs->context = 0;
- prs->oldcontext = 0;
- prs->tagtype = 0;
- prs->attcur = 0;
- prs->attflag = 0;
- prs->valflag = 0;
- prs->entpos = 0;
- prs->nr_bytes = 0;
- prs->nr_lines = 0;
- prs->uni_max = 0;
- prs->uni_len = 0;
-}
-
-void
-iks_parser_delete (iksparser *prs)
-{
- if (prs->deleteHook) prs->deleteHook (prs->user_data);
- if (prs->stack) iks_free (prs->stack);
- if (prs->atts) iks_free (prs->atts);
- if (prs->s) iks_stack_delete (prs->s); else iks_free (prs);
-}
-/* iksemel (XML parser for Jabber)
-** Copyright (C) 2000-2004 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 *s
-
-struct 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_attrib
-
-struct 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) )->len
-
-struct 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;
- size_t len;
-
- 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;
- IKS_ATTRIB_NAME (y) = iks_stack_strdup (x->s, name, 0);
- 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) {
- len = strlen (value);
- IKS_ATTRIB_VALUE (y) = iks_stack_strdup (x->s, value, len);
- 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;
-}
-
-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 (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;
- }
-}
-
-void
-iks_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) 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 ikstype
-iks_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_t
-iks_cdata_size (iks *x)
-{
- if (x) return IKS_CDATA_LEN (x);
- return 0;
-}
-
-int
-iks_has_children (iks *x)
-{
- if (x && IKS_TAG == x->type && IKS_TAG_CHILDREN (x)) return 1;
- return 0;
-}
-
-int
-iks_has_attribs (iks *x)
-{
- if (x && IKS_TAG == x->type && IKS_TAG_ATTRIBS (x)) return 1;
- return 0;
-}
-
-/***** Serializing *****/
-
-static size_t
-escape_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));
-}
-/* iksemel (XML parser for Jabber)
-** Copyright (C) 2000-2003 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"
-
-struct dom_data {
- iks **iksptr;
- iks *current;
- size_t chunk_size;
-};
-
-static int
-tagHook (struct dom_data *data, char *name, char **atts, int type)
-{
- iks *x;
-
- if (IKS_OPEN == type || IKS_SINGLE == type) {
- if (data->current) {
- x = iks_insert (data->current, name);
- } else {
- ikstack *s;
- s = iks_stack_new (data->chunk_size, data->chunk_size);
- x = iks_new_within (name, s);
- }
- if (atts) {
- int i=0;
- while (atts[i]) {
- iks_insert_attrib (x, atts[i], atts[i+1]);
- i += 2;
- }
- }
- data->current = x;
- }
- if (IKS_CLOSE == type || IKS_SINGLE == type) {
- x = iks_parent (data->current);
- if (x)
- data->current = x;
- else {
- *(data->iksptr) = data->current;
- data->current = NULL;
- }
- }
- return IKS_OK;
-}
-
-static int
-cdataHook (struct dom_data *data, char *cdata, size_t len)
-{
- if (data->current) iks_insert_cdata (data->current, cdata, len);
- return IKS_OK;
-}
-
-static void
-deleteHook (struct dom_data *data)
-{
- if (data->current) iks_delete (data->current);
- data->current = NULL;
-}
-
-iksparser *
-iks_dom_new (iks **iksptr)
-{
- ikstack *s;
- struct dom_data *data;
-
- *iksptr = NULL;
- s = iks_stack_new (DEFAULT_DOM_CHUNK_SIZE, 0);
- if (!s) return NULL;
- data = iks_stack_alloc (s, sizeof (struct dom_data));
- data->iksptr = iksptr;
- data->current = NULL;
- data->chunk_size = DEFAULT_DOM_IKS_CHUNK_SIZE;
- return iks_sax_extend (s, data, (iksTagHook *) tagHook, (iksCDataHook *) cdataHook, (iksDeleteHook *) deleteHook);
-}
-
-void
-iks_set_size_hint (iksparser *prs, size_t approx_size)
-{
- size_t cs;
- struct dom_data *data = iks_user_data (prs);
-
- cs = approx_size / 10;
- if (cs < DEFAULT_DOM_IKS_CHUNK_SIZE) cs = DEFAULT_DOM_IKS_CHUNK_SIZE;
- data->chunk_size = cs;
-}
-
-iks *
-iks_tree (const char *xml_str, size_t len, int *err)
-{
- iksparser *prs;
- iks *x;
- int e;
-
- if (0 == len) len = strlen (xml_str);
- prs = iks_dom_new (&x);
- if (!prs) {
- if (err) *err = IKS_NOMEM;
- return NULL;
- }
- e = iks_parse (prs, xml_str, len, 1);
- if (err) *err = e;
- iks_parser_delete (prs);
- return x;
-}
-
-int
-iks_load (const char *fname, iks **xptr)
-{
- iksparser *prs;
- char *buf;
- FILE *f;
- int len, done = 0;
- int ret;
-
- *xptr = NULL;
-
- buf = iks_malloc (FILE_IO_BUF_SIZE);
- if (!buf) return IKS_NOMEM;
- ret = IKS_NOMEM;
- prs = iks_dom_new (xptr);
- if (prs) {
- f = fopen (fname, "r");
- if (f) {
- while (0 == done) {
- len = fread (buf, 1, FILE_IO_BUF_SIZE, f);
- if (len < FILE_IO_BUF_SIZE) {
- if (0 == feof (f)) {
- ret = IKS_FILE_RWERR;
- len = 0;
- }
- done = 1;
- }
- if (len > 0) {
- int e;
- e = iks_parse (prs, buf, len, done);
- if (IKS_OK != e) {
- ret = e;
- break;
- }
- if (done) ret = IKS_OK;
- }
- }
- fclose (f);
- } else {
- if (ENOENT == errno) ret = IKS_FILE_NOFILE;
- else ret = IKS_FILE_NOACCESS;
- }
- iks_parser_delete (prs);
- }
- iks_free (buf);
- return ret;
-}
-
-int
-iks_save (const char *fname, iks *x)
-{
- FILE *f;
- char *data;
- int ret;
-
- ret = IKS_NOMEM;
- data = iks_string (NULL, x);
- if (data) {
- ret = IKS_FILE_NOACCESS;
- f = fopen (fname, "w");
- if (f) {
- ret = IKS_FILE_RWERR;
- if (fputs (data, f) >= 0) ret = IKS_OK;
- fclose (f);
- }
- iks_free (data);
- }
- return ret;
-}