#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;
}