Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

z_bytes example #218

Merged
merged 15 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ status_print(project_version)

declare_cache_var(ZENOHCXX_ZENOHC ON BOOL "Build for Zenoh-c target")
declare_cache_var(ZENOHCXX_ZENOHPICO OFF BOOL "Build for Zenoh-pico target")
declare_cache_var(ZENOHCXX_EXAMPLES_PROTOBUF ON BOOL "Build Protobuf example (turn off if you have problems with installed Protobuf version)")

set_default_build_type(Release)

Expand Down
23 changes: 23 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@ if(ZENOHCXX_ZENOHPICO)
add_dependencies(examples examples_zenohpico)
endif()

function(add_protobuf target)
if(ZENOHCXX_EXAMPLES_PROTOBUF)
find_package(Protobuf)
if(Protobuf_FOUND)
message(STATUS "Found Protobuf ${protobuf_VERSION}, will build Protobuf example!")

protobuf_generate_cpp(pb_src pb_hdr ${CMAKE_CURRENT_LIST_DIR}/universal/proto/entity.proto)

add_library(example_message ${pb_hdr} ${pb_src})
target_include_directories(example_message INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(example_message PUBLIC protobuf::libprotobuf)

target_link_libraries(${target} PRIVATE example_message)
target_compile_definitions(${target} PRIVATE -DZENOH_CPP_EXMAPLE_WITH_PROTOBUF)
else()
message("Protobuf not found, will build without Protobuf example!")
endif()
endif()
endfunction()

function(add_example file mode lib)
get_filename_component(filename ${file} NAME_WE)
set(target ${filename}_${mode})
Expand All @@ -22,6 +42,9 @@ function(add_example file mode lib)
target_link_libraries(${target} PUBLIC ${lib})
set_property(TARGET ${target} PROPERTY LANGUAGE CXX)
set_property(TARGET ${target} PROPERTY CXX_STANDARD 17)
if("${target}" MATCHES "z_bytes_*")
add_protobuf(${target})
endif()
copy_dlls(${target})
endfunction()

Expand Down
6 changes: 6 additions & 0 deletions examples/universal/proto/entity.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
syntax = "proto3";

message Entity {
uint32 id = 1;
string name = 2;
}
179 changes: 179 additions & 0 deletions examples/universal/z_bytes.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
//
// Copyright (c) 2022 ZettaScale Technology
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
//
// Contributors:
// ZettaScale Zenoh Team, <[email protected]>
//
#include <iostream>

#ifdef ZENOH_CPP_EXMAPLE_WITH_PROTOBUF
#include "entity.pb.h"
#endif

#include "zenoh.hxx"
using namespace zenoh;

int _main(int argc, char** argv) {
// Numeric: u8, u16, u32, u128, usize, i8, i16, i32, i128, isize, f32, f64
{
const uint32_t input = 1234;
const auto payload = Bytes::serialize(input);
const auto output = payload.deserialize<uint32_t>();
assert(input == output);
// Corresponding encoding to be used in operations like `.put()`, `.reply()`, etc.
const auto encoding = Encoding("zenoh/uint32");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have Encoding constants instead of using the string form?

Copy link
Contributor

@DenisBiryukov91 DenisBiryukov91 Sep 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not yet, will do in separate pr, since they are introduced in pico by eclipse-zenoh/zenoh-pico#673

}

// String
{
// C-String
{
const char* input = "test";
const auto payload = Bytes::serialize(input);
const auto output = payload.deserialize<std::string>();
assert(input == output);
}
// std::string
{
const std::string input = "test";
const auto payload = Bytes::serialize(input);
const auto output = payload.deserialize<std::string>();
assert(input == output);
}
// Corresponding encoding to be used in operations like `.put()`, `.reply()`, etc.
const auto encoding = Encoding("zenoh/string");
}

// Vec<u8>: The deserialization should be infallible
{
const std::vector<uint8_t> input = {1, 2, 3, 4};
const auto payload = Bytes::serialize(input);
const auto output = payload.deserialize<std::vector<uint8_t>>();
assert(input == output);
// Corresponding encoding to be used in operations like `.put()`, `.reply()`, etc.
const auto encoding = Encoding("zenoh/bytes");
}

// Writer & Reader
{
// serialization
Bytes bytes;
auto writer = bytes.writer();

const uint32_t i1 = 1234;
const std::string i2 = "test";
const std::vector<uint8_t> i3 = {1, 2, 3, 4};

writer.append_bounded(i1);
writer.append_bounded(i2);
writer.append_bounded(i3);

// deserialization
auto reader = bytes.reader();

const auto o1 = reader.read_bounded().deserialize<uint32_t>();
const auto o2 = reader.read_bounded().deserialize<std::string>();
const auto o3 = reader.read_bounded().deserialize<std::vector<uint8_t>>();

assert(i1 == o1);
assert(i2 == o2);
assert(i3 == o3);
}

// Iterator
{
const int32_t input[] = {1, 2, 3, 4};
const auto payload = Bytes::serialize_from_iter(input, input + 4);

auto idx = 0;
auto it = payload.iter();
for (auto elem = it.next(); elem.has_value(); elem = it.next()) {
assert(input[idx++] == elem.value().deserialize<int32_t>());
}
}

// Iterator RAW
{
const std::vector<uint8_t> input = {1, 2, 3, 4};
const auto payload = Bytes::serialize(input);

size_t idx = 0;
auto it = payload.slice_iter();
for (auto elem = it.next(); elem.has_value(); elem = it.next()) {
const auto& slice = elem.value();
for (size_t i = 0; i < slice.len; ++i) {
assert(input[idx++] == slice.data[i]);
}
}
}

// HashMap
{
const std::unordered_map<uint64_t, std::string> input = {{0, "abc"}, {1, "def"}};
const auto payload = Bytes::serialize(input);
const auto output = payload.deserialize<std::unordered_map<uint64_t, std::string>>();
assert(input == output);
}

#ifdef ZENOH_CPP_EXMAPLE_WITH_PROTOBUF
// Protobuf
// This example is conditionally compiled depending on build system being able to find Protobuf installation
{
// (Protobuf recommendation) Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;

// Construct PB message
Entity input;
input.set_id(1234);
input.set_name("John Doe");

// Serialize PB message into wire format
const auto input_wire_pb = input.SerializeAsString();

// Put PB wire format into Bytes
const auto payload = Bytes::serialize(input_wire_pb);

// Extract PB wire format
const auto output_wire_pb = payload.deserialize<std::string>();

// wire PB data is equal
assert(input_wire_pb == output_wire_pb);

// deserialize output wire PB into PB message
Entity output;
const auto parsed = output.ParseFromString(output_wire_pb);
assert(parsed);

// data is equal
assert(input.id() == output.id());
assert(input.name() == output.name());

// Corresponding encoding to be used in operations like `.put()`, `.reply()`, etc.
const auto encoding = Encoding("application/protobuf");

// (Protobuf recommendation) Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary();
}
#endif

return 0;
}

int main(int argc, char** argv) {
try {
#ifdef ZENOHCXX_ZENOHC
init_log_from_env_or("error");
#endif
return _main(argc, argv);
} catch (ZException e) {
std::cout << "Received an error :" << e.what() << "\n";
}
}
Loading