--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lm_message_node.c Sun Feb 01 21:28:57 2009 +0200
@@ -0,0 +1,267 @@
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <loudmouth/loudmouth.h>
+
+#include "lm_types.h"
+
+/// lm.message_node
+/// Object, representing xml node of the message.
+/// Cannot be created directly, only as a part of message tree.
+
+/// lm.message_node.bless
+/// Blesses given pointer to lm message node object.
+/// A: lightuserdata (C lm message node object)
+/// R: lm message node object
+static int llm_message_node_bless_lua (lua_State *L)
+{
+ luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "loudmouth message node lightuserdata expected");
+ llm_message_node_bless (L, lua_touserdata (L, 1));
+ lua_remove (L, -2);
+ return 1;
+}
+
+/// message_node:name
+/// Gets a name of message node.
+/// R: string
+static int llm_message_node_name (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ lua_pushstring (L, object->message_node->name);
+ lua_remove (L, -2);
+ return 1;
+}
+
+/// message_node:next
+/// Gets next message node.
+/// R: lm message node object or nil
+static int llm_message_node_next (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ LmMessageNode *node = object->message_node->next;
+ if (node)
+ llm_message_node_bless (L, node);
+ else
+ lua_pushnil (L);
+ lua_remove (L, -2);
+ return 1;
+}
+
+/// message_node:prev
+/// Gets previous message node.
+/// R: lm message node object or nil
+static int llm_message_node_prev (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ LmMessageNode *node = object->message_node->prev;
+ if (node)
+ llm_message_node_bless (L, node);
+ else
+ lua_pushnil (L);
+ lua_remove (L, -2);
+ return 1;
+}
+
+/// message_node:children
+/// Gets first child node (raw access used).
+/// R: lm message node object or nil
+static int llm_message_node_children (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ LmMessageNode *node = object->message_node->children;
+ if (node)
+ llm_message_node_bless (L, node);
+ else
+ lua_pushnil (L);
+ lua_remove (L, -2);
+ return 1;
+}
+
+/// message_node:parent
+/// Gets parent message node.
+/// R: lm message node object or nil
+static int llm_message_node_parent (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ LmMessageNode *node = object->message_node->parent;
+ if (node)
+ llm_message_node_bless (L, node);
+ else
+ lua_pushnil (L);
+ lua_remove (L, -2);
+ return 1;
+}
+
+/// message_node:value
+/// Gets or sets a value of message node.
+/// A: string (optional value)
+/// R: string (if called without arguments)
+static int llm_message_node_value (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ if (lua_gettop (L) > 1) { // Set
+ const char *value = luaL_checkstring (L, 2);
+ lm_message_node_set_value (object->message_node, value);
+ lua_pop (L, 2);
+ return 0;
+ } else { // Get
+ lua_pushstring (L, lm_message_node_get_value (object->message_node));
+ lua_remove (L, -2);
+ return 1;
+ }
+}
+
+/// message_node:child
+/// Gets or creates child node object with given name.
+/// A: string (name), string (optional value)
+/// R: lm message node object or nil
+static int llm_message_node_child (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ const char *name = luaL_checkstring (L, 2);
+ LmMessageNode *child;
+
+ if (lua_gettop (L) > 2) { // Add
+ child = lm_message_node_add_child (object->message_node, name,
+ luaL_checkstring (L, 3));
+ lua_pop (L, 1);
+ } else { // Get
+ child = lm_message_node_get_child (object->message_node, name);
+ if (!child) {
+ lua_pushnil (L);
+ return 1;
+ }
+ }
+ llm_message_node_bless (L, child);
+ // XXX lm_message_node_unref (child);
+ lua_remove (L, -2);
+ lua_remove (L, -2);
+ return 1;
+}
+
+/// message_node:find_child
+/// Searches for node with a given name over all node subtree.
+/// A: string (name)
+/// R: lm message node object or nil
+static int llm_message_node_find_child (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ const char *name = luaL_checkstring (L, 2);
+ LmMessageNode *child;
+
+ child = lm_message_node_get_child (object->message_node, name);
+ if (!child)
+ lua_pushnil (L);
+ else {
+ llm_message_node_bless (L, child);
+ // XXX lm_message_node_unref (child);
+ }
+ lua_remove (L, -2);
+ lua_remove (L, -2);
+ return 1;
+}
+
+/// message_node:raw
+/// Gets or sets raw mode flag for node.
+/// When set, value of node will not be escaped.
+/// A: boolean (optional)
+/// V: boolean (if called with no apguments)
+static int llm_message_node_raw (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ if (lua_gettop (L) > 1) { // Set
+ luaL_checktype (L, 2, LUA_TBOOLEAN);
+ lm_message_node_set_raw_mode (object->message_node, lua_toboolean (L, 2));
+ lua_pop (L, 2);
+ return 0;
+ } else { // Get
+ lua_pushboolean (L, lm_message_node_get_raw_mode (object->message_node));
+ lua_remove (L, -2);
+ return 1;
+ }
+}
+
+/// message_node:attribute
+/// Gets or sets value of node attribute with a given name.
+/// A: string (name), string (optional value)
+/// R: string (when called with one aprgument)
+static int llm_message_node_attribute (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ const char *name = luaL_checkstring (L, 2);
+ if (lua_gettop (L) > 2) { // Set
+ lm_message_node_set_attribute (object->message_node, name, luaL_checkstring (L, 3));
+ lua_pop (L, 3);
+ return 0;
+ } else { // Get
+ lua_pushstring (L, lm_message_node_get_attribute (object->message_node, name));
+ lua_remove (L, -2);
+ lua_remove (L, -2);
+ return 1;
+ }
+}
+
+/// message_node:xml
+/// Returns node representation in xml.
+/// R: string
+static int llm_message_node_xml (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ lua_pushstring (L, lm_message_node_to_string (object->message_node));
+ lua_remove (L, -2);
+ return 1;
+}
+
+/// message_node:pointer
+/// Returns pointer to underlying C structure.
+/// R: lightuserdata
+static int llm_message_node_pointer (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ lua_pushlightuserdata (L, object->message_node);
+ lua_remove (L, -2);
+ return 1;
+}
+
+static int llm_message_node_gc (lua_State *L)
+{
+ llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+ lm_message_node_unref (object->message_node);
+ lua_pop (L, 1);
+ return 0;
+}
+
+static const luaL_Reg llm_message_node_reg_f[] = {
+ { "bless", llm_message_node_bless_lua },
+ { NULL, NULL },
+};
+
+static const luaL_Reg llm_message_node_reg_m[] = {
+ { "name", llm_message_node_name },
+ { "next", llm_message_node_next },
+ { "prev", llm_message_node_prev },
+ { "children", llm_message_node_children },
+ { "parent", llm_message_node_parent },
+ { "value", llm_message_node_value },
+ { "child", llm_message_node_child },
+ { "find_child", llm_message_node_find_child },
+ { "attribute", llm_message_node_attribute },
+ { "raw", llm_message_node_raw },
+ { "xml", llm_message_node_xml },
+ { "pointer", llm_message_node_pointer },
+ { "__gc", llm_message_node_gc },
+ { NULL, NULL },
+};
+
+int luaopen_lm_message_node (lua_State *L)
+{
+ luaL_newmetatable (L, "loudmouth.message_node");
+ lua_pushstring (L, "__index");
+ lua_pushvalue (L, -2);
+ lua_settable (L, -3);
+ luaL_register (L, NULL, llm_message_node_reg_m);
+ lua_pop (L, 1);
+ luaL_register (L, "lm.message_node", llm_message_node_reg_f);
+ return 1;
+}
+