From 0eee567c4ec7847bc2b1e7d78004c3c7198de5ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Wed, 16 Oct 2019 13:57:31 -0400
Subject: [PATCH] c wrapper: add support to create, ref/unref dht_value

---
 c/opendht.cpp | 42 ++++++++++++++++++++++++++++++++++++------
 c/opendht_c.h |  8 +++++++-
 2 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/c/opendht.cpp b/c/opendht.cpp
index 16c59fd4..2d78c62d 100644
--- a/c/opendht.cpp
+++ b/c/opendht.cpp
@@ -1,6 +1,8 @@
 #include "opendht_c.h"
 #include "opendht.h"
 
+using ValueSp = std::shared_ptr<dht::Value>;
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -11,11 +13,19 @@ const char* dht_infohash_print(const dht_infohash* h)
     return reinterpret_cast<const dht::InfoHash*>(h)->to_c_str();
 }
 
+void dht_infohash_zero(dht_infohash* h) {
+    *reinterpret_cast<dht::InfoHash*>(h) = dht::InfoHash{};
+}
+
 void dht_infohash_random(dht_infohash* h)
 {
     *reinterpret_cast<dht::InfoHash*>(h) = dht::InfoHash::getRandom();
 }
 
+bool dht_infohash_is_zero(const dht_infohash* h) {
+    return static_cast<bool>(*reinterpret_cast<const dht::InfoHash*>(h));
+}
+
 const char* dht_pkid_print(const dht_pkid* h)
 {
     return reinterpret_cast<const dht::PkId*>(h)->to_c_str();
@@ -38,12 +48,25 @@ dht_data_view dht_blob_get_data(const dht_blob* data)
 // dht::Value
 dht_data_view dht_value_get_data(const dht_value* data)
 {
+    const ValueSp& vsp(*reinterpret_cast<const ValueSp*>(data));
     dht_data_view view;
-    view.data = reinterpret_cast<const dht::Value*>(data)->data.data();
-    view.size = reinterpret_cast<const dht::Value*>(data)->data.size();
+    view.data = vsp->data.data();
+    view.size = vsp->data.size();
     return view;
 }
 
+dht_value* dht_value_new(const uint8_t* data, size_t size) {
+    return reinterpret_cast<dht_value*>(new ValueSp(std::make_shared<dht::Value>(data, size)));
+}
+
+dht_value* dht_value_ref(const dht_value* v) {
+    return reinterpret_cast<dht_value*>(new ValueSp(*reinterpret_cast<const ValueSp*>(v)));
+}
+
+void dht_value_unref(dht_value* v) {
+    delete reinterpret_cast<ValueSp*>(v);
+}
+
 // dht::crypto::PublicKey
 dht_publickey* dht_publickey_new() {
     return reinterpret_cast<dht_publickey*>(new dht::crypto::PublicKey);
@@ -140,7 +163,7 @@ void dht_runner_get(dht_runner* r, const dht_infohash* h, dht_get_cb cb, dht_don
     auto runner = reinterpret_cast<dht::DhtRunner*>(r);
     auto hash = reinterpret_cast<const dht::InfoHash*>(h);
     runner->get(*hash, [cb,cb_user_data](std::shared_ptr<dht::Value> value){
-        return cb(reinterpret_cast<dht_value*>(value.get()), cb_user_data);
+        return cb(reinterpret_cast<const dht_value*>(&value), cb_user_data);
     }, [done_cb, cb_user_data](bool ok){
         done_cb(ok, cb_user_data);
     });
@@ -153,7 +176,7 @@ dht_op_token* dht_runner_listen(dht_runner* r, const dht_infohash* h, dht_value_
     auto fret = new std::future<size_t>;
     *fret = runner->listen(*hash, [cb,cb_user_data](const std::vector<std::shared_ptr<dht::Value>>& values, bool expired) {
         for (const auto& value : values) {
-            if (not cb(reinterpret_cast<dht_value*>(value.get()), expired, cb_user_data))
+            if (not cb(reinterpret_cast<const dht_value*>(&value), expired, cb_user_data))
                 return false;
         }
         return true;
@@ -161,8 +184,7 @@ dht_op_token* dht_runner_listen(dht_runner* r, const dht_infohash* h, dht_value_
     return (dht_op_token*)fret;
 }
 
-void
-dht_runner_cancel_listen(dht_runner* r, const dht_infohash* h, dht_op_token* t)
+void dht_runner_cancel_listen(dht_runner* r, const dht_infohash* h, dht_op_token* t)
 {
     auto runner = reinterpret_cast<dht::DhtRunner*>(r);
     auto hash = reinterpret_cast<const dht::InfoHash*>(h);
@@ -170,6 +192,14 @@ dht_runner_cancel_listen(dht_runner* r, const dht_infohash* h, dht_op_token* t)
     runner->cancelListen(*hash, std::move(*token));
 }
 
+void dht_runner_shutdown(dht_runner* r, dht_shutdown_cb done_cb, void* cb_user_data)
+{
+    auto runner = reinterpret_cast<dht::DhtRunner*>(r);
+    runner->shutdown([done_cb, cb_user_data](){
+        done_cb(cb_user_data);
+    });
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/c/opendht_c.h b/c/opendht_c.h
index b0c74162..19c138d2 100644
--- a/c/opendht_c.h
+++ b/c/opendht_c.h
@@ -22,6 +22,9 @@ typedef struct dht_data_view dht_data_view;
 struct OPENDHT_C_PUBLIC dht_value;
 typedef struct dht_value dht_value;
 OPENDHT_C_PUBLIC dht_data_view dht_value_get_data(const dht_value* data);
+OPENDHT_C_PUBLIC dht_value* dht_value_new(const uint8_t* data, size_t size);
+OPENDHT_C_PUBLIC dht_value* dht_value_ref(const dht_value*);
+OPENDHT_C_PUBLIC void dht_value_unref(dht_value*);
 
 // dht::Blob
 struct OPENDHT_C_PUBLIC dht_blob;
@@ -32,8 +35,10 @@ OPENDHT_C_PUBLIC void dht_blob_delete(dht_blob* data);
 // dht::InfoHash
 struct OPENDHT_C_PUBLIC dht_infohash { uint8_t d[HASH_LEN]; };
 typedef struct dht_infohash dht_infohash;
+OPENDHT_C_PUBLIC void dht_infohash_zero(dht_infohash* h);
 OPENDHT_C_PUBLIC void dht_infohash_random(dht_infohash* h);
 OPENDHT_C_PUBLIC const char* dht_infohash_print(const dht_infohash* h);
+OPENDHT_C_PUBLIC bool dht_infohash_is_zero(const dht_infohash* h);
 
 // dht::PkId
 struct OPENDHT_C_PUBLIC dht_pkid { uint8_t d[32]; };
@@ -46,7 +51,7 @@ typedef struct dht_publickey dht_publickey;
 OPENDHT_C_PUBLIC dht_publickey* dht_publickey_new();
 OPENDHT_C_PUBLIC void dht_publickey_delete(dht_publickey* pk);
 OPENDHT_C_PUBLIC int dht_publickey_unpack(dht_publickey* pk, const uint8_t* dat, size_t dat_size);
-OPENDHT_C_PUBLIC int dht_publickey_pack(dht_publickey* pk, char* out, size_t* outlen);
+OPENDHT_C_PUBLIC int dht_publickey_pack(dht_publickey* pk, char* out, size_t* out_size);
 OPENDHT_C_PUBLIC dht_infohash dht_publickey_get_id(const dht_publickey* pk);
 OPENDHT_C_PUBLIC dht_pkid dht_publickey_get_long_id(const dht_publickey* pk);
 OPENDHT_C_PUBLIC bool dht_publickey_check_signature(const dht_publickey* pk, const char* data, size_t data_size, const char* signature, size_t signature_size);
@@ -84,6 +89,7 @@ OPENDHT_C_PUBLIC void dht_runner_bootstrap(dht_runner* runner, const char* host,
 OPENDHT_C_PUBLIC void dht_runner_get(dht_runner* runner, const dht_infohash* hash, dht_get_cb cb, dht_done_cb done_cb, void* cb_user_data);
 OPENDHT_C_PUBLIC dht_op_token* dht_runner_listen(dht_runner* runner, const dht_infohash* hash, dht_value_cb cb, void* cb_user_data);
 OPENDHT_C_PUBLIC void dht_runner_cancel_listen(dht_runner* runner, const dht_infohash* hash, dht_op_token* token);
+OPENDHT_C_PUBLIC void dht_runner_shutdown(dht_runner* runner, dht_shutdown_cb done_cb, void* cb_user_data);
 
 #ifdef __cplusplus
 }
-- 
GitLab