using Gee; namespace Xmpp { public string get_bare_jid(string jid) { return jid.split("/")[0]; } public bool is_bare_jid(string jid) { return !jid.contains("/"); } public string? get_resource_part(string jid) { return jid.split("/")[1]; } public string random_uuid() { uint32 b1 = Random.next_int(); uint16 b2 = (uint16)Random.next_int(); uint16 b3 = (uint16)(Random.next_int() | 0x4000u) & ~0xb000u; uint16 b4 = (uint16)(Random.next_int() | 0x8000u) & ~0x4000u; uint16 b5_1 = (uint16)Random.next_int(); uint32 b5_2 = Random.next_int(); return "%08x-%04x-%04x-%04x-%04x%08x".printf(b1, b2, b3, b4, b5_1, b5_2); } public abstract class StanzaListener : Object { public abstract string action_group { get; } public abstract string[] after_actions { get; } public abstract async void run(Core.XmppStream stream, T stanza); } public class StanzaListenerHolder : Object { private ArrayList> listeners = new ArrayList>(); public new void connect(StanzaListener listener) { listeners.add(listener); resort_list(); } public new void disconnect(StanzaListener listener) { listeners.remove(listener); resort_list(); } public async void run(Core.XmppStream stream, T stanza) { foreach (StanzaListener l in listeners) { yield l.run(stream, stanza); } } private Gee.List> set_minus(Gee.List> main_set, Gee.List> minus) { Gee.List> res = new ArrayList>(); foreach (StanzaListener l in main_set) { if (!minus.contains(l)) { res.add(l); } } return res; } private bool set_contains_action(Gee.List> s, string[] actions) { foreach(StanzaListener l in s) { if (l.action_group in actions) { return true; } } return false; } private void resort_list() { ArrayList> new_list = new ArrayList>(); while (listeners.size > new_list.size) { bool changed = false; foreach (StanzaListener l in listeners) { Gee.List> remaining = set_minus(listeners, new_list); if (!set_contains_action(remaining, l.after_actions)) { new_list.add(l); changed = true; } } if (!changed) warning("Can't sort listeners"); } listeners = new_list; } } }