1-- Prosody IM 2-- Copyright (C) 2008-2017 Matthew Wild 3-- Copyright (C) 2008-2017 Waqas Hussain 4-- Copyright (C) 2011-2017 Kim Alvefur 5-- 6-- This project is MIT/X11 licensed. Please see the 7-- COPYING file in the source package for more information. 8-- 9-- XEP-0313: Message Archive Management for Prosody 10-- 11 12local stanza = require"util.stanza".stanza; 13local tostring, tonumber = tostring, tonumber; 14local type = type; 15local pairs = pairs; 16 17local xmlns_rsm = 'http://jabber.org/protocol/rsm'; 18 19local element_parsers = {}; 20 21do 22 local parsers = element_parsers; 23 local function xs_int(st) 24 return tonumber((st:get_text())); 25 end 26 local function xs_string(st) 27 return st:get_text(); 28 end 29 30 parsers.after = xs_string; 31 parsers.before = function(st) 32 local text = st:get_text(); 33 return text == "" or text; 34 end; 35 parsers.max = xs_int; 36 parsers.index = xs_int; 37 38 parsers.first = function(st) 39 return { index = tonumber(st.attr.index); st:get_text() }; 40 end; 41 parsers.last = xs_string; 42 parsers.count = xs_int; 43end 44 45local element_generators = setmetatable({ 46 first = function(st, data) 47 if type(data) == "table" then 48 st:tag("first", { index = data.index }):text(data[1]):up(); 49 else 50 st:tag("first"):text(tostring(data)):up(); 51 end 52 end; 53 before = function(st, data) 54 if data == true then 55 st:tag("before"):up(); 56 else 57 st:tag("before"):text(tostring(data)):up(); 58 end 59 end 60}, { 61 __index = function(_, name) 62 return function(st, data) 63 st:tag(name):text(tostring(data)):up(); 64 end 65 end; 66}); 67 68 69local function parse(set) 70 local rs = {}; 71 for tag in set:childtags() do 72 local name = tag.name; 73 local parser = name and element_parsers[name]; 74 if parser then 75 rs[name] = parser(tag); 76 end 77 end 78 return rs; 79end 80 81local function generate(t) 82 local st = stanza("set", { xmlns = xmlns_rsm }); 83 for k,v in pairs(t) do 84 if element_parsers[k] then 85 element_generators[k](st, v); 86 end 87 end 88 return st; 89end 90 91local function get(st) 92 local set = st:get_child("set", xmlns_rsm); 93 if set and #set.tags > 0 then 94 return parse(set); 95 end 96end 97 98return { parse = parse, generate = generate, get = get }; 99