|
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 |