#include <xs/export.h>
#include <xs/unievent/Udp.h>
#include <xs/typemap/expected.h>
#include <xs/unievent/Listener.h>
#include <xs/CallbackDispatcher.h>
using namespace xs;
using namespace xs::unievent;
using namespace panda::unievent;
using panda::string;
using panda::string_view;
using panda::net::SockAddr;
static PERL_THREAD_LOCAL struct {
Simple on_receive = Simple::shared("on_receive");
Simple on_send = Simple::shared("on_send");
} cbn;
struct XSUdpListener : IUdpListener, XSListener {
void on_receive (const UdpSP& h, string& buf, const SockAddr& sa, unsigned flags, const ErrorCode& err) override {
call(cbn.on_receive, xs::out(h), err ? Sv::undef : xs::out(buf), xs::out(&sa), Simple(flags), xs::out(err));
}
void on_send (const UdpSP& h, const ErrorCode& err, const SendRequestSP& req) override {
call(cbn.on_send, xs::out(h), xs::out(err), xs::out(req));
}
};
MODULE = UniEvent::Udp PACKAGE = UniEvent::Udp
PROTOTYPES: DISABLE
BOOT {
Stash s(__PACKAGE__);
s.inherit("UniEvent::Handle");
s.add_const_sub("TYPE", Simple(Udp::TYPE.name));
xs::exp::create_constants(s, {
{"PARTIAL", Udp::Flags::PARTIAL },
{"IPV6ONLY", Udp::Flags::IPV6ONLY },
{"REUSEADDR", Udp::Flags::REUSEADDR },
{"MMSG_CHUNK", Udp::Flags::MMSG_CHUNK },
{"MMSG_FREE", Udp::Flags::MMSG_FREE },
{"RECVMMSG", Udp::Flags::RECVMMSG },
{"LEAVE_GROUP", (unsigned)Udp::Membership::LEAVE_GROUP},
{"JOIN_GROUP", (unsigned)Udp::Membership::JOIN_GROUP }
});
xs::at_perl_destroy([]() {
cbn.on_receive = nullptr;
cbn.on_send = nullptr;
});
unievent::register_perl_class(Udp::TYPE, s);
}
Udp* Udp::new (Loop* loop = Loop::default_loop(), int domain = AF_UNSPEC, int flags = 0) {
RETVAL = make_backref<Udp>(loop, domain, flags);
}
void Udp::open (Sv sock) {
XSRETURN_EXPECTED(THIS->open(sv2sock(sock), Ownership::SHARE));
}
void Udp::bind (string_view host, uint16_t port, AddrInfoHints hints = AddrInfoHints(), unsigned flags = 0) {
XSRETURN_EXPECTED(THIS->bind(host, port, hints, flags));
}
void Udp::bind_addr (SockAddr addr, unsigned flags = 0) {
XSRETURN_EXPECTED(THIS->bind(addr, flags));
}
#// connect($host, $port, [$hints])
#// connect($sockaddr)
void Udp::connect (Sv host_or_sockaddr, uint16_t port = 0, AddrInfoHints hints = AddrInfoHints()) {
if (items < 3) XSRETURN_EXPECTED(THIS->connect(xs::in<SockAddr>(host_or_sockaddr)));
else XSRETURN_EXPECTED(THIS->connect(xs::in<string_view>(host_or_sockaddr), port, hints));
}
void Udp::recv_start (Udp::receive_fn cb = nullptr) {
XSRETURN_EXPECTED(THIS->recv_start(cb));
}
void Udp::recv_stop () {
XSRETURN_EXPECTED(THIS->recv_stop());
}
XSCallbackDispatcher* Udp::receive_event () {
RETVAL = XSCallbackDispatcher::create(THIS->receive_event);
}
void Udp::receive_callback (Udp::receive_fn cb) {
THIS->receive_event.remove_all();
if (cb) THIS->receive_event.add(cb);
}
XSCallbackDispatcher* Udp::send_event () {
RETVAL = XSCallbackDispatcher::create(THIS->send_event);
}
void Udp::send_callback (Udp::send_fn cb) {
THIS->send_event.remove_all();
if (cb) THIS->send_event.add(cb);
}
Ref Udp::event_listener (Sv lst = Sv(), bool weak = false) {
RETVAL = event_listener<XSUdpListener>(THIS, ST(0), lst, weak);
}
SendRequestSP Udp::send (Sv sv, SockAddr sa, Udp::send_fn cb = nullptr) {
auto buf = sv2buf(sv);
if (!buf) XSRETURN(0);
SendRequestSP req = new SendRequest(buf);
req->addr = sa;
if (cb) req->event.add(cb);
THIS->send(req);
RETVAL = req;
}
void Udp::sockaddr () : ALIAS(peeraddr=1) {
auto res = ix == 0 ? THIS->sockaddr() : THIS->peeraddr();
XSRETURN_EXPECTED(res);
}
void Udp::set_membership (string_view multicast_addr, string_view interface_addr, int membership) {
XSRETURN_EXPECTED(THIS->set_membership(multicast_addr, interface_addr, (Udp::Membership)membership));
}
void Udp::set_source_membership (string_view multicast_addr, string_view interface_addr, string_view source_addr, int membership) {
XSRETURN_EXPECTED(THIS->set_source_membership(multicast_addr, interface_addr, source_addr, (Udp::Membership)membership));
}
void Udp::set_multicast_loop (bool on) {
XSRETURN_EXPECTED(THIS->set_multicast_loop(on));
}
void Udp::set_multicast_ttl (int ttl) {
XSRETURN_EXPECTED(THIS->set_multicast_ttl(ttl));
}
void Udp::set_multicast_interface (string_view interface_addr) {
XSRETURN_EXPECTED(THIS->set_multicast_interface(interface_addr));
}
void Udp::set_broadcast (bool on) {
XSRETURN_EXPECTED(THIS->set_broadcast(on));
}
void Udp::set_ttl (int ttl) {
XSRETURN_EXPECTED(THIS->set_ttl(ttl));
}
size_t Udp::send_queue_size ()
void Udp::recv_buffer_size (Simple newval = Simple()) {
if (newval) XSRETURN_EXPECTED(THIS->recv_buffer_size(newval));
else XSRETURN_EXPECTED(THIS->recv_buffer_size());
}
void Udp::send_buffer_size (Simple newval = Simple()) {
if (newval) XSRETURN_EXPECTED(THIS->send_buffer_size(newval));
else XSRETURN_EXPECTED(THIS->send_buffer_size());
}
bool Udp::using_recvmmsg ()