diff --git a/.gitignore b/.gitignore index d7a6cf967..49b20fcc2 100644 --- a/.gitignore +++ b/.gitignore @@ -70,4 +70,8 @@ dkms.conf .cache # Platform dependent generated files -include/zenoh_configure.h \ No newline at end of file +include/zenoh_configure.h + +# Build resources +.build_resources* +src/opaque_types/mod.rs \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 00aa5cac2..d236e99fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ declare_cache_var_true_if_vscode(ZENOHC_BUILD_IN_SOURCE_TREE "Do build inside so declare_cache_var(ZENOHC_BUILD_WITH_LOGGER_AUTOINIT TRUE BOOL "Enable logger-autoinit zenoh-c feature") declare_cache_var(ZENOHC_BUILD_WITH_SHARED_MEMORY TRUE BOOL "Enable shared-memory zenoh-c feature") declare_cache_var(ZENOHC_CUSTOM_TARGET "" STRING "Rust target for cross compilation, 'aarch64-unknown-linux-gnu' for example") -declare_cache_var(ZENOHC_CARGO_CHANNEL "stable" STRING "Cargo channel selected: stable or nightly") +declare_cache_var(ZENOHC_CARGO_CHANNEL "" STRING "Cargo channel parameter. Should be '+stable', '+nightly' or empty value") declare_cache_var(ZENOHC_CARGO_FLAGS "" STRING "Additional cargo flags") declare_cache_var(ZENOHC_LIB_STATIC FALSE BOOL "Alias zenohc::lib target to zenohc::static if TRUE, to zenohc::shared if FALSE") @@ -198,8 +198,8 @@ file(GLOB_RECURSE rust_sources "Cargo.toml.in" "src/*.rs" "build.rs" "splitguide add_custom_command( OUTPUT ${libs} COMMAND ${CMAKE_COMMAND} -E echo \"RUSTFLAGS = $$RUSTFLAGS\" - COMMAND ${CMAKE_COMMAND} -E echo \"cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_flags}\" - COMMAND cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_flags} + COMMAND ${CMAKE_COMMAND} -E echo \"cargo ${ZENOHC_CARGO_CHANNEL} build ${cargo_flags}\" + COMMAND cargo ${ZENOHC_CARGO_CHANNEL} build ${cargo_flags} VERBATIM COMMAND_EXPAND_LISTS DEPENDS "${rust_sources}" diff --git a/Cargo.lock b/Cargo.lock index 1c62eb1df..7d52c4ed7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,9 +417,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ "android-tzdata", "iana-time-zone", @@ -2953,7 +2953,7 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-trait", "base64", @@ -2996,6 +2996,7 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-transport", "zenoh-util", ] @@ -3003,7 +3004,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "zenoh-collections", ] @@ -3024,6 +3025,7 @@ dependencies = [ "libc", "log", "rand", + "regex", "serde_yaml", "spin 0.9.8", "zenoh", @@ -3035,7 +3037,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "log", "serde", @@ -3048,12 +3050,12 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "flume", "json5", @@ -3073,7 +3075,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-global-executor", "lazy_static", @@ -3085,7 +3087,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "aes", "hmac", @@ -3098,7 +3100,7 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "bincode", "env_logger 0.11.2", @@ -3113,13 +3115,14 @@ dependencies = [ "zenoh-result", "zenoh-runtime", "zenoh-sync", + "zenoh-task", "zenoh-util", ] [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "hashbrown 0.14.0", "keyed-set", @@ -3133,7 +3136,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-trait", "zenoh-config", @@ -3151,7 +3154,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-trait", "flume", @@ -3174,7 +3177,7 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-trait", "base64", @@ -3202,7 +3205,7 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-trait", "log", @@ -3220,7 +3223,7 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-trait", "base64", @@ -3248,7 +3251,7 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-trait", "log", @@ -3269,7 +3272,7 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-trait", "futures", @@ -3289,7 +3292,7 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-trait", "futures-util", @@ -3310,7 +3313,7 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "proc-macro2", "quote", @@ -3321,7 +3324,7 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "const_format", "libloading", @@ -3337,7 +3340,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "const_format", "rand", @@ -3351,7 +3354,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "anyhow", ] @@ -3359,8 +3362,9 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ + "futures", "lazy_static", "tokio", "zenoh-collections", @@ -3370,7 +3374,7 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "log", "serde", @@ -3382,7 +3386,7 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "event-listener 4.0.0", "futures", @@ -3393,10 +3397,23 @@ dependencies = [ "zenoh-runtime", ] +[[package]] +name = "zenoh-task" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +dependencies = [ + "futures", + "log", + "tokio", + "tokio-util", + "zenoh-core", + "zenoh-runtime", +] + [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-trait", "flume", @@ -3422,13 +3439,14 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-util", ] [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" dependencies = [ "async-std", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 95867f95f..8e0541888 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,6 +59,7 @@ zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/ze [build-dependencies] cbindgen = "0.24.3" fs2 = "0.4.3" +regex = "1.7.1" serde_yaml = "0.9.19" [lib] diff --git a/Cargo.toml.in b/Cargo.toml.in index f434df3a1..a8123bcd5 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -59,6 +59,7 @@ zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/ze [build-dependencies] cbindgen = "0.24.3" fs2 = "0.4.3" +regex = "1.7.1" serde_yaml = "0.9.19" [lib] diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock new file mode 100644 index 000000000..a6f37dab3 --- /dev/null +++ b/build-resources/opaque-types/Cargo.lock @@ -0,0 +1,2624 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + +[[package]] +name = "array-init" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +dependencies = [ + "concurrent-queue", + "event-listener 5.2.0", + "event-listener-strategy 0.5.0", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +dependencies = [ + "async-lock 3.3.0", + "async-task", + "concurrent-queue", + "fastrand 2.0.2", + "futures-lite 2.3.0", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.2.0", + "async-executor", + "async-io 2.3.2", + "async-lock 3.3.0", + "blocking", + "futures-lite 2.3.0", + "once_cell", + "tokio", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +dependencies = [ + "async-lock 3.3.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.3.0", + "parking", + "polling 3.6.0", + "rustix 0.38.32", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy 0.4.0", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.32", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-signal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +dependencies = [ + "async-io 2.3.2", + "async-lock 2.8.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.32", + "signal-hook-registry", + "slab", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite 1.13.0", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" + +[[package]] +name = "async-trait" +version = "0.1.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +dependencies = [ + "async-channel 2.2.0", + "async-lock 3.3.0", + "async-task", + "fastrand 2.0.2", + "futures-io", + "futures-lite 2.3.0", + "piper", + "tracing", +] + +[[package]] +name = "bumpalo" +version = "3.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cache-padded" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" + +[[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +dependencies = [ + "event-listener 5.2.0", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand 2.0.2", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "git-version" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" +dependencies = [ + "git-version-macro", +] + +[[package]] +name = "git-version-macro" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipnetwork" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" +dependencies = [ + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keyed-set" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79e110283e09081809ca488cf3a9709270c6d4d4c4a32674c39cc438366615a" +dependencies = [ + "hashbrown 0.13.2", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets 0.52.4", +] + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.5.0", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +dependencies = [ + "value-bag", +] + +[[package]] +name = "lz4_flex" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "nix" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-types" +version = "0.1.0" +dependencies = [ + "zenoh", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-float" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "pest_meta" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.2", + "futures-io", +] + +[[package]] +name = "pnet_base" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cf6fb3ab38b68d01ab2aea03ed3d1132b4868fa4e06285f29f16da01c5f4c" +dependencies = [ + "no-std-net", +] + +[[package]] +name = "pnet_datalink" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad5854abf0067ebbd3967f7d45ebc8976ff577ff0c7bd101c4973ae3c70f98fe" +dependencies = [ + "ipnetwork", + "libc", + "pnet_base", + "pnet_sys", + "winapi", +] + +[[package]] +name = "pnet_sys" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "417c0becd1b573f6d544f73671070b039051e5ad819cc64aa96377b536128d00" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 0.38.32", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ringbuffer-spsc" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1938faa63a2362ee1747afb2d10567d0fb1413b9cbd6198a8541485c4f773" +dependencies = [ + "array-init", + "cache-padded", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" + +[[package]] +name = "rustls-webpki" +version = "0.102.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "serde", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shared_memory" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba8593196da75d9dc4f69349682bd4c2099f8cde114257d1ef7ef1b33d1aba54" +dependencies = [ + "cfg-if", + "libc", + "nix", + "rand", + "win-sys", +] + +[[package]] +name = "shellexpand" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +dependencies = [ + "dirs", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stop-token" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" +dependencies = [ + "async-channel 1.9.0", + "cfg-if", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "token-cell" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a2b964fdb303b08a4eab04d7c1bad2bca33f8eee334ccd28802f1041c6eb87" +dependencies = [ + "paste", +] + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.6", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "futures-util", + "hashbrown 0.14.3", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uhlc" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b6df3f3e948b40e20c38a6d1fd6d8f91b3573922fc164e068ad3331560487e" +dependencies = [ + "humantime", + "lazy_static", + "log", + "rand", + "serde", + "spin", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "unzip-n" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e7e85a0596447f0f2ac090e16bc4c516c6fe91771fb0c0ccf7fa3dae896b9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "getrandom", +] + +[[package]] +name = "validated_struct" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feef04c049b4beae3037a2a31b8da40d8cebec0b97456f24c7de0ede4ed9efed" +dependencies = [ + "json5", + "serde", + "serde_json", + "validated_struct_macros", +] + +[[package]] +name = "validated_struct_macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d4444a980afa9ef0d29c2a3f4d952ec0495a7a996a9c78b52698b71bc21edb4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unzip-n", +] + +[[package]] +name = "value-bag" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.55", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "win-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b7b128a98c1cfa201b09eb49ba285887deb3cbe7466a98850eb1adabb452be5" +dependencies = [ + "windows", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45296b64204227616fdbf2614cefa4c236b98ee64dfaaaa435207ed99fe7829f" +dependencies = [ + "windows_aarch64_msvc 0.34.0", + "windows_i686_gnu 0.34.0", + "windows_i686_msvc 0.34.0", + "windows_x86_64_gnu 0.34.0", + "windows_x86_64_msvc 0.34.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "zenoh" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "base64", + "const_format", + "env_logger", + "event-listener 4.0.3", + "flume", + "form_urlencoded", + "futures", + "git-version", + "lazy_static", + "log", + "ordered-float", + "paste", + "petgraph", + "rand", + "regex", + "rustc_version", + "serde", + "serde_json", + "socket2 0.5.6", + "stop-token", + "tokio", + "tokio-util", + "uhlc", + "uuid", + "vec_map", + "zenoh-buffers", + "zenoh-codec", + "zenoh-collections", + "zenoh-config", + "zenoh-core", + "zenoh-crypto", + "zenoh-keyexpr", + "zenoh-link", + "zenoh-macros", + "zenoh-plugin-trait", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-shm", + "zenoh-sync", + "zenoh-transport", + "zenoh-util", +] + +[[package]] +name = "zenoh-buffers" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "zenoh-collections", +] + +[[package]] +name = "zenoh-codec" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "log", + "serde", + "uhlc", + "zenoh-buffers", + "zenoh-protocol", + "zenoh-shm", +] + +[[package]] +name = "zenoh-collections" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" + +[[package]] +name = "zenoh-config" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "flume", + "json5", + "log", + "num_cpus", + "secrecy", + "serde", + "serde_json", + "serde_yaml", + "validated_struct", + "zenoh-core", + "zenoh-protocol", + "zenoh-result", + "zenoh-util", +] + +[[package]] +name = "zenoh-core" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-global-executor", + "lazy_static", + "tokio", + "zenoh-result", + "zenoh-runtime", +] + +[[package]] +name = "zenoh-crypto" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "aes", + "hmac", + "rand", + "rand_chacha", + "sha3", + "zenoh-result", +] + +[[package]] +name = "zenoh-keyexpr" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "hashbrown 0.14.3", + "keyed-set", + "rand", + "schemars", + "serde", + "token-cell", + "zenoh-result", +] + +[[package]] +name = "zenoh-link" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "zenoh-config", + "zenoh-link-commons", + "zenoh-protocol", + "zenoh-result", +] + +[[package]] +name = "zenoh-link-commons" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "flume", + "futures", + "log", + "rustls", + "rustls-webpki", + "serde", + "tokio", + "tokio-util", + "zenoh-buffers", + "zenoh-codec", + "zenoh-core", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-util", +] + +[[package]] +name = "zenoh-macros" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", + "zenoh-keyexpr", +] + +[[package]] +name = "zenoh-plugin-trait" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "const_format", + "libloading", + "log", + "serde", + "serde_json", + "zenoh-keyexpr", + "zenoh-macros", + "zenoh-result", + "zenoh-util", +] + +[[package]] +name = "zenoh-protocol" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "const_format", + "rand", + "serde", + "uhlc", + "zenoh-buffers", + "zenoh-keyexpr", + "zenoh-result", +] + +[[package]] +name = "zenoh-result" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "anyhow", +] + +[[package]] +name = "zenoh-runtime" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "lazy_static", + "tokio", + "zenoh-collections", + "zenoh-result", +] + +[[package]] +name = "zenoh-shm" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "log", + "serde", + "shared_memory", + "zenoh-buffers", + "zenoh-result", +] + +[[package]] +name = "zenoh-sync" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "event-listener 4.0.3", + "futures", + "tokio", + "zenoh-buffers", + "zenoh-collections", + "zenoh-core", + "zenoh-runtime", +] + +[[package]] +name = "zenoh-transport" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "flume", + "log", + "lz4_flex", + "paste", + "rand", + "ringbuffer-spsc", + "serde", + "sha3", + "tokio", + "tokio-util", + "zenoh-buffers", + "zenoh-codec", + "zenoh-collections", + "zenoh-config", + "zenoh-core", + "zenoh-crypto", + "zenoh-link", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-shm", + "zenoh-sync", + "zenoh-util", +] + +[[package]] +name = "zenoh-util" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-std", + "async-trait", + "flume", + "home", + "humantime", + "lazy_static", + "libc", + "libloading", + "log", + "pnet_datalink", + "shellexpand", + "tokio", + "winapi", + "zenoh-core", + "zenoh-result", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml new file mode 100644 index 000000000..6e8319bb0 --- /dev/null +++ b/build-resources/opaque-types/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "opaque-types" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } \ No newline at end of file diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs new file mode 100644 index 000000000..354e8d999 --- /dev/null +++ b/build-resources/opaque-types/src/lib.rs @@ -0,0 +1,41 @@ +use zenoh::sample::Sample; +use zenoh::buffers::{ZBuf, ZBufReader}; + +#[macro_export] +macro_rules! get_opaque_type_data { +($src_type:ty, $expr:expr) => { + const _: () = { + let align = std::mem::align_of::<$src_type>(); + let size = std::mem::size_of::<$src_type>(); + let mut msg: [u8; 61] = *b"type: , align: , size: "; + let mut i = 0; + while i < 4 { + msg[i as usize + 46] = b'0' + ((align / 10u32.pow(3 - i) as usize) % 10) as u8; + msg[i as usize + 57] = b'0' + ((size / 10u32.pow(3 - i) as usize) % 10) as u8; + i += 1; + } + let mut i: usize = 0; + while i < $expr.len() { + msg[i as usize + 5] = $expr.as_bytes()[i]; + i += 1; + } + panic!("{}", unsafe { + std::str::from_utf8_unchecked(msg.as_slice()) + }); + }; + } +} + +/// A split buffer that owns all of its data. +/// +/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. +get_opaque_type_data!(Option, "z_owned_buffer_t"); + +/// An owned sample. +/// +/// This is a read only type that can only be constructed by cloning a `z_sample_t`. +/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. +get_opaque_type_data!(Option, "zc_owned_sample_t"); + +/// A reader for payload data. +get_opaque_type_data!(ZBufReader, "zc_payload_reader"); \ No newline at end of file diff --git a/build.rs b/build.rs index 17dde1894..703bde4c1 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,8 @@ use fs2::FileExt; +use regex::Regex; use std::io::{Read, Write}; +use std::path::PathBuf; +use std::process::{Command, Stdio}; use std::{borrow::Cow, collections::HashMap, io::BufWriter, path::Path}; const GENERATION_PATH: &str = "include/zenoh-gen.h"; @@ -23,7 +26,10 @@ const HEADER: &str = r"// #endif "; +use std::env; + fn main() { + generate_opaque_types(); cbindgen::generate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) .expect("Unable to generate bindings") .write_to_file(GENERATION_PATH); @@ -36,7 +42,87 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=src"); println!("cargo:rerun-if-changed=splitguide.yaml"); - println!("cargo:rerun-if-changed=cbindgen.toml") + println!("cargo:rerun-if-changed=cbindgen.toml"); + println!("cargo:rerun-if-changed=build-resources") +} + +fn get_build_rs_path() -> PathBuf { + let file_path = file!(); + let mut path_buf = PathBuf::new(); + path_buf.push(file_path); + path_buf.parent().unwrap().to_path_buf() +} + +fn produce_opaque_types_data() -> PathBuf { + let target = env::var("TARGET").unwrap(); + let current_folder = get_build_rs_path(); + let manifest_path = current_folder.join("./build-resources/opaque-types/Cargo.toml"); + let output_file_path = current_folder.join("./.build_resources_opaque_types.txt"); + let out_file = std::fs::File::create(output_file_path.clone()).unwrap(); + let stdio = Stdio::from(out_file); + let _ = Command::new("cargo") + .arg("build") + .arg("--target") + .arg(target) + .arg("--manifest-path") + .arg(manifest_path) + .stderr(stdio) + .output() + .unwrap(); + + output_file_path +} + +fn generate_opaque_types() { + let current_folder = get_build_rs_path(); + let path_in = produce_opaque_types_data(); + let path_out = current_folder.join("./src/opaque_types/mod.rs"); + + let data_in = std::fs::read_to_string(path_in).unwrap(); + let mut data_out = String::new(); + let docs = get_opaque_type_docs(); + + let re = Regex::new(r"type:(\w+) *, align:0*(\d+), size:0*(\d+)").unwrap(); + for (_, [type_name, align, size]) in re.captures_iter(&data_in).map(|c| c.extract()) { + let s = format!( + "#[repr(C, align({align}))] +pub struct {type_name} {{ + _0: [u8; {size}], +}} +" + ); + if let Some(doc) = docs.get(type_name) { + for d in doc { + data_out += d; + data_out += "\r\n"; + } + } + data_out += &s; + } + std::fs::write(path_out, data_out).unwrap(); +} + +fn get_opaque_type_docs() -> HashMap> { + let current_folder = get_build_rs_path(); + let path_in = current_folder.join("./build-resources/opaque-types/src/lib.rs"); + let re = Regex::new(r#"get_opaque_type_data!\(.*, "(\w+)"\)"#).unwrap(); + let mut comments = std::vec::Vec::::new(); + let mut res = HashMap::>::new(); + + for line in std::fs::read_to_string(path_in).unwrap().lines() { + if line.starts_with("///") { + comments.push(line.to_string()); + continue; + } + if comments.is_empty() { + continue; + } + if let Some(c) = re.captures(line) { + res.insert(c[1].to_string(), comments.clone()); + } + comments.clear(); + } + res } fn configure() { diff --git a/examples/z_get.c b/examples/z_get.c index 272bef89a..9866212f7 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -57,16 +57,19 @@ int main(int argc, char **argv) { z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get_options_t opts = z_get_options_default(); if (value != NULL) { - opts.value.payload = z_bytes_from_str(value); + opts.payload = zc_payload_encode_from_string(value); } z_get(z_loan(s), keyexpr, "", z_move(channel.send), - &opts); // here, the send is moved and will be dropped by zenoh when adequate + z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply = z_reply_null(); + z_owned_str_t payload_value = z_str_null(); for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); - printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, sample.payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_get_liveliness.c b/examples/z_get_liveliness.c index c667cb03a..9a00f3ca3 100644 --- a/examples/z_get_liveliness.c +++ b/examples/z_get_liveliness.c @@ -53,7 +53,7 @@ int main(int argc, char **argv) { for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); printf(">> Alive token ('%s')\n", z_loan(keystr)); z_drop(z_move(keystr)); } else { diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index c0b02a274..471f7e227 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -49,8 +49,9 @@ int main(int argc, char **argv) { opts.target = Z_QUERY_TARGET_ALL; z_owned_reply_channel_t channel = zc_reply_non_blocking_fifo_new(16); z_get(z_loan(s), keyexpr, "", z_move(channel.send), - &opts); // here, the send is moved and will be dropped by zenoh when adequate + z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply = z_reply_null(); + z_owned_str_t payload_value = z_str_null(); for (bool call_success = z_call(channel.recv, &reply); !call_success || z_check(reply); call_success = z_call(channel.recv, &reply)) { if (!call_success) { @@ -58,8 +59,10 @@ int main(int argc, char **argv) { } if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); - printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, sample.payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_ping.c b/examples/z_ping.c index fdc08f71d..a5c0954d0 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -54,6 +54,7 @@ int main(int argc, char** argv) { for (int i = 0; i < args.size; i++) { data[i] = i % 10; } + zc_owned_payload_t payload = zc_payload_encode_from_bytes((z_bytes_t){.start = data, .len = args.size}); z_mutex_lock(&mutex); if (args.warmup_ms) { printf("Warming up for %dms...\n", args.warmup_ms); @@ -61,7 +62,7 @@ int main(int argc, char** argv) { unsigned long elapsed_us = 0; while (elapsed_us < args.warmup_ms * 1000) { - z_publisher_put(z_loan(pub), data, args.size, NULL); + z_publisher_put(z_loan(pub), z_move(payload), NULL); int s = z_condvar_wait(&cond, &mutex); if (s != 0) { handle_error_en(s, "z_condvar_wait"); @@ -72,7 +73,7 @@ int main(int argc, char** argv) { unsigned long* results = z_malloc(sizeof(unsigned long) * args.number_of_pings); for (int i = 0; i < args.number_of_pings; i++) { z_clock_t measure_start = z_clock_now(); - z_publisher_put(z_loan(pub), data, args.size, NULL); + z_publisher_put(z_loan(pub), z_move(payload), NULL); int s = z_condvar_wait(&cond, &mutex); if (s != 0) { handle_error_en(s, "z_condvar_wait"); diff --git a/examples/z_pong.c b/examples/z_pong.c index 8dbb2631e..772280696 100644 --- a/examples/z_pong.c +++ b/examples/z_pong.c @@ -6,10 +6,8 @@ void callback(const z_sample_t* sample, void* context) { z_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); #ifdef ZENOH_C // The zc_owned_payload_t API is exclusive to zenoh-c, but allows avoiding some copies. - zc_owned_payload_t payload = zc_sample_payload_rcinc(sample); - zc_publisher_put_owned(pub, z_move(payload), NULL); -#else - z_publisher_put(pub, sample->payload.start, sample->payload.len, NULL); + zc_owned_payload_t payload = z_sample_owned_payload(sample); + z_publisher_put(pub, z_move(payload), NULL); #endif } void drop(void* context) { @@ -21,15 +19,17 @@ void drop(void* context) { // valid. } struct args_t { - char* config_path; // -c - uint8_t help_requested; // -h + char* config_path; // -c + uint8_t help_requested; // -h }; struct args_t parse_args(int argc, char** argv); int main(int argc, char** argv) { struct args_t args = parse_args(argc, argv); if (args.help_requested) { - printf("-c (optional, string): the path to a configuration file for the session. If this option isn't passed, the default configuration will be used.\n"); + printf( + "-c (optional, string): the path to a configuration file for the session. If this option isn't passed, the " + "default configuration will be used.\n"); return 1; } z_owned_config_t config = args.config_path ? zc_config_from_file(args.config_path) : z_config_default(); diff --git a/examples/z_pub.c b/examples/z_pub.c index ecc95e42d..9dd496153 100644 --- a/examples/z_pub.c +++ b/examples/z_pub.c @@ -71,7 +71,8 @@ int main(int argc, char **argv) { printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_publisher_put(z_loan(pub), (const uint8_t *)buf, strlen(buf), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index a24133e91..530d9dc29 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -71,7 +71,8 @@ int main(int argc, char **argv) { sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_publisher_put(z_loan(pub), (const uint8_t *)buf, strlen(buf), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pub_cache.c b/examples/z_pub_cache.c index 770bf9d93..622896948 100644 --- a/examples/z_pub_cache.c +++ b/examples/z_pub_cache.c @@ -63,7 +63,8 @@ int main(int argc, char **argv) { z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)buf, strlen(buf), NULL); + zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } z_drop(z_move(pub_cache)); diff --git a/examples/z_pub_shm.c b/examples/z_pub_shm.c index 10970bf62..3c032e02f 100644 --- a/examples/z_pub_shm.c +++ b/examples/z_pub_shm.c @@ -84,7 +84,7 @@ int main(int argc, char **argv) { z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); zc_owned_payload_t payload = zc_shmbuf_into_payload(z_move(shmbuf)); - zc_publisher_put_owned(z_loan(pub), z_move(payload), &options); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pub_thr.c b/examples/z_pub_thr.c index 8686c33eb..e0568973c 100644 --- a/examples/z_pub_thr.c +++ b/examples/z_pub_thr.c @@ -54,7 +54,8 @@ int main(int argc, char **argv) { } while (1) { - z_publisher_put(z_loan(pub), (const uint8_t *)value, len, NULL); + zc_owned_payload_t payload = zc_payload_encode_from_bytes((z_bytes_t){.start = value, .len = len}); + z_publisher_put(z_loan(pub), z_move(payload), NULL); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pull.c b/examples/z_pull.c index 0af23f7e2..094dc0a6b 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -17,9 +17,12 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/examples/z_put.c b/examples/z_put.c index 498d1e958..503fb5c36 100644 --- a/examples/z_put.c +++ b/examples/z_put.c @@ -48,7 +48,8 @@ int main(int argc, char **argv) { z_put_options_t options = z_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); options.attachment = z_bytes_map_as_attachment(&attachment); - int res = z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)value, strlen(value), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(value); + int res = z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), &options); if (res < 0) { printf("Put failed...\n"); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index 15564be7c..620dd9594 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -17,9 +17,12 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 9d6ec7702..577ef146e 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -22,16 +22,21 @@ z_keyexpr_t keyexpr; void query_handler(const z_query_t *query, void *context) { z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); z_bytes_t pred = z_query_parameters(query); - z_value_t payload_value = z_query_value(query); - if (payload_value.payload.len > 0) { - printf(">> [Queryable ] Received Query '%s?%.*s' with value '%.*s'\n", z_loan(keystr), (int)pred.len, - pred.start, (int)payload_value.payload.len, payload_value.payload.start); + zc_payload_t payload = z_query_value(query).payload; + if (zc_payload_len(payload) > 0) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(payload, &payload_value); + printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, + pred.start, z_loan(payload_value)); + z_drop(z_move(payload_value)); } else { printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); } z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_query_reply(query, z_keyexpr((const char *)context), (const unsigned char *)value, strlen(value), &options); + + zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); + z_query_reply(query, z_keyexpr((const char *)context), z_move(reply_payload), &options); z_drop(z_move(keystr)); } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 672ddd607..6c3ca0df1 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -68,16 +68,20 @@ int main(int argc, char **argv) { z_query_t query = z_loan(oquery); z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(&query)); z_bytes_t pred = z_query_parameters(&query); - z_value_t payload_value = z_query_value(&query); - if (payload_value.payload.len > 0) { - printf(">> [Queryable ] Received Query '%s?%.*s' with value '%.*s'\n", z_loan(keystr), (int)pred.len, - pred.start, (int)payload_value.payload.len, payload_value.payload.start); + zc_payload_t payload = z_query_value(&query).payload; + if (zc_payload_len(payload) > 0) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(payload, &payload_value); + printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, + pred.start, z_loan(payload_value)); + z_drop(z_move(payload_value)); } else { printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); } z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_query_reply(&query, keyexpr, (const unsigned char *)value, strlen(value), &options); + zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); + z_query_reply(&query, keyexpr, z_move(reply_payload), &options); z_drop(z_move(keystr)); z_drop(z_move(oquery)); } diff --git a/examples/z_sub.c b/examples/z_sub.c index 867c1277e..ffa63703b 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -17,9 +17,12 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index 58b0afd81..b703e6ad6 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -23,21 +23,25 @@ int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { } void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload_value)); + z_attachment_t attachment = z_sample_attachment(sample); // checks if attachment exists - if (z_check(sample->attachment)) { + if (z_check(attachment)) { // reads full attachment - z_attachment_iterate(sample->attachment, attachment_reader, NULL); + z_attachment_iterate(attachment, attachment_reader, NULL); // reads particular attachment item - z_bytes_t index = z_attachment_get(sample->attachment, z_bytes_from_str("index")); - if (z_check(index)) { + z_bytes_t index = z_attachment_get(attachment, z_bytes_from_str("index")); + if (z_bytes_is_initialized(&index)) { printf(" message number: %.*s\n", (int)index.len, index.start); } } + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/examples/z_sub_liveliness.c b/examples/z_sub_liveliness.c index 36bf64515..5916200b2 100644 --- a/examples/z_sub_liveliness.c +++ b/examples/z_sub_liveliness.c @@ -15,8 +15,8 @@ #include "zenoh.h" void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - switch (sample->kind) { + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + switch (z_sample_kind(sample)) { case Z_SAMPLE_KIND_PUT: printf(">> [LivelinessSubscriber] New alive token ('%s')\n", z_loan(keystr)); break; diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 84b125fbe..4326d856f 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -169,8 +169,8 @@ typedef enum zcu_reply_keyexpr_t { * and empty slices are represented using a possibly dangling pointer for `start`. */ typedef struct z_bytes_t { - size_t len; const uint8_t *start; + size_t len; } z_bytes_t; /** * The body of a loop over an attachment's key-value pairs. @@ -203,6 +203,10 @@ typedef struct z_attachment_t { const void *data; z_attachment_iter_driver_t iteration_driver; } z_attachment_t; +typedef struct z_owned_bytes_t { + uint8_t *start; + size_t len; +} z_owned_bytes_t; /** * A map of maybe-owned vector of bytes to owned vector of bytes. * @@ -376,74 +380,13 @@ typedef struct z_owned_closure_reply_t { void (*call)(struct z_owned_reply_t*, void*); void (*drop)(void*); } z_owned_closure_reply_t; -/** - * A loaned key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, - * both for local processing and network-wise. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_keyexpr_t { - uint64_t _0[4]; -} z_keyexpr_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_keyexpr_t { - uint32_t _0[5]; -} z_keyexpr_t; -#endif -/** - * The encoding of a payload, in a MIME-like format. - * - * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. - * - * Members: - * z_encoding_prefix_t prefix: The integer prefix of this encoding. - * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. - */ -typedef struct z_encoding_t { - enum z_encoding_prefix_t prefix; - struct z_bytes_t suffix; -} z_encoding_t; -typedef struct z_timestamp_t { - uint64_t time; - struct z_id_t id; -} z_timestamp_t; -/** - * QoS settings of zenoh message. - * - */ -typedef struct z_qos_t { - uint8_t _0; -} z_qos_t; /** * A data sample. * * A sample is the value associated to a given resource at a given point in time. - * - * Members: - * z_keyexpr_t keyexpr: The resource key of this data sample. - * z_bytes_t payload: The value of this data sample. - * z_encoding_t encoding: The encoding of the value of this data sample. - * z_sample_kind_t kind: The kind of this data sample (PUT or DELETE). - * z_timestamp_t timestamp: The timestamp of this data sample. - * z_attachment_t attachment: The attachment of this data sample. */ typedef struct z_sample_t { - struct z_keyexpr_t keyexpr; - struct z_bytes_t payload; - struct z_encoding_t encoding; - const void *_zc_buf; - enum z_sample_kind_t kind; - struct z_timestamp_t timestamp; - struct z_qos_t qos; - struct z_attachment_t attachment; + const void *_inner; } z_sample_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. @@ -558,6 +501,28 @@ typedef struct ALIGN(4) z_owned_keyexpr_t { uint32_t _0[5]; } z_owned_keyexpr_t; #endif +/** + * A loaned key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, + * both for local processing and network-wise. + */ +#if !defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_keyexpr_t { + uint64_t _0[4]; +} z_keyexpr_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_keyexpr_t { + uint32_t _0[5]; +} z_keyexpr_t; +#endif /** * An owned zenoh publisher. * @@ -626,6 +591,19 @@ typedef struct z_delete_options_t { enum z_congestion_control_t congestion_control; enum z_priority_t priority; } z_delete_options_t; +/** + * The encoding of a payload, in a MIME-like format. + * + * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. + * + * Members: + * z_encoding_prefix_t prefix: The integer prefix of this encoding. + * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. + */ +typedef struct z_encoding_t { + enum z_encoding_prefix_t prefix; + struct z_bytes_t suffix; +} z_encoding_t; /** * An owned payload encoding. * @@ -641,7 +619,7 @@ typedef struct z_delete_options_t { */ typedef struct z_owned_encoding_t { enum z_encoding_prefix_t prefix; - struct z_bytes_t suffix; + struct z_owned_bytes_t suffix; bool _dropped; } z_owned_encoding_t; /** @@ -651,16 +629,19 @@ typedef struct z_query_consolidation_t { enum z_consolidation_mode_t mode; } z_query_consolidation_t; /** - * A zenoh value. + * A split buffer that owns all of its data. * - * Members: - * z_bytes_t payload: The payload of this zenoh value. - * z_encoding_t encoding: The encoding of this zenoh value `payload`. + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. */ -typedef struct z_value_t { - struct z_bytes_t payload; - struct z_encoding_t encoding; -} z_value_t; +typedef struct ALIGN(8) z_owned_buffer_t { + uint8_t _0[40]; +} z_owned_buffer_t; +/** + * An owned payload, backed by a reference counted owner. + * + * The `payload` field may be modified, and Zenoh will take the new values into account. + */ +typedef struct z_owned_buffer_t zc_owned_payload_t; /** * Options passed to the :c:func:`z_get` function. * @@ -674,7 +655,8 @@ typedef struct z_value_t { typedef struct z_get_options_t { enum z_query_target_t target; struct z_query_consolidation_t consolidation; - struct z_value_t value; + zc_owned_payload_t payload; + struct z_encoding_t encoding; struct z_attachment_t attachment; uint64_t timeout_ms; } z_get_options_t; @@ -754,6 +736,13 @@ typedef struct z_put_options_t { enum z_priority_t priority; struct z_attachment_t attachment; } z_put_options_t; +/** + * QoS settings of zenoh message. + * + */ +typedef struct z_qos_t { + uint8_t _0; +} z_qos_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -791,6 +780,26 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; +/** + * A loan of a `z_owned_buffer_t`. + * + * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. + */ +typedef struct z_buffer_t { + struct z_owned_buffer_t *_inner; +} z_buffer_t; +typedef struct z_buffer_t zc_payload_t; +/** + * A zenoh value. + * + * Members: + * zc_payload_t payload: The payload of this zenoh value. + * z_encoding_t encoding: The encoding of this zenoh value `payload`. + */ +typedef struct z_value_t { + zc_payload_t payload; + struct z_encoding_t encoding; +} z_value_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -816,6 +825,10 @@ typedef struct z_owned_reply_channel_t { struct z_owned_closure_reply_t send; struct z_owned_reply_channel_closure_t recv; } z_owned_reply_channel_t; +typedef struct z_timestamp_t { + uint64_t time; + struct z_id_t id; +} z_timestamp_t; typedef struct z_owned_scouting_config_t { struct z_owned_config_t _config; unsigned long zc_timeout_ms; @@ -873,21 +886,20 @@ typedef struct zc_liveliness_get_options_t { uint32_t timeout_ms; } zc_liveliness_get_options_t; /** - * An owned payload, backed by a reference counted owner. - * - * The `payload` field may be modified, and Zenoh will take the new values into account, - * however, assuming `ostart` and `olen` are the respective values of `payload.start` and - * `payload.len` when constructing the `zc_owned_payload_t payload` value was created, - * then `payload.start` MUST remain within the `[ostart, ostart + olen[` interval, and - * `payload.len` must remain within `[0, olen -(payload.start - ostart)]`. + * A reader for payload data. + */ +typedef struct ALIGN(8) zc_payload_reader { + uint8_t _0[24]; +} zc_payload_reader; +/** + * An owned sample. * - * Should this invariant be broken when the payload is passed to one of zenoh's `put_owned` - * functions, then the operation will fail (but the passed value will still be consumed). + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. */ -typedef struct zc_owned_payload_t { - struct z_bytes_t payload; - size_t _owner[5]; -} zc_owned_payload_t; +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[224]; +} zc_owned_sample_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; } zc_owned_shmbuf_t; @@ -1064,13 +1076,23 @@ ZENOHC_API struct z_attachment_t z_attachment_null(void); /** * Returns ``true`` if `b` is initialized. */ -ZENOHC_API bool z_bytes_check(const struct z_bytes_t *b); +ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *b); +ZENOHC_API struct z_owned_bytes_t z_bytes_clone(const struct z_bytes_t *b); +/** + * Returns the gravestone value for `z_bytes_t` + */ +ZENOHC_API struct z_bytes_t z_bytes_empty(void); /** * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). * - * `str == NULL` will cause this to return `z_bytes_null()` + * `str == NULL` will cause this to return `z_bytes_empty()` */ ZENOHC_API struct z_bytes_t z_bytes_from_str(const char *str); +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_bytes_is_initialized(const struct z_bytes_t *b); +ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *b); /** * Aliases `this` into a generic `z_attachment_t`, allowing it to be passed to corresponding APIs. */ @@ -1161,14 +1183,14 @@ ZENOHC_API struct z_owned_bytes_map_t z_bytes_map_null(void); /** * Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). * - * `str == NULL` will cause this to return `z_bytes_null()` + * `str == NULL` will cause this to return `z_bytes_empty()` */ ZENOHC_API struct z_bytes_t z_bytes_new(const char *str); /** - * Returns the gravestone value for `z_bytes_t` + * Returns the gravestone value for `z_owned_bytes_t` */ -ZENOHC_API struct z_bytes_t z_bytes_null(void); +ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); /** * Constructs a `len` bytes long view starting at `start`. */ @@ -1519,7 +1541,7 @@ int8_t z_get(struct z_session_t session, struct z_keyexpr_t keyexpr, const char *parameters, struct z_owned_closure_reply_t *callback, - const struct z_get_options_t *options); + struct z_get_options_t *options); ZENOHC_API struct z_get_options_t z_get_options_default(void); /** * Returns ``true`` if `hello` is valid. @@ -1757,22 +1779,24 @@ ZENOHC_API struct z_owned_publisher_t z_publisher_null(void); */ ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); /** - * Sends a `PUT` message onto the publisher's key expression. + * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. + * + * This is avoids copies when transfering data that was either: + * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - constructed from a `zc_owned_shmbuf_t` * * The payload's encoding can be sepcified through the options. * * Parameters: * session: The zenoh session. * payload: The value to put. - * len: The length of the value to put. * options: The publisher put options. * Returns: * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API int8_t z_publisher_put(struct z_publisher_t publisher, - const uint8_t *payload, - size_t len, + zc_owned_payload_t *payload, const struct z_publisher_put_options_t *options); /** * Constructs the default value for :c:type:`z_publisher_put_options_t`. @@ -1796,7 +1820,11 @@ ZENOHC_API struct z_owned_pull_subscriber_t z_pull_subscriber_null(void); */ ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default(void); /** - * Put data. + * Put data, transfering the buffer ownership. + * + * This is avoids copies when transfering data that was either: + * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - constructed from a `zc_owned_shmbuf_t` * * The payload's encoding can be sepcified through the options. * @@ -1804,7 +1832,6 @@ ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default( * session: The zenoh session. * keyexpr: The key expression to put. * payload: The value to put. - * len: The length of the value to put. * options: The put options. * Returns: * ``0`` in case of success, negative values in case of failure. @@ -1812,8 +1839,7 @@ ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default( ZENOHC_API int8_t z_put(struct z_session_t session, struct z_keyexpr_t keyexpr, - const uint8_t *payload, - size_t len, + zc_owned_payload_t *payload, const struct z_put_options_t *opts); /** * Constructs the default value for :c:type:`z_put_options_t`. @@ -1940,14 +1966,12 @@ struct z_bytes_t z_query_parameters(const struct z_query_t *query); * query: The query to reply to. * key: The key of this reply. * payload: The value of this reply. - * len: The length of the value of this reply. * options: The options of this reply. */ ZENOHC_API int8_t z_query_reply(const struct z_query_t *query, struct z_keyexpr_t key, - const uint8_t *payload, - size_t len, + zc_owned_payload_t *payload, const struct z_query_reply_options_t *options); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. @@ -2039,6 +2063,47 @@ ZENOHC_API struct z_owned_reply_t z_reply_null(void); */ ZENOHC_API struct z_sample_t z_reply_ok(const struct z_owned_reply_t *reply); +/** + * The sample's attachment. + * + * `sample` is aliased by the return value. + */ +ZENOHC_API struct z_attachment_t z_sample_attachment(const struct z_sample_t *sample); +/** + * The encoding of the payload. + */ +ZENOHC_API struct z_encoding_t z_sample_encoding(const struct z_sample_t *sample); +/** + * The Key Expression of the sample. + * + * `sample` is aliased by its return value. + */ +ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); +/** + * The sample's kind (put or delete). + */ +ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); +/** + * Returns the sample's payload after incrementing its internal reference count. + * + * Note that other samples may have received the same buffer, meaning that mutating this buffer may + * affect the samples received by other subscribers. + */ +ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sample); +/** + * The sample's data, the return value aliases the sample. + * + * If you need ownership of the buffer, you may use `z_sample_owned_payload`. + */ +ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); +/** + * The qos with which the sample was received. + */ +ZENOHC_API struct z_qos_t z_sample_qos(const struct z_sample_t *sample); +/** + * The samples timestamp + */ +ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); /** * Scout for routers and/or peers. * @@ -2362,62 +2427,68 @@ ZENOHC_API void zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t /** * Returns `false` if `payload` is the gravestone value. */ -ZENOHC_API bool zc_payload_check(const struct zc_owned_payload_t *payload); +ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); +/** + * Increments internal payload reference count, returning owned payload. + */ +ZENOHC_API zc_owned_payload_t zc_payload_clone(zc_payload_t payload); +/** + * Decodes payload into null-terminated string + */ +ZENOHC_API int8_t zc_payload_decode_into_bytes(zc_payload_t payload, struct z_owned_bytes_t *b); +/** + * Decodes payload into null-terminated string + */ +ZENOHC_API int8_t zc_payload_decode_into_string(zc_payload_t payload, struct z_owned_str_t *cstr); /** * Decrements `payload`'s backing refcount, releasing the memory if appropriate. */ -ZENOHC_API void zc_payload_drop(struct zc_owned_payload_t *payload); +ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); +/** + * Encodes byte sequence by aliasing. + */ +ZENOHC_API zc_owned_payload_t zc_payload_encode_from_bytes(struct z_bytes_t bytes); +/** + * Encodes a null-terminated string by aliasing. + */ +ZENOHC_API zc_owned_payload_t zc_payload_encode_from_string(const char *cstr); +/** + * Returns total number bytes in the payload. + */ +ZENOHC_API size_t zc_payload_len(zc_payload_t payload); +/** + * Returns a :c:type:`zc_payload_t` loaned from `payload`. + */ +ZENOHC_API zc_payload_t zc_payload_loan(const zc_owned_payload_t *payload); /** * Constructs `zc_owned_payload_t`'s gravestone value. */ -ZENOHC_API struct zc_owned_payload_t zc_payload_null(void); +ZENOHC_API zc_owned_payload_t zc_payload_null(void); /** * Clones the `payload` by incrementing its reference counter. */ -ZENOHC_API struct zc_owned_payload_t zc_payload_rcinc(const struct zc_owned_payload_t *payload); +ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); /** - * Sends a `PUT` message onto the publisher's key expression, transfering the buffer ownership. + * Creates a reader for the specified `payload`. * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload's encoding can be sepcified through the options. + * Returns 0 in case of success, -1 if `payload` is not valid. + */ +ZENOHC_API int8_t zc_payload_reader_init(zc_payload_t payload, struct zc_payload_reader *reader); +/** + * Reads data into specified destination. * - * Parameters: - * session: The zenoh session. - * payload: The value to put. - * len: The length of the value to put. - * options: The publisher put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. + * Will read at most `len` bytes. + * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. */ ZENOHC_API -int8_t zc_publisher_put_owned(struct z_publisher_t publisher, - struct zc_owned_payload_t *payload, - const struct z_publisher_put_options_t *options); +size_t zc_payload_reader_read(struct zc_payload_reader *reader, + uint8_t *dest, + size_t len); /** - * Put data, transfering the buffer ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` + * Returns number of the remaining bytes in the payload * - * The payload's encoding can be sepcified through the options. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to put. - * payload: The value to put. - * options: The put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. */ -ZENOHC_API -int8_t zc_put_owned(struct z_session_t session, - struct z_keyexpr_t keyexpr, - struct zc_owned_payload_t *payload, - const struct z_put_options_t *opts); +ZENOHC_API size_t zc_payload_reader_remaining(const struct zc_payload_reader *reader); /** * Creates a new blocking fifo channel, returned as a pair of closures. * @@ -2471,9 +2542,28 @@ struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); ZENOHC_API struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); /** - * Clones the sample's payload by incrementing its backing refcount (this doesn't imply any copies). + * Returns `true` if `sample` is valid. + * + * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * unless the value has been dropped already. + */ +ZENOHC_API +bool zc_sample_check(const struct zc_owned_sample_t *sample); +/** + * Clone a sample in the cheapest way available. + */ +ZENOHC_API struct zc_owned_sample_t zc_sample_clone(const struct z_sample_t *sample); +/** + * Destroy the sample. + */ +ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); +/** + * Borrow the sample, allowing calling its accessor methods. + * + * Calling this function using a dropped sample is undefined behaviour. */ -ZENOHC_API struct zc_owned_payload_t zc_sample_payload_rcinc(const struct z_sample_t *sample); +ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); +ZENOHC_API struct zc_owned_sample_t zc_sample_null(void); /** * Increments the session's reference count, returning a new owning handle. */ @@ -2528,7 +2618,7 @@ ZENOHC_API void zc_shmbuf_drop(struct zc_owned_shmbuf_t *buf); /** * Constructs an owned payload from an owned SHM buffer. */ -ZENOHC_API struct zc_owned_payload_t zc_shmbuf_into_payload(struct zc_owned_shmbuf_t *buf); +ZENOHC_API zc_owned_payload_t zc_shmbuf_into_payload(struct zc_owned_shmbuf_t *buf); /** * Returns the length of the SHM buffer. * diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index fa6668d48..815b2df85 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -14,6 +14,7 @@ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ + zc_owned_payload_t : zc_payload_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ )(&x) @@ -73,8 +74,8 @@ z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ z_owned_reply_channel_t * : z_reply_channel_null, \ z_owned_bytes_map_t * : z_bytes_map_null, \ - z_attachment_t * : z_attachment_null, \ zc_owned_payload_t * : zc_payload_null, \ + z_attachment_t * : z_attachment_null, \ zc_owned_shmbuf_t * : zc_shmbuf_null, \ zc_owned_shm_manager_t * : zc_shm_manager_null, \ ze_owned_publication_cache_t * : ze_publication_cache_null, \ @@ -88,7 +89,7 @@ z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ - z_bytes_t : z_bytes_check, \ + z_owned_bytes_t : z_bytes_check, \ z_owned_subscriber_t : z_subscriber_check, \ z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ @@ -98,8 +99,8 @@ z_owned_query_t : z_query_check, \ z_owned_str_t : z_str_check, \ z_owned_bytes_map_t : z_bytes_map_check, \ + zc_owned_payload_t: zc_payload_check, \ z_attachment_t : z_attachment_check, \ - zc_owned_payload_t : zc_payload_check, \ zc_owned_shmbuf_t : zc_shmbuf_check, \ zc_owned_shm_manager_t : zc_shm_manager_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ @@ -141,6 +142,7 @@ template<> struct zenoh_loan_type{ typedef z_pull_sub template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; +template<> struct zenoh_loan_type{ typedef zc_payload_t type; }; template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } @@ -153,6 +155,7 @@ template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_en template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } +template<> inline zc_payload_t z_loan(const zc_owned_payload& x) { return zc_payload_loan(&x); } template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } template struct zenoh_drop_type { typedef T type; }; @@ -171,6 +174,7 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -200,6 +204,7 @@ template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } +template<> inline void z_drop(zc_owned_payload* v) { zc_payload_drop(v); } template<> inline void z_drop(zc_owned_payload_t* v) { zc_payload_drop(v); } template<> inline void z_drop(zc_owned_shmbuf_t* v) { zc_shmbuf_drop(v); } template<> inline void z_drop(zc_owned_shm_manager_t* v) { zc_shm_manager_drop(v); } @@ -229,6 +234,7 @@ inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_query_t& v) { v = z_query_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } +inline void z_null(zc_owned_payload& v) { v = zc_payload_null(); } inline void z_null(zc_owned_payload_t& v) { v = zc_payload_null(); } inline void z_null(zc_owned_shmbuf_t& v) { v = zc_shmbuf_null(); } inline void z_null(zc_owned_shm_manager_t& v) { v = zc_shm_manager_null(); } @@ -251,7 +257,7 @@ inline bool z_check(const z_owned_keyexpr_t& v) { return z_keyexpr_check(&v); } inline bool z_check(const z_keyexpr_t& v) { return z_keyexpr_is_initialized(&v); } inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } -inline bool z_check(const z_bytes_t& v) { return z_bytes_check(&v); } +inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } inline bool z_check(const zc_owned_payload_t& v) { return zc_payload_check(&v); } inline bool z_check(const zc_owned_shmbuf_t& v) { return zc_shmbuf_check(&v); } inline bool z_check(const zc_owned_shm_manager_t& v) { return zc_shm_manager_check(&v); } @@ -263,6 +269,7 @@ inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } +inline bool z_check(const zc_owned_payload& v) { return zc_payload_check(&v); } inline bool z_check(const z_owned_bytes_map_t& v) { return z_bytes_map_check(&v); } inline bool z_check(const z_attachment_t& v) { return z_attachment_check(&v); } inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } diff --git a/src/attachment.rs b/src/attachment.rs index e776fa238..045596c47 100644 --- a/src/attachment.rs +++ b/src/attachment.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, cell::UnsafeCell, collections::HashMap}; use libc::c_void; -use crate::{impl_guarded_transmute, z_bytes_null, z_bytes_t}; +use crate::{impl_guarded_transmute, z_bytes_empty, z_bytes_t}; use zenoh::sample::{Attachment, AttachmentBuilder}; @@ -13,6 +13,7 @@ use zenoh::sample::{Attachment, AttachmentBuilder}; /// /// Returning `0` is treated as `continue`. /// Returning any other value is treated as `break`. +#[allow(non_camel_case_types)] pub type z_attachment_iter_body_t = extern "C" fn(key: z_bytes_t, value: z_bytes_t, context: *mut c_void) -> i8; @@ -20,6 +21,7 @@ pub type z_attachment_iter_body_t = /// /// This function is expected to call `loop_body` once for each key-value pair /// within `iterator`, passing `context`, and returning any non-zero value immediately (breaking iteration). +#[allow(non_camel_case_types)] pub type z_attachment_iter_driver_t = Option< extern "C" fn( iterator: *const c_void, @@ -99,7 +101,7 @@ pub extern "C" fn z_attachment_get(this: z_attachment_t, key: z_bytes_t) -> z_by let mut context = attachment_get_iterator_context { key, - value: z_bytes_null(), + value: z_bytes_empty(), }; if this.iteration_driver.map_or(false, |iteration_driver| { @@ -111,7 +113,7 @@ pub extern "C" fn z_attachment_get(this: z_attachment_t, key: z_bytes_t) -> z_by }) { context.value } else { - z_bytes_null() + z_bytes_empty() } } @@ -176,7 +178,7 @@ pub struct z_owned_bytes_map_t { _1: [usize; 4], } -impl_guarded_transmute!( +impl_guarded_transmute!(noderefs Option, Cow<'static, [u8]>>>, z_owned_bytes_map_t ); @@ -235,12 +237,12 @@ pub extern "C" fn z_bytes_map_is_empty(this: &mut z_owned_bytes_map_t) -> bool { pub extern "C" fn z_bytes_map_get(this: &z_owned_bytes_map_t, key: z_bytes_t) -> z_bytes_t { let this = unsafe { &*this.get() }; let (Some(this), Some(key)) = (this.as_ref(), key.as_slice()) else { - return z_bytes_null(); + return z_bytes_empty(); }; if let Some(value) = this.get(key) { value.as_ref().into() } else { - z_bytes_null() + z_bytes_empty() } } diff --git a/src/collections.rs b/src/collections.rs index 9fd0c3c16..d55a9fa1b 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh team, // + use libc::{c_char, size_t}; use zenoh::prelude::ZenohId; @@ -21,8 +22,8 @@ use zenoh::prelude::ZenohId; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct z_bytes_t { - pub len: size_t, pub start: *const u8, + pub len: size_t, } impl z_bytes_t { @@ -46,15 +47,54 @@ impl Default for z_bytes_t { } } +#[repr(C)] +#[derive(Clone, Debug)] +pub struct z_owned_bytes_t { + pub start: *mut u8, + pub len: size_t, +} + +impl Drop for z_owned_bytes_t { + fn drop(&mut self) { + unsafe { z_bytes_drop(self) } + } +} + +impl z_owned_bytes_t { + pub fn new(data: &[u8]) -> z_owned_bytes_t { + if data.is_empty() { + return z_bytes_null(); + } + let data = data.to_vec().into_boxed_slice(); + z_owned_bytes_t { + len: data.len(), + start: Box::leak(data).as_mut_ptr(), + } + } + + pub fn preallocate(len: usize) -> z_owned_bytes_t { + let data = vec![0u8; len].into_boxed_slice(); + z_owned_bytes_t { + len, + start: Box::leak(data).as_mut_ptr(), + } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { + std::ptr::copy_nonoverlapping(value.as_ptr(), self.start.add(start), value.len()); + } +} + /// Returns ``true`` if `b` is initialized. #[no_mangle] -pub extern "C" fn z_bytes_check(b: &z_bytes_t) -> bool { +pub extern "C" fn z_bytes_is_initialized(b: &z_bytes_t) -> bool { !b.start.is_null() } /// Returns the gravestone value for `z_bytes_t` #[no_mangle] -pub extern "C" fn z_bytes_null() -> z_bytes_t { +pub const extern "C" fn z_bytes_empty() -> z_bytes_t { z_bytes_t { len: 0, start: core::ptr::null(), @@ -63,12 +103,12 @@ pub extern "C" fn z_bytes_null() -> z_bytes_t { /// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_bytes_null()` +/// `str == NULL` will cause this to return `z_bytes_empty()` #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_from_str(str: *const c_char) -> z_bytes_t { if str.is_null() { - z_bytes_null() + z_bytes_empty() } else { let len = unsafe { libc::strlen(str) }; z_bytes_t { @@ -81,7 +121,7 @@ pub unsafe extern "C" fn z_bytes_from_str(str: *const c_char) -> z_bytes_t { #[deprecated = "Renamed to z_bytes_from_str"] /// Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_bytes_null()` +/// `str == NULL` will cause this to return `z_bytes_empty()` #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_new(str: *const c_char) -> z_bytes_t { @@ -93,7 +133,7 @@ pub unsafe extern "C" fn z_bytes_new(str: *const c_char) -> z_bytes_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_wrap(start: *const u8, len: usize) -> z_bytes_t { if start.is_null() { - z_bytes_null() + z_bytes_empty() } else { z_bytes_t { len, start } } @@ -101,15 +141,48 @@ pub unsafe extern "C" fn z_bytes_wrap(start: *const u8, len: usize) -> z_bytes_t /// Frees `b` and invalidates it for double-drop safety. #[allow(clippy::missing_safety_doc)] -pub(crate) unsafe fn z_bytes_drop(b: &mut z_bytes_t) { +pub unsafe extern "C" fn z_bytes_drop(b: &mut z_owned_bytes_t) { if !b.start.is_null() { std::mem::drop(Box::from_raw( core::ptr::slice_from_raw_parts(b.start, b.len).cast_mut(), )); - b.start = std::ptr::null(); + b.start = std::ptr::null_mut(); + b.len = 0; + } +} + +/// Returns the gravestone value for `z_owned_bytes_t` +#[no_mangle] +pub const extern "C" fn z_bytes_null() -> z_owned_bytes_t { + z_owned_bytes_t { + len: 0, + start: core::ptr::null_mut(), + } +} + +#[no_mangle] +pub const extern "C" fn z_bytes_loan(b: &z_owned_bytes_t) -> z_bytes_t { + z_bytes_t { + len: b.len, + start: b.start, } } +#[no_mangle] +pub extern "C" fn z_bytes_clone(b: &z_bytes_t) -> z_owned_bytes_t { + if !z_bytes_is_initialized(b) { + z_bytes_null() + } else { + z_owned_bytes_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) }) + } +} + +/// Returns ``true`` if `b` is initialized. +#[no_mangle] +pub extern "C" fn z_bytes_check(b: &z_owned_bytes_t) -> bool { + !b.start.is_null() +} + impl From for z_bytes_t { #[inline] fn from(pid: ZenohId) -> Self { diff --git a/src/commons.rs b/src/commons.rs index 8ac21cb11..ed0f9dbf0 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -12,17 +12,19 @@ // ZettaScale Zenoh team, // +use std::ops::Deref; + use crate::collections::*; use crate::keyexpr::*; use crate::z_congestion_control_t; use crate::z_id_t; use crate::z_priority_t; +use crate::zc_owned_payload_t; +use crate::zc_payload_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; -use zenoh::buffers::ZBuf; use zenoh::prelude::SampleKind; -use zenoh::prelude::SplitBuffer; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::QoS; @@ -90,127 +92,12 @@ impl From> for z_timestamp_t { } } -/// An owned payload, backed by a reference counted owner. -/// -/// The `payload` field may be modified, and Zenoh will take the new values into account, -/// however, assuming `ostart` and `olen` are the respective values of `payload.start` and -/// `payload.len` when constructing the `zc_owned_payload_t payload` value was created, -/// then `payload.start` MUST remain within the `[ostart, ostart + olen[` interval, and -/// `payload.len` must remain within `[0, olen -(payload.start - ostart)]`. -/// -/// Should this invariant be broken when the payload is passed to one of zenoh's `put_owned` -/// functions, then the operation will fail (but the passed value will still be consumed). -#[allow(non_camel_case_types)] -#[repr(C)] -pub struct zc_owned_payload_t { - pub payload: z_bytes_t, - pub _owner: [usize; 5], -} -impl Default for zc_owned_payload_t { - fn default() -> Self { - zc_payload_null() - } -} -impl TryFrom for zc_owned_payload_t { - type Error = (); - fn try_from(buf: ZBuf) -> Result { - let std::borrow::Cow::Borrowed(payload) = buf.contiguous() else { - return Err(()); - }; - Ok(Self { - payload: payload.into(), - _owner: unsafe { std::mem::transmute(buf) }, - }) - } -} -impl zc_owned_payload_t { - pub fn take(&mut self) -> Option { - if !z_bytes_check(&self.payload) { - return None; - } - let start = std::mem::replace(&mut self.payload.start, std::ptr::null()); - let len = std::mem::replace(&mut self.payload.len, 0); - let mut buf: ZBuf = unsafe { std::mem::transmute(self._owner) }; - { - let mut slices = buf.zslices_mut(); - let slice = slices.next().unwrap(); - assert!( - slices.next().is_none(), - "A multi-slice buffer reached zenoh-c, which is definitely a bug, please report it." - ); - let start_offset = unsafe { start.offset_from(slice.as_slice().as_ptr()) }; - let Ok(start_offset) = start_offset.try_into() else { - return None; - }; - *slice = match slice.subslice(start_offset, start_offset + len) { - Some(s) => s, - None => return None, - }; - } - Some(buf) - } - fn owner(&self) -> Option<&ZBuf> { - if !z_bytes_check(&self.payload) { - return None; - } - unsafe { std::mem::transmute(&self._owner) } - } -} -impl Drop for zc_owned_payload_t { - fn drop(&mut self) { - self.take(); - } -} - -/// Clones the `payload` by incrementing its reference counter. -#[no_mangle] -pub extern "C" fn zc_payload_rcinc(payload: &zc_owned_payload_t) -> zc_owned_payload_t { - match payload.owner() { - None => Default::default(), - Some(payload) => payload.clone().try_into().unwrap_or_default(), - } -} -/// Returns `false` if `payload` is the gravestone value. -#[no_mangle] -pub extern "C" fn zc_payload_check(payload: &zc_owned_payload_t) -> bool { - !payload.payload.start.is_null() -} -/// Decrements `payload`'s backing refcount, releasing the memory if appropriate. -#[no_mangle] -pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { - unsafe { std::ptr::replace(payload, zc_payload_null()) }; -} -/// Constructs `zc_owned_payload_t`'s gravestone value. -#[no_mangle] -pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { - zc_owned_payload_t { - payload: z_bytes_t { - len: 0, - start: std::ptr::null(), - }, - _owner: unsafe { core::mem::MaybeUninit::zeroed().assume_init() }, - } -} - /// QoS settings of zenoh message. /// #[repr(C)] pub struct z_qos_t(u8); impl_guarded_transmute!(QoS, z_qos_t); -impl_guarded_transmute!(z_qos_t, QoS); - -impl From for z_qos_t { - fn from(qos: QoS) -> Self { - qos.transmute() - } -} - -impl From for QoS { - fn from(qos: z_qos_t) -> QoS { - qos.transmute() - } -} /// Returns message priority. #[no_mangle] @@ -236,63 +123,118 @@ pub extern "C" fn z_qos_default() -> z_qos_t { /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. -/// -/// Members: -/// z_keyexpr_t keyexpr: The resource key of this data sample. -/// z_bytes_t payload: The value of this data sample. -/// z_encoding_t encoding: The encoding of the value of this data sample. -/// z_sample_kind_t kind: The kind of this data sample (PUT or DELETE). -/// z_timestamp_t timestamp: The timestamp of this data sample. -/// z_attachment_t attachment: The attachment of this data sample. #[repr(C)] pub struct z_sample_t<'a> { - pub keyexpr: z_keyexpr_t, - pub payload: z_bytes_t, - pub encoding: z_encoding_t, - pub _zc_buf: &'a c_void, - pub kind: z_sample_kind_t, - pub timestamp: z_timestamp_t, - pub qos: z_qos_t, - pub attachment: z_attachment_t, + _inner: &'a (), +} +impl<'a> core::ops::Deref for z_sample_t<'a> { + type Target = Sample; + fn deref(&self) -> &Self::Target { + unsafe { core::mem::transmute::<&(), &Sample>(self._inner) } + } } impl<'a> z_sample_t<'a> { - pub fn new(sample: &'a Sample, owner: &'a ZBuf) -> Self { - let std::borrow::Cow::Borrowed(payload) = owner.contiguous() else { - panic!("Attempted to construct z_sample_t from discontiguous buffer, this is definitely a bug in zenoh-c, please report it.") - }; + pub fn new(sample: &'a Sample) -> Self { z_sample_t { - keyexpr: (&sample.key_expr).into(), - payload: z_bytes_t::from(payload), - encoding: (&sample.encoding).into(), - _zc_buf: unsafe { std::mem::transmute(owner) }, - kind: sample.kind.into(), - timestamp: sample.timestamp.as_ref().into(), - qos: sample.qos.into(), - attachment: match &sample.attachment { - Some(attachment) => z_attachment_t { - data: attachment as *const _ as *mut c_void, - iteration_driver: Some(attachment_iteration_driver), - }, - None => z_attachment_null(), - }, + _inner: unsafe { core::mem::transmute(sample) }, } } } -/// Clones the sample's payload by incrementing its backing refcount (this doesn't imply any copies). +/// The Key Expression of the sample. +/// +/// `sample` is aliased by its return value. #[no_mangle] -pub extern "C" fn zc_sample_payload_rcinc(sample: Option<&z_sample_t>) -> zc_owned_payload_t { - let Some(sample) = sample else { - return zc_payload_null(); - }; - let buf = unsafe { std::mem::transmute::<_, &ZBuf>(sample._zc_buf).clone() }; - zc_owned_payload_t { - payload: sample.payload, - _owner: unsafe { std::mem::transmute(buf) }, +pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { + (&sample.key_expr).into() +} +/// The encoding of the payload. +#[no_mangle] +pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { + (&sample.encoding).into() +} +/// The sample's data, the return value aliases the sample. +/// +/// If you need ownership of the buffer, you may use `z_sample_owned_payload`. +#[no_mangle] +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { + Some(&sample.payload).into() +} +/// Returns the sample's payload after incrementing its internal reference count. +/// +/// Note that other samples may have received the same buffer, meaning that mutating this buffer may +/// affect the samples received by other subscribers. +#[no_mangle] +pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { + sample.payload.clone().into() +} +/// The sample's kind (put or delete). +#[no_mangle] +pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { + sample.kind.into() +} +/// The samples timestamp +#[no_mangle] +pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { + sample.timestamp.as_ref().into() +} +/// The qos with which the sample was received. +#[no_mangle] +pub extern "C" fn z_sample_qos(sample: &z_sample_t) -> z_qos_t { + sample.qos.into() +} +/// The sample's attachment. +/// +/// `sample` is aliased by the return value. +#[no_mangle] +pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { + match &sample.attachment { + Some(attachment) => z_attachment_t { + data: attachment as *const _ as *mut c_void, + iteration_driver: Some(attachment_iteration_driver), + }, + None => z_attachment_null(), } } +pub use crate::zc_owned_sample_t; +impl_guarded_transmute!(Option, zc_owned_sample_t); + +/// Clone a sample in the cheapest way available. +#[no_mangle] +pub extern "C" fn zc_sample_clone(sample: &z_sample_t) -> zc_owned_sample_t { + Some(sample.deref().clone()).into() +} + +/// Returns `true` if `sample` is valid. +/// +/// Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed +/// unless the value has been dropped already. +#[no_mangle] +pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { + sample.is_some() +} + +/// Borrow the sample, allowing calling its accessor methods. +/// +/// Calling this function using a dropped sample is undefined behaviour. +#[no_mangle] +pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> z_sample_t { + z_sample_t::new(unsafe { sample.as_ref().unwrap_unchecked() }) +} + +/// Destroy the sample. +#[no_mangle] +pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { + core::mem::drop(sample.take()); +} + +#[no_mangle] +pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { + None.into() +} + /// A :c:type:`z_encoding_t` integer `prefix`. /// /// - **Z_ENCODING_PREFIX_EMPTY** @@ -482,7 +424,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { #[repr(C)] pub struct z_owned_encoding_t { pub prefix: z_encoding_prefix_t, - pub suffix: z_bytes_t, + pub suffix: z_owned_bytes_t, pub _dropped: bool, } @@ -490,7 +432,7 @@ impl z_owned_encoding_t { pub fn null() -> Self { z_owned_encoding_t { prefix: z_encoding_prefix_t::Empty, - suffix: z_bytes_t::default(), + suffix: z_bytes_null(), _dropped: true, } } @@ -548,7 +490,7 @@ pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { z_encoding_t { prefix: encoding.prefix, - suffix: encoding.suffix, + suffix: z_bytes_loan(&encoding.suffix), } } @@ -556,7 +498,7 @@ impl From for z_owned_encoding_t { fn from(val: z_encoding_t) -> Self { z_owned_encoding_t { prefix: val.prefix, - suffix: val.suffix, + suffix: z_bytes_clone(&val.suffix), _dropped: false, } } @@ -570,13 +512,30 @@ pub struct z_owned_str_t { pub _cstr: *mut libc::c_char, } +impl z_owned_str_t { + #[allow(clippy::missing_safety_doc)] + pub unsafe fn preallocate(len: usize) -> z_owned_str_t { + let cstr = libc::malloc(len + 1) as *mut libc::c_char; + *cstr.add(len) = 0; + z_owned_str_t { _cstr: cstr } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { + std::ptr::copy_nonoverlapping( + value.as_ptr(), + (self._cstr as *mut u8).add(start), + value.len(), + ); + } +} + impl From<&[u8]> for z_owned_str_t { fn from(value: &[u8]) -> Self { unsafe { - let cstr = libc::malloc(value.len() + 1) as *mut libc::c_char; - std::ptr::copy_nonoverlapping(value.as_ptr(), cstr as _, value.len()); - *cstr.add(value.len()) = 0; - z_owned_str_t { _cstr: cstr } + let mut cstr = Self::preallocate(value.len()); + cstr.insert_unchecked(0, value); + cstr } } } @@ -591,6 +550,9 @@ impl Drop for z_owned_str_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_str_drop(s: &mut z_owned_str_t) { + if s._cstr.is_null() { + return; + } libc::free(std::mem::transmute(s._cstr)); s._cstr = std::ptr::null_mut(); } diff --git a/src/config.rs b/src/config.rs index 6e259f3b5..80e3a38f1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -15,7 +15,7 @@ use libc::{c_char, c_uint}; use std::ffi::CStr; use zenoh::config::{Config, ValidatedMap, WhatAmI}; -use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null, GuardedTransmute}; +use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -76,11 +76,6 @@ pub struct z_config_t(*const z_owned_config_t); pub struct z_owned_config_t(*mut ()); impl_guarded_transmute!(Option>, z_owned_config_t); -impl From>> for z_owned_config_t { - fn from(v: Option>) -> Self { - v.transmute() - } -} /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] pub extern "C" fn z_config_loan(s: &z_owned_config_t) -> z_config_t { diff --git a/src/get.rs b/src/get.rs index 012a8abaa..3e9e4ded4 100644 --- a/src/get.rs +++ b/src/get.rs @@ -15,14 +15,14 @@ use libc::c_char; use libc::c_void; use std::{ - borrow::Cow, convert::TryFrom, ffi::CStr, ops::{Deref, DerefMut}, }; +use zenoh::buffers::ZBuf; use zenoh::{ - prelude::{ConsolidationMode, KeyExpr, QueryTarget, SplitBuffer}, + prelude::{ConsolidationMode, KeyExpr, QueryTarget}, query::{Mode, QueryConsolidation, Reply}, sample::AttachmentBuilder, value::Value, @@ -33,10 +33,13 @@ use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, z_attachment_t, }; +use crate::z_encoding_default; +use crate::zc_owned_payload_t; +use crate::zc_payload_null; +use crate::zc_payload_t; use crate::{ - impl_guarded_transmute, z_bytes_t, z_closure_reply_call, z_encoding_default, z_encoding_t, - z_keyexpr_t, z_owned_closure_reply_t, z_sample_t, z_session_t, GuardedTransmute, - LOG_INVALID_SESSION, + impl_guarded_transmute, z_closure_reply_call, z_encoding_t, z_keyexpr_t, + z_owned_closure_reply_t, z_sample_t, z_session_t, GuardedTransmute, LOG_INVALID_SESSION, }; type ReplyInner = Option; @@ -56,16 +59,10 @@ pub struct z_owned_reply_t([u64; 30]); #[repr(C, align(8))] pub struct z_owned_reply_t([u64; 19]); -impl_guarded_transmute!(ReplyInner, z_owned_reply_t); +impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t); impl From for z_owned_reply_t { - fn from(mut val: ReplyInner) -> Self { - if let Some(val) = &mut val { - match &mut val.sample { - Ok(inner) => inner.payload = inner.payload.contiguous().into_owned().into(), - Err(inner) => inner.payload = inner.payload.contiguous().into_owned().into(), - }; - } + fn from(val: ReplyInner) -> Self { val.transmute() } } @@ -101,10 +98,7 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { if let Some(sample) = reply.as_ref().and_then(|s| s.sample.as_ref().ok()) { - if let Cow::Owned(_) = sample.payload.contiguous() { - unreachable!("z_reply_ok found a payload that wasn't contiguous by the time it was reached, which breaks some crate assertions. This is definitely a bug with zenoh, please contact us.") - } - z_sample_t::new(sample, &sample.payload) + z_sample_t::new(sample) } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Ok despite that not being the case") } @@ -113,11 +107,11 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { /// A zenoh value. /// /// Members: -/// z_bytes_t payload: The payload of this zenoh value. +/// zc_payload_t payload: The payload of this zenoh value. /// z_encoding_t encoding: The encoding of this zenoh value `payload`. #[repr(C)] pub struct z_value_t { - pub payload: z_bytes_t, + pub payload: zc_payload_t, pub encoding: z_encoding_t, } @@ -129,10 +123,7 @@ pub struct z_value_t { pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { if let Some(inner) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { z_value_t { - payload: match &inner.payload.contiguous() { - Cow::Borrowed(payload) => crate::z_bytes_t { start: payload.as_ptr(), len: payload.len() }, - Cow::Owned(_) => unreachable!("z_reply_err found a payload that wasn't contiguous by the time it was reached, which breaks some crate assertions."), - }, + payload: Some(&inner.payload).into(), encoding: (&inner.encoding).into(), } } else { @@ -165,7 +156,8 @@ pub extern "C" fn z_reply_null() -> z_owned_reply_t { pub struct z_get_options_t { pub target: z_query_target_t, pub consolidation: z_query_consolidation_t, - pub value: z_value_t, + pub payload: zc_owned_payload_t, + pub encoding: z_encoding_t, pub attachment: z_attachment_t, pub timeout_ms: u64, } @@ -175,12 +167,8 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { target: QueryTarget::default().into(), consolidation: QueryConsolidation::default().into(), timeout_ms: 0, - value: { - z_value_t { - payload: z_bytes_t::empty(), - encoding: z_encoding_default(), - } - }, + payload: zc_payload_null(), + encoding: z_encoding_default(), attachment: z_attachment_null(), } } @@ -206,7 +194,7 @@ pub unsafe extern "C" fn z_get( keyexpr: z_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, - options: Option<&z_get_options_t>, + options: Option<&mut z_get_options_t>, ) -> i8 { let mut closure = z_owned_closure_reply_t::empty(); std::mem::swap(callback, &mut closure); @@ -223,8 +211,13 @@ pub unsafe extern "C" fn z_get( if let Some(options) = options { q = q .consolidation(options.consolidation) - .target(options.target.into()) - .with_value(&options.value); + .target(options.target.into()); + + if let Some(payload) = options.payload.take() { + let mut value = Value::new(payload); + value = value.encoding(options.encoding.into()); + q = q.with_value(value); + } if options.timeout_ms != 0 { q = q.timeout(std::time::Duration::from_millis(options.timeout_ms)); } @@ -302,30 +295,29 @@ impl From for QueryTarget { impl From<&z_value_t> for Value { #[inline] fn from(val: &z_value_t) -> Value { - unsafe { - let value: Value = - std::slice::from_raw_parts(val.payload.start, val.payload.len).into(); - let encoding = std::str::from_utf8(std::slice::from_raw_parts( + let payload: Option<&ZBuf> = val.payload.into(); + let payload = match payload { + Some(b) => b.clone(), + None => ZBuf::empty(), + }; + let encoding = unsafe { + std::str::from_utf8(std::slice::from_raw_parts( val.encoding.suffix.start, val.encoding.suffix.len, )) - .expect("encodings must be UTF8"); - value.encoding( - zenoh::prelude::Encoding::new(val.encoding.prefix as u8, encoding).unwrap(), - ) - } + .expect("encodings must be UTF8") + }; + let v = Value::new(payload); + v.encoding(zenoh::prelude::Encoding::new(val.encoding.prefix as u8, encoding).unwrap()) } } impl From<&Value> for z_value_t { #[inline] fn from(val: &Value) -> z_value_t { - let std::borrow::Cow::Borrowed(payload) = val.payload.contiguous() else { - panic!("Would have returned a reference to a temporary, make sure you the Value's payload is contiguous BEFORE calling this constructor.") - }; z_value_t { encoding: (&val.encoding).into(), - payload: payload.into(), + payload: Some(&val.payload).into(), } } } diff --git a/src/keyexpr.rs b/src/keyexpr.rs index c0a90ae68..7742b3948 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -63,27 +63,11 @@ pub struct z_owned_keyexpr_t([u32; 5]); impl_guarded_transmute!(Option>, z_owned_keyexpr_t); -impl From>> for z_owned_keyexpr_t { - fn from(val: Option>) -> Self { - val.transmute() - } -} impl From> for z_owned_keyexpr_t { fn from(val: KeyExpr<'static>) -> Self { Some(val).into() } } -impl Deref for z_owned_keyexpr_t { - type Target = Option>; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl DerefMut for z_owned_keyexpr_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute(self) } - } -} impl z_owned_keyexpr_t { pub fn null() -> Self { None::.into() @@ -183,8 +167,8 @@ pub struct z_keyexpr_t([u64; 4]); #[repr(C, align(4))] pub struct z_keyexpr_t([u32; 5]); -impl_guarded_transmute!(Option>, z_keyexpr_t); -impl_guarded_transmute!(z_keyexpr_t, z_owned_keyexpr_t); +impl_guarded_transmute!(noderefs Option>, z_keyexpr_t); +impl_guarded_transmute!(noderefs z_keyexpr_t, z_owned_keyexpr_t); impl<'a> From> for z_keyexpr_t { fn from(val: KeyExpr<'a>) -> Self { diff --git a/src/lib.rs b/src/lib.rs index de6584885..20f766352 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,8 @@ mod config; pub use crate::config::*; mod commons; pub use crate::commons::*; +mod payload; +pub use crate::payload::*; mod keyexpr; pub use crate::keyexpr::*; mod info; @@ -55,6 +57,8 @@ pub use querying_subscriber::*; pub mod attachment; pub use platform::*; pub mod platform; +pub use opaque_types::*; +pub mod opaque_types; #[cfg(feature = "shared-memory")] mod shm; @@ -62,9 +66,37 @@ trait GuardedTransmute { fn transmute(self) -> D; } +/// For internal use only. +/// +/// This macro is used to establish the equivalence between a Rust type (first parameter) and a C layout (second parameter). +/// +/// It automatically implements `From`, `Deref` and `DerefMut` to make writing code around these equivalent types. +/// +/// Because carrying around the proper semantics of lifetimes is hard, this macro fails to produce working code when lifetimes are +/// present in either parameter. You may then call it with the `noderefs` prefix to avoid the offending implementations being defined. #[macro_export] macro_rules! impl_guarded_transmute { ($src_type:ty, $dst_type:ty) => { + impl_guarded_transmute!(noderefs $src_type, $dst_type); + impl From<$src_type> for $dst_type { + fn from(value: $src_type) -> $dst_type { + unsafe { core::mem::transmute(value) } + } + } + impl core::ops::Deref for $dst_type { + type Target = $src_type; + fn deref(&self) -> &$src_type { + unsafe { core::mem::transmute(self) } + } + } + impl core::ops::DerefMut for $dst_type { + fn deref_mut(&mut self) -> &mut $src_type { + unsafe { core::mem::transmute(self) } + } + } + + }; + (noderefs $src_type:ty, $dst_type:ty) => { const _: () = { let src = std::mem::align_of::<$src_type>(); let dst = std::mem::align_of::<$dst_type>(); @@ -81,12 +113,36 @@ macro_rules! impl_guarded_transmute { }); } }; - impl $crate::GuardedTransmute<$dst_type> for $src_type { + impl $crate::GuardedTransmute<$dst_type> for $src_type { fn transmute(self) -> $dst_type { unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } } } }; + ($src_type:ty, $dst_type:ty, $($gen: tt)*) => { + impl<$($gen)*> $crate::GuardedTransmute<$dst_type> for $src_type { + fn transmute(self) -> $dst_type { + unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } + } + } + impl<$($gen)*> From<$src_type> for $dst_type { + fn from(value: $src_type) -> $dst_type { + unsafe { core::mem::transmute(value) } + } + } + impl<$($gen)*> core::ops::Deref for $dst_type { + type Target = $src_type; + fn deref(&self) -> &$src_type { + unsafe { core::mem::transmute(self) } + } + } + impl<$($gen)*> core::ops::DerefMut for $dst_type { + fn deref_mut(&mut self) -> &mut $src_type { + unsafe { core::mem::transmute(self) } + } + } + + }; } pub(crate) const LOG_INVALID_SESSION: &str = "Invalid session"; diff --git a/src/liveliness.rs b/src/liveliness.rs index 0a7c689dd..b3c61a7de 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -14,7 +14,7 @@ use zenoh::{ liveliness::{Liveliness, LivelinessToken}, - prelude::{SessionDeclarations, SplitBuffer}, + prelude::SessionDeclarations, }; use zenoh_util::core::{zresult::ErrNo, SyncResolve}; @@ -177,12 +177,7 @@ pub extern "C" fn zc_liveliness_declare_subscriber( .liveliness() .declare_subscriber(key) .callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + let sample = z_sample_t::new(&sample); z_closure_sample_call(&callback, &sample) }) .res() diff --git a/src/opaque_types/.gitkeep b/src/opaque_types/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/src/payload.rs b/src/payload.rs new file mode 100644 index 000000000..a1745ba36 --- /dev/null +++ b/src/payload.rs @@ -0,0 +1,296 @@ +use core::slice; +use std::slice::from_raw_parts_mut; +use std::{any::Any, ops::Deref, ptr::NonNull}; + +use zenoh::buffers::reader::HasReader; +use zenoh::buffers::reader::Reader; +use zenoh::buffers::ZBufReader; +use zenoh::buffers::{buffer::SplitBuffer, ZBuf, ZSliceBuffer}; + +use crate::{ + impl_guarded_transmute, z_bytes_empty, z_bytes_null, z_bytes_t, z_owned_bytes_t, z_owned_str_t, + z_str_null, GuardedTransmute, +}; + +pub use crate::z_owned_buffer_t; +impl_guarded_transmute!(Option, z_owned_buffer_t); + +impl Default for z_owned_buffer_t { + fn default() -> Self { + z_buffer_null() + } +} +impl From for z_owned_buffer_t { + fn from(value: ZBuf) -> Self { + Some(value).transmute() + } +} + +/// The gravestone value for `z_owned_buffer_t`. +#[no_mangle] +extern "C" fn z_buffer_null() -> z_owned_buffer_t { + None::.transmute() +} + +/// Decrements the buffer's reference counter, destroying it if applicable. +/// +/// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. +#[no_mangle] +extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { + core::mem::drop(buffer.take()) +} + +/// Returns `true` if the buffer is in a valid state. +#[no_mangle] +extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { + buffer.is_some() +} + +/// Loans the buffer, allowing you to call functions that only need a loan of it. +#[no_mangle] +extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { + buffer.as_ref().into() +} + +/// A loan of a `z_owned_buffer_t`. +/// +/// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. +#[repr(C)] +#[derive(Clone, Copy, Default)] +pub struct z_buffer_t { + _inner: Option>, +} + +impl_guarded_transmute!(noderefs Option<&ZBuf>, z_buffer_t); +impl_guarded_transmute!(noderefs z_buffer_t, Option<&'static ZBuf>); + +impl From> for z_buffer_t { + fn from(value: Option<&ZBuf>) -> Self { + value.transmute() + } +} + +impl From for Option<&'static ZBuf> { + fn from(value: z_buffer_t) -> Self { + value.transmute() + } +} + +/// Increments the buffer's reference count, returning an owned version of the buffer. +#[no_mangle] +extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { + match buffer._inner { + Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, + None => ZBuf::empty().into(), + } +} + +/// Returns the number of slices in the buffer. +/// +/// If the return value is 0 or 1, then the buffer's data is contiguous in memory. +#[no_mangle] +extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { + match buffer.into() { + None => 0, + Some(buf) => ZBuf::slices(buf).len(), + } +} + +/// Returns total number bytes in the buffer. +#[no_mangle] +extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { + match buffer.into() { + None => 0, + Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), + } +} + +/// Returns the `index`th slice of the buffer, aliasing it. +/// +/// Out of bounds accesses will return `z_bytes_empty`. +#[no_mangle] +extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { + match buffer.into() { + None => z_bytes_empty(), + Some(buf) => ZBuf::slices(buf) + .nth(index) + .map_or(z_bytes_empty(), |slice| slice.into()), + } +} + +/// An owned payload, backed by a reference counted owner. +/// +/// The `payload` field may be modified, and Zenoh will take the new values into account. +#[allow(non_camel_case_types)] +pub type zc_owned_payload_t = z_owned_buffer_t; + +/// Clones the `payload` by incrementing its reference counter. +#[no_mangle] +pub extern "C" fn zc_payload_rcinc(payload: &zc_owned_payload_t) -> zc_owned_payload_t { + z_buffer_clone(z_buffer_loan(payload)) +} +/// Returns `false` if `payload` is the gravestone value. +#[no_mangle] +pub extern "C" fn zc_payload_check(payload: &zc_owned_payload_t) -> bool { + z_buffer_check(payload) +} +/// Decrements `payload`'s backing refcount, releasing the memory if appropriate. +#[no_mangle] +pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { + z_buffer_drop(payload) +} +/// Constructs `zc_owned_payload_t`'s gravestone value. +#[no_mangle] +pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { + z_buffer_null() +} + +/// Returns a :c:type:`zc_payload_t` loaned from `payload`. +#[no_mangle] +pub extern "C" fn zc_payload_loan(payload: &zc_owned_payload_t) -> zc_payload_t { + z_buffer_loan(payload) +} + +#[allow(non_camel_case_types)] +pub type zc_payload_t = z_buffer_t; + +/// Increments internal payload reference count, returning owned payload. +#[no_mangle] +pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t { + z_buffer_clone(payload) +} + +/// Decodes payload into null-terminated string +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_decode_into_string( + payload: zc_payload_t, + cstr: &mut z_owned_str_t, +) -> i8 { + let payload: Option<&ZBuf> = payload.into(); + if payload.is_none() { + *cstr = z_str_null(); + return 0; + } + *cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); + let payload = payload.unwrap(); + + let mut pos = 0; + for s in payload.slices() { + cstr.insert_unchecked(pos, s); + pos += s.len(); + } + 0 +} + +/// Decodes payload into null-terminated string +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_decode_into_bytes( + payload: zc_payload_t, + b: &mut z_owned_bytes_t, +) -> i8 { + let payload: Option<&ZBuf> = payload.into(); + if payload.is_none() { + *b = z_bytes_null(); + return 0; + } + *b = z_owned_bytes_t::preallocate(zc_payload_len(payload.into())); + let payload = payload.unwrap(); + + let mut pos = 0; + for s in payload.slices() { + b.insert_unchecked(pos, s); + pos += s.len(); + } + 0 +} + +unsafe impl Send for z_bytes_t {} +unsafe impl Sync for z_bytes_t {} + +impl ZSliceBuffer for z_bytes_t { + fn as_slice(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.start, self.len) } + } + fn as_mut_slice(&mut self) -> &mut [u8] { + unsafe { slice::from_raw_parts_mut(self.start as *mut u8, self.len) } + } + fn as_any(&self) -> &dyn Any { + self + } +} + +/// Encodes byte sequence by aliasing. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_encode_from_bytes(bytes: z_bytes_t) -> zc_owned_payload_t { + ZBuf::from(bytes).into() +} + +/// Encodes a null-terminated string by aliasing. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_encode_from_string( + cstr: *const libc::c_char, +) -> zc_owned_payload_t { + let bytes = z_bytes_t { + start: cstr as *const u8, + len: libc::strlen(cstr), + }; + zc_payload_encode_from_bytes(bytes) +} + +/// Returns total number bytes in the payload. +#[no_mangle] +pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { + z_buffer_len(payload) +} + +pub use crate::zc_payload_reader; +impl_guarded_transmute!(ZBufReader<'static>, zc_payload_reader); +impl_guarded_transmute!(noderefs zc_payload_reader, ZBufReader<'static>); + +/// Creates a reader for the specified `payload`. +/// +/// Returns 0 in case of success, -1 if `payload` is not valid. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_reader_init( + payload: zc_payload_t, + reader: *mut zc_payload_reader, +) -> i8 { + if payload._inner.is_none() { + return -1; + } + *reader = payload.transmute().unwrap().reader().transmute(); + 0 +} + +/// Reads data into specified destination. +/// +/// Will read at most `len` bytes. +/// Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_reader_read( + reader: *mut zc_payload_reader, + dest: *mut u8, + len: usize, +) -> usize { + let buf = unsafe { from_raw_parts_mut(dest, len) }; + reader + .as_mut() + .unwrap() + .read(buf) + .map(|n| n.get()) + .unwrap_or(0) +} + +/// Returns number of the remaining bytes in the payload +/// +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_reader_remaining(reader: *const zc_payload_reader) -> usize { + reader.as_ref().unwrap().remaining() +} diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index dbd9d94b8..a16664352 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -22,8 +22,8 @@ pub struct ZMutexPtr { #[derive(Clone, Copy)] pub struct z_mutex_t(usize); -impl_guarded_transmute!(z_mutex_t, ZMutexPtr); -impl_guarded_transmute!(ZMutexPtr, z_mutex_t); +impl_guarded_transmute!(noderefs z_mutex_t, ZMutexPtr); +impl_guarded_transmute!(noderefs ZMutexPtr, z_mutex_t); // using the same error codes as in GNU pthreads, but with negative sign // due to convention to return negative values on error @@ -141,8 +141,8 @@ struct ZCondvarPtr { #[derive(Clone, Copy)] pub struct z_condvar_t(usize); -impl_guarded_transmute!(z_condvar_t, ZCondvarPtr); -impl_guarded_transmute!(ZCondvarPtr, z_condvar_t); +impl_guarded_transmute!(noderefs z_condvar_t, ZCondvarPtr); +impl_guarded_transmute!(noderefs ZCondvarPtr, z_condvar_t); #[no_mangle] #[allow(clippy::missing_safety_doc)] @@ -233,8 +233,8 @@ pub struct z_task_t(usize); #[derive(Clone, Copy)] pub struct z_task_attr_t(usize); -impl_guarded_transmute!(z_task_t, ZTaskPtr); -impl_guarded_transmute!(ZTaskPtr, z_task_t); +impl_guarded_transmute!(noderefs z_task_t, ZTaskPtr); +impl_guarded_transmute!(noderefs ZTaskPtr, z_task_t); struct FunArgPair { fun: unsafe extern "C" fn(arg: *mut c_void), diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 5b96a904c..ee4c85959 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -20,7 +20,7 @@ use zenoh_util::core::SyncResolve; use crate::{ impl_guarded_transmute, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t, - GuardedTransmute, UninitializedKeyExprError, + UninitializedKeyExprError, }; /// Options passed to the :c:func:`ze_declare_publication_cache` function. @@ -53,8 +53,6 @@ pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache } } -type PublicationCache = Option>>; - /// An owned zenoh publication_cache. /// /// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. @@ -68,26 +66,9 @@ type PublicationCache = Option>>; #[repr(C)] pub struct ze_owned_publication_cache_t([usize; 1]); +type PublicationCache = Option>>; impl_guarded_transmute!(PublicationCache, ze_owned_publication_cache_t); -impl From for ze_owned_publication_cache_t { - fn from(val: PublicationCache) -> Self { - val.transmute() - } -} - -impl AsRef for ze_owned_publication_cache_t { - fn as_ref(&self) -> &PublicationCache { - unsafe { std::mem::transmute(self) } - } -} - -impl AsMut for ze_owned_publication_cache_t { - fn as_mut(&mut self) -> &mut PublicationCache { - unsafe { std::mem::transmute(self) } - } -} - impl ze_owned_publication_cache_t { pub fn new(pub_cache: zenoh_ext::PublicationCache<'static>) -> Self { Some(Box::new(pub_cache)).into() @@ -187,7 +168,7 @@ pub extern "C" fn ze_publication_cache_check(pub_cache: &ze_owned_publication_ca pub extern "C" fn ze_undeclare_publication_cache( pub_cache: &mut ze_owned_publication_cache_t, ) -> i8 { - if let Some(p) = pub_cache.as_mut().take() { + if let Some(p) = pub_cache.take() { if let Err(e) = p.close().res_sync() { log::error!("{}", e); return e.errno().get(); diff --git a/src/publisher.rs b/src/publisher.rs index 42681093f..6647655bd 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -75,7 +75,7 @@ pub struct z_owned_publisher_t([u64; 7]); #[repr(C, align(4))] pub struct z_owned_publisher_t([u32; 8]); -impl_guarded_transmute!(Option>, z_owned_publisher_t); +impl_guarded_transmute!(noderefs Option>, z_owned_publisher_t); impl<'a> From>> for z_owned_publisher_t { fn from(val: Option) -> Self { @@ -234,14 +234,17 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t } } -/// Sends a `PUT` message onto the publisher's key expression. +/// Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. +/// +/// This is avoids copies when transfering data that was either: +/// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher +/// - constructed from a `zc_owned_shmbuf_t` /// /// The payload's encoding can be sepcified through the options. /// /// Parameters: /// session: The zenoh session. /// payload: The value to put. -/// len: The length of the value to put. /// options: The publisher put options. /// Returns: /// ``0`` in case of success, negative values in case of failure. @@ -249,12 +252,15 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_publisher_put( publisher: z_publisher_t, - payload: *const u8, - len: usize, + payload: Option<&mut zc_owned_payload_t>, options: Option<&z_publisher_put_options_t>, ) -> i8 { if let Some(p) = publisher.as_ref() { - let value: Value = std::slice::from_raw_parts(payload, len).into(); + let Some(payload) = payload.and_then(|p| p.take()) else { + log::debug!("Attempted to put without a payload"); + return i8::MIN; + }; + let value: Value = payload.into(); let put = match options { Some(options) => { let mut put = p.put(value.encoding(options.encoding.into())); @@ -282,49 +288,6 @@ pub unsafe extern "C" fn z_publisher_put( } } -/// Sends a `PUT` message onto the publisher's key expression, transfering the buffer ownership. -/// -/// This is avoids copies when transfering data that was either: -/// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher -/// - constructed from a `zc_owned_shmbuf_t` -/// -/// The payload's encoding can be sepcified through the options. -/// -/// Parameters: -/// session: The zenoh session. -/// payload: The value to put. -/// len: The length of the value to put. -/// options: The publisher put options. -/// Returns: -/// ``0`` in case of success, negative values in case of failure. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_publisher_put_owned( - publisher: z_publisher_t, - payload: Option<&mut zc_owned_payload_t>, - options: Option<&z_publisher_put_options_t>, -) -> i8 { - if let Some(p) = publisher.as_ref() { - let Some(payload) = payload.and_then(|p| p.take()) else { - log::debug!("Attempted to put without a payload"); - return i8::MIN; - }; - let value: Value = payload.into(); - let put = match options { - Some(options) => p.put(value.encoding(options.encoding.into())), - None => p.put(value), - }; - if let Err(e) = put.res_sync() { - log::error!("{}", e); - e.errno().get() - } else { - 0 - } - } else { - i8::MIN - } -} - /// Represents the set of options that can be applied to the delete operation by a previously declared publisher, /// whenever issued via :c:func:`z_publisher_delete`. #[repr(C)] @@ -387,7 +350,7 @@ pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_owned_keyex #[repr(C, align(8))] pub struct zcu_owned_matching_listener_t([u64; 4]); -impl_guarded_transmute!( +impl_guarded_transmute!(noderefs Option>, zcu_owned_matching_listener_t ); diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index 931b48d84..ebef7064b 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -1,4 +1,3 @@ -use crate::GuardedTransmute; // // Copyright (c) 2017, 2022 ZettaScale Technology. // @@ -23,7 +22,6 @@ use crate::z_reliability_t; use crate::LOG_INVALID_SESSION; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::SplitBuffer; use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; @@ -56,21 +54,9 @@ impl_guarded_transmute!(PullSubscriber, z_owned_pull_subscriber_t); #[allow(non_camel_case_types)] pub struct z_pull_subscriber_t<'a>(&'a z_owned_pull_subscriber_t); -impl From for z_owned_pull_subscriber_t { - fn from(val: PullSubscriber) -> Self { - val.transmute() - } -} - -impl AsRef for z_owned_pull_subscriber_t { - fn as_ref(&self) -> &PullSubscriber { - unsafe { std::mem::transmute(self) } - } -} - impl<'a> AsRef for z_pull_subscriber_t<'a> { fn as_ref(&self) -> &PullSubscriber { - self.0.as_ref() + self.0 } } @@ -163,12 +149,7 @@ pub extern "C" fn z_declare_pull_subscriber( let mut res = s .declare_subscriber(keyexpr) .callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) .pull_mode(); diff --git a/src/put.rs b/src/put.rs index b5d9f2f94..5e2d59aec 100644 --- a/src/put.rs +++ b/src/put.rs @@ -14,9 +14,9 @@ use crate::commons::*; use crate::keyexpr::*; use crate::session::*; +use crate::zc_owned_payload_t; use crate::LOG_INVALID_SESSION; use libc::c_void; -use libc::size_t; use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; use zenoh::publication::CongestionControl; use zenoh::sample::AttachmentBuilder; @@ -135,62 +135,6 @@ pub extern "C" fn z_put_options_default() -> z_put_options_t { } } -/// Put data. -/// -/// The payload's encoding can be sepcified through the options. -/// -/// Parameters: -/// session: The zenoh session. -/// keyexpr: The key expression to put. -/// payload: The value to put. -/// len: The length of the value to put. -/// options: The put options. -/// Returns: -/// ``0`` in case of success, negative values in case of failure. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_put( - session: z_session_t, - keyexpr: z_keyexpr_t, - payload: *const u8, - len: size_t, - opts: Option<&z_put_options_t>, -) -> i8 { - match session.upgrade() { - Some(s) => { - let mut res = s - .put(keyexpr, std::slice::from_raw_parts(payload, len)) - .kind(SampleKind::Put); - if let Some(opts) = opts { - res = res - .encoding(opts.encoding) - .congestion_control(opts.congestion_control.into()) - .priority(opts.priority.into()); - if z_attachment_check(&opts.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - opts.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - res = res.with_attachment(attachment_builder.build()); - }; - } - match res.res_sync() { - Err(e) => { - log::error!("{}", e); - e.errno().get() - } - Ok(()) => 0, - } - } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - i8::MIN - } - } -} - /// Put data, transfering the buffer ownership. /// /// This is avoids copies when transfering data that was either: @@ -208,7 +152,7 @@ pub unsafe extern "C" fn z_put( /// ``0`` in case of success, negative values in case of failure. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn zc_put_owned( +pub extern "C" fn z_put( session: z_session_t, keyexpr: z_keyexpr_t, payload: Option<&mut zc_owned_payload_t>, @@ -223,6 +167,15 @@ pub extern "C" fn zc_put_owned( .encoding(opts.encoding) .congestion_control(opts.congestion_control.into()) .priority(opts.priority.into()); + if z_attachment_check(&opts.attachment) { + let mut attachment_builder = AttachmentBuilder::new(); + z_attachment_iterate( + opts.attachment, + insert_in_attachment_builder, + &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, + ); + res = res.with_attachment(attachment_builder.build()); + }; } match res.res_sync() { Err(e) => { diff --git a/src/queryable.rs b/src/queryable.rs index 5a7112afc..dd932188c 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -17,17 +17,16 @@ use crate::attachment::{ }; use crate::{ impl_guarded_transmute, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, - z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, GuardedTransmute, + z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, zc_payload_t, LOG_INVALID_SESSION, }; use libc::c_void; use std::ops::{Deref, DerefMut}; use zenoh::prelude::SessionDeclarations; use zenoh::{ - prelude::{Sample, SplitBuffer}, + prelude::Sample, queryable::{Query, Queryable as CallbackQueryable}, sample::AttachmentBuilder, - value::Value, }; use zenoh_util::core::{zresult::ErrNo, SyncResolve}; @@ -52,22 +51,6 @@ pub struct z_owned_queryable_t([u32; 4]); impl_guarded_transmute!(Queryable, z_owned_queryable_t); -impl From for z_owned_queryable_t { - fn from(val: Queryable) -> Self { - val.transmute() - } -} -impl AsRef for z_owned_queryable_t { - fn as_ref(&self) -> &Queryable { - unsafe { std::mem::transmute(self) } - } -} -impl AsMut for z_owned_queryable_t { - fn as_mut(&mut self) -> &mut Queryable { - unsafe { std::mem::transmute(self) } - } -} - impl z_owned_queryable_t { pub fn null() -> Self { None.into() @@ -263,7 +246,7 @@ pub extern "C" fn z_declare_queryable( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> i8 { - if let Some(qable) = qable.as_mut().take() { + if let Some(qable) = qable.take() { if let Err(e) = qable.undeclare().res_sync() { log::error!("{}", e); return e.errno().get(); @@ -290,15 +273,13 @@ pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { /// query: The query to reply to. /// key: The key of this reply. /// payload: The value of this reply. -/// len: The length of the value of this reply. /// options: The options of this reply. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_reply( query: &z_query_t, key: z_keyexpr_t, - payload: *const u8, - len: usize, + payload: Option<&mut zc_owned_payload_t>, options: Option<&z_query_reply_options_t>, ) -> i8 { let Some(query) = query.as_ref() else { @@ -306,30 +287,28 @@ pub unsafe extern "C" fn z_query_reply( return i8::MIN; }; if let Some(key) = &*key { - let mut s = Sample::new( - key.clone().into_owned(), - std::slice::from_raw_parts(payload, len), - ); - if let Some(o) = options { - s.encoding = o.encoding.into(); - if z_attachment_check(&o.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - o.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - s = s.with_attachment(attachment_builder.build()); - }; - } - if let Err(e) = query.reply(Ok(s)).res_sync() { - log::error!("{}", e); - return e.errno().get(); + if let Some(payload) = payload.and_then(|p| p.take()) { + let mut s = Sample::new(key.clone().into_owned(), payload); + if let Some(o) = options { + s.encoding = o.encoding.into(); + if z_attachment_check(&o.attachment) { + let mut attachment_builder = AttachmentBuilder::new(); + z_attachment_iterate( + o.attachment, + insert_in_attachment_builder, + &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, + ); + s = s.with_attachment(attachment_builder.build()); + }; + } + if let Err(e) = query.reply(Ok(s)).res_sync() { + log::error!("{}", e); + return e.errno().get(); + } + return 0; } - 0 - } else { - i8::MIN } + i8::MIN } /// Get a query's key by aliasing it. @@ -363,14 +342,15 @@ pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_bytes_t { #[no_mangle] pub unsafe extern "C" fn z_query_value(query: &z_query_t) -> z_value_t { match query.as_ref().and_then(|q| q.value()) { - Some(value) => { + Some(value) => + { #[allow(mutable_transmutes)] - if let std::borrow::Cow::Owned(payload) = value.payload.contiguous() { - unsafe { std::mem::transmute::<_, &mut Value>(value).payload = payload.into() } - } value.into() } - None => (&Value::empty()).into(), + None => z_value_t { + payload: zc_payload_t::default(), + encoding: z_encoding_default(), + }, } } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index d407f9646..910f1b89b 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -15,7 +15,6 @@ use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::SplitBuffer; use zenoh_ext::*; use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; @@ -25,10 +24,10 @@ use crate::{ z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, z_query_target_default, z_query_target_t, z_reliability_t, z_sample_t, z_session_t, zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, - GuardedTransmute, LOG_INVALID_SESSION, + LOG_INVALID_SESSION, }; -struct FetchingSubscriberWrapper { +pub struct FetchingSubscriberWrapper { fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, session: z_session_t, } @@ -54,27 +53,9 @@ impl_guarded_transmute!(FetchingSubscriber, ze_owned_querying_subscriber_t); #[allow(non_camel_case_types)] pub struct ze_querying_subscriber_t<'a>(&'a ze_owned_querying_subscriber_t); -impl From for ze_owned_querying_subscriber_t { - fn from(val: FetchingSubscriber) -> Self { - val.transmute() - } -} - -impl AsRef for ze_owned_querying_subscriber_t { - fn as_ref(&self) -> &FetchingSubscriber { - unsafe { std::mem::transmute(self) } - } -} - impl<'a> AsRef for ze_querying_subscriber_t<'a> { fn as_ref(&self) -> &FetchingSubscriber { - self.0.as_ref() - } -} - -impl AsMut for ze_owned_querying_subscriber_t { - fn as_mut(&mut self) -> &mut FetchingSubscriber { - unsafe { std::mem::transmute(self) } + self.0 } } @@ -204,12 +185,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( } match sub .callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) .res() @@ -276,7 +252,7 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn ze_undeclare_querying_subscriber(sub: &mut ze_owned_querying_subscriber_t) -> i8 { - if let Some(s) = sub.as_mut().take() { + if let Some(s) = sub.take() { if let Err(e) = s.fetching_subscriber.close().res_sync() { log::warn!("{}", e); return e.errno().get(); diff --git a/src/session.rs b/src/session.rs index a4329fbf6..2caab85ea 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh team, // -use crate::{config::*, impl_guarded_transmute, zc_init_logger, GuardedTransmute}; +use crate::{config::*, impl_guarded_transmute, zc_init_logger}; use std::sync::{Arc, Weak}; use zenoh::prelude::sync::SyncResolve; use zenoh::Session; @@ -33,24 +33,6 @@ pub struct z_owned_session_t(usize); impl_guarded_transmute!(Option>, z_owned_session_t); -impl From>> for z_owned_session_t { - fn from(val: Option>) -> Self { - val.transmute() - } -} - -impl AsRef>> for z_owned_session_t { - fn as_ref(&self) -> &Option> { - unsafe { std::mem::transmute(self) } - } -} - -impl AsMut>> for z_owned_session_t { - fn as_mut(&mut self) -> &mut Option> { - unsafe { std::mem::transmute(self) } - } -} - impl AsRef>> for z_session_t { fn as_ref(&self) -> &Option> { unsafe { std::mem::transmute(self) } @@ -150,7 +132,7 @@ pub extern "C" fn z_session_check(session: &z_owned_session_t) -> bool { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { - let Some(s) = session.as_mut().take() else { + let Some(s) = session.take() else { return 0; }; let s = match Arc::try_unwrap(s) { diff --git a/src/subscriber.rs b/src/subscriber.rs index 910ec424b..d82086f7f 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -18,11 +18,9 @@ use crate::keyexpr::*; use crate::session::*; use crate::z_closure_sample_call; use crate::z_owned_closure_sample_t; -use crate::GuardedTransmute; use crate::LOG_INVALID_SESSION; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::SplitBuffer; use zenoh::subscriber::Reliability; use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; @@ -84,24 +82,6 @@ pub struct z_owned_subscriber_t([u32; 1]); impl_guarded_transmute!(Subscriber, z_owned_subscriber_t); -impl From for z_owned_subscriber_t { - fn from(sub: Subscriber) -> Self { - sub.transmute() - } -} - -impl AsRef for z_owned_subscriber_t { - fn as_ref(&self) -> &Subscriber { - unsafe { std::mem::transmute(self) } - } -} - -impl AsMut for z_owned_subscriber_t { - fn as_mut(&mut self) -> &mut Subscriber { - unsafe { std::mem::transmute(self) } - } -} - impl z_owned_subscriber_t { pub fn new(sub: zenoh::subscriber::Subscriber<'static, ()>) -> Self { Some(Box::new(sub)).into() @@ -125,7 +105,7 @@ pub struct z_subscriber_t(*const z_owned_subscriber_t); impl AsRef for z_subscriber_t { fn as_ref(&self) -> &Subscriber { - unsafe { (*self.0).as_ref() } + unsafe { &(*self.0) } } } @@ -199,12 +179,7 @@ pub extern "C" fn z_declare_subscriber( match session.upgrade() { Some(s) => { let mut res = s.declare_subscriber(keyexpr).callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }); if let Some(opts) = opts { @@ -240,7 +215,7 @@ pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_owned_ke #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_undeclare_subscriber(sub: &mut z_owned_subscriber_t) -> i8 { - if let Some(s) = sub.as_mut().take() { + if let Some(s) = sub.take() { if let Err(e) = s.undeclare().res_sync() { log::warn!("{}", e); return e.errno().get(); diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 43ce08cc3..e7b72ef96 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -56,7 +56,8 @@ void query_handler(const z_query_t *query, void *arg) { z_value_t payload_value = z_query_value(query); (void)(payload_value); z_query_reply_options_t _ret_qreply_opt = z_query_reply_options_default(); - z_query_reply(query, z_keyexpr(z_loan(k_str)), (const uint8_t *)value, strlen(value), &_ret_qreply_opt); + zc_owned_payload_t payload = zc_payload_encode_from_string(value); + z_query_reply(query, z_keyexpr(z_loan(k_str)), z_move(payload), &_ret_qreply_opt); z_drop(z_move(k_str)); } @@ -68,7 +69,7 @@ void reply_handler(z_owned_reply_t *reply, void *arg) { if (z_reply_is_ok(reply)) { z_sample_t sample = z_reply_ok(reply); - z_owned_str_t k_str = z_keyexpr_to_string(sample.keyexpr); + z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_session_t *)arg, sample.keyexpr); @@ -87,7 +88,7 @@ volatile unsigned int datas = 0; void data_handler(const z_sample_t *sample, void *arg) { datas++; - z_owned_str_t k_str = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(sample)); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_session_t *)arg, sample->keyexpr); @@ -260,7 +261,8 @@ int main(int argc, char **argv) { z_encoding_t _ret_encoding = z_encoding_default(); _ret_encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); _ret_put_opt.encoding = _ret_encoding; - _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), (const uint8_t *)value, strlen(value), &_ret_put_opt); + zc_owned_payload_t payload = zc_payload_encode_from_string(value); + _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), z_move(payload), &_ret_put_opt); assert(_ret_int8 == 0); z_sleep_s(SLEEP); @@ -292,7 +294,8 @@ int main(int argc, char **argv) { assert(z_check(_ret_pub)); z_publisher_put_options_t _ret_pput_opt = z_publisher_put_options_default(); - _ret_int8 = z_publisher_put(z_loan(_ret_pub), (const uint8_t *)value, strlen(value), &_ret_pput_opt); + payload = zc_payload_encode_from_string(value); + _ret_int8 = z_publisher_put(z_loan(_ret_pub), z_move(payload), &_ret_pput_opt); assert(_ret_int8 == 0); z_sleep_s(SLEEP); diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c new file mode 100644 index 000000000..10b1a3177 --- /dev/null +++ b/tests/z_api_payload_test.c @@ -0,0 +1,43 @@ +// +// 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, + +#include +#include +#include +#include + +#include "zenoh.h" + +#undef NDEBUG +#include + +void test_reader() { + uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + uint8_t data_out[10] = {0}; + z_bytes_t bytes = {.start = data, .len = 10 }; + + zc_owned_payload_t payload = zc_payload_encode_from_bytes(bytes); + zc_payload_reader reader; + zc_payload_reader_init(z_loan(payload), &reader); + assert(zc_payload_reader_remaining(&reader) == 10); + + zc_payload_reader_read(&reader, data_out, 5); + assert(zc_payload_reader_remaining(&reader) == 5); + zc_payload_reader_read(&reader, data_out, 5); + assert(zc_payload_reader_remaining(&reader) == 0); + assert(memcmp(data, data_out, 10)); +} + +int main(int argc, char **argv) { + test_reader(); +} diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 82c27b97f..03a6d893c 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -61,7 +61,8 @@ int run_publisher() { // values for cache for (int i = 0; i < values_count / 2; ++i) { - z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)values[i], strlen(values[i]), NULL); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } SEM_POST(sem_pub); @@ -70,7 +71,8 @@ int run_publisher() { // values for subscribe for (int i = values_count / 2; i < values_count; ++i) { - z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)values[i], strlen(values[i]), NULL); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } printf("wait: sem_sub\n"); @@ -85,14 +87,20 @@ int run_publisher() { void data_handler(const z_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - - ASSERT_STR_BYTES_EQUAL(values[val_num], sample->payload); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { + perror("Unexpected value received"); + z_drop(z_move(payload_value)); + exit(-1); + } + z_drop(z_move(payload_value)); printf("data_handler: %i\n", val_num); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index c7f502a59..ccb2c1e82 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -55,7 +55,8 @@ int run_publisher() { options.attachment = z_bytes_map_as_attachment(&map); for (int i = 0; i < values_count; ++i) { z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_VAR), z_bytes_from_str(values[i])); - z_publisher_put(z_loan(pub), (const uint8_t *)values[i], strlen(values[i]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); @@ -66,22 +67,26 @@ int run_publisher() { void data_handler(const z_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - if (strncmp(values[val_num], (const char *)sample->payload.start, (int)sample->payload.len)) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); + z_drop(z_move(payload_value)); exit(-1); } + z_drop(z_move(payload_value)); - z_bytes_t v_const = z_attachment_get(sample->attachment, z_bytes_from_str(K_CONST)); + z_bytes_t v_const = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_bytes_t v_var = z_attachment_get(sample->attachment, z_bytes_from_str(K_VAR)); + z_bytes_t v_var = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[val_num], v_var); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index cf005a80f..ad5969fa2 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -49,7 +49,8 @@ int run_publisher() { for (int i = 0; i < values_count; ++i) { z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_publisher_put(z_loan(pub), (const uint8_t *)values[i], strlen(values[i]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); @@ -59,21 +60,24 @@ int run_publisher() { void data_handler(const z_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - if (strncmp(values[val_num], (const char *)sample->payload.start, (int)sample->payload.len)) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); + z_drop(z_move(payload_value)); exit(-1); } + z_drop(z_move(payload_value)); - if (z_qos_get_congestion_control(sample->qos) != Z_CONGESTION_CONTROL_BLOCK - || z_qos_get_priority(sample->qos) != Z_PRIORITY_DATA - ) { + if (z_qos_get_congestion_control(z_sample_qos(sample)) != Z_CONGESTION_CONTROL_BLOCK || + z_qos_get_priority(z_sample_qos(sample)) != Z_PRIORITY_DATA) { perror("Unexpected QoS values"); exit(-1); } diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index ce1ac9f42..909da8c24 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -50,8 +50,8 @@ void query_handler(const z_query_t *query, void *context) { z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); options.attachment = z_bytes_map_as_attachment(&map); - z_query_reply(query, z_keyexpr((const char *)context), (const uint8_t *)values[value_num], - strlen(values[value_num]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[value_num]); + z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); z_drop(z_move(keystr)); z_drop(z_move(map)); @@ -109,14 +109,20 @@ int run_get() { assert(z_reply_is_ok(&reply)); z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); - - ASSERT_STR_BYTES_EQUAL(values[val_num], sample.payload); - - z_bytes_t v_const = z_attachment_get(sample.attachment, z_bytes_from_str(K_CONST)); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { + perror("Unexpected value received"); + z_drop(z_move(payload_value)); + exit(-1); + } + + z_bytes_t v_const = z_attachment_get(z_sample_attachment(&sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); + z_drop(z_move(payload_value)); } z_drop(z_move(reply)); z_drop(z_move(channel)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 2999451c4..3b3abad94 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -34,8 +34,8 @@ void query_handler(const z_query_t *query, void *context) { z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_query_reply(query, z_keyexpr((const char *)context), (const uint8_t *)values[value_num], - strlen(values[value_num]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[value_num]); + z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); z_drop(z_move(keystr)); if (++value_num == values_count) { @@ -85,11 +85,17 @@ int run_get() { assert(z_reply_is_ok(&reply)); z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); - - ASSERT_STR_BYTES_EQUAL(values[val_num], sample.payload); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { + perror("Unexpected value received"); + z_drop(z_move(payload_value)); + exit(-1); + } z_drop(z_move(keystr)); + z_drop(z_move(payload_value)); } z_drop(z_move(reply)); z_drop(z_move(channel));