#ifndef INCL_SX_H
#define INCL_SX_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ac-stdint.h"
#include <expat/expat.h>
#include <util/util.h>
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _sx_st *sx_t;
typedef struct _sx_env_st *sx_env_t;
typedef struct _sx_plugin_st *sx_plugin_t;
typedef enum {
event_WANT_READ,
event_WANT_WRITE,
event_READ,
event_WRITE,
event_STREAM,
event_OPEN,
event_PACKET,
event_CLOSED,
event_ERROR
} sx_event_t;
typedef enum {
state_NONE,
state_STREAM_RECEIVED,
state_STREAM_SENT,
state_STREAM,
state_OPEN,
state_CLOSING,
state_CLOSED
} _sx_state_t;
typedef enum {
type_NONE,
type_CLIENT,
type_SERVER
} _sx_type_t;
typedef int (*sx_callback_t)(sx_t s, sx_event_t e, void *data, void *arg);
typedef int (*sx_plugin_init_t)(sx_env_t env, sx_plugin_t p, va_list args);
#define SX_SUCCESS (0x00)
#define SX_ERR_STREAM (0x01)
#define SX_ERR_AUTH (0x02)
#define SX_ERR_XML_PARSE (0x03)
typedef struct _sx_error_st {
int code;
char *generic;
char *specific;
} sx_error_t;
#define _sx_gen_error(e,c,g,s) do { e.code = c; e.generic = g; e.specific = s; } while(0);
typedef void (*_sx_notify_t)(sx_t s, void *arg);
typedef struct _sx_buf_st *sx_buf_t;
struct _sx_buf_st {
char *data;
int len;
char *heap;
_sx_notify_t notify;
void *notify_arg;
};
#define stream_err_BAD_FORMAT (0)
#define stream_err_BAD_NAMESPACE_PREFIX (1)
#define stream_err_CONFLICT (2)
#define stream_err_CONNECTION_TIMEOUT (3)
#define stream_err_HOST_GONE (4)
#define stream_err_HOST_UNKNOWN (5)
#define stream_err_IMPROPER_ADDRESSING (6)
#define stream_err_INTERNAL_SERVER_ERROR (7)
#define stream_err_INVALID_FROM (8)
#define stream_err_INVALID_ID (9)
#define stream_err_INVALID_NAMESPACE (10)
#define stream_err_INVALID_XML (11)
#define stream_err_NOT_AUTHORIZED (12)
#define stream_err_POLICY_VIOLATION (13)
#define stream_err_REMOTE_CONNECTION_FAILED (14)
#define stream_err_RESTRICTED_XML (15)
#define stream_err_RESOURCE_CONSTRAINT (16)
#define stream_err_SEE_OTHER_HOST (17)
#define stream_err_SYSTEM_SHUTDOWN (18)
#define stream_err_UNDEFINED_CONDITION (19)
#define stream_err_UNSUPPORTED_ENCODING (20)
#define stream_err_UNSUPPORTED_STANZA_TYPE (21)
#define stream_err_UNSUPPORTED_VERSION (22)
#define stream_err_XML_NOT_WELL_FORMED (23)
#define stream_err_LAST (24)
sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg);
void sx_free(sx_t s);
void sx_client_init(sx_t s, unsigned int flags, char *ns, char *to, char *from, char *version);
void sx_server_init(sx_t s, unsigned int flags);
int sx_can_read(sx_t s);
int sx_can_write(sx_t s);
void sx_nad_write_elem(sx_t s, nad_t nad, int elem);
#define sx_nad_write(s,nad) sx_nad_write_elem(s, nad, 0)
void sx_raw_write(sx_t s, char *buf, int len);
void sx_auth(sx_t s, const char *auth_method, const char *auth_id);
sx_env_t sx_env_new(void);
void sx_env_free(sx_env_t env);
sx_plugin_t sx_env_plugin(sx_env_t env, sx_plugin_init_t init, ...);
void sx_error(sx_t s, int err, char *text);
void sx_close(sx_t s);
void sx_kill(sx_t s);
long sx_scale_limit(int size, char *scale);
void _sx_element_start(void *arg, const char *name, const char **atts);
void _sx_element_end(void *arg, const char *name);
void _sx_cdata(void *arg, const char *str, int len);
void _sx_namespace_start(void *arg, const char *prefix, const char *uri);
void _sx_process_read(sx_t s, sx_buf_t buf);
void _sx_nad_process(sx_t s, nad_t nad);
void _sx_chain_io_plugin(sx_t s, sx_plugin_t p);
void _sx_chain_nad_plugin(sx_t s, sx_plugin_t p);
int _sx_chain_io_write(sx_t s, sx_buf_t buf);
int _sx_chain_io_read(sx_t s, sx_buf_t buf);
int _sx_chain_nad_write(sx_t s, nad_t nad, int elem);
int _sx_chain_nad_read(sx_t s, nad_t nad);
sx_buf_t _sx_buffer_new(char *data, int len, _sx_notify_t notify, void *notify_arg);
void _sx_buffer_free(sx_buf_t buf);
void _sx_buffer_clear(sx_buf_t buf);
void _sx_buffer_alloc_margin(sx_buf_t buf, int before, int after);
void _sx_buffer_set(sx_buf_t buf, char *newdata, int newlength, char *newheap);
int _sx_nad_write(sx_t s, nad_t nad, int elem);
void sx_raw_write(sx_t s, char *buf, int len);
void _sx_reset(sx_t s);
void _sx_error(sx_t s, int err, char *text);
void _sx_close(sx_t s);
typedef struct _sx_chain_st *_sx_chain_t;
struct _sx_chain_st {
sx_plugin_t p;
_sx_chain_t wnext;
_sx_chain_t rnext;
};
struct _sx_st {
sx_env_t env;
int tag;
sx_callback_t cb;
void *cb_arg;
_sx_type_t type;
unsigned int flags;
char *ns;
char *req_to;
char *req_from;
char *req_version;
char *res_to;
char *res_from;
char *res_version;
char *id;
_sx_chain_t wio, rio;
_sx_chain_t wnad, rnad;
jqueue_t wbufq;
sx_buf_t wbufpending;
jqueue_t rnadq;
int want_read, want_write;
_sx_state_t state;
XML_Parser expat;
int depth;
int fail;
nad_cache_t nad_cache;
nad_t nad;
void **plugin_data;
char *auth_method;
char *auth_id;
int reentry;
int has_reset;
int ssf;
long max_stanza_bytes;
long max_message_bytes;
};
struct _sx_plugin_st {
sx_env_t env;
int magic;
int index;
void *private;
void (*new)(sx_t s, sx_plugin_t p);
void (*free)(sx_t s, sx_plugin_t p);
void (*client)(sx_t s, sx_plugin_t p);
void (*server)(sx_t s, sx_plugin_t p);
int (*wio)(sx_t s, sx_plugin_t p, sx_buf_t buf);
int (*rio)(sx_t s, sx_plugin_t p, sx_buf_t buf);
int (*wnad)(sx_t s, sx_plugin_t p, nad_t nad, int elem);
int (*rnad)(sx_t s, sx_plugin_t p, nad_t nad);
void (*header)(sx_t s, sx_plugin_t p, sx_buf_t buf);
void (*stream)(sx_t s, sx_plugin_t p);
void (*features)(sx_t s, sx_plugin_t p, nad_t nad);
int (*process)(sx_t s, sx_plugin_t p, nad_t nad);
void (*unload)(sx_plugin_t p);
};
struct _sx_env_st {
sx_plugin_t *plugins;
int nplugins;
};
#define ZONE __FILE__,__LINE__
void __sx_debug(char *file, int line, const char *msgfmt, ...);
int __sx_event(char *file, int line, sx_t s, sx_event_t e, void *data);
#define _sx_event(s,e,data) __sx_event(ZONE, s, e, data)
#ifdef SX_DEBUG
#define _sx_debug if(get_debug_flag()) __sx_debug
#define _sx_state(s,st) do { _sx_debug(ZONE, "%d state change from %d to %d", s->tag, s->state, st); s->state = st; } while(0)
#else
#define _sx_debug if(0) __sx_debug
#define _sx_state(s,st) s->state = st
#endif
#ifdef __cplusplus
}
#endif
#endif