aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <tederminant@gmail.com>2019-06-04 16:13:52 -0400
committerDeterminant <tederminant@gmail.com>2019-06-04 16:13:52 -0400
commitebada91a1327da99f1827c7e4c15fc3bee527d58 (patch)
tree904aeb2afbc54612b704f89a80c7a48953943220
parent9f294eb2e0ae0bed8120fc34fd9782f2f0a9ac74 (diff)
more bindings
-rw-r--r--CMakeLists.txt9
-rw-r--r--include/salticidae/event.h25
-rw-r--r--include/salticidae/msg.h15
-rw-r--r--include/salticidae/network.h18
-rw-r--r--include/salticidae/stream.h16
-rw-r--r--include/salticidae/type.h27
-rw-r--r--src/event.cpp24
-rw-r--r--src/msg.cpp23
-rw-r--r--src/network.cpp22
-rw-r--r--src/stream.cpp27
-rw-r--r--src/type.cpp20
-rw-r--r--test/test_msgnet_c.c128
12 files changed, 270 insertions, 84 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 29ea67d..e0bcae2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,11 +31,14 @@ find_package(OpenSSL REQUIRED)
include_directories(include)
add_library(salticidae
OBJECT
+ src/type.cpp
src/util.cpp
- src/conn.cpp
- src/network.cpp
+ src/event.cpp
src/stream.cpp
- src/netaddr.cpp)
+ src/msg.cpp
+ src/netaddr.cpp
+ src/conn.cpp
+ src/network.cpp)
option(BUILD_SHARED "build shared library." OFF)
if(BUILD_SHARED)
diff --git a/include/salticidae/event.h b/include/salticidae/event.h
index 19bd250..27d081a 100644
--- a/include/salticidae/event.h
+++ b/include/salticidae/event.h
@@ -645,9 +645,34 @@ class ThreadCall {
}
+#ifdef SALTICIDAE_CBINDINGS
using eventcontext_t = salticidae::EventContext;
+using sigev_t = salticidae::SigEvent;
+#endif
#else
+
+#ifdef SALTICIDAE_CBINDINGS
typedef struct eventcontext_t;
+typedef struct sigevent_t;
+#endif
+
#endif
+
+#ifdef SALTICIDAE_CBINDINGS
+extern "C" {
+
+eventcontext_t *eventcontext_new();
+void eventcontext_dispatch(eventcontext_t *self);
+void eventcontext_stop(eventcontext_t *self);
+void eventcontext_free(eventcontext_t *self);
+
+typedef void (*sigev_callback_t)(int fd, int events);
+sigev_t *sigev_new(const eventcontext_t *self, sigev_callback_t cb);
+void sigev_add(sigev_t *self, int sig);
+void sigev_free(sigev_t *self);
+
+}
+#endif
+
#endif
diff --git a/include/salticidae/msg.h b/include/salticidae/msg.h
index 128e287..6964ab2 100644
--- a/include/salticidae/msg.h
+++ b/include/salticidae/msg.h
@@ -267,14 +267,27 @@ const size_t MsgBase<OpcodeType>::header_size =
0;
}
+#ifdef SALTICIDAE_CBINDINGS
using msg_t = salticidae::MsgBase<_opcode_t>;
+#endif
+
#else
+
+#ifdef SALTICIDAE_CBINDINGS
typedef struct msg_t msg_t;
#endif
+#endif
+
+#ifdef SALTICIDAE_CBINDINGS
extern "C" {
-void msg_new();
+msg_t *msg_new(_opcode_t opcode, bytearray_t *_moved_payload);
+datastream_t *msg_get_payload(msg_t *msg);
+const _opcode_t &msg_get_opcode(const msg_t *msg);
+void msg_free(msg_t *msg);
+
}
+#endif
#endif
diff --git a/include/salticidae/network.h b/include/salticidae/network.h
index 12fe720..b176b65 100644
--- a/include/salticidae/network.h
+++ b/include/salticidae/network.h
@@ -782,22 +782,28 @@ const O PeerNetwork<O, _, OPCODE_PONG>::MsgPong::opcode = OPCODE_PONG;
}
+#ifdef SALTICIDAE_CBINDINGS
using msgnetwork_t = salticidae::MsgNetwork<_opcode_t>;
using msgnetwork_config_t = msgnetwork_t::Config;
using msgnetwork_conn_t = msgnetwork_t::conn_t;
+#endif
#else
+
+#ifdef SALTICIDAE_CBINDINGS
typedef struct msg_t;
typedef struct msgnetwork_t;
typedef struct msgnetwork_config_t;
typedef struct msgnetwork_conn_t;
#endif
+#endif
+
+#ifdef SALTICIDAE_CBINDINGS
extern "C" {
void salticidae_injected_msg_callback(const msg_t *msg, msgnetwork_conn_t *conn);
-msg_t _test_create_msg();
msgnetwork_t *msgnetwork_new(const eventcontext_t *ec, const msgnetwork_config_t *config);
bool msgnetwork_send_msg(msgnetwork_t *self, const msg_t *msg, const msgnetwork_conn_t *conn);
@@ -806,13 +812,21 @@ msgnetwork_conn_t *msgnetwork_connect(msgnetwork_t *self, const netaddr_t *addr)
void msgnetwork_listen(msgnetwork_t *self, const netaddr_t *listen_addr);
-typedef void (*msgnetwork_msg_callback_t)(const msg_t *msg, const msgnetwork_conn_t *conn);
+typedef void (*msgnetwork_msg_callback_t)(const msg_t *, const msgnetwork_conn_t *);
#ifdef SALTICIDAE_CBINDINGS_STR_OP
void msgnetwork_reg_handler(msgnetwork_t *self, const char *opcode, msgnetwork_msg_callback_t cb);
#else
void msgnetwork_reg_handler(msgnetwork_t *self, uint8_t opcode, msgnetwork_msg_callback_t cb);
#endif
+
+typedef void (*msgnetwork_conn_callback_t)(const msgnetwork_conn_t *, bool);
+
+void msgnetwork_reg_conn_handler(msgnetwork_t *self, msgnetwork_conn_callback_t cb);
+
+msgnetwork_t *msgnetwork_conn_get_net(const msgnetwork_conn_t *conn);
+
}
+#endif
#endif
diff --git a/include/salticidae/stream.h b/include/salticidae/stream.h
index 9eda2bd..e146273 100644
--- a/include/salticidae/stream.h
+++ b/include/salticidae/stream.h
@@ -467,14 +467,21 @@ namespace std {
};
}
+#ifdef SALTICIDAE_CBINDINGS
using uint256_t = salticidae::uint256_t;
using datastream_t = salticidae::DataStream;
+#endif
#else
+
+#ifdef SALTICIDAE_CBINDINGS
typedef struct datastream_t;
typedef struct uint256_t;
#endif
+#endif
+
+#ifdef SALTICIDAE_CBINDINGS
extern "C" {
uint256_t *uint256_new();
@@ -499,8 +506,17 @@ void datastream_put_i16(datastream_t *self, int16_t val);
void datastream_put_i32(datastream_t *self, int32_t val);
void datastream_put_data(datastream_t *self,
uint8_t *begin, uint8_t *end);
+
+uint8_t datastream_get_u8(datastream_t *self);
+uint16_t datastream_get_u16(datastream_t *self);
+uint32_t datastream_get_u32(datastream_t *self);
+int8_t datastream_get_i8(datastream_t *self);
+int16_t datastream_get_i16(datastream_t *self);
+int32_t datastream_get_i32(datastream_t *self);
const uint8_t *datastream_get_data_inplace(datastream_t *self, size_t len);
uint256_t *datastream_get_hash(const datastream_t *self);
}
#endif
+
+#endif
diff --git a/include/salticidae/type.h b/include/salticidae/type.h
index 3ec202a..0ebcce7 100644
--- a/include/salticidae/type.h
+++ b/include/salticidae/type.h
@@ -35,6 +35,9 @@
#include <functional>
#include <mutex>
+#include "config.h"
+
+#ifdef __cplusplus
namespace salticidae {
const auto _1 = std::placeholders::_1;
@@ -89,10 +92,32 @@ inline auto generic_bind(ReturnType(ClassType::* f)(Args...), FArgs&&... fargs)
}
+#ifdef SALTICIDAE_CBINDINGS
+using bytearray_t = salticidae::bytearray_t;
+#endif
+
+#else
+
+#ifdef SALTICIDAE_CBINDINGS
+typedef struct bytearray_t bytearray_t;
+#endif
+
+#endif
+
#ifdef SALTICIDAE_CBINDINGS_STR_OP
-using _opcode_t = std::string;
+using _opcode_t = char *;
#else
using _opcode_t = uint8_t;
#endif
+#ifdef SALTICIDAE_CBINDINGS
+extern "C" {
+
+uint8_t *bytearray_data(bytearray_t *arr);
+size_t bytearray_size(bytearray_t *arr);
+void bytearray_free();
+
+}
+#endif
+
#endif
diff --git a/src/event.cpp b/src/event.cpp
new file mode 100644
index 0000000..050914c
--- /dev/null
+++ b/src/event.cpp
@@ -0,0 +1,24 @@
+#ifdef SALTICIDAE_CBINDINGS
+#include "salticidae/event.h"
+
+extern "C" {
+
+eventcontext_t *eventcontext_new() { return new eventcontext_t(); }
+
+void eventcontext_dispatch(eventcontext_t *self) { return self->dispatch(); }
+
+void eventcontext_stop(eventcontext_t *self) { return self->stop(); }
+
+void eventcontext_free(eventcontext_t *self) { delete self; }
+
+void sigev_new(const eventcontext_t *self, sigev_callback_t cb) {
+ return new SigEvent(*self, cb);
+}
+
+void sigev_add(sigev_t *self, int sig) { self->add(sig); }
+
+void sigev_delete() { delete self; }
+
+}
+
+#endif
diff --git a/src/msg.cpp b/src/msg.cpp
index e69de29..e75d7d4 100644
--- a/src/msg.cpp
+++ b/src/msg.cpp
@@ -0,0 +1,23 @@
+#ifdef SALTICIDAE_CBINDINGS
+#include "salticidae/msg.h"
+
+extern "C" {
+
+msg_t *msg_new(_opcode_t opcode, bytearray_t *_moved_payload) {
+ auto res = new msg_t(opcode, *payload);
+ bytearray_free(payload);
+}
+
+datastream_t *msg_get_payload(msg_t *msg) {
+ return new datastream_t(msg->get_payload());
+}
+
+const _opcode_t msg_get_opcode(const msg_t *msg) {
+ return msg->get_opcode();
+}
+
+void msg_free(msg_t *msg) { delete msg; }
+
+}
+
+#endif
diff --git a/src/network.cpp b/src/network.cpp
index cefe723..0b12131 100644
--- a/src/network.cpp
+++ b/src/network.cpp
@@ -1,16 +1,11 @@
-#include "salticidae/network.h"
#ifdef SALTICIDAE_CBINDINGS
+#include "salticidae/network.h"
using namespace salticidae;
extern "C" {
-msg_t _test_create_msg() {
- return msg_t(0x0, bytearray_t());
-}
-
-
-msgnetwork_t *msgnetwork_new(const EventContext *ec, const msgnetwork_config_t *config) {
+msgnetwork_t *msgnetwork_new(const eventcontext_t *ec, const msgnetwork_config_t *config) {
return new msgnetwork_t(*ec, *config);
}
@@ -47,6 +42,19 @@ void msgnetwork_reg_handler(msgnetwork_t *self,
}
#endif
+void msgnetwork_reg_conn_handler(msgnetwork_t *self, msgnetwork_conn_callback_t cb) {
+ self->reg_conn_handler([cb](const ConnPool::conn_t &_conn, bool connected) {
+ auto conn = salticidae::static_pointer_cast<msgnetwork_t::Conn>(_conn);
+ cb(&conn, connected);
+ });
+}
+
+msgnetwork_t *msgnetwork_conn_get_net(const msgnetwork_conn_t *conn) {
+ return (*conn)->get_net();
+}
+
+void msgnetwork_start(msgnetwork_t *self) { self->start(); }
+
}
#endif
diff --git a/src/stream.cpp b/src/stream.cpp
index 8846414..f3dd322 100644
--- a/src/stream.cpp
+++ b/src/stream.cpp
@@ -1,9 +1,8 @@
+#ifdef SALTICIDAE_CBINDINGS
#include "salticidae/stream.h"
using namespace salticidae;
-#ifdef __cplusplus
-
extern "C" {
uint256_t *uint256_new() { return new uint256_t(); }
@@ -56,6 +55,30 @@ void datastream_put_data(datastream_t *self,
self->put_data(begin, end);
}
+uint8_t datastream_get_u8(datastream_t *self) {
+ uint8_t val; *self >> val; return val;
+}
+
+uint16_t datastream_get_u16(datastream_t *self) {
+ uint16_t val; *self >> val; return val;
+}
+
+uint32_t datastream_get_u32(datastream_t *self) {
+ uint32_t val; *self >> val; return val;
+}
+
+int8_t datastream_get_i8(datastream_t *self) {
+ int8_t val; *self >> val; return val;
+}
+
+int16_t datastream_get_i16(datastream_t *self) {
+ int16_t val; *self >> val; return val;
+}
+
+int32_t datastream_get_i32(datastream_t *self) {
+ int32_t val; *self >> val; return val;
+}
+
const uint8_t *datastream_get_data_inplace(datastream_t *self, size_t len) {
return self->get_data_inplace(len);
}
diff --git a/src/type.cpp b/src/type.cpp
new file mode 100644
index 0000000..8290a07
--- /dev/null
+++ b/src/type.cpp
@@ -0,0 +1,20 @@
+#ifdef SALTICIDAE_CBINDINGS
+#include "salticidae/type.h"
+
+extern "C" {
+
+uint8_t *bytearray_data(bytearray_t *arr) {
+ return &(*arr)[0];
+}
+
+size_t bytearray_size(bytearray_t *arr) {
+ return arr->size();
+}
+
+void bytearray_free(bytearray_t *arr) {
+ delete arr;
+}
+
+}
+
+#endif
diff --git a/test/test_msgnet_c.c b/test/test_msgnet_c.c
index 1098e19..b6ba5a0 100644
--- a/test/test_msgnet_c.c
+++ b/test/test_msgnet_c.c
@@ -36,73 +36,81 @@ typedef struct MsgHello {
const char *text;
} MsgHello;
/** Defines how to serialize the msg. */
-datastream_t msg_hello_serialize(const char *name, const char *text) {
- datastream_t *serialized = msgnet_
+datastream_t *msg_hello_serialize(const char *name, const char *text) {
+ datastream_t *serialized = datastream_new();
serialized << htole((uint32_t)name.length());
serialized << name << text;
+ return serialized;
}
/** Defines how to parse the msg. */
-MsgHello MsgHello(DataStream &&s) {
+MsgHello msg_hello_unserialize(datastream_t *s) {
MsgHello res;
uint32_t len;
- s >> len;
+ len = datastream_get_u32(s);
len = letoh(len);
- res.name = std::string((const char *)s.get_data_inplace(len), len);
- len = s.size();
- res.text = std::string((const char *)s.get_data_inplace(len), len);
- return res;
-}
-/** Acknowledgement Message. */
-struct MsgAck {
- static const uint8_t opcode = 0x1;
- DataStream serialized;
- MsgAck() {}
- MsgAck(DataStream &&s) {}
-};
+ const char *name = (const char *)malloc(len + 1);
+ memmove(name, datastream_get_data_inplace(s, len), len);
+ name[len] = 0;
-const uint8_t MsgHello::opcode;
-const uint8_t MsgAck::opcode;
+ len = datastream_size(s);
+ const char *text = (const char *)malloc(len + 1);
+ memmove(text, datastream_get_data_inplace(s, len), len);
+ text[len] = 0;
-using MsgNetworkByteOp = MsgNetwork<uint8_t>;
+ res.name = name;
+ res.text = text;
+ return res;
+}
+
+datastream_t *msg_ack_serialize() { return datastream_new(); }
-typedef struct MyNet {
+struct MyNet {
msgnetwork_t *net;
- const std::string name;
+ const char *name;
const NetAddr peer;
-} MyNet;
+} alice, bob;
-void msg_hello_handler(const msg_t *msg, const msgnetwork_conn_t *conn) {
+void on_receive_hello(const msg_t *msg, const msgnetwork_conn_t *conn) {
+ msgnetwork_t *net = msgnetwork_conn_get_net(conn);
+ printf("[%s] %s says %s\n", name, msg.name, msg.text);
+ msg_t *msg = msg_new(0x1, msg_ack_serialize());
+ /* send acknowledgement */
+ send_msg(msg, conn);
+ msg_free(msg);
}
-void msg_ack_handler(const msg_t *msg, const msgnetwork_conn_t *conn) {
+void on_receive_ack(const msg_t *msg, const msgnetwork_conn_t *conn) {
+ auto net = static_cast<MyNet *>(conn->get_net());
+ printf("[%s] the peer knows\n", net->name.c_str());
}
-void alice_conn_handler(const msgnetwork_conn_t *conn, bool connected) {
+void conn_handler(const msgnetwork_conn_t *conn, bool connected) {
+ msgnetwork_t *net = msgnetwork_conn_get_net(conn);
+ const char *name = net == alice.net ? alice.name : bob.name;
if (connected)
{
if (conn->get_mode() == ConnPool::Conn::ACTIVE)
{
- puts("[alice] Connected, sending hello.");
+ puts("[%s] Connected, sending hello.", name);
/* send the first message through this connection */
msgnetwork_send_msg(alice,
msg_hello_serialize("alice", "Hello there!"), conn);
}
else
- printf("[alice] Accepted, waiting for greetings.\n",
- this->name.c_str());
+ printf("[%s] Accepted, waiting for greetings.\n", name);
}
else
{
- printf("[alice] Disconnected, retrying.\n", this->name.c_str());
+ printf("[%s] Disconnected, retrying.\n", name);
/* try to reconnect to the same address */
connect(conn->get_addr());
}
}
-MyNet mynet_new(const salticidae::EventContext &ec,
+MyNet gen_mynet(const eventcontext_t *ec,
const char *name,
const netaddr_t *peer) {
MyNet res;
@@ -110,62 +118,46 @@ MyNet mynet_new(const salticidae::EventContext &ec,
res.net = msgnetwork_new(ec, netconfig);
res.name = name;
res.peer = peer;
-
- /* message handler could be a bound method */
- reg_handler(salticidae::generic_bind(&MyNet::on_receive_hello, this, _1, _2));
-
- reg_conn_handler([this](const ConnPool::conn_t &conn, bool connected) {
- });
- }
-
- void on_receive_hello(MsgHello &&msg, const MyNet::conn_t &conn) {
- printf("[%s] %s says %s\n",
- name.c_str(),
- msg.name.c_str(), msg.text.c_str());
- /* send acknowledgement */
- send_msg(MsgAck(), conn);
- }
};
-void on_receive_ack(MsgAck &&msg, const MyNet::conn_t &conn) {
- auto net = static_cast<MyNet *>(conn->get_net());
- printf("[%s] the peer knows\n", net->name.c_str());
+void on_term_signal(int) {
+ ec.stop();
}
int main() {
- salticidae::EventContext ec;
- NetAddr alice_addr("127.0.0.1:12345");
- NetAddr bob_addr("127.0.0.1:12346");
+ eventcontext_t *ec = eventcontext_new();
+ netaddr_t *alice_addr = netaddr_new_from_sipport("127.0.0.1:12345");
+ netaddr_t *bob_addr = netaddr_new_from_sipport("127.0.0.1:12346");
/* test two nodes in the same main loop */
- MyNet alice(ec, "Alice", bob_addr);
- MyNet bob(ec, "Bob", alice_addr);
+ alice = gen_mynet(ec, "Alice", bob_addr);
+ bob = gen_mynet(ec, "Bob", alice_addr);
- /* message handler could be a normal function */
- alice.reg_handler(on_receive_ack);
- bob.reg_handler(on_receive_ack);
+ msgnetwork_reg_handler(alice.net, MSG_OPCODE_HELLO, on_receive_hello);
+ msgnetwork_reg_handler(alice.net, MSG_OPCODE_HELLO, on_receive_hello);
+ msgnetwork_reg_handler(bob.net, MSG_OPCODE_HELLO, on_receive_hello);
+ msgnetwork_reg_handler(bob.net, MSG_OPCODE_HELLO, on_receive_hello);
/* start all threads */
- alice.start();
- bob.start();
+ msgnetwork_start(alice.net);
+ msgnetwork_start(bob.net);
/* accept incoming connections */
- alice.listen(alice_addr);
- bob.listen(bob_addr);
+ msgnetwork_listen(alice_addr);
+ msgnetwork_listen(bob_addr);
/* try to connect once */
- alice.connect(bob_addr);
- bob.connect(alice_addr);
+ msgnetwork_connect(bob_addr);
+ msgnetwork_connect(alice_addr);
/* the main loop can be shutdown by ctrl-c or kill */
- auto shutdown = [&](int) {ec.stop();};
- salticidae::SigEvent ev_sigint(ec, shutdown);
- salticidae::SigEvent ev_sigterm(ec, shutdown);
- ev_sigint.add(SIGINT);
- ev_sigterm.add(SIGTERM);
+ sigev_t *ev_sigint = sigev_new(ec, on_term_signal);
+ sigev_t *ev_sigterm = sigev_new(ec, on_term_signal);
+ sigev_add(ev_sigint, SIGINT);
+ sigev_add(ev_sigterm, SIGTERM);
/* enter the main loop */
- ec.dispatch();
+ eventcontext_dispatch(ec);
return 0;
}