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

Add z_bytes example #673

Merged
merged 16 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from 12 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
66 changes: 66 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,69 @@ Primitives
.. autocfunction:: primitives.h::zp_send_keep_alive
.. autocfunction:: primitives.h::zp_send_join_options_default
.. autocfunction:: primitives.h::zp_send_join
.. autocfunction:: encoding.h::z_encoding_zenoh_bytes
.. autocfunction:: encoding.h::z_encoding_zenoh_int8
.. autocfunction:: encoding.h::z_encoding_zenoh_int16
.. autocfunction:: encoding.h::z_encoding_zenoh_int32
.. autocfunction:: encoding.h::z_encoding_zenoh_int64
.. autocfunction:: encoding.h::z_encoding_zenoh_int128
.. autocfunction:: encoding.h::z_encoding_zenoh_uint8
.. autocfunction:: encoding.h::z_encoding_zenoh_uint16
.. autocfunction:: encoding.h::z_encoding_zenoh_uint32
.. autocfunction:: encoding.h::z_encoding_zenoh_uint64
.. autocfunction:: encoding.h::z_encoding_zenoh_uint128
.. autocfunction:: encoding.h::z_encoding_zenoh_float32
.. autocfunction:: encoding.h::z_encoding_zenoh_float64
.. autocfunction:: encoding.h::z_encoding_zenoh_bool
.. autocfunction:: encoding.h::z_encoding_zenoh_string
.. autocfunction:: encoding.h::z_encoding_zenoh_error
.. autocfunction:: encoding.h::z_encoding_application_octet_stream
.. autocfunction:: encoding.h::z_encoding_text_plain
.. autocfunction:: encoding.h::z_encoding_application_json
.. autocfunction:: encoding.h::z_encoding_text_json
.. autocfunction:: encoding.h::z_encoding_application_cdr
.. autocfunction:: encoding.h::z_encoding_application_cbor
.. autocfunction:: encoding.h::z_encoding_application_yaml
.. autocfunction:: encoding.h::z_encoding_text_yaml
.. autocfunction:: encoding.h::z_encoding_text_json5
.. autocfunction:: encoding.h::z_encoding_application_python_serialized_object
.. autocfunction:: encoding.h::z_encoding_application_protobuf
.. autocfunction:: encoding.h::z_encoding_application_java_serialized_object
.. autocfunction:: encoding.h::z_encoding_application_openmetrics_text
.. autocfunction:: encoding.h::z_encoding_image_png
.. autocfunction:: encoding.h::z_encoding_image_jpeg
.. autocfunction:: encoding.h::z_encoding_image_gif
.. autocfunction:: encoding.h::z_encoding_image_bmp
.. autocfunction:: encoding.h::z_encoding_image_webp
.. autocfunction:: encoding.h::z_encoding_application_xml
.. autocfunction:: encoding.h::z_encoding_application_x_www_form_urlencoded
.. autocfunction:: encoding.h::z_encoding_text_html
.. autocfunction:: encoding.h::z_encoding_text_xml
.. autocfunction:: encoding.h::z_encoding_text_css
.. autocfunction:: encoding.h::z_encoding_text_javascript
.. autocfunction:: encoding.h::z_encoding_text_markdown
.. autocfunction:: encoding.h::z_encoding_text_csv
.. autocfunction:: encoding.h::z_encoding_application_sql
.. autocfunction:: encoding.h::z_encoding_application_coap_payload
.. autocfunction:: encoding.h::z_encoding_application_json_patch_json
.. autocfunction:: encoding.h::z_encoding_application_json_seq
.. autocfunction:: encoding.h::z_encoding_application_jsonpath
.. autocfunction:: encoding.h::z_encoding_application_jwt
.. autocfunction:: encoding.h::z_encoding_application_mp4
.. autocfunction:: encoding.h::z_encoding_application_soap_xml
.. autocfunction:: encoding.h::z_encoding_application_yang
.. autocfunction:: encoding.h::z_encoding_audio_aac
.. autocfunction:: encoding.h::z_encoding_audio_flac
.. autocfunction:: encoding.h::z_encoding_audio_mp4
.. autocfunction:: encoding.h::z_encoding_audio_ogg
.. autocfunction:: encoding.h::z_encoding_audio_vorbis
.. autocfunction:: encoding.h::z_encoding_video_h261
.. autocfunction:: encoding.h::z_encoding_video_h263
.. autocfunction:: encoding.h::z_encoding_video_h264
.. autocfunction:: encoding.h::z_encoding_video_h265
.. autocfunction:: encoding.h::z_encoding_video_h266
.. autocfunction:: encoding.h::z_encoding_video_mp4
.. autocfunction:: encoding.h::z_encoding_video_ogg
.. autocfunction:: encoding.h::z_encoding_video_raw
.. autocfunction:: encoding.h::z_encoding_video_vp8
.. autocfunction:: encoding.h::z_encoding_video_vp9
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ if(UNIX)
add_example(z_pong unix/c11/z_pong.c)
add_example(z_pub_thr unix/c11/z_pub_thr.c)
add_example(z_sub_thr unix/c11/z_sub_thr.c)
add_example(z_bytes unix/c11/z_bytes.c)
endif()
elseif(MSVC)
add_example(z_put windows/z_put.c)
Expand Down
198 changes: 198 additions & 0 deletions examples/unix/c11/z_bytes.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
//
// Copyright (c) 2024 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 <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zenoh-pico.h>

#undef NDEBUG
#include <assert.h>

#include "zenoh-pico/system/platform.h"

typedef struct kv_pair_t {
const char *key;
const char *value;
} kv_pair_t;

typedef struct kv_pairs_tx_t {
const kv_pair_t *data;
uint32_t len;
uint32_t current_idx;
} kv_pairs_tx_t;

typedef struct kv_pair_decoded_t {
z_owned_string_t key;
z_owned_string_t value;
} kv_pair_decoded_t;

typedef struct kv_pairs_rx_t {
kv_pair_decoded_t *data;
uint32_t len;
uint32_t current_idx;
} kv_pairs_rx_t;

static bool hashmap_iter(z_owned_bytes_t *kv_pair, void *context);
static bool iter_body(z_owned_bytes_t *b, void *context);
static void parse_hashmap(kv_pairs_rx_t *kvp, const z_loaned_bytes_t *hashmap);
static void drop_hashmap(kv_pairs_rx_t *kvp);

int main(void) {
// z_owned_encoding_t encoding;
z_owned_bytes_t payload;

// Number types: uint8, uint16, uint32, uint64, int8, int16, int32, int64, float, double
uint32_t input_u32 = 123456;
uint32_t output_u32 = 0;
z_bytes_serialize_from_uint32(&payload, input_u32);
z_bytes_deserialize_into_uint32(z_loan(payload), &output_u32);
assert(input_u32 == output_u32);
z_drop(z_move(payload));
// Corresponding encoding to be used in operations options like `z_put()`, `z_get()`, etc.
// encoding = ZP_ENCODING_ZENOH_UINT32;

// String, also work with and z_owned_string_t
const char *input_str = "test";
z_owned_string_t output_string;
z_bytes_serialize_from_str(&payload, input_str);
z_bytes_deserialize_into_string(z_loan(payload), &output_string);
assert(strncmp(input_str, z_string_data(z_loan(output_string)), strlen(input_str)) == 0);
z_drop(z_move(payload));
z_drop(z_move(output_string));
// Corresponding encoding to be used in operations options like `z_put()`, `z_get()`, etc.
// encoding = ZP_ENCODING_ZENOH_STRING;

// Bytes, also work with z_owned_slice_t
const uint8_t input_bytes[] = {1, 2, 3, 4};
z_owned_slice_t output_bytes;
z_bytes_serialize_from_buf(&payload, input_bytes, sizeof(input_bytes));
z_bytes_deserialize_into_slice(z_loan(payload), &output_bytes);
assert(memcmp(input_bytes, z_slice_data(z_loan(output_bytes)), sizeof(input_bytes)) == 0);
z_drop(z_move(payload));
z_drop(z_move(output_bytes));
// Corresponding encoding to be used in operations options like `z_put()`, `z_get()`, etc.
// encoding = ZP_ENCODING_ZENOH_BYTES; // That's the default value

// Writer reader
uint8_t input_writer[] = {0, 1, 2, 3, 4};
uint8_t output_reader[5] = {0};
z_bytes_empty(&payload);
z_bytes_writer_t writer = z_bytes_get_writer(z_bytes_loan_mut(&payload));
z_bytes_writer_write_all(&writer, input_writer, 3);
z_bytes_writer_write_all(&writer, input_writer + 3, 2);
z_bytes_reader_t reader = z_bytes_get_reader(z_bytes_loan(&payload));
z_bytes_reader_read(&reader, output_reader, sizeof(output_reader));
assert(0 == memcmp(input_writer, output_reader, sizeof(output_reader)));
z_drop(z_move(payload));

// Bytes iterator
uint8_t result_iter[] = {0, 1, 2, 3, 4};
uint8_t output_iter[5] = {0};
uint8_t context = 0;
z_bytes_from_iter(&payload, iter_body, (void *)(&context));
z_bytes_iterator_t it = z_bytes_get_iterator(z_bytes_loan(&payload));

z_owned_bytes_t current_item;
size_t i = 0;
while (z_bytes_iterator_next(&it, &current_item)) {
z_bytes_deserialize_into_uint8(z_bytes_loan(&current_item), &output_reader[i]);
z_bytes_drop(z_bytes_move(&current_item));
i++;
}
assert(memcmp(output_iter, result_iter, sizeof(output_iter)));
z_drop(z_move(payload));

// Hash map
kv_pair_t input_hashmap[1];
input_hashmap[0] = (kv_pair_t){.key = "test_key", .value = "test_value"};
kv_pairs_tx_t ctx = (kv_pairs_tx_t){.data = input_hashmap, .current_idx = 0, .len = 1};
z_bytes_from_iter(&payload, hashmap_iter, (void *)&ctx);
kv_pairs_rx_t output_hashmap = {
.current_idx = 0, .len = 16, .data = (kv_pair_decoded_t *)malloc(16 * sizeof(kv_pair_decoded_t))};
parse_hashmap(&output_hashmap, z_loan(payload));
assert(strncmp(input_hashmap[0].key, _z_string_data(z_loan(output_hashmap.data[0].key)),
strlen(input_hashmap[0].key)) == 0);
assert(strncmp(input_hashmap[0].value, _z_string_data(z_loan(output_hashmap.data[0].value)),
strlen(input_hashmap[0].value)) == 0);
z_drop(z_move(payload));
drop_hashmap(&output_hashmap);

// Slice iterator
kv_pair_t input_val[1];
input_val[0] = (kv_pair_t){.key = "test_key", .value = "test_value"};
ctx = (kv_pairs_tx_t){.data = input_val, .current_idx = 0, .len = 1};
z_bytes_from_iter(&payload, hashmap_iter, (void *)&ctx);
z_bytes_slice_iterator_t slice_iter = z_bytes_get_slice_iterator(z_bytes_loan(&payload));
z_view_slice_t curr_slice;
while (z_bytes_slice_iterator_next(&slice_iter, &curr_slice)) {
printf("slice len: %d, slice data: '%.*s'\n", (int)z_slice_len(z_view_slice_loan(&curr_slice)),
(int)z_slice_len(z_view_slice_loan(&curr_slice)),
Copy link
Contributor

Choose a reason for hiding this comment

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

this is not good since it will print garbage, could we rather print slice content as list of hexadecimal values ?

(const char *)z_slice_data(z_view_slice_loan(&curr_slice)));
}
z_drop(z_move(payload));

return 0;
}

static bool iter_body(z_owned_bytes_t *b, void *context) {
uint8_t *val = (uint8_t *)context;
if (*val >= 5) {
return false;
} else {
z_bytes_serialize_from_uint8(b, *val);
}
*val = *val + 1;
return true;
}

static bool hashmap_iter(z_owned_bytes_t *kv_pair, void *context) {
kv_pairs_tx_t *kvs = (kv_pairs_tx_t *)(context);
z_owned_bytes_t k, v;
if (kvs->current_idx >= kvs->len) {
return false;
} else {
z_bytes_serialize_from_str(&k, kvs->data[kvs->current_idx].key);
z_bytes_serialize_from_str(&v, kvs->data[kvs->current_idx].value);
z_bytes_from_pair(kv_pair, z_move(k), z_move(v));
kvs->current_idx++;
return true;
}
}

static void parse_hashmap(kv_pairs_rx_t *kvp, const z_loaned_bytes_t *hashmap) {
z_owned_bytes_t kv, first, second;
z_bytes_iterator_t iter = z_bytes_get_iterator(hashmap);

while (kvp->current_idx < kvp->len && z_bytes_iterator_next(&iter, &kv)) {
z_bytes_deserialize_into_pair(z_loan(kv), &first, &second);
z_bytes_deserialize_into_string(z_loan(first), &kvp->data[kvp->current_idx].key);
z_bytes_deserialize_into_string(z_loan(second), &kvp->data[kvp->current_idx].value);
z_bytes_drop(z_bytes_move(&first));
z_bytes_drop(z_bytes_move(&second));
z_bytes_drop(z_bytes_move(&kv));
kvp->current_idx++;
}
}

static void drop_hashmap(kv_pairs_rx_t *kvp) {
for (size_t i = 0; i < kvp->current_idx; i++) {
z_string_drop(z_string_move(&kvp->data[i].key));
z_string_drop(z_string_move(&kvp->data[i].value));
}
z_free(kvp->data);
}
1 change: 1 addition & 0 deletions include/zenoh-pico.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define ZENOH_PICO_TWEAK 0

#include "zenoh-pico/api/constants.h"
#include "zenoh-pico/api/encoding.h"
#include "zenoh-pico/api/handlers.h"
#include "zenoh-pico/api/macros.h"
#include "zenoh-pico/api/primitives.h"
Expand Down
1 change: 1 addition & 0 deletions include/zenoh-pico.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define ZENOH_PICO_TWEAK @ZENOH_PICO_TWEAK@

#include "zenoh-pico/api/constants.h"
#include "zenoh-pico/api/encoding.h"
#include "zenoh-pico/api/handlers.h"
#include "zenoh-pico/api/macros.h"
#include "zenoh-pico/api/primitives.h"
Expand Down
87 changes: 0 additions & 87 deletions include/zenoh-pico/api/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,93 +109,6 @@ typedef enum {
typedef enum { Z_SAMPLE_KIND_PUT = 0, Z_SAMPLE_KIND_DELETE = 1 } z_sample_kind_t;
#define Z_SAMPLE_KIND_DEFAULT Z_SAMPLE_KIND_PUT

/**
* Default encoding values used by Zenoh.
*
* An encoding has a similar role to Content-type in HTTP: it indicates, when present, how data should be interpreted by
* the application.
*
* Please note the Zenoh protocol does not impose any encoding value nor it operates on it.
* It can be seen as some optional metadata that is carried over by Zenoh in such a way the application may perform
* different operations depending on the encoding value.
*
* A set of associated constants are provided to cover the most common encodings for user convenience.
* This is particularly useful in helping Zenoh to perform additional wire-level optimizations.
*
* Register your encoding metadata from a string with :c:func:`z_encoding_from_str`. To get the optimization, you need
* Z_FEATURE_ENCODING_VALUES to 1 and your string should follow the format: "<constant>;<optional additional data>"
*
* E.g: "text/plain;utf8"
*
* Here is the list of constants:
*/
// "zenoh/bytes"
// "zenoh/int8"
// "zenoh/int16"
// "zenoh/int32"
// "zenoh/int64"
// "zenoh/int128"
// "zenoh/uint8"
// "zenoh/uint16"
// "zenoh/uint32"
// "zenoh/uint64"
// "zenoh/uint128"
// "zenoh/float32"
// "zenoh/float64"
// "zenoh/bool"
// "zenoh/string"
// "zenoh/error"
// "application/octet-stream"
// "text/plain"
// "application/json"
// "text/json"
// "application/cdr"
// "application/cbor"
// "application/yaml"
// "text/yaml"
// "text/json5"
// "application/python-serialized-object"
// "application/protobuf"
// "application/java-serialized-object"
// "application/openmetrics-text"
// "image/png"
// "image/jpeg"
// "image/gif"
// "image/bmp"
// "image/webp"
// "application/xml"
// "application/x-www-form-urlencoded"
// "text/html"
// "text/xml"
// "text/css"
// "text/javascript"
// "text/markdown"
// "text/csv"
// "application/sql"
// "application/coap-payload"
// "application/json-patch+json"
// "application/json-seq"
// "application/jsonpath"
// "application/jwt"
// "application/mp4"
// "application/soap+xml"
// "application/yang"
// "audio/aac"
// "audio/flac"
// "audio/mp4"
// "audio/ogg"
// "audio/vorbis"
// "video/h261"
// "video/h263"
// "video/h264"
// "video/h265"
// "video/h266"
// "video/mp4"
// "video/ogg"
// "video/raw"
// "video/vp8"
// "video/vp9"

/**
* Consolidation mode values.
*
Expand Down
Loading
Loading