lm_message_node.c
changeset 0 84fdfb0344c9
child 6 90073cbb535d
--- /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;
+}
+