diff -r 000000000000 -r 84fdfb0344c9 lm_message.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lm_message.c Sun Feb 01 21:28:57 2009 +0200 @@ -0,0 +1,163 @@ + +#include +#include +#include + +#include "util.h" +#include "lm_types.h" + +/// lm.message +/// Module, representing individual message. +/// Message have a type and optionally a sub type. + +/// message type +/// Message type (root tag type). +/// V: message, presence, iq, stream, stream error, stream features, auth, challenge, response, success, failure, proceed, starttls, unknown, stream:stream, stream:error, stream:feature +const string2enum_t llm_message_type[] = { + { "message", LM_MESSAGE_TYPE_MESSAGE }, + { "presence", LM_MESSAGE_TYPE_PRESENCE }, + { "iq", LM_MESSAGE_TYPE_IQ }, + { "stream", LM_MESSAGE_TYPE_STREAM }, + { "stream error", LM_MESSAGE_TYPE_STREAM_ERROR }, + { "stream features", LM_MESSAGE_TYPE_STREAM_FEATURES }, + { "auth", LM_MESSAGE_TYPE_AUTH }, + { "challenge", LM_MESSAGE_TYPE_CHALLENGE }, + { "response", LM_MESSAGE_TYPE_RESPONSE }, + { "success", LM_MESSAGE_TYPE_SUCCESS }, + { "failure", LM_MESSAGE_TYPE_FAILURE }, + { "proceed", LM_MESSAGE_TYPE_PROCEED }, + { "starttls", LM_MESSAGE_TYPE_STARTTLS }, + { "unknown", LM_MESSAGE_TYPE_UNKNOWN }, + { "stream:stream", LM_MESSAGE_TYPE_STREAM }, + { "stream:error", LM_MESSAGE_TYPE_STREAM_ERROR }, + { "stream:features", LM_MESSAGE_TYPE_STREAM_FEATURES }, + { NULL, 0 }, +}; + +/// message sub type +/// Message subtype, not all combinations of type and subtype are possible. +/// V: not set, available, normal, chat, groupchat, headline, unavailable, probe, subscribe, unsubscribe, subscribed, unsubscribed, get, set, result, error, not_set +const string2enum_t llm_message_sub_type[] = { + { "not set", LM_MESSAGE_SUB_TYPE_NOT_SET }, + { "available", LM_MESSAGE_SUB_TYPE_AVAILABLE }, + { "normal", LM_MESSAGE_SUB_TYPE_NORMAL }, + { "chat", LM_MESSAGE_SUB_TYPE_CHAT }, + { "groupchat", LM_MESSAGE_SUB_TYPE_GROUPCHAT }, + { "headline", LM_MESSAGE_SUB_TYPE_HEADLINE }, + { "unavailable", LM_MESSAGE_SUB_TYPE_UNAVAILABLE }, + { "probe", LM_MESSAGE_SUB_TYPE_PROBE }, + { "subscribe", LM_MESSAGE_SUB_TYPE_SUBSCRIBE }, + { "unsubscribe", LM_MESSAGE_SUB_TYPE_UNSUBSCRIBE }, + { "subscribed", LM_MESSAGE_SUB_TYPE_SUBSCRIBED }, + { "unsubscribed", LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED }, + { "get", LM_MESSAGE_SUB_TYPE_GET }, + { "set", LM_MESSAGE_SUB_TYPE_SET }, + { "result", LM_MESSAGE_SUB_TYPE_RESULT }, + { "error", LM_MESSAGE_SUB_TYPE_ERROR }, + { "not_set", LM_MESSAGE_SUB_TYPE_NOT_SET }, + { NULL, 0 }, +}; + +/// lm.message.new +/// Creates new message object. +/// A: string (to), message type, message sub type (optional) +/// R: lm message object +static int llm_message_new (lua_State *L) +{ + const char *to = luaL_checkstring (L, 1); + int type = luaL_checkenum (L, 2, llm_message_type); + LmMessage *message; + if (lua_gettop (L) > 2) { + message = lm_message_new_with_sub_type (to, type, + luaL_checkenum (L, 3, llm_message_sub_type)); + lua_pop (L, 1); + } else + message = lm_message_new (to, type); + lua_pop (L, 2); + llm_message_bless (L, message); + lm_message_unref (message); + return 1; +} + +/// lm.message.bless +/// Blesses given pointer to lm message object. +/// A: lightuserdata (C lm message object) +/// R: lm message object +static int llm_message_bless_lua (lua_State *L) +{ + luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "lm message lightuserdata expected"); + llm_message_bless (L, lua_touserdata (L, 1)); + lua_remove (L, -2); + return 1; +} + +/// message:node +/// Returns root node object of message. +/// R: lm message node object +static int llm_message_node (lua_State *L) +{ + llm_message_t *object = luaL_checklm_message (L, 1); + LmMessageNode *node = lm_message_get_node (object->message); + llm_message_node_bless (L, node); + // XXX lm_message_node_unref (node); + lua_remove (L, -2); + return 1; +} + +/// message:type +/// Returns two strings: message type and message sub type. +/// R: message type, message sub type +static int llm_message_kind (lua_State *L) +{ + llm_message_t *object = luaL_checklm_message (L, 1); + luaL_pushenum (L, lm_message_get_type (object->message), llm_message_type); + luaL_pushenum (L, lm_message_get_sub_type (object->message), llm_message_sub_type); + lua_remove (L, -3); + return 2; +} + +/// message:pointer +/// Returns pointer to underlying C loudmouth structure. +/// R: lightuserdata +static int llm_message_pointer (lua_State *L) +{ + llm_message_t *object = luaL_checklm_message (L, 1); + lua_pushlightuserdata (L, object->message); + lua_remove (L, -2); + return 1; +} + +static int llm_message_gc (lua_State *L) +{ + llm_message_t *object = luaL_checklm_message (L, 1); + lm_message_unref (object->message); + lua_pop (L, 1); + return 0; +} + +static const luaL_Reg llm_message_reg_f[] = { + { "new", llm_message_new }, + { "bless", llm_message_bless_lua }, + { NULL, NULL }, +}; + +static const luaL_Reg llm_message_reg_m[] = { + { "node", llm_message_node }, + { "type", llm_message_kind }, + { "pointer", llm_message_pointer }, + { "__gc", llm_message_gc }, + { NULL, NULL }, +}; + +int luaopen_lm_message (lua_State *L) +{ + luaL_newmetatable (L, "loudmouth.message"); + lua_pushstring (L, "__index"); + lua_pushvalue (L, -2); + lua_settable (L, -3); + luaL_register (L, NULL, llm_message_reg_m); + lua_pop (L, 1); + luaL_register (L, "lm.message", llm_message_reg_f); + return 1; +} +