Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
louiz’
biboumi
Commits
26ffc8fe
Commit
26ffc8fe
authored
Jun 19, 2014
by
louiz’
Browse files
Implement a way to add callbacks, waiting for an IRC event to return an iq
parent
a705b9af
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/bridge/bridge.cpp
View file @
26ffc8fe
...
...
@@ -4,6 +4,7 @@
#include
<irc/irc_message.hpp>
#include
<network/poller.hpp>
#include
<utils/encoding.hpp>
#include
<utils/tolower.hpp>
#include
<logger/logger.hpp>
#include
<utils/split.hpp>
#include
<stdexcept>
...
...
@@ -369,3 +370,20 @@ void Bridge::remove_preferred_from_jid(const std::string& nick)
if
(
it
!=
this
->
preferred_user_from
.
end
())
this
->
preferred_user_from
.
erase
(
it
);
}
void
Bridge
::
add_waiting_iq
(
iq_responder_callback_t
&&
callback
)
{
this
->
waiting_iq
.
emplace_back
(
std
::
move
(
callback
));
}
void
Bridge
::
trigger_response_iq
(
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
)
{
auto
it
=
this
->
waiting_iq
.
begin
();
while
(
it
!=
this
->
waiting_iq
.
end
())
{
if
((
*
it
)(
irc_hostname
,
message
)
==
true
)
it
=
this
->
waiting_iq
.
erase
(
it
);
else
++
it
;
}
}
src/bridge/bridge.hpp
View file @
26ffc8fe
...
...
@@ -7,12 +7,21 @@
#include
<irc/iid.hpp>
#include
<unordered_map>
#include
<functional>
#include
<string>
#include
<memory>
class
XmppComponent
;
class
Poller
;
/**
* A callback called for each IrcMessage we receive. If the message triggers
* a response, it must send an iq and return true (in that case it is
* removed from the list), otherwise it must do nothing and just return
* false.
*/
typedef
std
::
function
<
bool
(
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
)
>
iq_responder_callback_t
;
/**
* One bridge is spawned for each XMPP user that uses the component. The
* bridge spawns IrcClients when needed (when the user wants to join a
...
...
@@ -131,6 +140,16 @@ public:
* Remove the preferred jid for the given IRC nick
*/
void
remove_preferred_from_jid
(
const
std
::
string
&
nick
);
/**
* Add a callback to the waiting iq list.
*/
void
add_waiting_iq
(
iq_responder_callback_t
&&
callback
);
/**
* Iter over all the waiting_iq, call the iq_responder_filter_t for each,
* whenever one of them returns true: call the corresponding
* iq_responder_callback_t and remove the callback from the list.
*/
void
trigger_response_iq
(
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
);
private:
/**
...
...
@@ -173,6 +192,13 @@ private:
* from='#somechan%server@biboumi/ToTo'
*/
std
::
unordered_map
<
std
::
string
,
std
::
string
>
preferred_user_from
;
/**
* A list of callbacks that are waiting for some IrcMessage to trigger a
* response. We add callbacks in this list whenever we received an IQ
* request and we need a response from IRC to be able to provide the
* response iq.
*/
std
::
list
<
iq_responder_callback_t
>
waiting_iq
;
Bridge
(
const
Bridge
&
)
=
delete
;
Bridge
(
Bridge
&&
other
)
=
delete
;
...
...
src/irc/iid.cpp
View file @
26ffc8fe
...
...
@@ -20,6 +20,14 @@ Iid::Iid(const std::string& iid):
this
->
set_server
(
iid
);
}
Iid
::
Iid
(
const
Iid
&
other
)
:
is_channel
(
other
.
is_channel
),
is_user
(
other
.
is_user
),
local
(
other
.
local
),
server
(
other
.
server
)
{
}
Iid
::
Iid
()
:
is_channel
(
false
),
is_user
(
false
)
...
...
src/irc/iid.hpp
View file @
26ffc8fe
...
...
@@ -43,6 +43,7 @@ class Iid
{
public:
explicit
Iid
(
const
std
::
string
&
iid
);
explicit
Iid
(
const
Iid
&
);
explicit
Iid
();
void
set_local
(
const
std
::
string
&
loc
);
...
...
@@ -59,7 +60,6 @@ private:
std
::
string
local
;
std
::
string
server
;
Iid
(
const
Iid
&
)
=
delete
;
Iid
(
Iid
&&
)
=
delete
;
Iid
&
operator
=
(
const
Iid
&
)
=
delete
;
Iid
&
operator
=
(
Iid
&&
)
=
delete
;
...
...
src/irc/irc_client.cpp
View file @
26ffc8fe
...
...
@@ -136,8 +136,11 @@ void IrcClient::parse_in_buffer(const size_t)
if
(
pos
==
std
::
string
::
npos
)
break
;
IrcMessage
message
(
this
->
in_buf
.
substr
(
0
,
pos
));
log_debug
(
"IRC RECEIVING: "
<<
message
);
this
->
in_buf
=
this
->
in_buf
.
substr
(
pos
+
2
,
std
::
string
::
npos
);
log_debug
(
"IRC RECEIVING: "
<<
message
);
// Call the standard callback (if any), associated with the command
// name that we just received.
auto
cb
=
irc_callbacks
.
find
(
message
.
command
);
if
(
cb
!=
irc_callbacks
.
end
())
{
...
...
@@ -149,6 +152,8 @@ void IrcClient::parse_in_buffer(const size_t)
}
else
log_info
(
"No handler for command "
<<
message
.
command
);
// Try to find a waiting_iq, which response will be triggered by this IrcMessage
this
->
bridge
->
trigger_response_iq
(
this
->
hostname
,
message
);
}
}
...
...
src/xmpp/xmpp_component.cpp
View file @
26ffc8fe
...
...
@@ -220,14 +220,20 @@ void XmppComponent::send_stream_error(const std::string& name, const std::string
}
void
XmppComponent
::
send_stanza_error
(
const
std
::
string
&
kind
,
const
std
::
string
&
to
,
const
std
::
string
&
from
,
const
std
::
string
&
id
,
const
std
::
string
&
error_type
,
const
std
::
string
&
defined_condition
,
const
std
::
string
&
text
)
const
std
::
string
&
id
,
const
std
::
string
&
error_type
,
const
std
::
string
&
defined_condition
,
const
std
::
string
&
text
,
const
bool
fulljid
)
{
Stanza
node
(
kind
);
if
(
!
to
.
empty
())
node
[
"to"
]
=
to
;
if
(
!
from
.
empty
())
node
[
"from"
]
=
from
;
{
if
(
fulljid
)
node
[
"from"
]
=
from
;
else
node
[
"from"
]
=
from
+
"@"
+
this
->
served_hostname
;
}
if
(
!
id
.
empty
())
node
[
"id"
]
=
id
;
node
[
"type"
]
=
"error"
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment