lm_message_node.c
changeset 0 84fdfb0344c9
child 6 90073cbb535d
equal deleted inserted replaced
-1:000000000000 0:84fdfb0344c9
       
     1 
       
     2 #include <lua.h>
       
     3 #include <lauxlib.h>
       
     4 #include <loudmouth/loudmouth.h>
       
     5 
       
     6 #include "lm_types.h"
       
     7 
       
     8 /// lm.message_node
       
     9 /// Object, representing xml node of the message.
       
    10 /// Cannot be created directly, only as a part of message tree.
       
    11 
       
    12 /// lm.message_node.bless
       
    13 /// Blesses given pointer to lm message node object.
       
    14 /// A: lightuserdata (C lm message node object)
       
    15 /// R: lm message node object
       
    16 static int llm_message_node_bless_lua (lua_State *L)
       
    17 {
       
    18 	luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "loudmouth message node lightuserdata expected");
       
    19 	llm_message_node_bless (L, lua_touserdata (L, 1));
       
    20 	lua_remove (L, -2);
       
    21 	return 1;
       
    22 }
       
    23 
       
    24 /// message_node:name
       
    25 /// Gets a name of message node.
       
    26 /// R: string
       
    27 static int llm_message_node_name (lua_State *L)
       
    28 {
       
    29 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
    30 	lua_pushstring (L, object->message_node->name);
       
    31 	lua_remove (L, -2);
       
    32 	return 1;
       
    33 }
       
    34 
       
    35 /// message_node:next
       
    36 /// Gets next message node.
       
    37 /// R: lm message node object or nil
       
    38 static int llm_message_node_next (lua_State *L)
       
    39 {
       
    40 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
    41 	LmMessageNode *node = object->message_node->next;
       
    42 	if (node)
       
    43 		llm_message_node_bless (L, node);
       
    44 	else
       
    45 		lua_pushnil (L);
       
    46 	lua_remove (L, -2);
       
    47 	return 1;
       
    48 }
       
    49 
       
    50 /// message_node:prev
       
    51 /// Gets previous message node.
       
    52 /// R: lm message node object or nil
       
    53 static int llm_message_node_prev (lua_State *L)
       
    54 {
       
    55 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
    56 	LmMessageNode *node = object->message_node->prev;
       
    57 	if (node)
       
    58 		llm_message_node_bless (L, node);
       
    59 	else
       
    60 		lua_pushnil (L);
       
    61 	lua_remove (L, -2);
       
    62 	return 1;
       
    63 }
       
    64 
       
    65 /// message_node:children
       
    66 /// Gets first child node (raw access used).
       
    67 /// R: lm message node object or nil
       
    68 static int llm_message_node_children (lua_State *L)
       
    69 {
       
    70 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
    71 	LmMessageNode *node = object->message_node->children;
       
    72 	if (node)
       
    73 		llm_message_node_bless (L, node);
       
    74 	else
       
    75 		lua_pushnil (L);
       
    76 	lua_remove (L, -2);
       
    77 	return 1;
       
    78 }
       
    79 
       
    80 /// message_node:parent
       
    81 /// Gets parent message node.
       
    82 /// R: lm message node object or nil
       
    83 static int llm_message_node_parent (lua_State *L)
       
    84 {
       
    85 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
    86 	LmMessageNode *node = object->message_node->parent;
       
    87 	if (node)
       
    88 		llm_message_node_bless (L, node);
       
    89 	else
       
    90 		lua_pushnil (L);
       
    91 	lua_remove (L, -2);
       
    92 	return 1;
       
    93 }
       
    94 
       
    95 /// message_node:value
       
    96 /// Gets or sets a value of message node.
       
    97 /// A: string (optional value)
       
    98 /// R: string (if called without arguments)
       
    99 static int llm_message_node_value (lua_State *L)
       
   100 {
       
   101 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
   102 	if (lua_gettop (L) > 1) { // Set
       
   103 		const char *value = luaL_checkstring (L, 2);
       
   104 		lm_message_node_set_value (object->message_node, value);
       
   105 		lua_pop (L, 2);
       
   106 		return 0;
       
   107 	} else { // Get
       
   108 		lua_pushstring (L, lm_message_node_get_value (object->message_node));
       
   109 		lua_remove (L, -2);
       
   110 		return 1;
       
   111 	}
       
   112 }
       
   113 
       
   114 /// message_node:child
       
   115 /// Gets or creates child node object with given name.
       
   116 /// A: string (name), string (optional value)
       
   117 /// R: lm message node object or nil
       
   118 static int llm_message_node_child (lua_State *L)
       
   119 {
       
   120 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
   121 	const char *name = luaL_checkstring (L, 2);
       
   122 	LmMessageNode *child;
       
   123 
       
   124 	if (lua_gettop (L) > 2) { // Add
       
   125 		child = lm_message_node_add_child (object->message_node, name,
       
   126 						   luaL_checkstring (L, 3));
       
   127 		lua_pop (L, 1);
       
   128 	} else { // Get
       
   129 		child = lm_message_node_get_child (object->message_node, name);
       
   130 		if (!child) {
       
   131 			lua_pushnil (L);
       
   132 			return 1;
       
   133 		}
       
   134 	}
       
   135 	llm_message_node_bless (L, child);
       
   136 	// XXX lm_message_node_unref (child);
       
   137 	lua_remove (L, -2);
       
   138 	lua_remove (L, -2);
       
   139 	return 1;
       
   140 }
       
   141 
       
   142 /// message_node:find_child
       
   143 /// Searches for node with a given name over all node subtree.
       
   144 /// A: string (name)
       
   145 /// R: lm message node object or nil
       
   146 static int llm_message_node_find_child (lua_State *L)
       
   147 {
       
   148 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
   149 	const char *name = luaL_checkstring (L, 2);
       
   150 	LmMessageNode *child;
       
   151 
       
   152 	child = lm_message_node_get_child (object->message_node, name);
       
   153 	if (!child)
       
   154 		lua_pushnil (L);
       
   155 	else {
       
   156 		llm_message_node_bless (L, child);
       
   157 		// XXX lm_message_node_unref (child);
       
   158 	}
       
   159 	lua_remove (L, -2);
       
   160 	lua_remove (L, -2);
       
   161 	return 1;
       
   162 }
       
   163 
       
   164 /// message_node:raw
       
   165 /// Gets or sets raw mode flag for node.
       
   166 /// When set, value of node will not be escaped.
       
   167 /// A: boolean (optional)
       
   168 /// V: boolean (if called with no apguments)
       
   169 static int llm_message_node_raw (lua_State *L)
       
   170 {
       
   171 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
   172 	if (lua_gettop (L) > 1) { // Set
       
   173 		luaL_checktype (L, 2, LUA_TBOOLEAN);
       
   174 		lm_message_node_set_raw_mode (object->message_node, lua_toboolean (L, 2));
       
   175 		lua_pop (L, 2);
       
   176 		return 0;
       
   177 	} else { // Get
       
   178 		lua_pushboolean (L, lm_message_node_get_raw_mode (object->message_node));
       
   179 		lua_remove (L, -2);
       
   180 		return 1;
       
   181 	}
       
   182 }
       
   183 
       
   184 /// message_node:attribute
       
   185 /// Gets or sets value of node attribute with a given name.
       
   186 /// A: string (name), string (optional value)
       
   187 /// R: string (when called with one aprgument)
       
   188 static int llm_message_node_attribute (lua_State *L)
       
   189 {
       
   190 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
   191 	const char *name = luaL_checkstring (L, 2);
       
   192 	if (lua_gettop (L) > 2) { // Set
       
   193 		lm_message_node_set_attribute (object->message_node, name, luaL_checkstring (L, 3));
       
   194 		lua_pop (L, 3);
       
   195 		return 0;
       
   196 	} else { // Get
       
   197 		lua_pushstring (L, lm_message_node_get_attribute (object->message_node, name));
       
   198 		lua_remove (L, -2);
       
   199 		lua_remove (L, -2);
       
   200 		return 1;
       
   201 	}
       
   202 }
       
   203 
       
   204 /// message_node:xml
       
   205 /// Returns node representation in xml.
       
   206 /// R: string
       
   207 static int llm_message_node_xml (lua_State *L)
       
   208 {
       
   209 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
   210 	lua_pushstring (L, lm_message_node_to_string (object->message_node));
       
   211 	lua_remove (L, -2);
       
   212 	return 1;
       
   213 }
       
   214 
       
   215 /// message_node:pointer
       
   216 /// Returns pointer to underlying C structure.
       
   217 /// R: lightuserdata
       
   218 static int llm_message_node_pointer (lua_State *L)
       
   219 {
       
   220 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
   221 	lua_pushlightuserdata (L, object->message_node);
       
   222 	lua_remove (L, -2);
       
   223 	return 1;
       
   224 }
       
   225 
       
   226 static int llm_message_node_gc (lua_State *L)
       
   227 {
       
   228 	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
       
   229 	lm_message_node_unref (object->message_node);
       
   230 	lua_pop (L, 1);
       
   231 	return 0;
       
   232 }
       
   233 
       
   234 static const luaL_Reg llm_message_node_reg_f[] = {
       
   235 	{ "bless", llm_message_node_bless_lua },
       
   236 	{ NULL,    NULL                       },
       
   237 };
       
   238 
       
   239 static const luaL_Reg llm_message_node_reg_m[] = {
       
   240 	{ "name",       llm_message_node_name       },
       
   241 	{ "next",       llm_message_node_next       },
       
   242 	{ "prev",       llm_message_node_prev       },
       
   243 	{ "children",   llm_message_node_children   },
       
   244 	{ "parent",     llm_message_node_parent     },
       
   245 	{ "value",      llm_message_node_value      },
       
   246 	{ "child",      llm_message_node_child      },
       
   247 	{ "find_child", llm_message_node_find_child },
       
   248 	{ "attribute",  llm_message_node_attribute  },
       
   249 	{ "raw",        llm_message_node_raw        },
       
   250 	{ "xml",        llm_message_node_xml        },
       
   251 	{ "pointer",    llm_message_node_pointer    },
       
   252 	{ "__gc",       llm_message_node_gc         },
       
   253 	{ NULL,         NULL                        },
       
   254 };
       
   255 
       
   256 int luaopen_lm_message_node (lua_State *L)
       
   257 {
       
   258 	luaL_newmetatable (L, "loudmouth.message_node");
       
   259 	lua_pushstring (L, "__index");
       
   260 	lua_pushvalue (L, -2);
       
   261 	lua_settable (L, -3);
       
   262 	luaL_register (L, NULL, llm_message_node_reg_m);
       
   263 	lua_pop (L, 1);
       
   264 	luaL_register (L, "lm.message_node", llm_message_node_reg_f);
       
   265 	return 1;
       
   266 }
       
   267