VLink 2.0.0
A high-performance communication middleware
Loading...
Searching...
No Matches
types.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 by Thun Lu. All rights reserved.
3 * Author: Thun Lu <thun.lu@zohomail.cn>
4 * Repo: https://github.com/thun-res/vlink
5 * _ __ __ _ __
6 * | | / / / / (_) ____ / /__
7 * | | / / / / / / / __ \ / //_/
8 * | |/ / / /___ / / / / / / / ,<
9 * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24/**
25 * @file types.h
26 * @brief Core type definitions shared across all VLink node implementations.
27 *
28 * @details
29 * Defines the fundamental enumerations and plain-data structs that are used
30 * throughout the VLink implementation layer. These types are part of the
31 * internal ABI between the @c Node<> template, the transport @c Conf
32 * implementations, and the @c NodeImpl backend classes.
33 *
34 * @par Node Type Bitmask (@c ImplType)
35 * @c ImplType values can be bitwise-OR'd together when querying combined roles:
36 *
37 * | Value | Hex | Description |
38 * | ----------------- | ---- | --------------------------------- |
39 * | kUnknownImplType | 0x00 | Type not yet determined. |
40 * | kPublisher | 0x01 | Event publisher node. |
41 * | kSubscriber | 0x02 | Event subscriber node. |
42 * | kSetter | 0x04 | Field setter node. |
43 * | kGetter | 0x08 | Field getter node. |
44 * | kServer | 0x10 | Method server node. |
45 * | kClient | 0x20 | Method client node. |
46 *
47 * @par Transport Types (@c TransportType)
48 *
49 * | Value | URL Prefix | Transport |
50 * | -------- | ------------ | ------------------------------------ |
51 * | kUnknown | (none) | Unknown or unsupported. |
52 * | kIntra | intra:// | In-process queue (no serialisation). |
53 * | kShm | shm:// | Iceoryx shared memory. |
54 * | kShm2 | shm2:// | Iceoryx2 shared memory. |
55 * | kZenoh | zenoh:// | Zenoh publish/subscribe. |
56 * | kDds | dds:// | Fast-DDS RTPS. |
57 * | kDdsc | ddsc:// | CycloneDDS. |
58 * | kDdsr | ddsr:// | RTI DDS. |
59 * | kDdst | ddst:// | TravoDDS. |
60 * | kSomeip | someip:// | SOME/IP via vsomeip. |
61 * | kMqtt | mqtt:// | MQTT publish/subscribe. |
62 * | kFdbus | fdbus:// | FDBus IPC. |
63 * | kQnx | qnx:// | QNX IPC (QNX only). |
64 */
65
66#pragma once
67
68#include <chrono>
69#include <cstdint>
70#include <iostream>
71#include <string>
72#include <string_view>
73
74#include "../base/bytes.h"
75#include "../base/macros.h"
76
77namespace vlink {
78
79/**
80 * @enum ImplType
81 * @brief Bitmask identifying the role of a VLink node implementation.
82 *
83 * @details
84 * Values can be combined with bitwise-OR to represent compound roles, e.g.
85 * @c (kPublisher | kSubscriber) for a topic that has both publisher and
86 * subscriber endpoints. The @c VLINK_ALLOW_IMPL_TYPE macro uses these
87 * combined flags to restrict which node types a transport @c Conf may serve.
88 */
89enum ImplType : uint8_t {
90 kUnknownImplType = 0, ///< Type not yet determined.
91 kServer = 16, ///< Method server (RPC responder).
92 kClient = 32, ///< Method client (RPC caller).
93 kPublisher = 1, ///< Event publisher (N-to-N broadcast).
94 kSubscriber = 2, ///< Event subscriber (receive broadcast).
95 kSetter = 4, ///< Field setter (update latest value).
96 kGetter = 8, ///< Field getter (retrieve latest value).
97};
98
99/**
100 * @enum TransportType
101 * @brief Enumeration of all supported transport backends.
102 *
103 * @details
104 * Determined at URL construction time from the transport prefix string.
105 * Concrete transport @c Conf classes use this enum to identify themselves.
106 */
107enum class TransportType : uint8_t {
108 kUnknown = 0, ///< Unknown or unsupported transport.
109 kIntra = 1, ///< In-process queue (intra://).
110 kShm = 2, ///< Iceoryx shared memory (shm://).
111 kShm2 = 3, ///< Iceoryx2 shared memory (shm2://).
112 kZenoh = 4, ///< Zenoh publish/subscribe (zenoh://).
113 kDds = 5, ///< Fast-DDS RTPS (dds://).
114 kDdsc = 6, ///< CycloneDDS (ddsc://).
115 kDdsr = 7, ///< RTI DDS (ddsr://).
116 kDdst = 8, ///< TravoDDS (ddst://).
117 kSomeip = 9, ///< SOME/IP via vsomeip (someip://).
118 kMqtt = 10, ///< MQTT (mqtt://).
119 kFdbus = 11, ///< FDBus IPC (fdbus://).
120 kQnx = 12, ///< QNX IPC (qnx://; QNX only).
121};
122
123/**
124 * @enum InitType
125 * @brief Controls whether a node is initialised immediately at construction.
126 *
127 * @details
128 * Pass @c kWithoutInit to defer initialisation until @c init() is called
129 * explicitly, allowing properties (e.g. DDS QoS, IP binding) to be set
130 * before the underlying transport is started.
131 */
132enum class InitType : uint8_t {
133 kWithoutInit = 0, ///< Defer initialisation; call init() manually.
134 kWithInit = 1, ///< Initialise immediately in the constructor.
135};
136
137/**
138 * @enum SecurityType
139 * @brief Controls whether a node uses encrypted/authenticated transport.
140 *
141 * @details
142 * Selects the security variant at compile time via the template parameter
143 * of @c Publisher<T, SecurityType>, @c Subscriber<T, SecurityType>, etc.
144 * @c kWithSecurity enables AES-128-CBC encryption on the serialised message
145 * payload. Supported on all transports except @c intra:// and @c dds://
146 * with CDR serialisation, which trigger a fatal log if security is enabled.
147 */
148enum class SecurityType : uint8_t {
149 kWithoutSecurity = 0, ///< Plain (unauthenticated) transport.
150 kWithSecurity = 1, ///< Encrypted and authenticated transport.
151};
152
153/**
154 * @enum ActionType
155 * @brief Identifies the type of message action for recording purposes.
156 *
157 * @details
158 * Used by @c NodeImpl::try_record() to tag each captured message with its
159 * originating operation so that the bag writer can reconstruct message flow
160 * during playback.
161 */
162enum class ActionType : uint8_t {
163 kUnknownAction = 0, ///< Action type not classified.
164 kClientRequest = 1, ///< RPC request sent by a Client node.
165 kClientResponse = 2, ///< RPC response received by a Client node.
166 kServerRequest = 3, ///< RPC request received by a Server node.
167 kServerResponse = 4, ///< RPC response sent by a Server node.
168 kPublish = 5, ///< Message published by a Publisher node.
169 kSubscribe = 6, ///< Message received by a Subscriber node.
170 kSet = 7, ///< Field value written by a Setter node.
171 kGet = 8 ///< Field value read by a Getter node.
172};
173
174/**
175 * @enum SchemaType
176 * @brief Coarse runtime schema family used by discovery, bag metadata, and proxy routing.
177 *
178 * @details
179 * @c ser_type stores the concrete wire/type identifier (for example a protobuf
180 * full name or a FlatBuffers table name), while @c SchemaType captures only the
181 * high-level runtime decoding category so tools can choose the correct decode
182 * stack without maintaining a second parallel enum.
183 */
184enum class SchemaType : uint8_t {
185 kUnknown = 0, ///< Decode category is not known.
186 kRaw = 1, ///< Treat the payload as opaque/raw bytes.
187 kZeroCopy = 2, ///< Decode using VLink zero-copy message structs.
188 kProtobuf = 3, ///< Decode using the Protocol Buffers stack.
189 kFlatbuffers = 4, ///< Decode using the FlatBuffers stack.
190};
191
192/**
193 * @struct Timeout
194 * @brief Compile-time timeout constants used by blocking wait methods.
195 *
196 * @details
197 * Provides canonical timeout values used throughout the @c Publisher,
198 * @c Subscriber, @c Client, etc. public APIs for @c wait_for_* calls.
199 */
200struct Timeout final {
201 [[maybe_unused]] static constexpr std::chrono::milliseconds kDefaultInterval{
202 5'000}; ///< Default wait timeout: 5 seconds.
203 [[maybe_unused]] static constexpr std::chrono::milliseconds kInfinite{-1}; ///< Wait indefinitely (negative timeout).
204};
205
206/**
207 * @struct SampleLostInfo
208 * @brief Cumulative sample delivery statistics for a subscriber or getter.
209 *
210 * @details
211 * Populated by @c SubscriberImpl::get_lost() and @c GetterImpl::get_lost().
212 * The @c total field counts every message expected (both delivered and lost);
213 * @c lost counts those that were never delivered due to queue overflow or
214 * network loss.
215 * Supports streaming via @c operator<<.
216 */
217struct SampleLostInfo final {
218 uint64_t total{0}; ///< Total number of samples expected (delivered + lost).
219 uint64_t lost{0}; ///< Number of samples that were dropped or missed.
220
221 /**
222 * @brief Streams a human-readable summary to @p ostream.
223 *
224 * @details
225 * Format: @c "SampleLostInfo:[total]N[lost]M".
226 *
227 * @param ostream Output stream to write to.
228 * @param info Instance to print.
229 * @return Reference to @p ostream.
230 */
231 VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const SampleLostInfo& info) noexcept;
232};
233
234/**
235 * @struct SchemaData
236 * @brief Carries one serialized schema blob for runtime registration or embedding.
237 *
238 * @details
239 * Used by schema-aware tools such as bag readers, MCAP writers, and schema
240 * plugins to move imported schema metadata around without assuming a specific
241 * schema language. The @c encoding field stores the original schema payload
242 * encoding (for example @c "protobuf", @c "flatbuffers", or @c "vlink_msg"),
243 * while @c schema_type captures the coarse runtime family used by discovery,
244 * bag routing, and proxy consumers.
245 */
247 std::string name; ///< Schema subject name, typically a fully-qualified message or table type.
248 std::string encoding; ///< Schema encoding identifier (e.g. @c "protobuf" or @c "flatbuffers").
249 SchemaType schema_type{SchemaType::kUnknown}; ///< Coarse runtime schema family derived from @c encoding.
250 Bytes data; ///< Raw serialized schema bytes (e.g. FileDescriptorSet or BFBS).
251
252 /**
253 * @brief Returns whether a schema type enum value is within the supported range.
254 *
255 * @param schema_type Schema type value to validate.
256 * @return @c true when @p schema_type is a supported enum member.
257 */
258 [[nodiscard]] static bool is_valid_type(SchemaType schema_type) noexcept;
259
260 /**
261 * @brief Returns whether a schema type carries concrete runtime schema metadata.
262 *
263 * @details
264 * Unlike @c is_valid_type(), this excludes @c kUnknown and @c kRaw. It is
265 * used by schema caching / bag embedding code to decide whether a schema can
266 * be indexed or persisted as a real schema entry.
267 *
268 * @param schema_type Schema type value to classify.
269 * @return @c true for protobuf / flatbuffers / zerocopy families.
270 */
271 [[nodiscard]] static bool is_real_type(SchemaType schema_type) noexcept;
272
273 /**
274 * @brief Converts a schema type to its canonical persisted encoding label.
275 *
276 * @param schema_type Schema type to convert.
277 * @return Canonical encoding string, or an empty view for unknown values.
278 */
279 [[nodiscard]] static std::string_view convert_type(SchemaType schema_type) noexcept;
280
281 /**
282 * @brief Parses a schema type from an encoding label.
283 *
284 * @param encoding Encoding string such as @c "protobuf", @c "fbs", @c "blob", or @c "zerocopy".
285 * @return Matching schema type, or @c SchemaType::kUnknown.
286 */
287 [[nodiscard]] static SchemaType convert_encoding(std::string_view encoding) noexcept;
288
289 /**
290 * @brief Infers a coarse schema family directly from a concrete @c ser_type string.
291 *
292 * @details
293 * This lightweight constexpr helper is intentionally conservative:
294 * - zero-copy types are recognised by the @c "vlink::zerocopy::" prefix
295 * - textual/raw payload types map to @c SchemaType::kRaw
296 * - protobuf / flatbuffers are not guessed from names here
297 *
298 * @param ser_type Concrete serialisation type string.
299 * @return Matching schema family, or @c SchemaType::kUnknown.
300 */
301 [[nodiscard]] static constexpr SchemaType infer_ser_type(std::string_view ser_type) noexcept;
302
303 /**
304 * @brief Resolves the best available schema family from explicit, encoding and ser hints.
305 *
306 * @details
307 * Resolution order is:
308 * 1. explicit @p schema_type when already known
309 * 2. inferred family from @p encoding
310 * 3. inferred family from @p ser_type
311 *
312 * @param schema_type Explicit schema family hint.
313 * @param ser_type Concrete serialisation type string.
314 * @param encoding Persisted schema encoding label.
315 * @return Best-effort resolved schema family, or @c SchemaType::kUnknown.
316 */
317 [[nodiscard]] static SchemaType resolve_type(SchemaType schema_type, std::string_view ser_type = {},
318 std::string_view encoding = {}) noexcept;
319};
320
321/**
322 * @struct Version
323 * @brief Semantic version number with comparison and string conversion utilities.
324 *
325 * @details
326 * Used by @c NodeImpl::check_version() to compare the compile-time VLink version
327 * against the runtime library version. All fields default to @c -1 (invalid).
328 */
329struct VLINK_EXPORT Version final {
330 int major{-1}; ///< Major version number; -1 if not set.
331 int minor{-1}; ///< Minor version number; -1 if not set.
332 int patch{-1}; ///< Patch version number; -1 if not set.
333
334 /**
335 * @brief Returns @c true when both versions are identical.
336 *
337 * @param target Version to compare against.
338 * @return @c true if major, minor, and patch are all equal.
339 */
340 [[nodiscard]] bool operator==(const Version& target) const noexcept;
341
342 /**
343 * @brief Returns @c true when versions differ.
344 *
345 * @param target Version to compare against.
346 * @return Logical negation of @c operator==.
347 */
348 [[nodiscard]] bool operator!=(const Version& target) const noexcept;
349
350 /**
351 * @brief Returns @c true when this version is older than @p target.
352 *
353 * @details
354 * Compares major first, then minor, then patch (numeric order).
355 *
356 * @param target Version to compare against.
357 * @return @c true if this version is strictly less than @p target.
358 */
359 [[nodiscard]] bool operator<(const Version& target) const noexcept;
360
361 /**
362 * @brief Returns @c true when this version is newer than @p target.
363 *
364 * @param target Version to compare against.
365 * @return @c true if this version is strictly greater than @p target.
366 */
367 [[nodiscard]] bool operator>(const Version& target) const noexcept;
368
369 /**
370 * @brief Parses a version string in @c "major.minor.patch" format.
371 *
372 * @details
373 * Uses @c std::from_chars for each component; components missing from the
374 * string remain @c -1.
375 *
376 * @param version_str String such as @c "2.1.0".
377 * @return Parsed @c Version; any missing component stays @c -1.
378 */
379 [[nodiscard]] static Version from_string(const std::string& version_str) noexcept;
380
381 /**
382 * @brief Converts this version to a @c "major.minor.patch" string.
383 *
384 * @return Formatted version string, e.g. @c "2.1.0".
385 */
386 [[nodiscard]] std::string to_string() const noexcept;
387
388 /**
389 * @brief Returns @c true when all three components are non-negative.
390 *
391 * @return @c true if the version was successfully parsed or explicitly set.
392 */
393 [[nodiscard]] bool is_valid() const noexcept;
394};
395
396////////////////////////////////////////////////////////////////
397/// Details
398////////////////////////////////////////////////////////////////
399
400constexpr SchemaType SchemaData::infer_ser_type(std::string_view ser_type) noexcept {
401 constexpr auto kHasPrefixFunction = [](std::string_view value, std::string_view prefix) noexcept {
402 if (prefix.size() > value.size()) {
403 return false;
404 }
405
406 for (size_t i = 0; i < prefix.size(); ++i) {
407 if (value[i] != prefix[i]) {
408 return false;
409 }
410 }
411
412 return true;
413 };
414
415 if (kHasPrefixFunction(ser_type, "vlink::zerocopy::")) {
417 }
418
419 if (ser_type == "raw" || ser_type == "string" || ser_type == "std::string" || ser_type == "text" ||
420 ser_type == "json" || ser_type == "application/json" || ser_type == "text/json") {
421 return SchemaType::kRaw;
422 }
423
425}
426
427} // namespace vlink
Versatile byte buffer with small-buffer optimisation, ownership semantics and compression.
Platform-independent macro definitions for the VLink library.
#define VLINK_EXPORT
Definition macros.h:85
STL namespace.