lm_message.c
changeset 0 84fdfb0344c9
child 4 5770be2d5f3f
--- /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;
+}
+