/*
** 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
*/

#ifndef IKSEMEL_H
#define IKSEMEL_H 1

#ifdef __cplusplus
extern "C" {
#endif

/*****  utility.c  *****/

typedef struct ikspool_s
{
	struct ikspool_s *next;
	int max;
	int len;
	char *data;
} ikspool;

struct ikstrnode
{
	struct ikstrnode *next;
	char *data;
	int len;
};

typedef struct ikstr_s
{
	struct ikstrnode *first;
	struct ikstrnode *last;
	ikspool *p;
	int flag;
	int len;
} ikstr;

typedef struct iksconv_s
{
#ifdef IKSEMEL_ICONV
	iconv_t to;
	iconv_t from;
#endif
	char *buffer;
	int len;
} iksconv;


/*****  sha.c  *****/

typedef struct
{
	unsigned long hash[5];
	unsigned long buf[80];
	int blen;
	unsigned long lenhi, lenlo;
} iksha;


/*****  iks.c  *****/

enum ikstype
{
	IKS_NONE,
	IKS_TAG,
	IKS_ATTRIBUTE,
	IKS_CDATA
};

typedef struct iks_s
{
	struct iks_s *next;
	struct iks_s *prev;
	struct iks_s *parent;
	struct iks_s *children;
	struct iks_s *lastchild;
	struct iks_s *attribs;
	struct iks_s *lastattrib;
	enum ikstype type;
	ikspool *p;
	char *name;
	char *cdata;
	int len;
} iks;


/*****  jabber.c  *****/

#define IKS_NS_CLIENT     "jabber:client"
#define IKS_NS_SERVER     "jabber:server"
#define IKS_NS_AUTH       "jabber:iq:auth"
#define IKS_NS_AUTH_0K    "jabber:iq:auth:0k"
#define IKS_NS_REGISTER   "jabber:iq:register"
#define IKS_NS_ROSTER     "jabber:iq:roster"
#define IKS_NS_OFFLINE    "jabber:x:offline"
#define IKS_NS_AGENT      "jabber:iq:agent"
#define IKS_NS_AGENTS     "jabber:iq:agents"
#define IKS_NS_BROWSE     "jabber:iq:browse"
#define IKS_NS_CONFERENCE "jabber:iq:conference"
#define IKS_NS_DELAY      "jabber:x:delay"
#define IKS_NS_VERSION    "jabber:iq:version"
#define IKS_NS_TIME       "jabber:iq:time"
#define IKS_NS_VCARD      "vcard-temp"
#define IKS_NS_PRIVATE    "jabber:iq:private"
#define IKS_NS_SEARCH     "jabber:iq:search"
#define IKS_NS_OOB        "jabber:iq:oob"
#define IKS_NS_XOOB       "jabber:x:oob"
#define IKS_NS_ADMIN      "jabber:iq:admin"
#define IKS_NS_FILTER     "jabber:iq:filter"
#define IKS_NS_GATEWAY    "jabber:iq:gateway"
#define IKS_NS_LAST       "jabber:iq:last"
#define IKS_NS_SIGNED     "jabber:x:signed"
#define IKS_NS_ENCRYPTED  "jabber:x:encrypted"
#define IKS_NS_ENVELOPE   "jabber:x:envelope"
#define IKS_NS_EVENT      "jabber:x:event"
#define IKS_NS_EXPIRE     "jabber:x:expire"
#define IKS_NS_XHTML      "http://www.w3.org/1999/xhtml"

#define	IKS_ID_RESOURCE 1
#define	IKS_ID_USER 2
#define IKS_ID_SERVER 4

typedef struct iksid_s
{
	ikspool *p;
	char *resource;
	char *user;
	char *server;
	char *full;
	char *partial;
} iksid;

enum ikspaktype
{
	IKS_PAK_UNKNOWN = 0,
	IKS_PAK_STREAM,
	IKS_PAK_ERROR,
	IKS_PAK_MESSAGE,
	IKS_PAK_PRESENCE,
	IKS_PAK_IQ,
	IKS_PAK_S10N
};

enum iksubtype
{
	IKS_TYPE_UNKNOWN = -1,
	IKS_TYPE_NONE = 0,
	IKS_TYPE_ERROR,

	IKS_TYPE_CHAT,
	IKS_TYPE_GROUPCHAT,
	IKS_TYPE_HEADLINE,

	IKS_TYPE_GET,
	IKS_TYPE_SET,
	IKS_TYPE_RESULT,

	IKS_TYPE_SUBSCRIBE,
	IKS_TYPE_SUBSCRIBED,
	IKS_TYPE_UNSUBSCRIBE,
	IKS_TYPE_UNSUBSCRIBED,
	IKS_TYPE_PROBE,
	IKS_TYPE_AVAILABLE,
	IKS_TYPE_UNAVAILABLE
};

enum ikshowtype
{
	IKS_SHOW_UNAVAILABLE = 0,
	IKS_SHOW_AVAILABLE,
	IKS_SHOW_CHAT,
	IKS_SHOW_AWAY,
	IKS_SHOW_XA,
	IKS_SHOW_DND
};

typedef struct ikspak_s
{
	iks *x;
	iksid *to;
	iksid *from;
	iks *query;
	char *ns;
	ikspool *p;
	enum ikspaktype type;
	enum iksubtype subtype;
	enum ikshowtype show;
} ikspak;


/*****  parser.c  *****/

enum iksrettype
{
	IKS_RET_OK,
	IKS_RET_NOMEM,
	IKS_RET_BADXML,
	IKS_RET_HOOK
};

#define IKS_DIR_IN 0
#define IKS_DIR_OUT 1

typedef void (iksTagStart)(void *udata, char *name, char **atts);
typedef void (iksTagEnd)(void *udata, char *name);
typedef void (iksCharData)(void *udata, char *data, int len);
typedef void (iksJPak)(void *udata, ikspak *pak);
typedef void (iksJLog)(void *udata, char *data, int dir);

typedef struct iksparser_s
{
	iks **iksptr;
	iksTagStart *tagStart;
	iksTagEnd *tagEnd;
	iksCharData *charData;
	iksJPak *jPak;
	iksJLog *jLog;
	void *udata;
	void *udata2;
	struct iksconn *conn;
	iks *current;
#ifdef IKSEMEL_EXPAT
	XML_Parser expat;
#else
	char *buffer;
	int buflen;
	int minpos;
	int context;
	int oldcontext;
	char *tagname;
	int tagflag;
	char **atts;
	int attcur;
	int attmax;
	int valflag;
	int entpos;
	char entity[8];
#endif
} iksparser;


/*****  io.c  *****/

#define IKS_JABBER_PORT 5222


/*****  prototypes  *****/

ikspool *iks_pool_new(int pagesize);
void *iks_pool_alloc(ikspool *p, int size);
char *iks_pool_strdup(ikspool *p, const char *src);
void iks_pool_delete(ikspool *p);
char *iks_strdup(const char *src);
char *iks_strcat(char *dest, const char *src);
int iks_strcmp(const char *a, const char *b);
int iks_strcasecmp(const char *a, const char *b);
int iks_strncmp(const char *a, const char *b, int n);
int iks_strncasecmp(const char *a, const char *b, int n);
int iks_strlen(const char *src);
ikstr *iks_str_new(ikspool *p);
void iks_str_add(ikstr *s, char *src);
void iks_spool(ikstr *s, ...);
char *iks_str_print(ikstr *s);
void iks_str_delete(ikstr *s);
char *iks_escape(ikspool *p, char *src, int len);
char *iks_unescape(ikspool *p, char *src, int len);


iksconv *iks_conv_new(char *codeset);
void iks_conv_delete(iksconv *conv);
char *iks_conv_locale(iksconv *conv, const char *src, int len);
char *iks_conv_utf8(iksconv *conv, const char *src, int len);


iksha *iks_sha_new(void);
void iks_sha_reset(iksha *sha);
void iks_sha_hash(iksha *sha, const unsigned char *data, int len, int finish);
void iks_sha_print(iksha *sha, char *hash);
void iks_sha_delete(iksha *sha);
void iks_sha(const char *data, char *hash);


iks *iks_new(const char *name);
iks *iks_new_pool(ikspool *p, const char *name);
iks *iks_insert(iks *x, const char *name);
iks *iks_insert_cdata(iks *x, const char *data, int len);
iks *iks_insert_attrib(iks *x, const char *name, const char *value);
iks *iks_insert_node(iks *x, iks *y);
void iks_hide(iks *x);
void iks_delete(iks *x);
iks *iks_next(iks *x);
iks *iks_prev(iks *x);
iks *iks_parent(iks *x);
iks *iks_child(iks *x);
iks *iks_attrib(iks *x);
iks *iks_find(iks *x, const char *name);
char *iks_find_cdata(iks *x, const char *name);
char *iks_find_attrib(iks *x, const char *name);
ikspool *iks_pool(iks *x);
enum ikstype iks_type(iks *x);
char *iks_name(iks *x);
char *iks_cdata(iks *x);
int iks_cdata_size(iks *x);
int iks_has_children(iks *x);
int iks_has_attribs(iks *x);
ikstr *iks_string(ikspool *p, iks *x);
int iks_compare(iks *x, iks *y);
iks *iks_duplicate(iks *x);


iksid *iks_id_new(ikspool *p, char *src);
void iks_id_set(iksid *id, char *src, int item);
int iks_id_cmp(iksid *a, iksid *b);
int iks_id_cmpx(iksid *a, iksid *b, int parts);
char *iks_id_print(iksid *id);
char *iks_id_printx(iksid *id, int parts);
ikspak *iks_packet(iks *x);
iks *iks_make_header(char *to, char *xmlns);
iks *iks_make_auth(iksid *id, char *pass, char *sid);
iks *iks_make_msg(enum iksubtype type, char *to, char *body, char *thread);
iks *iks_make_pres(enum iksubtype type, enum ikshowtype show, char *to, char *status);
iks *iks_make_iq(enum iksubtype type, const char *xmlns);


iksparser *iks_dom_new(iks **iksptr);
iksparser *iks_sax_new(void *udata, iksTagStart *ts, iksTagEnd *te, iksCharData *cd);
iksparser *iks_jabber_new(void *udata, iksJPak *jp);
void iks_set_logging(iksparser *prs, iksJLog *jl);
void iks_parser_delete(iksparser *prs);
int iks_parse(iksparser *prs, char *data, int len, int finish);


int iks_connect_tcp(iksparser *prs, char *server, int port);
int iks_fd(iksparser *prs);
int iks_recv(iksparser *prs, int timeout);
int iks_send(iksparser *prs, iks *x);
int iks_send_raw(iksparser *prs, char *data);
void iks_disconnect(iksparser *prs);
iks *iks_load(char *fname);
int iks_save(char *fname, iks *x);



#ifdef __cplusplus
}
#endif

#endif  /* IKSEMEL_H */
