Skip to content

Commit

Permalink
add support for transferring data ownership to Bytes via custom delet…
Browse files Browse the repository at this point in the history
…er (#335)

* add support for transferring data ownership to Bytes via custom deleter

* mention that deleter should be a thread safe
  • Loading branch information
DenisBiryukov91 authored Dec 18, 2024
1 parent 21b1d2c commit f7f084e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
18 changes: 18 additions & 0 deletions include/zenoh/api/bytes.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,24 @@ class Bytes : public Owned<::z_owned_bytes_t> {
detail::closures::_zenoh_drop_with_context, drop);
}

/// @brief Construct by taking ownership of sequence of bytes.
/// @tparam Deleter callable with signature void Deleter(uint8_t*).
/// @param ptr pointer to data.
/// @param len number of bytes to consider.
/// @param deleter a thread-safe delete function to be invoked once corresponding ``Bytes`` object and all of its
/// clones are destroyed.
template <class Deleter>
Bytes(uint8_t* ptr, size_t len, Deleter deleter) : Bytes() {
static_assert(std::is_invocable_r<void, Deleter, uint8_t*>::value,
"deleter should be callable with the following signature: void deleter(uint8_t* data)");
auto d = [p = ptr, del = std::move(deleter)]() mutable { del(p); };
using D = decltype(d);
using Dval = std::remove_reference_t<D>;
using DroppableType = typename detail::closures::Droppable<Dval>;
auto drop = DroppableType::into_context(std::forward<D>(d));
::z_bytes_from_buf(interop::as_owned_c_ptr(*this), ptr, len, detail::closures::_zenoh_drop_with_context, drop);
}

/// @brief Construct a shallow copy of this data.
Bytes clone() const {
Bytes b;
Expand Down
22 changes: 19 additions & 3 deletions tests/universal/bytes.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
using namespace zenoh;

void reader_writer() {
std::cout << "running reader_writer\n";
std::vector<uint8_t> data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Bytes::Writer writer;
writer.write_all(data.data(), 5);
Expand All @@ -39,7 +38,6 @@ void reader_writer() {
}

void reader_seek_tell() {
std::cout << "running reader_seek_tell\n";
std::vector<uint8_t> data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Bytes::Writer writer;
writer.write_all(data.data(), 5);
Expand Down Expand Up @@ -73,7 +71,6 @@ void reader_seek_tell() {
}

void reader_writer_append() {
std::cout << "running reader_writer_append\n";
std::vector<uint8_t> data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<uint8_t> data2 = {11, 12, 13, 14};
Bytes b, b2;
Expand Down Expand Up @@ -116,9 +113,28 @@ void from_into() {
assert(bs2.as_string() == s);
}

void custom_deleter() {
uint8_t* ptr = new uint8_t[10];
for (size_t i = 0; i < 10; i++) {
ptr[i] = i;
}

bool deleted = false;
auto deleter = [&deleted](uint8_t* data) {
deleted = true;
delete[] data;
};
{
Bytes b(ptr, 10, deleter);
assert(b.as_vector() == std::vector<uint8_t>(ptr, ptr + 10));
}
assert(deleted);
}

int main(int argc, char** argv) {
reader_writer();
reader_seek_tell();
reader_writer_append();
from_into();
custom_deleter();
}

0 comments on commit f7f084e

Please sign in to comment.