2 -- Copyright (C) 2008-2009 Matthew Wild
3 -- Copyright (C) 2008-2009 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
13 local t_concat = table.concat;
14 local t_insert = table.insert;
15 local tostring = tostring;
16 local tonumber = tonumber;
17 local select = select;
18 local st = require "util.stanza";
24 table=function(stanza, object)
26 for name, value in pairs(object) do
28 stanza:tag("name"):text(tostring(name)):up();
30 _lua_to_xmlrpc(stanza, value);
36 boolean=function(stanza, object)
37 stanza:tag("boolean"):text(object and "1" or "0"):up();
39 string=function(stanza, object)
40 stanza:tag("string"):text(object):up();
42 number=function(stanza, object)
43 stanza:tag("int"):text(tostring(object)):up();
45 ["nil"]=function(stanza, object) -- nil extension
46 stanza:tag("nil"):up();
49 _lua_to_xmlrpc = function(stanza, ...)
50 for i=1,select('#', ...) do
51 stanza:tag("param"):tag("value");
52 local object = select(i, ...);
53 local h = map[type(object)];
57 error("Type not supported by XML-RPC: " .. type(object));
62 function create_response(object)
63 local stanza = st.stanza("methodResponse"):tag("params"):tag("param"):tag("value");
64 _lua_to_xmlrpc(stanza, object);
65 stanza:up():up():up();
68 function create_error_response(faultCode, faultString)
69 local stanza = st.stanza("methodResponse"):tag("fault"):tag("value");
70 _lua_to_xmlrpc(stanza, {faultCode=faultCode, faultString=faultString});
75 function create_request(method_name, ...)
76 local stanza = st.stanza("methodCall")
77 :tag("methodName"):text(method_name):up()
79 _lua_to_xmlrpc(stanza, ...);
80 stanza:up():up():up();
85 local int_parse = function(stanza)
86 if #stanza.tags ~= 0 or #stanza == 0 then error("<"..stanza.name.."> must have a single text child"); end
87 local n = tonumber(t_concat(stanza));
88 if n then return n; end
89 error("Failed to parse content of <"..stanza.name..">");
92 methodCall=function(stanza)
93 if #stanza.tags ~= 2 then error("<methodCall> must have exactly two subtags"); end -- FIXME <params> is optional
94 if stanza.tags[1].name ~= "methodName" then error("First <methodCall> child tag must be <methodName>") end
95 if stanza.tags[2].name ~= "params" then error("Second <methodCall> child tag must be <params>") end
96 return _xmlrpc_to_lua(stanza.tags[1]), _xmlrpc_to_lua(stanza.tags[2]);
98 methodName=function(stanza)
99 if #stanza.tags ~= 0 then error("<methodName> must not have any subtags"); end
100 if #stanza == 0 then error("<methodName> must have text content"); end
101 return t_concat(stanza);
103 params=function(stanza)
105 for _, child in pairs(stanza.tags) do
106 if child.name ~= "param" then error("<params> can only have <param> children"); end;
107 t_insert(t, _xmlrpc_to_lua(child));
111 param=function(stanza)
112 if not(#stanza.tags == 1 and stanza.tags[1].name == "value") then error("<param> must have exactly one <value> child"); end
113 return _xmlrpc_to_lua(stanza.tags[1]);
115 value=function(stanza)
116 if #stanza.tags == 0 then return t_concat(stanza); end
117 if #stanza.tags ~= 1 then error("<value> must have a single child"); end
118 return _xmlrpc_to_lua(stanza.tags[1]);
123 boolean=function(stanza)
124 if #stanza.tags ~= 0 or #stanza == 0 then error("<boolean> must have a single text child"); end
125 local b = t_concat(stanza);
126 if b ~= "1" and b ~= "0" then error("Failed to parse content of <boolean>"); end
127 return b == "1" and true or false;
129 string=function(stanza)
130 if #stanza.tags ~= 0 then error("<string> must have a single text child"); end
131 return t_concat(stanza);
133 array=function(stanza)
134 if #stanza.tags ~= 1 then error("<array> must have a single <data> child"); end
135 return _xmlrpc_to_lua(stanza.tags[1]);
137 data=function(stanza)
139 for _,child in pairs(stanza.tags) do
140 if child.name ~= "value" then error("<data> can only have <value> children"); end
141 t_insert(t, _xmlrpc_to_lua(child));
145 struct=function(stanza)
147 for _,child in pairs(stanza.tags) do
148 if child.name ~= "member" then error("<struct> can only have <member> children"); end
149 local name, value = _xmlrpc_to_lua(child);
154 member=function(stanza)
155 if #stanza.tags ~= 2 then error("<member> must have exactly two subtags"); end -- FIXME <params> is optional
156 if stanza.tags[1].name ~= "name" then error("First <member> child tag must be <name>") end
157 if stanza.tags[2].name ~= "value" then error("Second <member> child tag must be <value>") end
158 return _xmlrpc_to_lua(stanza.tags[1]), _xmlrpc_to_lua(stanza.tags[2]);
160 name=function(stanza)
161 if #stanza.tags ~= 0 then error("<name> must have a single text child"); end
162 local n = t_concat(stanza)
163 if tostring(tonumber(n)) == n then n = tonumber(n); end
166 ["nil"]=function(stanza) -- nil extension
170 _xmlrpc_to_lua = function(stanza)
171 local h = rmap[stanza.name];
175 error("Unknown element: "..stanza.name);
178 function translate_request(stanza)
179 if stanza.name ~= "methodCall" then error("XML-RPC requests must have <methodCall> as root element"); end
180 return _xmlrpc_to_lua(stanza);