util/stanza.lua
author Matthew Wild <mwild1@gmail.com>
Tue, 11 Oct 2022 11:37:55 +0100
changeset 12767 d26eefe98d09
parent 12729 12ced5db29b2
child 12806 4a8740e01813
permissions -rw-r--r--
util.dbuffer: Add efficient shortcuts for discard() in certain cases If the buffer is already empty, nothing to do. If we're throwing away the whole buffer, we can just empty it and avoid read_chunk() (which in turn may collapse()). These shortcuts are much more efficient.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1523
841d61be198f Remove version number from copyright headers
Matthew Wild <mwild1@gmail.com>
parents: 1517
diff changeset
     1
-- Prosody IM
2923
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 2848
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 2848
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5435
diff changeset
     4
--
758
b1885732e979 GPL->MIT!
Matthew Wild <mwild1@gmail.com>
parents: 689
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
b1885732e979 GPL->MIT!
Matthew Wild <mwild1@gmail.com>
parents: 689
diff changeset
     6
-- COPYING file in the source package for more information.
4199
43cf7d96956f util.stanza: Whitespace fix after merge (complicated)
Matthew Wild <mwild1@gmail.com>
parents: 4184
diff changeset
     7
--
519
cccd610a0ef9 Insert copyright/license headers
Matthew Wild <mwild1@gmail.com>
parents: 373
diff changeset
     8
1984
f2b1f89e1d7c util.stanza: Don't add xmlns to tags when serializing if same as the parent tag's xmlns. Should hopefully shut up Gajim once and for all :)
Matthew Wild <mwild1@gmail.com>
parents: 1935
diff changeset
     9
8629
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    10
local error         =         error;
1
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
    11
local t_insert      =  table.insert;
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
    12
local t_remove      =  table.remove;
613
6c09127b50fb New, faster, stanza serialization
Matthew Wild <mwild1@gmail.com>
parents: 519
diff changeset
    13
local t_concat      =  table.concat;
829
b01fd698495e util/stanza: Added clone function
Waqas Hussain <waqas20@gmail.com>
parents: 776
diff changeset
    14
local s_match       =  string.match;
1
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
    15
local tostring      =      tostring;
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
    16
local setmetatable  =  setmetatable;
7753
e58524240b30 util.stanza: Add an is_stanza() function to check if an object is a stanza
Kim Alvefur <zash@zash.se>
parents: 7256
diff changeset
    17
local getmetatable  =  getmetatable;
1
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
    18
local pairs         =         pairs;
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
    19
local ipairs        =        ipairs;
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
    20
local type          =          type;
4
09c3845ed442 Presence unavailable on disconnect
matthew
parents: 2
diff changeset
    21
local s_gsub        =   string.gsub;
5424
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
    22
local s_sub         =    string.sub;
1431
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
    23
local s_find        =   string.find;
12410
a3ddf3f42212 util.stanza: Use table.move in clone
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
    24
local t_move        =    table.move or require "util.table".move;
12411
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
    25
local t_create = require"util.table".create;
145
fbb3a4ff9cf1 dialback keys now verified
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
    26
8602
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    27
local valid_utf8 = require "util.encodings".utf8.valid;
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    28
11643
ad39528e647d util.stanza: Remove Windows "support" (disabling ANSI color pretty printing)
Kim Alvefur <zash@zash.se>
parents: 11578
diff changeset
    29
local do_pretty_printing, termcolours = pcall(require, "util.termcolours");
262
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
    30
2955
f807dc244a5b util.stanza: Fixed a nil global access.
Waqas Hussain <waqas20@gmail.com>
parents: 2923
diff changeset
    31
local xmlns_stanzas = "urn:ietf:params:xml:ns:xmpp-stanzas";
12691
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
    32
local xmpp_stanzas_attr = { xmlns = xmlns_stanzas };
2955
f807dc244a5b util.stanza: Fixed a nil global access.
Waqas Hussain <waqas20@gmail.com>
parents: 2923
diff changeset
    33
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
    34
local _ENV = nil;
8558
4f0f5b49bb03 vairious: Add annotation when an empty environment is set [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8523
diff changeset
    35
-- luacheck: std none
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
    36
8523
e959bc51de75 util.stanza: Change __type to __name as this is used by Lua 5.3 in some error reporting functions
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    37
local stanza_mt = { __name = "stanza" };
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
    38
stanza_mt.__index = stanza_mt;
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
    39
11209
9d1e21c23784 util.stanza: Reject ASCII control characters (fixes #1606)
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
    40
local function valid_xml_cdata(str, attr)
9d1e21c23784 util.stanza: Reject ASCII control characters (fixes #1606)
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
    41
	return not s_find(str, attr and "[^\1\9\10\13\20-~\128-\247]" or "[^\9\10\13\20-~\128-\247]");
9d1e21c23784 util.stanza: Reject ASCII control characters (fixes #1606)
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
    42
end
9d1e21c23784 util.stanza: Reject ASCII control characters (fixes #1606)
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
    43
8629
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    44
local function check_name(name, name_type)
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    45
	if type(name) ~= "string" then
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    46
		error("invalid "..name_type.." name: expected string, got "..type(name));
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    47
	elseif #name == 0 then
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    48
		error("invalid "..name_type.." name: empty string");
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    49
	elseif s_find(name, "[<>& '\"]") then
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    50
		error("invalid "..name_type.." name: contains invalid characters");
11209
9d1e21c23784 util.stanza: Reject ASCII control characters (fixes #1606)
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
    51
	elseif not valid_xml_cdata(name, name_type == "attribute") then
9d1e21c23784 util.stanza: Reject ASCII control characters (fixes #1606)
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
    52
		error("invalid "..name_type.." name: contains control characters");
8629
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    53
	elseif not valid_utf8(name) then
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    54
		error("invalid "..name_type.." name: contains invalid utf8");
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    55
	end
8602
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    56
end
8629
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    57
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    58
local function check_text(text, text_type)
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    59
	if type(text) ~= "string" then
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    60
		error("invalid "..text_type.." value: expected string, got "..type(text));
11265
be38ae8fdfa5 util.stanza: Move misplaced argument to correct place
Kim Alvefur <zash@zash.se>
parents: 11209
diff changeset
    61
	elseif not valid_xml_cdata(text, false) then
11209
9d1e21c23784 util.stanza: Reject ASCII control characters (fixes #1606)
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
    62
		error("invalid "..text_type.." value: contains control characters");
11265
be38ae8fdfa5 util.stanza: Move misplaced argument to correct place
Kim Alvefur <zash@zash.se>
parents: 11209
diff changeset
    63
	elseif not valid_utf8(text) then
8629
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    64
		error("invalid "..text_type.." value: contains invalid utf8");
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    65
	end
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    66
end
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    67
8602
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    68
local function check_attr(attr)
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    69
	if attr ~= nil then
8629
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    70
		if type(attr) ~= "table" then
12142
644ca3583837 util.stanza: Make type error message consistent with others
Kim Alvefur <zash@zash.se>
parents: 11964
diff changeset
    71
			error("invalid attributes: expected table, got "..type(attr));
8629
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    72
		end
8602
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    73
		for k, v in pairs(attr) do
8629
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    74
			check_name(k, "attribute");
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    75
			check_text(v, "attribute");
8602
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    76
		end
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    77
	end
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    78
end
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    79
7259
9fbb9fbf7e52 Merge 0.10->trunk
Matthew Wild <mwild1@gmail.com>
parents: 6981 7256
diff changeset
    80
local function new_stanza(name, attr, namespaces)
8629
20532f191f8d util.stanza: Switch from asserts to if's, improve performance, errors and tests
Matthew Wild <mwild1@gmail.com>
parents: 8602
diff changeset
    81
	check_name(name, "tag");
8602
62bfc85a53c8 util.stanza: Add stricter validation for data passed to stanza builder API
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    82
	check_attr(attr);
6981
30c96a5db360 util.stanza, util.xml, util.xmppstream: Add support for tracking defined namespaces and their prefix (stanza.namespaces), knowing/preserving prefix names is required for some applications (thanks daurnimator)
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
    83
	local stanza = { name = name, attr = attr or {}, namespaces = namespaces, tags = {} };
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
    84
	return setmetatable(stanza, stanza_mt);
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
    85
end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
    86
7753
e58524240b30 util.stanza: Add an is_stanza() function to check if an object is a stanza
Kim Alvefur <zash@zash.se>
parents: 7256
diff changeset
    87
local function is_stanza(s)
e58524240b30 util.stanza: Add an is_stanza() function to check if an object is a stanza
Kim Alvefur <zash@zash.se>
parents: 7256
diff changeset
    88
	return getmetatable(s) == stanza_mt;
e58524240b30 util.stanza: Add an is_stanza() function to check if an object is a stanza
Kim Alvefur <zash@zash.se>
parents: 7256
diff changeset
    89
end
e58524240b30 util.stanza: Add an is_stanza() function to check if an object is a stanza
Kim Alvefur <zash@zash.se>
parents: 7256
diff changeset
    90
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
    91
function stanza_mt:query(xmlns)
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
    92
	return self:tag("query", { xmlns = xmlns });
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
    93
end
373
dd0345edeaf4 Add helper function for adding message bodies to stanzas
Matthew Wild <mwild1@gmail.com>
parents: 338
diff changeset
    94
dd0345edeaf4 Add helper function for adding message bodies to stanzas
Matthew Wild <mwild1@gmail.com>
parents: 338
diff changeset
    95
function stanza_mt:body(text, attr)
10120
4807535b8673 util.stanza: Use :text_tag internally everywhere
Kim Alvefur <zash@zash.se>
parents: 9928
diff changeset
    96
	return self:text_tag("body", text, attr);
373
dd0345edeaf4 Add helper function for adding message bodies to stanzas
Matthew Wild <mwild1@gmail.com>
parents: 338
diff changeset
    97
end
dd0345edeaf4 Add helper function for adding message bodies to stanzas
Matthew Wild <mwild1@gmail.com>
parents: 338
diff changeset
    98
8648
06c73b010488 util.stanza: Add :text_tag(), a shortcut for adding nodes with text
Kim Alvefur <zash@zash.se>
parents: 8643
diff changeset
    99
function stanza_mt:text_tag(name, text, attr, namespaces)
06c73b010488 util.stanza: Add :text_tag(), a shortcut for adding nodes with text
Kim Alvefur <zash@zash.se>
parents: 8643
diff changeset
   100
	return self:tag(name, attr, namespaces):text(text):up();
06c73b010488 util.stanza: Add :text_tag(), a shortcut for adding nodes with text
Kim Alvefur <zash@zash.se>
parents: 8643
diff changeset
   101
end
06c73b010488 util.stanza: Add :text_tag(), a shortcut for adding nodes with text
Kim Alvefur <zash@zash.se>
parents: 8643
diff changeset
   102
6981
30c96a5db360 util.stanza, util.xml, util.xmppstream: Add support for tracking defined namespaces and their prefix (stanza.namespaces), knowing/preserving prefix names is required for some applications (thanks daurnimator)
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
   103
function stanza_mt:tag(name, attr, namespaces)
7259
9fbb9fbf7e52 Merge 0.10->trunk
Matthew Wild <mwild1@gmail.com>
parents: 6981 7256
diff changeset
   104
	local s = new_stanza(name, attr, namespaces);
3638
6f58a3063c14 util.stanza, util.xmppstream, core.xmlhandlers: Allow stanza.last_add to be nil, and set it nil by default. Saves a table allocation per-element. 20% faster stanza building.
Waqas Hussain <waqas20@gmail.com>
parents: 3502
diff changeset
   105
	local last_add = self.last_add;
6f58a3063c14 util.stanza, util.xmppstream, core.xmlhandlers: Allow stanza.last_add to be nil, and set it nil by default. Saves a table allocation per-element. 20% faster stanza building.
Waqas Hussain <waqas20@gmail.com>
parents: 3502
diff changeset
   106
	if not last_add then last_add = {}; self.last_add = last_add; end
6f58a3063c14 util.stanza, util.xmppstream, core.xmlhandlers: Allow stanza.last_add to be nil, and set it nil by default. Saves a table allocation per-element. 20% faster stanza building.
Waqas Hussain <waqas20@gmail.com>
parents: 3502
diff changeset
   107
	(last_add[#last_add] or self):add_direct_child(s);
6f58a3063c14 util.stanza, util.xmppstream, core.xmlhandlers: Allow stanza.last_add to be nil, and set it nil by default. Saves a table allocation per-element. 20% faster stanza building.
Waqas Hussain <waqas20@gmail.com>
parents: 3502
diff changeset
   108
	t_insert(last_add, s);
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   109
	return self;
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   110
end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   111
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   112
function stanza_mt:text(text)
8643
8f13ec2ceb06 util.stanza: Allow :text(nil) and :text("") as harmless nops
Matthew Wild <mwild1@gmail.com>
parents: 8629
diff changeset
   113
	if text ~= nil and text ~= "" then
8f13ec2ceb06 util.stanza: Allow :text(nil) and :text("") as harmless nops
Matthew Wild <mwild1@gmail.com>
parents: 8629
diff changeset
   114
		local last_add = self.last_add;
8f13ec2ceb06 util.stanza: Allow :text(nil) and :text("") as harmless nops
Matthew Wild <mwild1@gmail.com>
parents: 8629
diff changeset
   115
		(last_add and last_add[#last_add] or self):add_direct_child(text);
8f13ec2ceb06 util.stanza: Allow :text(nil) and :text("") as harmless nops
Matthew Wild <mwild1@gmail.com>
parents: 8629
diff changeset
   116
	end
2482
a1570e371258 util.stanza: Trailing whitespace
Matthew Wild <mwild1@gmail.com>
parents: 2264
diff changeset
   117
	return self;
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   118
end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   119
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   120
function stanza_mt:up()
3638
6f58a3063c14 util.stanza, util.xmppstream, core.xmlhandlers: Allow stanza.last_add to be nil, and set it nil by default. Saves a table allocation per-element. 20% faster stanza building.
Waqas Hussain <waqas20@gmail.com>
parents: 3502
diff changeset
   121
	local last_add = self.last_add;
6f58a3063c14 util.stanza, util.xmppstream, core.xmlhandlers: Allow stanza.last_add to be nil, and set it nil by default. Saves a table allocation per-element. 20% faster stanza building.
Waqas Hussain <waqas20@gmail.com>
parents: 3502
diff changeset
   122
	if last_add then t_remove(last_add); end
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   123
	return self;
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   124
end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   125
11578
21217f7e82b9 util.stanza: add at_top helper
Jonas Schäfer <jonas@wielicki.name>
parents: 11268
diff changeset
   126
function stanza_mt:at_top()
21217f7e82b9 util.stanza: add at_top helper
Jonas Schäfer <jonas@wielicki.name>
parents: 11268
diff changeset
   127
	return self.last_add == nil or #self.last_add == 0
21217f7e82b9 util.stanza: add at_top helper
Jonas Schäfer <jonas@wielicki.name>
parents: 11268
diff changeset
   128
end
21217f7e82b9 util.stanza: add at_top helper
Jonas Schäfer <jonas@wielicki.name>
parents: 11268
diff changeset
   129
964
3296db2ad4a0 util.stanza: stanza:reset() method to reset building state
Matthew Wild <mwild1@gmail.com>
parents: 896
diff changeset
   130
function stanza_mt:reset()
3638
6f58a3063c14 util.stanza, util.xmppstream, core.xmlhandlers: Allow stanza.last_add to be nil, and set it nil by default. Saves a table allocation per-element. 20% faster stanza building.
Waqas Hussain <waqas20@gmail.com>
parents: 3502
diff changeset
   131
	self.last_add = nil;
964
3296db2ad4a0 util.stanza: stanza:reset() method to reset building state
Matthew Wild <mwild1@gmail.com>
parents: 896
diff changeset
   132
	return self;
3296db2ad4a0 util.stanza: stanza:reset() method to reset building state
Matthew Wild <mwild1@gmail.com>
parents: 896
diff changeset
   133
end
3296db2ad4a0 util.stanza: stanza:reset() method to reset building state
Matthew Wild <mwild1@gmail.com>
parents: 896
diff changeset
   134
180
d8b9a19d70eb Make add_child() behave as expected. Old add_child() is now add_direct_child()
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
   135
function stanza_mt:add_direct_child(child)
8892
c4e430c69f88 util.stanza: Verify that child tags added are really stanzas (closes #1165)
Kim Alvefur <zash@zash.se>
parents: 8648
diff changeset
   136
	if is_stanza(child) then
1
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
   137
		t_insert(self.tags, child);
8893
3490bc478804 util.stanza: Verify that other objects added as children are valid strings
Kim Alvefur <zash@zash.se>
parents: 8892
diff changeset
   138
		t_insert(self, child);
3490bc478804 util.stanza: Verify that other objects added as children are valid strings
Kim Alvefur <zash@zash.se>
parents: 8892
diff changeset
   139
	else
3490bc478804 util.stanza: Verify that other objects added as children are valid strings
Kim Alvefur <zash@zash.se>
parents: 8892
diff changeset
   140
		check_text(child, "text");
3490bc478804 util.stanza: Verify that other objects added as children are valid strings
Kim Alvefur <zash@zash.se>
parents: 8892
diff changeset
   141
		t_insert(self, child);
1
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
   142
	end
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   143
end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   144
180
d8b9a19d70eb Make add_child() behave as expected. Old add_child() is now add_direct_child()
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
   145
function stanza_mt:add_child(child)
3638
6f58a3063c14 util.stanza, util.xmppstream, core.xmlhandlers: Allow stanza.last_add to be nil, and set it nil by default. Saves a table allocation per-element. 20% faster stanza building.
Waqas Hussain <waqas20@gmail.com>
parents: 3502
diff changeset
   146
	local last_add = self.last_add;
6f58a3063c14 util.stanza, util.xmppstream, core.xmlhandlers: Allow stanza.last_add to be nil, and set it nil by default. Saves a table allocation per-element. 20% faster stanza building.
Waqas Hussain <waqas20@gmail.com>
parents: 3502
diff changeset
   147
	(last_add and last_add[#last_add] or self):add_direct_child(child);
180
d8b9a19d70eb Make add_child() behave as expected. Old add_child() is now add_direct_child()
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
   148
	return self;
d8b9a19d70eb Make add_child() behave as expected. Old add_child() is now add_direct_child()
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
   149
end
d8b9a19d70eb Make add_child() behave as expected. Old add_child() is now add_direct_child()
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
   150
9001
6bddc90eeb27 util.stanza: Add method for removing all children with a specific name, xmlns
Kim Alvefur <zash@zash.se>
parents: 7753
diff changeset
   151
function stanza_mt:remove_children(name, xmlns)
6bddc90eeb27 util.stanza: Add method for removing all children with a specific name, xmlns
Kim Alvefur <zash@zash.se>
parents: 7753
diff changeset
   152
	xmlns = xmlns or self.attr.xmlns;
6bddc90eeb27 util.stanza: Add method for removing all children with a specific name, xmlns
Kim Alvefur <zash@zash.se>
parents: 7753
diff changeset
   153
	return self:maptags(function (tag)
6bddc90eeb27 util.stanza: Add method for removing all children with a specific name, xmlns
Kim Alvefur <zash@zash.se>
parents: 7753
diff changeset
   154
		if (not name or tag.name == name) and tag.attr.xmlns == xmlns then
6bddc90eeb27 util.stanza: Add method for removing all children with a specific name, xmlns
Kim Alvefur <zash@zash.se>
parents: 7753
diff changeset
   155
			return nil;
6bddc90eeb27 util.stanza: Add method for removing all children with a specific name, xmlns
Kim Alvefur <zash@zash.se>
parents: 7753
diff changeset
   156
		end
6bddc90eeb27 util.stanza: Add method for removing all children with a specific name, xmlns
Kim Alvefur <zash@zash.se>
parents: 7753
diff changeset
   157
		return tag;
6bddc90eeb27 util.stanza: Add method for removing all children with a specific name, xmlns
Kim Alvefur <zash@zash.se>
parents: 7753
diff changeset
   158
	end);
6bddc90eeb27 util.stanza: Add method for removing all children with a specific name, xmlns
Kim Alvefur <zash@zash.se>
parents: 7753
diff changeset
   159
end
6bddc90eeb27 util.stanza: Add method for removing all children with a specific name, xmlns
Kim Alvefur <zash@zash.se>
parents: 7753
diff changeset
   160
2264
49580a13f71e util.stanza: Add stanza:get_child(name, xmlns) to find a child tag given a name/xmlns
Matthew Wild <mwild1@gmail.com>
parents: 2077
diff changeset
   161
function stanza_mt:get_child(name, xmlns)
49580a13f71e util.stanza: Add stanza:get_child(name, xmlns) to find a child tag given a name/xmlns
Matthew Wild <mwild1@gmail.com>
parents: 2077
diff changeset
   162
	for _, child in ipairs(self.tags) do
2482
a1570e371258 util.stanza: Trailing whitespace
Matthew Wild <mwild1@gmail.com>
parents: 2264
diff changeset
   163
		if (not name or child.name == name)
2264
49580a13f71e util.stanza: Add stanza:get_child(name, xmlns) to find a child tag given a name/xmlns
Matthew Wild <mwild1@gmail.com>
parents: 2077
diff changeset
   164
			and ((not xmlns and self.attr.xmlns == child.attr.xmlns)
49580a13f71e util.stanza: Add stanza:get_child(name, xmlns) to find a child tag given a name/xmlns
Matthew Wild <mwild1@gmail.com>
parents: 2077
diff changeset
   165
				or child.attr.xmlns == xmlns) then
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5435
diff changeset
   166
2264
49580a13f71e util.stanza: Add stanza:get_child(name, xmlns) to find a child tag given a name/xmlns
Matthew Wild <mwild1@gmail.com>
parents: 2077
diff changeset
   167
			return child;
49580a13f71e util.stanza: Add stanza:get_child(name, xmlns) to find a child tag given a name/xmlns
Matthew Wild <mwild1@gmail.com>
parents: 2077
diff changeset
   168
		end
49580a13f71e util.stanza: Add stanza:get_child(name, xmlns) to find a child tag given a name/xmlns
Matthew Wild <mwild1@gmail.com>
parents: 2077
diff changeset
   169
	end
12728
5b5b428d67e2 util.stanza: Return nil instead of nothing (fix test with luassert >=1.9)
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
   170
	return nil;
2264
49580a13f71e util.stanza: Add stanza:get_child(name, xmlns) to find a child tag given a name/xmlns
Matthew Wild <mwild1@gmail.com>
parents: 2077
diff changeset
   171
end
49580a13f71e util.stanza: Add stanza:get_child(name, xmlns) to find a child tag given a name/xmlns
Matthew Wild <mwild1@gmail.com>
parents: 2077
diff changeset
   172
4132
ccc16434dbe2 util.stanza: Add get_child_text() method to get the text of the specified child element (get_child() + get_text() rolled into one step)
Matthew Wild <mwild1@gmail.com>
parents: 3766
diff changeset
   173
function stanza_mt:get_child_text(name, xmlns)
ccc16434dbe2 util.stanza: Add get_child_text() method to get the text of the specified child element (get_child() + get_text() rolled into one step)
Matthew Wild <mwild1@gmail.com>
parents: 3766
diff changeset
   174
	local tag = self:get_child(name, xmlns);
ccc16434dbe2 util.stanza: Add get_child_text() method to get the text of the specified child element (get_child() + get_text() rolled into one step)
Matthew Wild <mwild1@gmail.com>
parents: 3766
diff changeset
   175
	if tag then
ccc16434dbe2 util.stanza: Add get_child_text() method to get the text of the specified child element (get_child() + get_text() rolled into one step)
Matthew Wild <mwild1@gmail.com>
parents: 3766
diff changeset
   176
		return tag:get_text();
ccc16434dbe2 util.stanza: Add get_child_text() method to get the text of the specified child element (get_child() + get_text() rolled into one step)
Matthew Wild <mwild1@gmail.com>
parents: 3766
diff changeset
   177
	end
ccc16434dbe2 util.stanza: Add get_child_text() method to get the text of the specified child element (get_child() + get_text() rolled into one step)
Matthew Wild <mwild1@gmail.com>
parents: 3766
diff changeset
   178
	return nil;
ccc16434dbe2 util.stanza: Add get_child_text() method to get the text of the specified child element (get_child() + get_text() rolled into one step)
Matthew Wild <mwild1@gmail.com>
parents: 3766
diff changeset
   179
end
ccc16434dbe2 util.stanza: Add get_child_text() method to get the text of the specified child element (get_child() + get_text() rolled into one step)
Matthew Wild <mwild1@gmail.com>
parents: 3766
diff changeset
   180
12640
e8934ce6ea0f util.stanza: Add method for extracting a single attribute value
Kim Alvefur <zash@zash.se>
parents: 12411
diff changeset
   181
function stanza_mt:get_child_attr(name, xmlns, attr)
e8934ce6ea0f util.stanza: Add method for extracting a single attribute value
Kim Alvefur <zash@zash.se>
parents: 12411
diff changeset
   182
	local tag = self:get_child(name, xmlns);
e8934ce6ea0f util.stanza: Add method for extracting a single attribute value
Kim Alvefur <zash@zash.se>
parents: 12411
diff changeset
   183
	if tag then
e8934ce6ea0f util.stanza: Add method for extracting a single attribute value
Kim Alvefur <zash@zash.se>
parents: 12411
diff changeset
   184
		return tag.attr[attr];
e8934ce6ea0f util.stanza: Add method for extracting a single attribute value
Kim Alvefur <zash@zash.se>
parents: 12411
diff changeset
   185
	end
e8934ce6ea0f util.stanza: Add method for extracting a single attribute value
Kim Alvefur <zash@zash.se>
parents: 12411
diff changeset
   186
	return nil;
e8934ce6ea0f util.stanza: Add method for extracting a single attribute value
Kim Alvefur <zash@zash.se>
parents: 12411
diff changeset
   187
end
e8934ce6ea0f util.stanza: Add method for extracting a single attribute value
Kim Alvefur <zash@zash.se>
parents: 12411
diff changeset
   188
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   189
function stanza_mt:child_with_name(name)
2482
a1570e371258 util.stanza: Trailing whitespace
Matthew Wild <mwild1@gmail.com>
parents: 2264
diff changeset
   190
	for _, child in ipairs(self.tags) do
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   191
		if child.name == name then return child; end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   192
	end
12728
5b5b428d67e2 util.stanza: Return nil instead of nothing (fix test with luassert >=1.9)
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
   193
	return nil;
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   194
end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   195
689
94b043fbaf33 Add child_with_ns() method to stanza elements, and fix child_with_name() to iterate tags rather than all children
Matthew Wild <mwild1@gmail.com>
parents: 680
diff changeset
   196
function stanza_mt:child_with_ns(ns)
2482
a1570e371258 util.stanza: Trailing whitespace
Matthew Wild <mwild1@gmail.com>
parents: 2264
diff changeset
   197
	for _, child in ipairs(self.tags) do
689
94b043fbaf33 Add child_with_ns() method to stanza elements, and fix child_with_name() to iterate tags rather than all children
Matthew Wild <mwild1@gmail.com>
parents: 680
diff changeset
   198
		if child.attr.xmlns == ns then return child; end
94b043fbaf33 Add child_with_ns() method to stanza elements, and fix child_with_name() to iterate tags rather than all children
Matthew Wild <mwild1@gmail.com>
parents: 680
diff changeset
   199
	end
12728
5b5b428d67e2 util.stanza: Return nil instead of nothing (fix test with luassert >=1.9)
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
   200
	return nil;
689
94b043fbaf33 Add child_with_ns() method to stanza elements, and fix child_with_name() to iterate tags rather than all children
Matthew Wild <mwild1@gmail.com>
parents: 680
diff changeset
   201
end
94b043fbaf33 Add child_with_ns() method to stanza elements, and fix child_with_name() to iterate tags rather than all children
Matthew Wild <mwild1@gmail.com>
parents: 680
diff changeset
   202
11790
39164ea2ab9e util.stanza: Add :get_child_with_attr() + tests
Matthew Wild <mwild1@gmail.com>
parents: 11646
diff changeset
   203
function stanza_mt:get_child_with_attr(name, xmlns, attr_name, attr_value, normalize)
39164ea2ab9e util.stanza: Add :get_child_with_attr() + tests
Matthew Wild <mwild1@gmail.com>
parents: 11646
diff changeset
   204
	for tag in self:childtags(name, xmlns) do
39164ea2ab9e util.stanza: Add :get_child_with_attr() + tests
Matthew Wild <mwild1@gmail.com>
parents: 11646
diff changeset
   205
		if (normalize and normalize(tag.attr[attr_name]) or tag.attr[attr_name]) == attr_value then
39164ea2ab9e util.stanza: Add :get_child_with_attr() + tests
Matthew Wild <mwild1@gmail.com>
parents: 11646
diff changeset
   206
			return tag;
39164ea2ab9e util.stanza: Add :get_child_with_attr() + tests
Matthew Wild <mwild1@gmail.com>
parents: 11646
diff changeset
   207
		end
39164ea2ab9e util.stanza: Add :get_child_with_attr() + tests
Matthew Wild <mwild1@gmail.com>
parents: 11646
diff changeset
   208
	end
12728
5b5b428d67e2 util.stanza: Return nil instead of nothing (fix test with luassert >=1.9)
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
   209
	return nil;
11790
39164ea2ab9e util.stanza: Add :get_child_with_attr() + tests
Matthew Wild <mwild1@gmail.com>
parents: 11646
diff changeset
   210
end
39164ea2ab9e util.stanza: Add :get_child_with_attr() + tests
Matthew Wild <mwild1@gmail.com>
parents: 11646
diff changeset
   211
1
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
   212
function stanza_mt:children()
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
   213
	local i = 0;
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
   214
	return function (a)
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
   215
			i = i + 1
3475
0307a3ac3885 util.stanza: Optimisation, remove useless if...then in stanza:children() iterator
Matthew Wild <mwild1@gmail.com>
parents: 3474
diff changeset
   216
			return a[i];
1
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
   217
		end, self, i;
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
   218
end
3474
730876bbe4e6 util.stanza: Add stanza:matched_children(name, xmlns) [name suggestions welcome]
Matthew Wild <mwild1@gmail.com>
parents: 2961
diff changeset
   219
4168
4919831b5b56 util.stanza: Clean up matching_tags() and replace :childtags() with it
Matthew Wild <mwild1@gmail.com>
parents: 4136
diff changeset
   220
function stanza_mt:childtags(name, xmlns)
3474
730876bbe4e6 util.stanza: Add stanza:matched_children(name, xmlns) [name suggestions welcome]
Matthew Wild <mwild1@gmail.com>
parents: 2961
diff changeset
   221
	local tags = self.tags;
730876bbe4e6 util.stanza: Add stanza:matched_children(name, xmlns) [name suggestions welcome]
Matthew Wild <mwild1@gmail.com>
parents: 2961
diff changeset
   222
	local start_i, max_i = 1, #tags;
730876bbe4e6 util.stanza: Add stanza:matched_children(name, xmlns) [name suggestions welcome]
Matthew Wild <mwild1@gmail.com>
parents: 2961
diff changeset
   223
	return function ()
4168
4919831b5b56 util.stanza: Clean up matching_tags() and replace :childtags() with it
Matthew Wild <mwild1@gmail.com>
parents: 4136
diff changeset
   224
		for i = start_i, max_i do
4919831b5b56 util.stanza: Clean up matching_tags() and replace :childtags() with it
Matthew Wild <mwild1@gmail.com>
parents: 4136
diff changeset
   225
			local v = tags[i];
4919831b5b56 util.stanza: Clean up matching_tags() and replace :childtags() with it
Matthew Wild <mwild1@gmail.com>
parents: 4136
diff changeset
   226
			if (not name or v.name == name)
4936
92c86e11fd44 util.stanza: Make stanza:childtags() behave like :get_child()
Kim Alvefur <zash@zash.se>
parents: 4749
diff changeset
   227
			and ((not xmlns and self.attr.xmlns == v.attr.xmlns)
92c86e11fd44 util.stanza: Make stanza:childtags() behave like :get_child()
Kim Alvefur <zash@zash.se>
parents: 4749
diff changeset
   228
				or v.attr.xmlns == xmlns) then
4168
4919831b5b56 util.stanza: Clean up matching_tags() and replace :childtags() with it
Matthew Wild <mwild1@gmail.com>
parents: 4136
diff changeset
   229
				start_i = i+1;
4919831b5b56 util.stanza: Clean up matching_tags() and replace :childtags() with it
Matthew Wild <mwild1@gmail.com>
parents: 4136
diff changeset
   230
				return v;
3474
730876bbe4e6 util.stanza: Add stanza:matched_children(name, xmlns) [name suggestions welcome]
Matthew Wild <mwild1@gmail.com>
parents: 2961
diff changeset
   231
			end
4168
4919831b5b56 util.stanza: Clean up matching_tags() and replace :childtags() with it
Matthew Wild <mwild1@gmail.com>
parents: 4136
diff changeset
   232
		end
4919831b5b56 util.stanza: Clean up matching_tags() and replace :childtags() with it
Matthew Wild <mwild1@gmail.com>
parents: 4136
diff changeset
   233
	end;
2
9bb397205f26 Working presence!
matthew
parents: 1
diff changeset
   234
end
1
b8787e859fd2 Switched to new connection framework, courtesy of the luadch project
matthew
parents: 0
diff changeset
   235
3477
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   236
function stanza_mt:maptags(callback)
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   237
	local tags, curr_tag = self.tags, 1;
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   238
	local n_children, n_tags = #self, #tags;
9220
7df29c5fbb9b util.stanza + tests: Bail out of loop if we are iterating too far, fixes #981
Matthew Wild <mwild1@gmail.com>
parents: 9002
diff changeset
   239
	local max_iterations = n_children + 1;
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5435
diff changeset
   240
3477
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   241
	local i = 1;
5414
efec29eb4cdd util.stanza: :maptags(): Fixes to make loop more robust on item removal
Matthew Wild <mwild1@gmail.com>
parents: 5090
diff changeset
   242
	while curr_tag <= n_tags and n_tags > 0 do
3477
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   243
		if self[i] == tags[curr_tag] then
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   244
			local ret = callback(self[i]);
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   245
			if ret == nil then
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   246
				t_remove(self, i);
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   247
				t_remove(tags, curr_tag);
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   248
				n_children = n_children - 1;
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   249
				n_tags = n_tags - 1;
5414
efec29eb4cdd util.stanza: :maptags(): Fixes to make loop more robust on item removal
Matthew Wild <mwild1@gmail.com>
parents: 5090
diff changeset
   250
				i = i - 1;
efec29eb4cdd util.stanza: :maptags(): Fixes to make loop more robust on item removal
Matthew Wild <mwild1@gmail.com>
parents: 5090
diff changeset
   251
				curr_tag = curr_tag - 1;
3477
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   252
			else
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   253
				self[i] = ret;
5435
f56e449a63e3 util.stanza: Use correct index when replacing the tag in .tags (thanks daurnimator)
Matthew Wild <mwild1@gmail.com>
parents: 5424
diff changeset
   254
				tags[curr_tag] = ret;
3477
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   255
			end
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   256
			curr_tag = curr_tag + 1;
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   257
		end
5414
efec29eb4cdd util.stanza: :maptags(): Fixes to make loop more robust on item removal
Matthew Wild <mwild1@gmail.com>
parents: 5090
diff changeset
   258
		i = i + 1;
9220
7df29c5fbb9b util.stanza + tests: Bail out of loop if we are iterating too far, fixes #981
Matthew Wild <mwild1@gmail.com>
parents: 9002
diff changeset
   259
		if i > max_iterations then
7df29c5fbb9b util.stanza + tests: Bail out of loop if we are iterating too far, fixes #981
Matthew Wild <mwild1@gmail.com>
parents: 9002
diff changeset
   260
			-- COMPAT: Hopefully temporary guard against #981 while we
7df29c5fbb9b util.stanza + tests: Bail out of loop if we are iterating too far, fixes #981
Matthew Wild <mwild1@gmail.com>
parents: 9002
diff changeset
   261
			-- figure out the root cause
7df29c5fbb9b util.stanza + tests: Bail out of loop if we are iterating too far, fixes #981
Matthew Wild <mwild1@gmail.com>
parents: 9002
diff changeset
   262
			error("Invalid stanza state! Please report this error.");
7df29c5fbb9b util.stanza + tests: Bail out of loop if we are iterating too far, fixes #981
Matthew Wild <mwild1@gmail.com>
parents: 9002
diff changeset
   263
		end
3477
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   264
	end
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   265
	return self;
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   266
end
6350b114e0e4 util.stanza: Add stanza:maptags() to apply a function over child tags (return nil to remove tag from stanza)
Matthew Wild <mwild1@gmail.com>
parents: 3475
diff changeset
   267
5424
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   268
function stanza_mt:find(path)
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   269
	local pos = 1;
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   270
	local len = #path + 1;
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   271
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   272
	repeat
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   273
		local xmlns, name, text;
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   274
		local char = s_sub(path, pos, pos);
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   275
		if char == "@" then
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   276
			return self.attr[s_sub(path, pos + 1)];
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   277
		elseif char == "{" then
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   278
			xmlns, pos = s_match(path, "^([^}]+)}()", pos + 1);
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   279
		end
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   280
		name, text, pos = s_match(path, "^([^@/#]*)([/#]?)()", pos);
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   281
		name = name ~= "" and name or nil;
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   282
		if pos == len then
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   283
			if text == "#" then
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   284
				return self:get_child_text(name, xmlns);
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   285
			end
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   286
			return self:get_child(name, xmlns);
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   287
		end
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   288
		self = self:get_child(name, xmlns);
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   289
	until not self
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   290
end
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   291
9928
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   292
local function _clone(stanza, only_top)
12411
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   293
	local attr = {};
9928
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   294
	for k,v in pairs(stanza.attr) do attr[k] = v; end
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   295
	local old_namespaces, namespaces = stanza.namespaces;
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   296
	if old_namespaces then
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   297
		namespaces = {};
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   298
		for k,v in pairs(old_namespaces) do namespaces[k] = v; end
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   299
	end
12411
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   300
	local tags, new;
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   301
	if only_top then
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   302
		tags = {};
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   303
		new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags };
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   304
	else
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   305
		tags = t_create(#stanza.tags, 0);
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   306
		new = t_create(#stanza, 4);
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   307
		new.name = stanza.name;
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   308
		new.attr = attr;
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   309
		new.namespaces = namespaces;
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   310
		new.tags = tags;
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   311
	end
b6b01724e04f util.stanza: Create tables with correct size to avoid reallocations
Kim Alvefur <zash@zash.se>
parents: 12410
diff changeset
   312
12410
a3ddf3f42212 util.stanza: Use table.move in clone
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
   313
	setmetatable(new, stanza_mt);
9928
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   314
	if not only_top then
12410
a3ddf3f42212 util.stanza: Use table.move in clone
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
   315
		t_move(stanza, 1, #stanza, 1, new);
a3ddf3f42212 util.stanza: Use table.move in clone
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
   316
		t_move(stanza.tags, 1, #stanza.tags, 1, tags);
a3ddf3f42212 util.stanza: Use table.move in clone
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
   317
		new:maptags(_clone);
9928
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   318
	end
12410
a3ddf3f42212 util.stanza: Use table.move in clone
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
   319
	return new;
9928
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   320
end
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   321
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   322
local function clone(stanza, only_top)
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   323
	if not is_stanza(stanza) then
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   324
		error("bad argument to clone: expected stanza, got "..type(stanza));
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   325
	end
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   326
	return _clone(stanza, only_top);
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   327
end
5424
7318527c6dea util.stanza: Add stanza:find(), a light weight XPath-like method
Kim Alvefur <zash@zash.se>
parents: 5414
diff changeset
   328
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   329
local escape_table = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" };
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   330
local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end
1931
f203330eb82e util.stanza: Make xml_escape publicly accessible
Matthew Wild <mwild1@gmail.com>
parents: 1874
diff changeset
   331
7256
f4e71242556a util.stanza: Some code cleanup [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
   332
local function _dostring(t, buf, self, _xml_escape, parentns)
1431
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   333
	local nsid = 0;
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   334
	local name = t.name
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   335
	t_insert(buf, "<"..name);
1416
f916f0ff90e5 util.stanza: Rewrote stanza_mt.__tostring. 20-30% faster stanza serialization. - #optimization
Waqas Hussain <waqas20@gmail.com>
parents: 1415
diff changeset
   336
	for k, v in pairs(t.attr) do
2077
e33658f6052c Changed separator between attribute names and prefixes from '|' to '\1' (optimization and cleanup).
Waqas Hussain <waqas20@gmail.com>
parents: 1984
diff changeset
   337
		if s_find(k, "\1", 1, true) then
e33658f6052c Changed separator between attribute names and prefixes from '|' to '\1' (optimization and cleanup).
Waqas Hussain <waqas20@gmail.com>
parents: 1984
diff changeset
   338
			local ns, attrk = s_match(k, "^([^\1]*)\1?(.*)$");
1416
f916f0ff90e5 util.stanza: Rewrote stanza_mt.__tostring. 20-30% faster stanza serialization. - #optimization
Waqas Hussain <waqas20@gmail.com>
parents: 1415
diff changeset
   339
			nsid = nsid + 1;
7256
f4e71242556a util.stanza: Some code cleanup [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
   340
			t_insert(buf, " xmlns:ns"..nsid.."='".._xml_escape(ns).."' ".."ns"..nsid..":"..attrk.."='".._xml_escape(v).."'");
2077
e33658f6052c Changed separator between attribute names and prefixes from '|' to '\1' (optimization and cleanup).
Waqas Hussain <waqas20@gmail.com>
parents: 1984
diff changeset
   341
		elseif not(k == "xmlns" and v == parentns) then
7256
f4e71242556a util.stanza: Some code cleanup [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
   342
			t_insert(buf, " "..k.."='".._xml_escape(v).."'");
776
89eb9f59993c util.stanza: Temporary fix for serializing attributes with namespaces
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   343
		end
1416
f916f0ff90e5 util.stanza: Rewrote stanza_mt.__tostring. 20-30% faster stanza serialization. - #optimization
Waqas Hussain <waqas20@gmail.com>
parents: 1415
diff changeset
   344
	end
1431
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   345
	local len = #t;
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   346
	if len == 0 then
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   347
		t_insert(buf, "/>");
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   348
	else
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   349
		t_insert(buf, ">");
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   350
		for n=1,len do
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   351
			local child = t[n];
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   352
			if child.name then
7256
f4e71242556a util.stanza: Some code cleanup [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
   353
				self(child, buf, self, _xml_escape, t.attr.xmlns);
1431
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   354
			else
7256
f4e71242556a util.stanza: Some code cleanup [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
   355
				t_insert(buf, _xml_escape(child));
1431
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   356
			end
4
09c3845ed442 Presence unavailable on disconnect
matthew
parents: 2
diff changeset
   357
		end
1431
9fe9ba693f4a util.stanza: Serializer optimizations, and nicer output for empty elements
Waqas Hussain <waqas20@gmail.com>
parents: 1420
diff changeset
   358
		t_insert(buf, "</"..name..">");
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   359
	end
626
cf1d26fd4d6f Optimized stanza_mt.__tostring (called when doing tostring(stanza))
Waqas Hussain <waqas20@gmail.com>
parents: 519
diff changeset
   360
end
cf1d26fd4d6f Optimized stanza_mt.__tostring (called when doing tostring(stanza))
Waqas Hussain <waqas20@gmail.com>
parents: 519
diff changeset
   361
function stanza_mt.__tostring(t)
cf1d26fd4d6f Optimized stanza_mt.__tostring (called when doing tostring(stanza))
Waqas Hussain <waqas20@gmail.com>
parents: 519
diff changeset
   362
	local buf = {};
2077
e33658f6052c Changed separator between attribute names and prefixes from '|' to '\1' (optimization and cleanup).
Waqas Hussain <waqas20@gmail.com>
parents: 1984
diff changeset
   363
	_dostring(t, buf, _dostring, xml_escape, nil);
626
cf1d26fd4d6f Optimized stanza_mt.__tostring (called when doing tostring(stanza))
Waqas Hussain <waqas20@gmail.com>
parents: 519
diff changeset
   364
	return t_concat(buf);
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   365
end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   366
242
f15afbcbc55c Add new top_tag() method to stanzas
Matthew Wild <mwild1@gmail.com>
parents: 209
diff changeset
   367
function stanza_mt.top_tag(t)
9928
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   368
	local top_tag_clone = clone(t, true);
5a2e53bef031 util.stanza: Fix :top_tag() handling of namespaced attributes
Matthew Wild <mwild1@gmail.com>
parents: 9736
diff changeset
   369
	return tostring(top_tag_clone):sub(1,-3)..">";
242
f15afbcbc55c Add new top_tag() method to stanzas
Matthew Wild <mwild1@gmail.com>
parents: 209
diff changeset
   370
end
f15afbcbc55c Add new top_tag() method to stanzas
Matthew Wild <mwild1@gmail.com>
parents: 209
diff changeset
   371
1420
1576a5aa52f8 util.stanza: Add stanza:get_text() to retrieve all child text nodes #api
Matthew Wild <mwild1@gmail.com>
parents: 1416
diff changeset
   372
function stanza_mt.get_text(t)
1576a5aa52f8 util.stanza: Add stanza:get_text() to retrieve all child text nodes #api
Matthew Wild <mwild1@gmail.com>
parents: 1416
diff changeset
   373
	if #t.tags == 0 then
1576a5aa52f8 util.stanza: Add stanza:get_text() to retrieve all child text nodes #api
Matthew Wild <mwild1@gmail.com>
parents: 1416
diff changeset
   374
		return t_concat(t);
1576a5aa52f8 util.stanza: Add stanza:get_text() to retrieve all child text nodes #api
Matthew Wild <mwild1@gmail.com>
parents: 1416
diff changeset
   375
	end
12728
5b5b428d67e2 util.stanza: Return nil instead of nothing (fix test with luassert >=1.9)
Kim Alvefur <zash@zash.se>
parents: 12144
diff changeset
   376
	return nil;
1420
1576a5aa52f8 util.stanza: Add stanza:get_text() to retrieve all child text nodes #api
Matthew Wild <mwild1@gmail.com>
parents: 1416
diff changeset
   377
end
1576a5aa52f8 util.stanza: Add stanza:get_text() to retrieve all child text nodes #api
Matthew Wild <mwild1@gmail.com>
parents: 1416
diff changeset
   378
2526
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   379
function stanza_mt.get_error(stanza)
11092
1f84d0e4d0c4 util.stanza: Extract Application-Specific Condition from errors
Kim Alvefur <zash@zash.se>
parents: 11090
diff changeset
   380
	local error_type, condition, text, extra_tag;
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5435
diff changeset
   381
2526
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   382
	local error_tag = stanza:get_child("error");
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   383
	if not error_tag then
11092
1f84d0e4d0c4 util.stanza: Extract Application-Specific Condition from errors
Kim Alvefur <zash@zash.se>
parents: 11090
diff changeset
   384
		return nil, nil, nil, nil;
2526
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   385
	end
7256
f4e71242556a util.stanza: Some code cleanup [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
   386
	error_type = error_tag.attr.type;
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5435
diff changeset
   387
5090
61c7c53c06d5 util.stanza: Use ipairs instead of childtags (behavior changed in 92c86e11fd44)
Kim Alvefur <zash@zash.se>
parents: 4936
diff changeset
   388
	for _, child in ipairs(error_tag.tags) do
2526
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   389
		if child.attr.xmlns == xmlns_stanzas then
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   390
			if not text and child.name == "text" then
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   391
				text = child:get_text();
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   392
			elseif not condition then
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   393
				condition = child.name;
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   394
			end
11092
1f84d0e4d0c4 util.stanza: Extract Application-Specific Condition from errors
Kim Alvefur <zash@zash.se>
parents: 11090
diff changeset
   395
		else
1f84d0e4d0c4 util.stanza: Extract Application-Specific Condition from errors
Kim Alvefur <zash@zash.se>
parents: 11090
diff changeset
   396
			extra_tag = child;
1f84d0e4d0c4 util.stanza: Extract Application-Specific Condition from errors
Kim Alvefur <zash@zash.se>
parents: 11090
diff changeset
   397
		end
1f84d0e4d0c4 util.stanza: Extract Application-Specific Condition from errors
Kim Alvefur <zash@zash.se>
parents: 11090
diff changeset
   398
		if condition and text and extra_tag then
1f84d0e4d0c4 util.stanza: Extract Application-Specific Condition from errors
Kim Alvefur <zash@zash.se>
parents: 11090
diff changeset
   399
			break;
2526
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   400
		end
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   401
	end
11092
1f84d0e4d0c4 util.stanza: Extract Application-Specific Condition from errors
Kim Alvefur <zash@zash.se>
parents: 11090
diff changeset
   402
	return error_type, condition or "undefined-condition", text, extra_tag;
2526
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   403
end
401ff68413a1 util.stanza: Add stanza:get_error() to return type, condition and text of a stanza error
Matthew Wild <mwild1@gmail.com>
parents: 2482
diff changeset
   404
12691
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   405
function stanza_mt.add_error(stanza, error_type, condition, error_message, error_by)
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   406
	local extra;
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   407
	if type(error_type) == "table" then -- an util.error or similar object
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   408
		if type(error_type.extra) == "table" then
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   409
			extra = error_type.extra;
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   410
		end
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   411
		if type(error_type.context) == "table" and type(error_type.context.by) == "string" then error_by = error_type.context.by; end
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   412
		error_type, condition, error_message = error_type.type, error_type.condition, error_type.text;
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   413
	end
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   414
	if stanza.attr.from == error_by then
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   415
		error_by = nil;
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   416
	end
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   417
	stanza:tag("error", {type = error_type, by = error_by}) --COMPAT: Some day xmlns:stanzas goes here
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   418
	:tag(condition, xmpp_stanzas_attr);
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   419
	if extra and condition == "gone" and type(extra.uri) == "string" then
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   420
		stanza:text(extra.uri);
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   421
	end
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   422
	stanza:up();
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   423
	if error_message then stanza:text_tag("text", error_message, xmpp_stanzas_attr); end
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   424
	if extra and is_stanza(extra.tag) then
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   425
		stanza:add_child(extra.tag);
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   426
	elseif extra and extra.namespace and extra.condition then
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   427
		stanza:tag(extra.condition, { xmlns = extra.namespace }):up();
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   428
	end
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   429
	return stanza:up();
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   430
end
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   431
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   432
local function preserialize(stanza)
90
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   433
	local s = { name = stanza.name, attr = stanza.attr };
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   434
	for _, child in ipairs(stanza) do
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   435
		if type(child) == "table" then
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   436
			t_insert(s, preserialize(child));
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   437
		else
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   438
			t_insert(s, child);
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   439
		end
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   440
	end
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   441
	return s;
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   442
end
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   443
9492
09b873ac7eb8 util.stanza: Set preserialize as freeze metamethod
Kim Alvefur <zash@zash.se>
parents: 9310
diff changeset
   444
stanza_mt.__freeze = preserialize;
09b873ac7eb8 util.stanza: Set preserialize as freeze metamethod
Kim Alvefur <zash@zash.se>
parents: 9310
diff changeset
   445
9678
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   446
local function deserialize(serialized)
90
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   447
	-- Set metatable
9678
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   448
	if serialized then
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   449
		local attr = serialized.attr;
2077
e33658f6052c Changed separator between attribute names and prefixes from '|' to '\1' (optimization and cleanup).
Waqas Hussain <waqas20@gmail.com>
parents: 1984
diff changeset
   450
		local attrx = {};
9678
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   451
		for att, val in pairs(attr) do
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   452
			if type(att) == "string" then
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   453
				if s_find(att, "|", 1, true) and not s_find(att, "\1", 1, true) then
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   454
					local ns,na = s_match(att, "^([^|]+)|(.+)$");
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   455
					attrx[ns.."\1"..na] = val;
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   456
				else
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   457
					attrx[att] = val;
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   458
				end
2077
e33658f6052c Changed separator between attribute names and prefixes from '|' to '\1' (optimization and cleanup).
Waqas Hussain <waqas20@gmail.com>
parents: 1984
diff changeset
   459
			end
e33658f6052c Changed separator between attribute names and prefixes from '|' to '\1' (optimization and cleanup).
Waqas Hussain <waqas20@gmail.com>
parents: 1984
diff changeset
   460
		end
9678
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   461
		local stanza = new_stanza(serialized.name, attrx);
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   462
		for _, child in ipairs(serialized) do
90
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   463
			if type(child) == "table" then
9678
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   464
				stanza:add_direct_child(deserialize(child));
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   465
			elseif type(child) == "string" then
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   466
				stanza:add_direct_child(child);
90
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   467
			end
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   468
		end
9678
6f97acc4583b util.stanza: Deserialize stanza without mutating input (fixes #711)
Kim Alvefur <zash@zash.se>
parents: 9634
diff changeset
   469
		return stanza;
90
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   470
	end
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   471
end
da468ed49a7b Stanza preserialize/deserialize helpers, to strip and restore stanzas respectively. Fixed mod_vcard to use these.
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
   472
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   473
local function message(attr, body)
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   474
	if not body then
7256
f4e71242556a util.stanza: Some code cleanup [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
   475
		return new_stanza("message", attr);
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   476
	else
10120
4807535b8673 util.stanza: Use :text_tag internally everywhere
Kim Alvefur <zash@zash.se>
parents: 9928
diff changeset
   477
		return new_stanza("message", attr):text_tag("body", body);
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   478
	end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   479
end
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   480
local function iq(attr)
9736
51583ea2b4fd util.stanza: Require a type attribute for iq stanzas
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
   481
	if not attr then
51583ea2b4fd util.stanza: Require a type attribute for iq stanzas
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
   482
		error("iq stanzas require id and type attributes");
51583ea2b4fd util.stanza: Require a type attribute for iq stanzas
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
   483
	end
51583ea2b4fd util.stanza: Require a type attribute for iq stanzas
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
   484
	if not attr.id then
9310
feaef6215bb8 util.stanza: Don't automatically generate ids for iq stanzas
Matthew Wild <mwild1@gmail.com>
parents: 9220
diff changeset
   485
		error("iq stanzas require an id attribute");
feaef6215bb8 util.stanza: Don't automatically generate ids for iq stanzas
Matthew Wild <mwild1@gmail.com>
parents: 9220
diff changeset
   486
	end
9736
51583ea2b4fd util.stanza: Require a type attribute for iq stanzas
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
   487
	if not attr.type then
51583ea2b4fd util.stanza: Require a type attribute for iq stanzas
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
   488
		error("iq stanzas require a type attribute");
51583ea2b4fd util.stanza: Require a type attribute for iq stanzas
Kim Alvefur <zash@zash.se>
parents: 9678
diff changeset
   489
	end
9310
feaef6215bb8 util.stanza: Don't automatically generate ids for iq stanzas
Matthew Wild <mwild1@gmail.com>
parents: 9220
diff changeset
   490
	return new_stanza("iq", attr);
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   491
end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   492
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   493
local function reply(orig)
10446
22db763c510c util.stanza: Check that argument to reply is a stanza
Kim Alvefur <zash@zash.se>
parents: 10120
diff changeset
   494
	if not is_stanza(orig) then
22db763c510c util.stanza: Check that argument to reply is a stanza
Kim Alvefur <zash@zash.se>
parents: 10120
diff changeset
   495
		error("bad argument to reply: expected stanza, got "..type(orig));
22db763c510c util.stanza: Check that argument to reply is a stanza
Kim Alvefur <zash@zash.se>
parents: 10120
diff changeset
   496
	end
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7761
diff changeset
   497
	return new_stanza(orig.name,
10447
f28718f46196 util.stanza: Remove redundant check for attrs
Kim Alvefur <zash@zash.se>
parents: 10446
diff changeset
   498
		{
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7761
diff changeset
   499
			to = orig.attr.from,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7761
diff changeset
   500
			from = orig.attr.to,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7761
diff changeset
   501
			id = orig.attr.id,
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7761
diff changeset
   502
			type = ((orig.name == "iq" and "result") or orig.attr.type)
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7761
diff changeset
   503
		});
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   504
end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   505
10450
5c2d1b13537c util.stanza: Support the 'by' attribute on errors
Kim Alvefur <zash@zash.se>
parents: 10449
diff changeset
   506
local function error_reply(orig, error_type, condition, error_message, error_by)
10448
4eab1f5a4f3b util.stanza: Check that argument to error_reply is a stanza
Kim Alvefur <zash@zash.se>
parents: 10447
diff changeset
   507
	if not is_stanza(orig) then
4eab1f5a4f3b util.stanza: Check that argument to error_reply is a stanza
Kim Alvefur <zash@zash.se>
parents: 10447
diff changeset
   508
		error("bad argument to error_reply: expected stanza, got "..type(orig));
10449
f53c03ab4357 util.stanza: Check that argument to error_reply is NOT a stanza of type error
Kim Alvefur <zash@zash.se>
parents: 10448
diff changeset
   509
	elseif orig.attr.type == "error" then
f53c03ab4357 util.stanza: Check that argument to error_reply is NOT a stanza of type error
Kim Alvefur <zash@zash.se>
parents: 10448
diff changeset
   510
		error("bad argument to error_reply: got stanza of type error which must not be replied to");
10448
4eab1f5a4f3b util.stanza: Check that argument to error_reply is a stanza
Kim Alvefur <zash@zash.se>
parents: 10447
diff changeset
   511
	end
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   512
	local t = reply(orig);
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   513
	t.attr.type = "error";
12691
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   514
	t:add_error(error_type, condition, error_message, error_by);
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   515
	t.last_add = { t[1] }; -- ready to add application-specific errors
5b69ecaf3427 util.stanza: Add add_error() to simplify adding error tags to existing stanzas
Matthew Wild <mwild1@gmail.com>
parents: 12640
diff changeset
   516
	return t;
60
44800be871f5 User registration, etc (jabber:iq:register)
Waqas Hussain <waqas20@gmail.com>
parents: 30
diff changeset
   517
end
44800be871f5 User registration, etc (jabber:iq:register)
Waqas Hussain <waqas20@gmail.com>
parents: 30
diff changeset
   518
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   519
local function presence(attr)
7256
f4e71242556a util.stanza: Some code cleanup [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
   520
	return new_stanza("presence", attr);
0
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   521
end
3e3171b59028 First commit, where do you want to go tomorrow?
matthew
parents:
diff changeset
   522
11646
7f2dee4249aa util.stanza: Export pretty printing function
Kim Alvefur <zash@zash.se>
parents: 11644
diff changeset
   523
local pretty;
262
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   524
if do_pretty_printing then
11643
ad39528e647d util.stanza: Remove Windows "support" (disabling ANSI color pretty printing)
Kim Alvefur <zash@zash.se>
parents: 11578
diff changeset
   525
	local getstyle, getstring = termcolours.getstyle, termcolours.getstring;
11644
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   526
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   527
	local blue1 = getstyle("1b3967");
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   528
	local blue2 = getstyle("13b5ea");
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   529
	local green1 = getstyle("439639");
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   530
	local green2 = getstyle("a0ce67");
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   531
	local orange1 = getstyle("d9541e");
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   532
	local orange2 = getstyle("e96d1f");
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   533
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   534
	local attr_replace = (
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   535
		getstring(green2, "%1") .. -- attr name
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   536
		getstring(green1, "%2") .. -- equal
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   537
		getstring(orange1, "%3") .. -- quote
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   538
		getstring(orange2, "%4") .. -- attr value
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   539
		getstring(orange1, "%5") -- quote
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   540
	);
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5435
diff changeset
   541
11644
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   542
	local text_replace = (
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   543
		getstring(green1, "%1") .. -- &
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   544
		getstring(green2, "%2") .. -- amp
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   545
		getstring(green1, "%3") -- ;
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   546
	);
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   547
11646
7f2dee4249aa util.stanza: Export pretty printing function
Kim Alvefur <zash@zash.se>
parents: 11644
diff changeset
   548
	function pretty(s)
11644
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   549
		-- Tag soup color
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   550
		-- Outer gsub call takes each <tag>, applies colour to the brackets, the
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   551
		-- tag name, then applies one inner gsub call to colour the attributes and
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   552
		-- another for any text content.
11964
12a3c05aa12d util.stanza: Adjust pretty printing for symmetry
Kim Alvefur <zash@zash.se>
parents: 11790
diff changeset
   553
		return (s:gsub("(<[?/]?)([^ >/?]*)(.-)([?/]?>)([^<]*)", function(opening_bracket, tag_name, attrs, closing_bracket, content)
11644
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   554
			return getstring(blue1, opening_bracket)..getstring(blue2, tag_name)..
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   555
				attrs:gsub("([^=]+)(=)([\"'])(.-)([\"'])", attr_replace) ..
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   556
			getstring(blue1, closing_bracket) ..
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   557
			content:gsub("(&#?)(%w+)(;)", text_replace);
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   558
		end, 100));
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   559
	end
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   560
262
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   561
	function stanza_mt.pretty_print(t)
11644
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   562
		return pretty(tostring(t));
262
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   563
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5435
diff changeset
   564
262
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   565
	function stanza_mt.pretty_top_tag(t)
11644
51598e46e136 util.stanza: Simplify and make pretty-printing look nicer
Kim Alvefur <zash@zash.se>
parents: 11643
diff changeset
   566
		return pretty(t:top_tag());
262
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   567
	end
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   568
else
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   569
	-- Sorry, fresh out of colours for you guys ;)
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   570
	stanza_mt.pretty_print = stanza_mt.__tostring;
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   571
	stanza_mt.pretty_top_tag = stanza_mt.top_tag;
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   572
end
8c73fb2ff4a2 A treat for Linux users ;)
Matthew Wild <mwild1@gmail.com>
parents: 251
diff changeset
   573
10721
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   574
function stanza_mt.indent(t, level, indent)
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   575
	if #t == 0 or (#t == 1 and type(t[1]) == "string") then
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   576
		-- Empty nodes wouldn't have any indentation
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   577
		-- Text-only nodes are preserved as to not alter the text content
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   578
		-- Optimization: Skip clone of these since we don't alter them
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   579
		return t;
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   580
	end
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   581
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   582
	indent = indent or "\t";
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   583
	level = level or 1;
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   584
	local tag = clone(t, true);
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   585
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   586
	for child in t:children() do
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   587
		if type(child) == "string" then
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   588
			-- Already indented text would look weird but let's ignore that for now.
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   589
			if child:find("%S") then
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   590
				tag:text("\n" .. indent:rep(level));
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   591
				tag:text(child);
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   592
			end
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   593
		elseif is_stanza(child) then
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   594
			tag:text("\n" .. indent:rep(level));
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   595
			tag:add_direct_child(child:indent(level+1, indent));
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   596
		end
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   597
	end
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   598
	-- before the closing tag
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   599
	tag:text("\n" .. indent:rep((level-1)));
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   600
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   601
	return tag;
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   602
end
05e4645fc9b3 util.stanza: Add method returning stanza with added indentation
Kim Alvefur <zash@zash.se>
parents: 10507
diff changeset
   603
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   604
return {
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   605
	stanza_mt = stanza_mt;
7256
f4e71242556a util.stanza: Some code cleanup [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 6824
diff changeset
   606
	stanza = new_stanza;
7753
e58524240b30 util.stanza: Add an is_stanza() function to check if an object is a stanza
Kim Alvefur <zash@zash.se>
parents: 7256
diff changeset
   607
	is_stanza = is_stanza;
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   608
	preserialize = preserialize;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   609
	deserialize = deserialize;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   610
	clone = clone;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   611
	message = message;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   612
	iq = iq;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   613
	reply = reply;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   614
	error_reply = error_reply;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   615
	presence = presence;
6824
5de30376bf98 util.stanza: Export xml_escape (missed during removal of module() calls)
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   616
	xml_escape = xml_escape;
11646
7f2dee4249aa util.stanza: Export pretty printing function
Kim Alvefur <zash@zash.se>
parents: 11644
diff changeset
   617
	pretty_print = pretty;
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6504
diff changeset
   618
};