--- /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 <lua.h>
+#include <lauxlib.h>
+#include <loudmouth/loudmouth.h>
+
+#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;
+}
+