util/caps.lua
changeset 3342 20e99763a08a
child 5776 bd0ff8ae98a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/caps.lua	Fri Jul 09 13:18:42 2010 +0100
@@ -0,0 +1,61 @@
+-- Prosody IM
+-- Copyright (C) 2008-2010 Matthew Wild
+-- Copyright (C) 2008-2010 Waqas Hussain
+-- 
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
+local base64 = require "util.encodings".base64.encode;
+local sha1 = require "util.hashes".sha1;
+
+local t_insert, t_sort, t_concat = table.insert, table.sort, table.concat;
+local ipairs = ipairs;
+
+module "caps"
+
+function calculate_hash(disco_info)
+	local identities, features, extensions = {}, {}, {};
+	for _, tag in ipairs(disco_info) do
+		if tag.name == "identity" then
+			t_insert(identities, (tag.attr.category or "").."\0"..(tag.attr.type or "").."\0"..(tag.attr["xml:lang"] or "").."\0"..(tag.attr.name or ""));
+		elseif tag.name == "feature" then
+			t_insert(features, tag.attr.var or "");
+		elseif tag.name == "x" and tag.attr.xmlns == "jabber:x:data" then
+			local form = {};
+			local FORM_TYPE;
+			for _, field in ipairs(tag.tags) do
+				if field.name == "field" and field.attr.var then
+					local values = {};
+					for _, val in ipairs(field.tags) do
+						val = #val.tags == 0 and val:get_text();
+						if val then t_insert(values, val); end
+					end
+					t_sort(values);
+					if field.attr.var == "FORM_TYPE" then
+						FORM_TYPE = values[1];
+					elseif #values > 0 then
+						t_insert(form, field.attr.var.."\0"..t_concat(values, "<"));
+					else
+						t_insert(form, field.attr.var);
+					end
+				end
+			end
+			t_sort(form);
+			form = t_concat(form, "<");
+			if FORM_TYPE then form = FORM_TYPE.."\0"..form; end
+			t_insert(extensions, form);
+		end
+	end
+	t_sort(identities);
+	t_sort(features);
+	t_sort(extensions);
+	if #identities > 0 then identities = t_concat(identities, "<"):gsub("%z", "/").."<"; else identities = ""; end
+	if #features > 0 then features = t_concat(features, "<").."<"; else features = ""; end
+	if #extensions > 0 then extensions = t_concat(extensions, "<"):gsub("%z", "<").."<"; else extensions = ""; end
+	local S = identities..features..extensions;
+	local ver = base64(sha1(S));
+	return ver, S;
+end
+
+return _M;