util/stanza.lua
changeset 8629 20532f191f8d
parent 8602 62bfc85a53c8
child 8643 8f13ec2ceb06
equal deleted inserted replaced
8628:08bf4df6fdb7 8629:20532f191f8d
     5 -- This project is MIT/X11 licensed. Please see the
     5 -- This project is MIT/X11 licensed. Please see the
     6 -- COPYING file in the source package for more information.
     6 -- COPYING file in the source package for more information.
     7 --
     7 --
     8 
     8 
     9 
     9 
    10 local assert        =        assert;
    10 local error         =         error;
    11 local t_insert      =  table.insert;
    11 local t_insert      =  table.insert;
    12 local t_remove      =  table.remove;
    12 local t_remove      =  table.remove;
    13 local t_concat      =  table.concat;
    13 local t_concat      =  table.concat;
    14 local s_format      = string.format;
    14 local s_format      = string.format;
    15 local s_match       =  string.match;
    15 local s_match       =  string.match;
    43 -- luacheck: std none
    43 -- luacheck: std none
    44 
    44 
    45 local stanza_mt = { __name = "stanza" };
    45 local stanza_mt = { __name = "stanza" };
    46 stanza_mt.__index = stanza_mt;
    46 stanza_mt.__index = stanza_mt;
    47 
    47 
    48 local function check_name(name)
    48 local function check_name(name, name_type)
    49 	assert(type(name) == "string", "tag name is not a string, "..type(name));
    49 	if type(name) ~= "string" then
    50 	assert(#name > 0, "tag name is empty");
    50 		error("invalid "..name_type.." name: expected string, got "..type(name));
    51 	assert(not s_find(name, "[<>& '\"]"), "tag name contains invalid characters");
    51 	elseif #name == 0 then
    52 	assert(valid_utf8(name), "tag name is invalid utf8");
    52 		error("invalid "..name_type.." name: empty string");
    53 end
    53 	elseif s_find(name, "[<>& '\"]") then
       
    54 		error("invalid "..name_type.." name: contains invalid characters");
       
    55 	elseif not valid_utf8(name) then
       
    56 		error("invalid "..name_type.." name: contains invalid utf8");
       
    57 	end
       
    58 end
       
    59 
       
    60 local function check_text(text, text_type)
       
    61 	if type(text) ~= "string" then
       
    62 		error("invalid "..text_type.." value: expected string, got "..type(text));
       
    63 	elseif not valid_utf8(text) then
       
    64 		error("invalid "..text_type.." value: contains invalid utf8");
       
    65 	end
       
    66 end
       
    67 
    54 local function check_attr(attr)
    68 local function check_attr(attr)
    55 	if attr ~= nil then
    69 	if attr ~= nil then
    56 		assert(type(attr) == "table", "attribute is not a table");
    70 		if type(attr) ~= "table" then
       
    71 			error("invalid attributes, expected table got "..type(attr));
       
    72 		end
    57 		for k, v in pairs(attr) do
    73 		for k, v in pairs(attr) do
    58 			assert(type(k) == "string", "non-string key in attributes");
    74 			check_name(k, "attribute");
    59 			assert(valid_utf8(k), "attribute name is not valid utf8");
    75 			check_text(v, "attribute");
    60 			assert(type(v) == "string", "non-string value in attributes");
    76 			if type(v) ~= "string" then
    61 			assert(valid_utf8(v), "attribute value is not valid utf8");
    77 				error("invalid attribute value for '"..k.."': expected string, got "..type(v));
    62 		end
    78 			elseif not valid_utf8(v) then
    63 	end
    79 				error("invalid attribute value for '"..k.."': contains invalid utf8");
    64 end
    80 			end
    65 local function check_text(text)
    81 		end
    66 	assert(type(text) == "string", "text is not a string");
    82 	end
    67 	assert(valid_utf8(text), "text is not valid utf8");
       
    68 end
    83 end
    69 
    84 
    70 local function new_stanza(name, attr, namespaces)
    85 local function new_stanza(name, attr, namespaces)
    71 	assert(name)
    86 	check_name(name, "tag");
    72 	check_name(name);
       
    73 	check_attr(attr);
    87 	check_attr(attr);
    74 	local stanza = { name = name, attr = attr or {}, namespaces = namespaces, tags = {} };
    88 	local stanza = { name = name, attr = attr or {}, namespaces = namespaces, tags = {} };
    75 	return setmetatable(stanza, stanza_mt);
    89 	return setmetatable(stanza, stanza_mt);
    76 end
    90 end
    77 
    91 
    95 	t_insert(last_add, s);
   109 	t_insert(last_add, s);
    96 	return self;
   110 	return self;
    97 end
   111 end
    98 
   112 
    99 function stanza_mt:text(text)
   113 function stanza_mt:text(text)
   100 	check_text(text);
   114 	check_text(text, "text");
   101 	local last_add = self.last_add;
   115 	local last_add = self.last_add;
   102 	(last_add and last_add[#last_add] or self):add_direct_child(text);
   116 	(last_add and last_add[#last_add] or self):add_direct_child(text);
   103 	return self;
   117 	return self;
   104 end
   118 end
   105 
   119