diff -r 000000000000 -r 84fdfb0344c9 lm_message_node.c --- /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 +#include +#include + +#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; +} +