Use delegates + object storage instead of listener objects

This commit is contained in:
fiaxh 2017-03-11 23:04:58 +01:00
parent 0ea4ac7e20
commit f40a34bdc1
18 changed files with 252 additions and 352 deletions

View file

@ -73,13 +73,6 @@ public class AvatarManager : StreamInteractionModule, Object {
} }
} }
private class PublishResponseListenerImpl : Object {
public void on_success(Core.XmppStream stream) {
}
public void on_error(Core.XmppStream stream) { }
}
public static AvatarManager? get_instance(StreamInteractor stream_interaction) { public static AvatarManager? get_instance(StreamInteractor stream_interaction) {
return (AvatarManager) stream_interaction.get_module(id); return (AvatarManager) stream_interaction.get_module(id);
} }

View file

@ -28,7 +28,7 @@ public class MucManager : StreamInteractionModule, Object {
public void join(Account account, Jid jid, string nick, string? password = null) { public void join(Account account, Jid jid, string nick, string? password = null) {
Core.XmppStream stream = stream_interactor.get_stream(account); Core.XmppStream stream = stream_interactor.get_stream(account);
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid.to_string(), nick, password, new MucEnterListenerImpl(this, jid, nick, account)); if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid.to_string(), nick, password, on_groupchat_joined, () => {}, Quadruple.create(this, jid, nick, account));
} }
public void part(Account account, Jid jid) { public void part(Account account, Jid jid) {
@ -73,10 +73,10 @@ public class MucManager : StreamInteractionModule, Object {
return is_groupchat(jid.bare_jid, account) && jid.is_full(); return is_groupchat(jid.bare_jid, account) && jid.is_full();
} }
public void get_bookmarks(Account account, Xep.Bookmarks.ConferencesRetrieveResponseListener listener) { public void get_bookmarks(Account account, Xep.Bookmarks.Module.OnResult listener, Object? store) {
Core.XmppStream? stream = stream_interactor.get_stream(account); Core.XmppStream? stream = stream_interactor.get_stream(account);
if (stream != null) { if (stream != null) {
stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, listener); stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, listener, store);
} }
} }
@ -158,7 +158,7 @@ public class MucManager : StreamInteractionModule, Object {
private void on_stream_negotiated(Account account) { private void on_stream_negotiated(Account account) {
Core.XmppStream stream = stream_interactor.get_stream(account); Core.XmppStream stream = stream_interactor.get_stream(account);
if (stream != null) stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, new BookmarksRetrieveResponseListener(this, account)); if (stream != null) stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, join_autojoin_conferences, Tuple.create(this, account));
} }
private void on_pre_message_received(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) { private void on_pre_message_received(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
@ -184,41 +184,26 @@ public class MucManager : StreamInteractionModule, Object {
} }
} }
private class BookmarksRetrieveResponseListener : Xep.Bookmarks.ConferencesRetrieveResponseListener, Object { private static void on_groupchat_joined(Core.XmppStream stream, Object? store) {
MucManager outer = null; Quadruple<MucManager, Jid, string, Account> quadruple = store as Quadruple<MucManager, Jid, string, Account>;
Account account = null; MucManager outer = quadruple.a;
Jid jid = quadruple.b;
string nick = quadruple.c;
Account account = quadruple.d;
outer.groupchat_joined(account, jid, nick);
}
public BookmarksRetrieveResponseListener(MucManager outer, Account account) { private static void join_autojoin_conferences(Core.XmppStream stream, ArrayList<Xep.Bookmarks.Conference> conferences, Object? o) {
this.outer = outer; Tuple<MucManager, Account> tuple = o as Tuple<MucManager, Account>;
this.account = account; MucManager outer = tuple.a;
} Account account = tuple.b;
foreach (Xep.Bookmarks.Conference bookmark in conferences) {
public void on_result(Core.XmppStream stream, ArrayList<Xep.Bookmarks.Conference> conferences) { Jid jid = new Jid(bookmark.jid);
foreach (Xep.Bookmarks.Conference bookmark in conferences) { outer.conference_bookmarks[jid] = bookmark;
Jid jid = new Jid(bookmark.jid); if (bookmark.autojoin) {
outer.conference_bookmarks[jid] = bookmark; outer.join(account, jid, bookmark.nick);
if (bookmark.autojoin) {
outer.join(account, jid, bookmark.nick);
}
} }
} }
} }
private class MucEnterListenerImpl : Xep.Muc.MucEnterListener, Object { // TODO
private MucManager outer;
private Jid jid;
private string nick;
private Account account;
public MucEnterListenerImpl(MucManager outer, Jid jid, string nick, Account account) {
this.outer = outer;
this.jid = jid;
this.nick = nick;
this.account = account;
}
public void on_success() {
outer.groupchat_joined(account, jid, nick);
}
public void on_error(Xep.Muc.MucEnterError error) { }
}
} }
} }

View file

@ -29,7 +29,7 @@ protected class ConferenceList : FilterableList {
}); });
foreach (Account account in stream_interactor.get_accounts()) { foreach (Account account in stream_interactor.get_accounts()) {
MucManager.get_instance(stream_interactor).get_bookmarks(account, new BookmarksListener(this, stream_interactor, account)); MucManager.get_instance(stream_interactor).get_bookmarks(account, on_conference_bookmarks_received, Tuple.create(this, account));
} }
} }
@ -42,18 +42,12 @@ protected class ConferenceList : FilterableList {
} }
} }
private class BookmarksListener : Xep.Bookmarks.ConferencesRetrieveResponseListener, Object { private static void on_conference_bookmarks_received(Core.XmppStream stream, ArrayList<Xep.Bookmarks.Conference> conferences, Object? o) {
ConferenceList outer; Tuple<ConferenceList, Account> tuple = o as Tuple<ConferenceList, Account>;
Account account; ConferenceList list = tuple.a;
public BookmarksListener(ConferenceList outer, StreamInteractor stream_interactor, Account account) { Account account = tuple.b;
this.outer = outer; list.lists[account] = conferences;
this.account = account; Idle.add(() => { list.refresh_conferences(); return false; });
}
public void on_result(Core.XmppStream stream, ArrayList<Xep.Bookmarks.Conference> conferences) {
outer.lists[account] = conferences;
Idle.add(() => { outer.refresh_conferences(); return false; });
}
} }
private void header(ListBoxRow row, ListBoxRow? before_row) { private void header(ListBoxRow row, ListBoxRow? before_row) {

View file

@ -33,19 +33,13 @@ namespace Xmpp.Bind {
var bind = stream.features.get_subnode("bind", NS_URI); var bind = stream.features.get_subnode("bind", NS_URI);
if (bind != null) { if (bind != null) {
var flag = new Flag(); var flag = new Flag();
StanzaNode bind_node = new StanzaNode.build("bind", NS_URI).add_self_xmlns() StanzaNode bind_node = new StanzaNode.build("bind", NS_URI).add_self_xmlns();
.put_node(new StanzaNode.build("resource", NS_URI).put_node(new StanzaNode.text(requested_resource))); bind_node.put_node(new StanzaNode.build("resource", NS_URI).put_node(new StanzaNode.text(requested_resource)));
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, new Iq.Stanza.set(bind_node), new IqResponseListenerImpl()); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, new Iq.Stanza.set(bind_node), on_bind_response);
stream.add_flag(flag); stream.add_flag(flag);
} }
} }
private class IqResponseListenerImpl : Iq.ResponseListener, Object {
public void on_result(XmppStream stream, Iq.Stanza iq) {
stream.get_module(Bind.Module.IDENTITY).iq_response_stanza(stream, iq);
}
}
public override void attach(XmppStream stream) { public override void attach(XmppStream stream) {
Iq.Module.require(stream); Iq.Module.require(stream);
stream.received_features_node.connect(this.received_features_node); stream.received_features_node.connect(this.received_features_node);
@ -69,6 +63,10 @@ namespace Xmpp.Bind {
public override string get_ns() { return NS_URI; } public override string get_ns() { return NS_URI; }
public override string get_id() { return ID; } public override string get_id() { return ID; }
private static void on_bind_response(XmppStream stream, Iq.Stanza iq) {
stream.get_module(Bind.Module.IDENTITY).iq_response_stanza(stream, iq);
}
} }
public class Flag : XmppStreamFlag { public class Flag : XmppStreamFlag {

View file

@ -12,14 +12,15 @@ namespace Xmpp.Iq {
private HashMap<string, ResponseListener> responseListeners = new HashMap<string, ResponseListener>(); private HashMap<string, ResponseListener> responseListeners = new HashMap<string, ResponseListener>();
private HashMap<string, ArrayList<Handler>> namespaceRegistrants = new HashMap<string, ArrayList<Handler>>(); private HashMap<string, ArrayList<Handler>> namespaceRegistrants = new HashMap<string, ArrayList<Handler>>();
public void send_iq(XmppStream stream, Iq.Stanza iq, ResponseListener? listener = null) { [CCode (has_target = false)] public delegate void OnResult(XmppStream stream, Iq.Stanza iq, Object reference);
public void send_iq(XmppStream stream, Iq.Stanza iq, OnResult? listener = null, Object? reference = null) {
try { try {
stream.write(iq.stanza); stream.write(iq.stanza);
} catch (IOStreamError e) { } catch (IOStreamError e) {
print(@"$(e.message)\n"); print(@"$(e.message)\n");
} }
if (listener != null) { if (listener != null) {
responseListeners.set(iq.id, listener); responseListeners[iq.id] = new ResponseListener(listener, reference);
} }
} }
@ -56,7 +57,7 @@ namespace Xmpp.Iq {
if (responseListeners.has_key(iq.id)) { if (responseListeners.has_key(iq.id)) {
ResponseListener? listener = responseListeners.get(iq.id); ResponseListener? listener = responseListeners.get(iq.id);
if (listener != null) { if (listener != null) {
listener.on_result(stream, iq); listener.on_result(stream, iq, listener.reference);
} }
responseListeners.unset(iq.id); responseListeners.unset(iq.id);
} }
@ -77,6 +78,16 @@ namespace Xmpp.Iq {
} }
} }
} }
private class ResponseListener {
public OnResult on_result { get; private set; }
public Object? reference { get; private set; }
public ResponseListener(OnResult on_result, Object? reference = null) {
this.on_result = on_result;
this.reference = reference;
}
}
} }
public interface Handler : Object { public interface Handler : Object {
@ -84,7 +95,4 @@ namespace Xmpp.Iq {
public abstract void on_iq_set(XmppStream stream, Iq.Stanza iq); public abstract void on_iq_set(XmppStream stream, Iq.Stanza iq);
} }
public interface ResponseListener : Object {
public abstract void on_result(XmppStream stream, Iq.Stanza iq);
}
} }

View file

@ -95,20 +95,18 @@ namespace Xmpp.Roster {
Flag.get_flag(stream).iq_id = random_uuid(); Flag.get_flag(stream).iq_id = random_uuid();
StanzaNode query_node = new StanzaNode.build("query", NS_URI).add_self_xmlns(); StanzaNode query_node = new StanzaNode.build("query", NS_URI).add_self_xmlns();
Iq.Stanza iq = new Iq.Stanza.get(query_node, Flag.get_flag(stream).iq_id); Iq.Stanza iq = new Iq.Stanza.get(query_node, Flag.get_flag(stream).iq_id);
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, new IqResponseListenerImpl()); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, on_roster_get_received);
} }
private class IqResponseListenerImpl : Iq.ResponseListener, Object { private static void on_roster_get_received(XmppStream stream, Iq.Stanza iq) {
public void on_result(XmppStream stream, Iq.Stanza iq) { Flag flag = Flag.get_flag(stream);
Flag flag = Flag.get_flag(stream); if (iq.id == flag.iq_id) {
if (iq.id == flag.iq_id) { StanzaNode? query_node = iq.stanza.get_subnode("query", NS_URI);
StanzaNode? query_node = iq.stanza.get_subnode("query", NS_URI); foreach (StanzaNode item_node in query_node.sub_nodes) {
foreach (StanzaNode item_node in query_node.sub_nodes) { Item item = new Item.from_stanza_node(item_node);
Item item = new Item.from_stanza_node(item_node); flag.roster_items[item.jid] = item;
flag.roster_items[item.jid] = item;
}
stream.get_module(Module.IDENTITY).received_roster(stream, flag.roster_items.values);
} }
stream.get_module(Module.IDENTITY).received_roster(stream, flag.roster_items.values);
} }
} }
@ -116,7 +114,7 @@ namespace Xmpp.Roster {
StanzaNode query_node = new StanzaNode.build("query", NS_URI).add_self_xmlns() StanzaNode query_node = new StanzaNode.build("query", NS_URI).add_self_xmlns()
.put_node(roster_item.stanza_node); .put_node(roster_item.stanza_node);
Iq.Stanza iq = new Iq.Stanza.set(query_node); Iq.Stanza iq = new Iq.Stanza.set(query_node);
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, null); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq);
} }
} }
} }

View file

@ -18,4 +18,44 @@ namespace Xmpp {
UUID.unparse_upper(rand, str); UUID.unparse_upper(rand, str);
return (string) str; return (string) str;
} }
public class Tuple<A,B> : Object {
public A a { get; private set; }
public B b { get; private set; }
public Tuple(A a, B b) {
this.a = a;
this.b = b;
}
public static Tuple<A,B> create<A,B>(A a, B b) {
return new Tuple<A,B>(a,b);
}
}
public class Triple<A,B,C> : Tuple<A,B> {
public C c { get; private set; }
public Triple(A a, B b, C c) {
base(a, b);
this.c = c;
}
public static new Triple<A,B,C> create<A,B,C>(A a, B b, C c) {
return new Triple<A,B,C>(a, b, c);
}
}
public class Quadruple<A,B,C,D> : Triple<A,B,C> {
public D d { get; private set; }
public Quadruple(A a, B b, C c, D d) {
base (a, b, c);
this.d = d;
}
public static new Quadruple<A,B,C,D> create<A,B,C,D>(A a, B b, C c, D d) {
return new Quadruple<A,B,C,D>(a, b, c, d);
}
}
} }

View file

@ -29,40 +29,18 @@ namespace Xmpp.Xep.ServiceDiscovery {
identities.add(new Identity(category, type, name)); identities.add(new Identity(category, type, name));
} }
public void request_info(XmppStream stream, string jid, InfoResponseListener response_listener) { [CCode (has_target = false)] public delegate void OnInfoResult(XmppStream stream, InfoResult query_result, Object? store);
public void request_info(XmppStream stream, string jid, OnInfoResult listener, Object? store) {
Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_INFO).add_self_xmlns()); Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_INFO).add_self_xmlns());
iq.to = jid; iq.to = jid;
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, new IqInfoResponseListener(response_listener)); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, on_request_info_response, Tuple.create(listener, store));
} }
private class IqInfoResponseListener : Iq.ResponseListener, Object { [CCode (has_target = false)] public delegate void OnItemsResult(XmppStream stream, ItemsResult query_result);
InfoResponseListener response_listener; public void request_items(XmppStream stream, string jid, OnItemsResult listener, Object? store) {
public IqInfoResponseListener(InfoResponseListener response_listener) {
this.response_listener = response_listener;
}
public void on_result(XmppStream stream, Iq.Stanza iq) {
InfoResult? result = InfoResult.create_from_iq(iq);
if (result != null) {
Flag.get_flag(stream).set_entitiy_features(iq.from, result.features);
response_listener.on_result(stream, result);
} else {
response_listener.on_error(stream, iq);
}
}
}
public void request_items(XmppStream stream, string jid, ItemsResponseListener response_listener) {
Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_ITEMS).add_self_xmlns()); Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_ITEMS).add_self_xmlns());
iq.to = jid; iq.to = jid;
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, new IqItemsResponseListener(response_listener)); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq);
}
private class IqItemsResponseListener : Iq.ResponseListener, Object {
ItemsResponseListener response_listener;
public IqItemsResponseListener(ItemsResponseListener response_listener) { this.response_listener = response_listener; }
public void on_result(XmppStream stream, Iq.Stanza iq) {
//response_listener.on_result(stream, new ServiceDiscoveryItemsResult.from_iq(iq));
}
} }
public void on_iq_get(XmppStream stream, Iq.Stanza iq) { public void on_iq_get(XmppStream stream, Iq.Stanza iq) {
@ -90,11 +68,21 @@ namespace Xmpp.Xep.ServiceDiscovery {
public override string get_ns() { return NS_URI; } public override string get_ns() { return NS_URI; }
public override string get_id() { return ID; } public override string get_id() { return ID; }
private static void on_request_info_response(XmppStream stream, Iq.Stanza iq, Object o) {
Tuple<OnInfoResult, Object> tuple = o as Tuple<OnInfoResult, Object>;
OnInfoResult on_result = tuple.a;
InfoResult? result = InfoResult.create_from_iq(iq);
if (result != null) {
Flag.get_flag(stream).set_entitiy_features(iq.from, result.features);
on_result(stream, result, tuple.b);
}
}
private void send_query_result(XmppStream stream, Iq.Stanza iq_request) { private void send_query_result(XmppStream stream, Iq.Stanza iq_request) {
InfoResult query_result = new ServiceDiscovery.InfoResult(iq_request); InfoResult query_result = new ServiceDiscovery.InfoResult(iq_request);
query_result.features = Flag.get_flag(stream).features; query_result.features = Flag.get_flag(stream).features;
query_result.identities = identities; query_result.identities = identities;
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, query_result.iq, null); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, query_result.iq);
} }
} }
@ -121,14 +109,4 @@ namespace Xmpp.Xep.ServiceDiscovery {
this.node = node; this.node = node;
} }
} }
public interface InfoResponseListener : Object {
public abstract void on_result(XmppStream stream, InfoResult query_result);
public void on_error(XmppStream stream, Iq.Stanza iq) { }
}
public interface ItemsResponseListener : Object {
public abstract void on_result(XmppStream stream, ItemsResult query_result);
public void on_error(XmppStream stream, Iq.Stanza iq) { }
}
} }

View file

@ -7,7 +7,7 @@ namespace Xmpp.Xep.Muc {
public class Flag : XmppStreamFlag { public class Flag : XmppStreamFlag {
public const string ID = "muc"; public const string ID = "muc";
private HashMap<string, MucEnterListener> enter_listeners = new HashMap<string, MucEnterListener>(); private HashMap<string, ListenerHolder> enter_listeners = new HashMap<string, ListenerHolder>();
private HashMap<string, string> enter_ids = new HashMap<string, string>(); private HashMap<string, string> enter_ids = new HashMap<string, string>();
private HashMap<string, string> own_nicks = new HashMap<string, string>(); private HashMap<string, string> own_nicks = new HashMap<string, string>();
private HashMap<string, string> subjects = new HashMap<string, string>(); private HashMap<string, string> subjects = new HashMap<string, string>();
@ -32,7 +32,7 @@ public class Flag : XmppStreamFlag {
public string? get_enter_id(string bare_jid) { return enter_ids[bare_jid]; } public string? get_enter_id(string bare_jid) { return enter_ids[bare_jid]; }
public MucEnterListener? get_enter_listener(string bare_jid) { return enter_listeners[bare_jid]; } public ListenerHolder? get_enter_listener(string bare_jid) { return enter_listeners[bare_jid]; }
public bool is_muc(string jid) { return own_nicks[jid] != null; } public bool is_muc(string jid) { return own_nicks[jid] != null; }
@ -51,7 +51,7 @@ public class Flag : XmppStreamFlag {
subjects_by[bare_jid] = full_jid; subjects_by[bare_jid] = full_jid;
} }
public void start_muc_enter(string bare_jid, string presence_id, MucEnterListener listener) { public void start_muc_enter(string bare_jid, string presence_id, ListenerHolder listener) {
enter_listeners[bare_jid] = listener; enter_listeners[bare_jid] = listener;
enter_ids[bare_jid] = presence_id; enter_ids[bare_jid] = presence_id;
} }

View file

@ -37,7 +37,7 @@ public class Module : XmppStreamModule {
public signal void received_occupant_role(XmppStream stream, string jid, string? role); public signal void received_occupant_role(XmppStream stream, string jid, string? role);
public signal void subject_set(XmppStream stream, string subject, string jid); public signal void subject_set(XmppStream stream, string subject, string jid);
public void enter(XmppStream stream, string bare_jid, string nick, string? password, MucEnterListener listener) { public void enter(XmppStream stream, string bare_jid, string nick, string? password, ListenerHolder.OnSuccess success_listener, ListenerHolder.OnError error_listener, Object? store) {
Presence.Stanza presence = new Presence.Stanza(); Presence.Stanza presence = new Presence.Stanza();
presence.to = bare_jid + "/" + nick; presence.to = bare_jid + "/" + nick;
StanzaNode x_node = new StanzaNode.build("x", NS_URI).add_self_xmlns(); StanzaNode x_node = new StanzaNode.build("x", NS_URI).add_self_xmlns();
@ -46,7 +46,7 @@ public class Module : XmppStreamModule {
} }
presence.stanza.put_node(x_node); presence.stanza.put_node(x_node);
Muc.Flag.get_flag(stream).start_muc_enter(bare_jid, presence.id, listener); Muc.Flag.get_flag(stream).start_muc_enter(bare_jid, presence.id, new ListenerHolder(success_listener, error_listener, store));
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence); stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
} }
@ -130,20 +130,22 @@ public class Module : XmppStreamModule {
string bare_jid = get_bare_jid(presence.from); string bare_jid = get_bare_jid(presence.from);
ErrorStanza? error_stanza = presence.get_error(); ErrorStanza? error_stanza = presence.get_error();
if (flag.get_enter_id(bare_jid) == error_stanza.original_id) { if (flag.get_enter_id(bare_jid) == error_stanza.original_id) {
MucEnterListener listener = flag.get_enter_listener(bare_jid); ListenerHolder listener = flag.get_enter_listener(bare_jid);
MucEnterError? error = null;
if (error_stanza.condition == ErrorStanza.CONDITION_NOT_AUTHORIZED && ErrorStanza.TYPE_AUTH == error_stanza.type_) { if (error_stanza.condition == ErrorStanza.CONDITION_NOT_AUTHORIZED && ErrorStanza.TYPE_AUTH == error_stanza.type_) {
listener.on_error(MucEnterError.PASSWORD_REQUIRED); error = MucEnterError.PASSWORD_REQUIRED;
} else if (ErrorStanza.CONDITION_REGISTRATION_REQUIRED == error_stanza.condition && ErrorStanza.TYPE_AUTH == error_stanza.type_) { } else if (ErrorStanza.CONDITION_REGISTRATION_REQUIRED == error_stanza.condition && ErrorStanza.TYPE_AUTH == error_stanza.type_) {
listener.on_error(MucEnterError.NOT_IN_MEMBER_LIST); error = MucEnterError.NOT_IN_MEMBER_LIST;
} else if (ErrorStanza.CONDITION_FORBIDDEN == error_stanza.condition && ErrorStanza.TYPE_AUTH == error_stanza.type_) { } else if (ErrorStanza.CONDITION_FORBIDDEN == error_stanza.condition && ErrorStanza.TYPE_AUTH == error_stanza.type_) {
listener.on_error(MucEnterError.BANNED); error = MucEnterError.BANNED;
} else if (ErrorStanza.CONDITION_CONFLICT == error_stanza.condition && ErrorStanza.TYPE_CANCEL == error_stanza.type_) { } else if (ErrorStanza.CONDITION_CONFLICT == error_stanza.condition && ErrorStanza.TYPE_CANCEL == error_stanza.type_) {
listener.on_error(MucEnterError.NICK_CONFLICT); error = MucEnterError.NICK_CONFLICT;
} else if (ErrorStanza.CONDITION_SERVICE_UNAVAILABLE == error_stanza.condition && ErrorStanza.TYPE_WAIT == error_stanza.type_) { } else if (ErrorStanza.CONDITION_SERVICE_UNAVAILABLE == error_stanza.condition && ErrorStanza.TYPE_WAIT == error_stanza.type_) {
listener.on_error(MucEnterError.OCCUPANT_LIMIT_REACHED); error = MucEnterError.OCCUPANT_LIMIT_REACHED;
} else if (ErrorStanza.CONDITION_ITEM_NOT_FOUND == error_stanza.condition && ErrorStanza.TYPE_CANCEL == error_stanza.type_) { } else if (ErrorStanza.CONDITION_ITEM_NOT_FOUND == error_stanza.condition && ErrorStanza.TYPE_CANCEL == error_stanza.type_) {
listener.on_error(MucEnterError.ROOM_DOESNT_EXIST); error = MucEnterError.ROOM_DOESNT_EXIST;
} }
if (error == null) listener.on_error(stream, error, listener.reference);
flag.finish_muc_enter(bare_jid); flag.finish_muc_enter(bare_jid);
} }
} }
@ -157,7 +159,8 @@ public class Module : XmppStreamModule {
ArrayList<int> status_codes = get_status_codes(x_node); ArrayList<int> status_codes = get_status_codes(x_node);
if (status_codes.contains(StatusCode.SELF_PRESENCE)) { if (status_codes.contains(StatusCode.SELF_PRESENCE)) {
string bare_jid = get_bare_jid(presence.from); string bare_jid = get_bare_jid(presence.from);
flag.get_enter_listener(bare_jid).on_success(); ListenerHolder listener = flag.get_enter_listener(bare_jid);
listener.on_success(stream, listener.reference);
flag.finish_muc_enter(bare_jid, get_resource_part(presence.from)); flag.finish_muc_enter(bare_jid, get_resource_part(presence.from));
} }
string? affiliation = x_node["item", "affiliation"].val; string? affiliation = x_node["item", "affiliation"].val;
@ -233,9 +236,17 @@ public enum StatusCode {
REMOVED_SHUTDOWN = 332 REMOVED_SHUTDOWN = 332
} }
public interface MucEnterListener : Object { public class ListenerHolder {
public abstract void on_success(); [CCode (has_target = false)] public delegate void OnSuccess(XmppStream stream, Object? store);
public abstract void on_error(MucEnterError error); public OnSuccess on_success { get; private set; }
[CCode (has_target = false)] public delegate void OnError(XmppStream stream, MucEnterError error, Object? store);
public OnError on_error { get; private set; }
public Object? reference { get; private set; }
public ListenerHolder(OnSuccess on_success, OnError on_error, Object? reference = null) {
this.on_success = on_success;
this.reference = reference;
}
} }
} }

View file

@ -2,7 +2,7 @@ using Xmpp.Core;
namespace Xmpp.Xep.Bookmarks { namespace Xmpp.Xep.Bookmarks {
public class Conference { public class Conference : Object {
public const string ATTRIBUTE_AUTOJOIN = "autojoin"; public const string ATTRIBUTE_AUTOJOIN = "autojoin";
public const string ATTRIBUTE_JID = "jid"; public const string ATTRIBUTE_JID = "jid";

View file

@ -11,9 +11,16 @@ public class Module : XmppStreamModule {
public signal void conferences_updated(XmppStream stream, ArrayList<Conference> conferences); public signal void conferences_updated(XmppStream stream, ArrayList<Conference> conferences);
public void get_conferences(XmppStream stream, ConferencesRetrieveResponseListener response_listener) { [CCode (has_target = false)] public delegate void OnResult(XmppStream stream, ArrayList<Conference> conferences, Object? reference);
public void get_conferences(XmppStream stream, OnResult listener, Object? store) {
StanzaNode get_node = new StanzaNode.build("storage", NS_URI).add_self_xmlns(); StanzaNode get_node = new StanzaNode.build("storage", NS_URI).add_self_xmlns();
stream.get_module(PrivateXmlStorage.Module.IDENTITY).retrieve(stream, get_node, new GetConferences(response_listener)); stream.get_module(PrivateXmlStorage.Module.IDENTITY).retrieve(stream, get_node, on_conferences_received, Tuple.create(listener, store));
}
private static void on_conferences_received(XmppStream stream, StanzaNode node, Object? o) {
Tuple<OnResult, Object?> tuple = o as Tuple<OnResult, Object?>;
OnResult on_result = tuple.a;
on_result(stream, get_conferences_from_stanza(node), tuple.b);
} }
public void set_conferences(XmppStream stream, ArrayList<Conference> conferences) { public void set_conferences(XmppStream stream, ArrayList<Conference> conferences) {
@ -21,89 +28,58 @@ public class Module : XmppStreamModule {
foreach (Conference conference in conferences) { foreach (Conference conference in conferences) {
storage_node.put_node(conference.stanza_node); storage_node.put_node(conference.stanza_node);
} }
stream.get_module(PrivateXmlStorage.Module.IDENTITY).store(stream, storage_node, new StoreResponseListenerImpl(conferences)); stream.get_module(PrivateXmlStorage.Module.IDENTITY).store(stream, storage_node, on_set_conferences_response, conferences);
} }
private class StoreResponseListenerImpl : PrivateXmlStorage.StoreResponseListener, Object { private static void on_set_conferences_response(XmppStream stream, Object? o) {
ArrayList<Conference> conferences; ArrayList<Conference> conferences = o as ArrayList<Conference>;
public StoreResponseListenerImpl(ArrayList<Conference> conferences) { stream.get_module(Module.IDENTITY).conferences_updated(stream, conferences);
this.conferences = conferences;
}
public void on_success(XmppStream stream) {
stream.get_module(Module.IDENTITY).conferences_updated(stream, conferences);
}
} }
public void add_conference(XmppStream stream, Conference add) { public void add_conference(XmppStream stream, Conference add) {
get_conferences(stream, new AddConference(add)); get_conferences(stream, on_add_conference_response, add);
}
private static void on_add_conference_response(XmppStream stream, ArrayList<Conference> conferences, Object? o) {
Conference add = o as Conference;
conferences.add(add);
stream.get_module(Module.IDENTITY).set_conferences(stream, conferences);
} }
public void replace_conference(XmppStream stream, Conference was, Conference modified) { public void replace_conference(XmppStream stream, Conference was, Conference modified) {
get_conferences(stream, new ModifyConference(was, modified)); get_conferences(stream, on_replace_conference_response, Tuple.create(was, modified));
}
private static void on_replace_conference_response(XmppStream stream, ArrayList<Conference> conferences, Object? o) {
Tuple<Conference, Conference> tuple = o as Tuple<Conference, Conference>;
Conference was = tuple.a;
Conference modified = tuple.b;
foreach (Conference conference in conferences) {
if (conference.name == was.name && conference.jid == was.jid && conference.autojoin == was.autojoin) {
conference.autojoin = modified.autojoin;
conference.name = modified.name;
conference.jid = modified.jid;
break;
}
}
stream.get_module(Module.IDENTITY).set_conferences(stream, conferences);
} }
public void remove_conference(XmppStream stream, Conference conference) { public void remove_conference(XmppStream stream, Conference conference) {
get_conferences(stream, new RemoveConference(conference)); get_conferences(stream, on_remove_conference_response, conference);
} }
private class GetConferences : PrivateXmlStorage.RetrieveResponseListener, Object { private static void on_remove_conference_response(XmppStream stream, ArrayList<Conference> conferences, Object? o) {
ConferencesRetrieveResponseListener response_listener; Conference remove = o as Conference;
Conference? rem = null;
public GetConferences(ConferencesRetrieveResponseListener response_listener) { foreach (Conference conference in conferences) {
this.response_listener = response_listener; if (conference.name == remove.name && conference.jid == remove.jid && conference.autojoin == remove.autojoin) {
} rem = conference;
break;
public void on_result(XmppStream stream, StanzaNode node) {
response_listener.on_result(stream, get_conferences_from_stanza(node));
}
}
private class AddConference : ConferencesRetrieveResponseListener, Object {
private Conference conference;
public AddConference(Conference conference) {
this.conference = conference;
}
public void on_result(XmppStream stream, ArrayList<Conference> conferences) {
conferences.add(conference);
stream.get_module(Module.IDENTITY).set_conferences(stream, conferences);
}
}
private class ModifyConference : ConferencesRetrieveResponseListener, Object {
private Conference was;
private Conference modified;
public ModifyConference(Conference was, Conference modified) {
this.was = was;
this.modified = modified;
}
public void on_result(XmppStream stream, ArrayList<Conference> conferences) {
foreach (Conference conference in conferences) {
if (conference.name == was.name && conference.jid == was.jid && conference.autojoin == was.autojoin) {
conference.autojoin = modified.autojoin;
conference.name = modified.name;
conference.jid = modified.jid;
break;
}
} }
stream.get_module(Module.IDENTITY).set_conferences(stream, conferences);
}
}
private class RemoveConference : ConferencesRetrieveResponseListener, Object {
private Conference remove;
public RemoveConference(Conference remove) {
this.remove = remove;
}
public void on_result(XmppStream stream, ArrayList<Conference> conferences) {
Conference? rem = null;
foreach (Conference conference in conferences) {
if (conference.name == remove.name && conference.jid == remove.jid && conference.autojoin == remove.autojoin) {
rem = conference;
}
}
if (rem != null) conferences.remove(rem);
stream.get_module(Module.IDENTITY).set_conferences(stream, conferences);
} }
if (rem != null) conferences.remove(rem);
stream.get_module(Module.IDENTITY).set_conferences(stream, conferences);
} }
public override void attach(XmppStream stream) { } public override void attach(XmppStream stream) { }
@ -127,8 +103,4 @@ public class Module : XmppStreamModule {
} }
} }
public interface ConferencesRetrieveResponseListener : Object {
public abstract void on_result(XmppStream stream, ArrayList<Conference> conferences);
}
} }

View file

@ -1,3 +1,5 @@
using Gee;
using Xmpp.Core; using Xmpp.Core;
namespace Xmpp.Xep.PrivateXmlStorage { namespace Xmpp.Xep.PrivateXmlStorage {
@ -7,35 +9,18 @@ namespace Xmpp.Xep.PrivateXmlStorage {
public const string ID = "0049_private_xml_storage"; public const string ID = "0049_private_xml_storage";
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, ID); public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, ID);
public void store(XmppStream stream, StanzaNode node, StoreResponseListener listener) { [CCode (has_target = false)] public delegate void OnSuccess(XmppStream stream, Object? reference);
public void store(XmppStream stream, StanzaNode node, OnSuccess listener, Object? reference) {
StanzaNode queryNode = new StanzaNode.build("query", NS_URI).add_self_xmlns().put_node(node); StanzaNode queryNode = new StanzaNode.build("query", NS_URI).add_self_xmlns().put_node(node);
Iq.Stanza iq = new Iq.Stanza.set(queryNode); Iq.Stanza iq = new Iq.Stanza.set(queryNode);
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, new IqStoreResponse(listener)); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, on_store_response, Tuple.create(listener, reference));
} }
private class IqStoreResponse : Iq.ResponseListener, Object { [CCode (has_target = false)] public delegate void OnResponse(XmppStream stream, StanzaNode node, Object? reference);
StoreResponseListener listener; public void retrieve(XmppStream stream, StanzaNode node, OnResponse listener, Object? reference) {
public IqStoreResponse(StoreResponseListener listener) {
this.listener = listener;
}
public void on_result(XmppStream stream, Iq.Stanza iq) {
listener.on_success(stream);
}
}
public void retrieve(XmppStream stream, StanzaNode node, RetrieveResponseListener responseListener) {
StanzaNode queryNode = new StanzaNode.build("query", NS_URI).add_self_xmlns().put_node(node); StanzaNode queryNode = new StanzaNode.build("query", NS_URI).add_self_xmlns().put_node(node);
Iq.Stanza iq = new Iq.Stanza.get(queryNode); Iq.Stanza iq = new Iq.Stanza.get(queryNode);
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, new IqRetrieveResponse(responseListener)); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, on_retrieve_response, Tuple.create(listener, reference));
}
private class IqRetrieveResponse : Iq.ResponseListener, Object {
RetrieveResponseListener response_listener;
public IqRetrieveResponse(RetrieveResponseListener response_listener) { this.response_listener = response_listener; }
public void on_result(XmppStream stream, Iq.Stanza iq) {
response_listener.on_result(stream, iq.stanza.get_subnode("query", NS_URI));
}
} }
public override void attach(XmppStream stream) { public override void attach(XmppStream stream) {
@ -50,13 +35,15 @@ namespace Xmpp.Xep.PrivateXmlStorage {
public override string get_ns() { return NS_URI; } public override string get_ns() { return NS_URI; }
public override string get_id() { return ID; } public override string get_id() { return ID; }
}
public interface StoreResponseListener : Object { private static void on_store_response(XmppStream stream, Iq.Stanza iq, Object o) {
public abstract void on_success(XmppStream stream); Tuple<OnSuccess, Object> tuple = o as Tuple<OnSuccess, Object>;
} tuple.a(stream, tuple.b);
}
public interface RetrieveResponseListener : Object { private static void on_retrieve_response(XmppStream stream, Iq.Stanza iq, Object o) {
public abstract void on_result(XmppStream stream, StanzaNode stanzaNode); Tuple<OnResponse, Object> tuple = o as Tuple<OnResponse, Object>;
tuple.a(stream, iq.stanza.get_subnode("query", NS_URI), tuple.b);
}
} }
} }

View file

@ -53,32 +53,22 @@ public class Module : XmppStreamModule {
} else { } else {
iq.to = get_bare_jid(presence.from); iq.to = get_bare_jid(presence.from);
} }
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, new IqResponseListenerImpl(this, storage, sha1)); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, on_received_vcard);
} }
} }
private class IqResponseListenerImpl : Iq.ResponseListener, Object { private static void on_received_vcard(XmppStream stream, Iq.Stanza iq) {
Module outer; if (iq.is_error()) return;
PixbufStorage storage; StanzaNode? vcard_node = iq.stanza.get_subnode("vCard", NS_URI);
string id; if (vcard_node == null) return;
public IqResponseListenerImpl(Module outer, PixbufStorage storage, string id) { StanzaNode? photo_node = vcard_node.get_subnode("PHOTO", NS_URI);
this.outer = outer; if (photo_node == null) return;
this.id = id; StanzaNode? binary_node = photo_node.get_subnode("BINVAL", NS_URI);
this.storage = storage; if (binary_node == null) return;
} string? content = binary_node.get_string_content();
public void on_result(XmppStream stream, Iq.Stanza iq) { if (content == null) return;
if (iq.is_error()) return; string sha1 = Checksum.compute_for_data(ChecksumType.SHA1, content.data);
StanzaNode? vcard_node = iq.stanza.get_subnode("vCard", NS_URI); stream.get_module(IDENTITY).received_avatar(stream, iq.from, sha1);
if (vcard_node == null) return;
StanzaNode? photo_node = vcard_node.get_subnode("PHOTO", NS_URI);
if (photo_node == null) return;
StanzaNode? binary_node = photo_node.get_subnode("BINVAL", NS_URI);
if (binary_node == null) return;
string? content = binary_node.get_string_content();
if (content == null) return;
storage.store(id, Base64.decode(content));
outer.received_avatar(stream, iq.from, id);
}
} }
} }
} }

View file

@ -17,23 +17,11 @@ namespace Xmpp.Xep.Pubsub {
event_listeners[node] = new EventListenerDelegate(on_result, reference); event_listeners[node] = new EventListenerDelegate(on_result, reference);
} }
public void request(XmppStream stream, string jid, string node, RequestResponseListener listener) { // TODO multiple nodes gehen auch [CCode (has_target = false)] public delegate void OnResult(XmppStream stream, string jid, string? id, StanzaNode? node, Object? storage);
public void request(XmppStream stream, string jid, string node, OnResult listener, Object? store) { // TODO multiple nodes gehen auch
Iq.Stanza a = new Iq.Stanza.get(new StanzaNode.build("pubsub", NS_URI).add_self_xmlns().put_node(new StanzaNode.build("items", NS_URI).put_attribute("node", node))); Iq.Stanza a = new Iq.Stanza.get(new StanzaNode.build("pubsub", NS_URI).add_self_xmlns().put_node(new StanzaNode.build("items", NS_URI).put_attribute("node", node)));
a.to = jid; a.to = jid;
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, a, new IqRequestResponseListener(listener)); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, a, on_received_request_response, Tuple.create(listener, store));
}
private class IqRequestResponseListener : Iq.ResponseListener, Object {
RequestResponseListener response_listener;
public IqRequestResponseListener(RequestResponseListener response_listener) { this.response_listener = response_listener; }
public void on_result(XmppStream stream, Iq.Stanza iq) {
StanzaNode event_node = iq.stanza.get_subnode("pubsub", NS_URI);
StanzaNode items_node = event_node != null ? event_node.get_subnode("items", NS_URI) : null;
StanzaNode item_node = items_node != null ? items_node.get_subnode("item", NS_URI) : null;
string? node = items_node != null ? items_node.get_attribute("node", NS_URI) : null;
string? id = item_node != null ? item_node.get_attribute("id", NS_URI) : null;
response_listener.on_result(stream, iq.from, id, item_node != null ? item_node.sub_nodes[0] : null);
}
} }
public void publish(XmppStream stream, string? jid, string node_id, string node, string item_id, StanzaNode content) { public void publish(XmppStream stream, string? jid, string node_id, string node, string item_id, StanzaNode content) {
@ -47,18 +35,6 @@ namespace Xmpp.Xep.Pubsub {
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, null); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, null);
} }
private class IqPublishResponseListener : Iq.ResponseListener, Object {
PublishResponseListener response_listener;
public IqPublishResponseListener(PublishResponseListener response_listener) { this.response_listener = response_listener; }
public void on_result(XmppStream stream, Iq.Stanza iq) {
if (iq.is_error()) {
response_listener.on_error(stream);
} else {
response_listener.on_success(stream);
}
}
}
public override void attach(XmppStream stream) { public override void attach(XmppStream stream) {
Iq.Module.require(stream); Iq.Module.require(stream);
Message.Module.require(stream); Message.Module.require(stream);
@ -87,10 +63,16 @@ namespace Xmpp.Xep.Pubsub {
event_listeners[node].on_result(stream, message.from, id, item_node.sub_nodes[0]); event_listeners[node].on_result(stream, message.from, id, item_node.sub_nodes[0]);
} }
} }
}
public interface RequestResponseListener : Object { private static void on_received_request_response(XmppStream stream, Iq.Stanza iq, Object o) {
public abstract void on_result(XmppStream stream, string jid, string? id, StanzaNode? node); Tuple<OnResult, Object?> tuple = o as Tuple<OnResult, Object?>;
OnResult on_result = tuple.a;
StanzaNode event_node = iq.stanza.get_subnode("pubsub", NS_URI);
StanzaNode items_node = event_node != null ? event_node.get_subnode("items", NS_URI) : null;
StanzaNode item_node = items_node != null ? items_node.get_subnode("item", NS_URI) : null;
string? id = item_node != null ? item_node.get_attribute("id", NS_URI) : null;
on_result(stream, iq.from, id, item_node != null ? item_node.sub_nodes[0] : null, tuple.b);
}
} }
public class EventListenerDelegate { public class EventListenerDelegate {
@ -103,9 +85,4 @@ namespace Xmpp.Xep.Pubsub {
this.reference = reference; this.reference = reference;
} }
} }
public interface PublishResponseListener : Object {
public abstract void on_success(XmppStream stream);
public abstract void on_error(XmppStream stream);
}
} }

View file

@ -34,17 +34,6 @@ namespace Xmpp.Xep.UserAvatars {
stream.get_module(Pubsub.Module.IDENTITY).publish(stream, null, NS_URI_METADATA, NS_URI_METADATA, sha1, metadata_node); stream.get_module(Pubsub.Module.IDENTITY).publish(stream, null, NS_URI_METADATA, NS_URI_METADATA, sha1, metadata_node);
} }
private class PublishResponseListenerImpl : Pubsub.PublishResponseListener, Object {
PublishResponseListener listener;
PublishResponseListenerImpl other;
public PublishResponseListenerImpl(PublishResponseListener listener, PublishResponseListenerImpl other) {
this.listener = listener;
this.other = other;
}
public void on_success(XmppStream stream) { listener.on_success(stream); }
public void on_error(XmppStream stream) { listener.on_error(stream); }
}
public override void attach(XmppStream stream) { public override void attach(XmppStream stream) {
Pubsub.Module.require(stream); Pubsub.Module.require(stream);
stream.get_module(Pubsub.Module.IDENTITY).add_filtered_notification(stream, NS_URI_METADATA, on_event_result, this); stream.get_module(Pubsub.Module.IDENTITY).add_filtered_notification(stream, NS_URI_METADATA, on_event_result, this);
@ -59,17 +48,7 @@ namespace Xmpp.Xep.UserAvatars {
if (storage.has_image(id)) { if (storage.has_image(id)) {
stream.get_module(Module.IDENTITY).received_avatar(stream, jid, id); stream.get_module(Module.IDENTITY).received_avatar(stream, jid, id);
} else { } else {
stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid, NS_URI_DATA, new PubsubRequestResponseListenerImpl(storage)); stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid, NS_URI_DATA, on_pubsub_data_response, storage);
}
}
class PubsubRequestResponseListenerImpl : Pubsub.RequestResponseListener, Object {
PixbufStorage storage;
public PubsubRequestResponseListenerImpl(PixbufStorage storage) { this.storage = storage; }
public void on_result(XmppStream stream, string jid, string? id, StanzaNode? node) {
if (node == null) return;
storage.store(id, Base64.decode(node.get_string_content()));
stream.get_module(Module.IDENTITY).received_avatar(stream, jid, id);
} }
} }
@ -79,10 +58,12 @@ namespace Xmpp.Xep.UserAvatars {
public override string get_ns() { return NS_URI; } public override string get_ns() { return NS_URI; }
public override string get_id() { return ID; } public override string get_id() { return ID; }
}
public interface PublishResponseListener : Object { private static void on_pubsub_data_response(XmppStream stream, string jid, string? id, StanzaNode? node, Object? o) {
public abstract void on_success(XmppStream stream); if (node == null) return;
public abstract void on_error(XmppStream stream); PixbufStorage storage = o as PixbufStorage;
storage.store(id, Base64.decode(node.get_string_content()));
stream.get_module(Module.IDENTITY).received_avatar(stream, jid, id);
}
} }
} }

View file

@ -58,26 +58,19 @@ namespace Xmpp.Xep.EntityCapabilities {
string ver_attribute = c_node.get_attribute("ver", NS_URI); string ver_attribute = c_node.get_attribute("ver", NS_URI);
ArrayList<string> capabilities = storage.get_features(ver_attribute); ArrayList<string> capabilities = storage.get_features(ver_attribute);
if (capabilities.size == 0) { if (capabilities.size == 0) {
stream.get_module(ServiceDiscovery.Module.IDENTITY) stream.get_module(ServiceDiscovery.Module.IDENTITY).request_info(stream, presence.from, on_received_info_response, Tuple.create(storage, ver_attribute));
.request_info(stream, presence.from, new ServiceDiscoveryInfoResponseListenerImpl(storage, ver_attribute));
} else { } else {
ServiceDiscovery.Flag.get_flag(stream).set_entitiy_features(presence.from, capabilities); ServiceDiscovery.Flag.get_flag(stream).set_entitiy_features(presence.from, capabilities);
} }
} }
} }
private class ServiceDiscoveryInfoResponseListenerImpl : ServiceDiscovery.InfoResponseListener, Object { private static void on_received_info_response(XmppStream stream, ServiceDiscovery.InfoResult query_result, Object? store) {
private Storage storage; Tuple<Storage, string> tuple = store as Tuple<Storage, string>;
private string entity; Storage storage = tuple.a;
string entity = tuple.b;
public ServiceDiscoveryInfoResponseListenerImpl(Storage storage, string entity) { if (compute_hash(query_result.identities, query_result.features) == entity) {
this.storage = storage; storage.store_features(entity, query_result.features);
this.entity = entity;
}
public void on_result(XmppStream stream, ServiceDiscovery.InfoResult query_result) {
if (compute_hash(query_result.identities, query_result.features) == entity) {
storage.store_features(entity, query_result.features);
}
} }
} }

View file

@ -9,20 +9,10 @@ namespace Xmpp.Xep.Ping {
public const string ID = "0199_ping"; public const string ID = "0199_ping";
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, ID); public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, ID);
public void send_ping(XmppStream stream, string jid, ResponseListener? listener = null) { public void send_ping(XmppStream stream, string jid, ResponseListener listener) {
Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("ping", NS_URI).add_self_xmlns()); Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("ping", NS_URI).add_self_xmlns());
iq.to = jid; iq.to = jid;
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, listener == null? null : new IqResponseListenerImpl(listener)); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, on_ping_response, listener);
}
private class IqResponseListenerImpl : Iq.ResponseListener, Object {
ResponseListener listener;
public IqResponseListenerImpl(ResponseListener listener) {
this.listener = listener;
}
public void on_result(XmppStream stream, Iq.Stanza iq) {
listener.on_result(stream);
}
} }
public override void attach(XmppStream stream) { public override void attach(XmppStream stream) {
@ -45,6 +35,11 @@ namespace Xmpp.Xep.Ping {
} }
public void on_iq_set(XmppStream stream, Iq.Stanza iq) { } public void on_iq_set(XmppStream stream, Iq.Stanza iq) { }
} }
private static void on_ping_response(XmppStream stream, Iq.Stanza iq, Object o) {
ResponseListener listener = o as ResponseListener;
listener.on_result(stream);
}
} }
public interface ResponseListener : Object { public interface ResponseListener : Object {