node: Use new loudmouth feature - public attribute list (v0.9.7) v0.9.7
authorMyhailo Danylenko <isbear@ukrpost.net>
Wed, 16 Mar 2016 01:53:56 +0200
changeset 66 a40beb82130c
parent 65 72ffcf688664
child 67 b6234242fc7e
node: Use new loudmouth feature - public attribute list (v0.9.7)
CMakeLists.txt
config.h.in
docs/api.mdwn
lm.lua
lm_message_node.c
--- a/CMakeLists.txt	Sat Mar 05 18:04:48 2016 +0200
+++ b/CMakeLists.txt	Wed Mar 16 01:53:56 2016 +0200
@@ -16,7 +16,7 @@
 
 cmake_minimum_required(VERSION 2.6)
 project(lua-lm C)
-set(PROJECT_VERSION "0.9.6")
+set(PROJECT_VERSION "0.9.7")
 
 ## User options
 option(DEBUG         "Enable debugging output" OFF)
@@ -55,6 +55,7 @@
 	pkg_check_modules(LM REQUIRED loudmouth-1.0)
 endif()
 include(CheckFunctionExists)
+include(CheckStructHasMember)
 set(CMAKE_REQUIRED_INCLUDES ${LM_INCLUDE_DIRS})
 set(CMAKE_REQUIRED_LIBRARIES ${LM_LIBRARIES})
 set(CMAKE_REQUIRED_FLAGS ${LM_LDFLAGS} ${LM_CFLAGS})
@@ -62,6 +63,7 @@
 check_function_exists(lm_connection_unregister_reply_handler HAVE_LM_CONNECTION_UNREGISTER_REPLY_HANDLER)
 check_function_exists(lm_ssl_set_ca HAVE_LM_SSL_SET_CA)
 check_function_exists(lm_ssl_set_cipher_list HAVE_LM_SSL_SET_CIPHER_LIST)
+check_struct_has_member("LmMessageNodeAttribute" next loudmouth/loudmouth.h HAVE_LM_MESSAGE_NODE_ATTRIBUTE)
 find_program(DOCGEN_EXECUTABLE NAMES docgen.pl docgen DOC "Docgen documentation generator script (optional)")
 # (this should be before targets definitions)
 link_directories(${LUA_LIBRARY_DIRS} ${GLIB_LIBRARY_DIRS} ${LM_LIBRARY_DIRS})
--- a/config.h.in	Sat Mar 05 18:04:48 2016 +0200
+++ b/config.h.in	Wed Mar 16 01:53:56 2016 +0200
@@ -37,6 +37,9 @@
 // define this, if your loudmouth have lm_ssl_set_cipher_list ()
 #cmakedefine HAVE_LM_SSL_SET_CIPHER_LIST
 
+// define this, if your loudmouth have LmMessageNodeAttribute
+#cmakedefine HAVE_LM_MESSAGE_NODE_ATTRIBUTE
+
 // building against lua 5.1
 #cmakedefine LUA51_COMPATIBILITY
 
--- a/docs/api.mdwn	Sat Mar 05 18:04:48 2016 +0200
+++ b/docs/api.mdwn	Wed Mar 16 01:53:56 2016 +0200
@@ -396,6 +396,11 @@
 **Arguments:** string (name), string (optional value)    
 **Return values:** string (when called with one aprgument) or [lm message node](#lm.message.node) object  
 
+<a name="message.node:attributes"></a>
+### message_node:attributes
+Returns a table with message node attributes.  
+**Return values:** table  
+
 <a name="message.node:xml"></a>
 ### message_node:xml
 Returns node representation in xml.  
--- a/lm.lua	Sat Mar 05 18:04:48 2016 +0200
+++ b/lm.lua	Wed Mar 16 01:53:56 2016 +0200
@@ -196,34 +196,34 @@
 	end
 end
 
--- TODO: multiple nodes with same name
-function lm.message_node.parse ( node, r )
+function lm.message_node.parse ( node )
+	-- attributes
+	local r = node:attributes ()
+	-- node value (text)
+	local value = n:value ()
+	if value then
+		s[1] = value
+	end
+	-- children nodes
 	local n = node:child ()
-	while n do
+	for n in node:children () do
 		local name = n:name ()
-		r[name] = { }
-		local value = n:value ()
-		if value then
-			r[name][1] = value
+		if type ( r[name] ) ~= 'table' then
+			r[name] = { }
 		end
-		lm.message_node.parse ( n, r[name] )
-		n = n:next ()
+		table.insert ( r[name], lm.message_node.parse ( n ) )
 	end
+	return r
 end
 
--- There are NO WAY to get a list of node attributes,
--- except brute force...
 function lm.message.parse ( message )
+	local r = lm.message_node.parse ( message )
+	-- message type we treat in a special way
 	local mtype, subtype = message:type ()
 	if subtype then
 		mtype = mtype .. '-' .. subtype
 	end
-	local r = { mtype = mtype }
-	local value = message:value ()
-	if value then
-		r[1] = value
-	end
-	lm.message_node.parse ( message, r )
+	r['mtype'] = mtype
 	return r
 end
 
--- a/lm_message_node.c	Sat Mar 05 18:04:48 2016 +0200
+++ b/lm_message_node.c	Wed Mar 16 01:53:56 2016 +0200
@@ -1,5 +1,5 @@
 
-/* Copyright 2009 Myhailo Danylenko
+/* Copyright 2009-2016 Myhailo Danylenko
 
 This file is part of lua-lm.
 
@@ -229,6 +229,23 @@
 	return 1;
 }
 
+/// message_node:attributes
+/// Returns a table with message node attributes.
+/// R: table
+int attributes_lm_node (lua_State *L)
+{
+	lua_newtable (L);
+#ifdef HAVE_LM_MESSAGE_NODE_ATTRIBUTE
+	LmMessageNode          *node = luaL_checkLmMessageNode (L, 1);
+	LmMessageNodeAttribute *attribute;
+	for (attribute = node -> attributes; attribute; attribute = attribute -> next) {
+		lua_pushstring (L, attribute -> value);
+		lua_setfield (L, -2, attribute -> name);
+	}
+#endif
+	return 1;
+}
+
 /// message_node:xml
 /// Returns node representation in xml.
 /// R: string