VLink  2.1.0
A high-performance communication middleware
url.h
浏览该文件的文档.
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 url.h
26  * @brief URL-driven configuration dispatcher that selects and forwards to a transport @c Conf.
27  *
28  * @details
29  * This is an internal implementation header used by every public node template
30  * to translate a URL string into a concrete transport backend. It also re-exports
31  * all transport @c *Conf headers and the @c *Impl headers so the impl layer can
32  * be pulled in with a single include. Two types are introduced:
33  *
34  * @par Protocol
35  * A small plain-data struct populated by the @c UrlParser pipeline. It owns
36  * the URL string (after any @c VLINK_URL_REMAP rewriting) plus the resolved
37  * @c TransportType and the parsed host, path, query dictionary and fragment.
38  * Only @c Url may construct a @c Protocol -- the constructor is private and
39  * @c Url is its only friend.
40  *
41  * @par Url
42  * A concrete @c Conf subclass that wraps a @c Protocol, builds the matching
43  * transport @c Conf in @c init_target_internal() and forwards every virtual
44  * @c Conf hook to that target. Constructing a @c Url is the entry point used
45  * by every public Node<> template to set up its transport backend.
46  *
47  * @par Protocol struct fields
48  * | Field | Meaning |
49  * | -------------- | -------------------------------------------------------- |
50  * | @c str | Full URL string after any @c VLINK_URL_REMAP rewrite. |
51  * | @c transport | Resolved transport backend identifier. |
52  * | @c host | Hostname or IP component, if any. |
53  * | @c path | Topic path component. |
54  * | @c dictionary | Query parameters parsed into a @c std::map. |
55  * | @c fragment | Fragment identifier following @c #. |
56  *
57  * @par Transport prefix to backend
58  * | URL prefix | Conf class created in @c init_target_internal() |
59  * | ------------- | ----------------------------------------------- |
60  * | @c intra:// | @c IntraConf |
61  * | @c shm:// | @c ShmConf |
62  * | @c shm2:// | @c Shm2Conf |
63  * | @c zenoh:// | @c ZenohConf |
64  * | @c dds:// | @c DdsConf |
65  * | @c ddsc:// | @c DdscConf |
66  * | @c ddsr:// | @c DdsrConf |
67  * | @c someip:// | @c SomeipConf |
68  * | @c mqtt:// | @c MqttConf |
69  * | @c fdbus:// | @c FdbusConf |
70  * | other | Unsupported; custom schemes are not registered. |
71  *
72  * @par Construction flow
73  * @code
74  * URL string -> UrlParser -> Protocol -> init_target_internal() -> *Conf
75  * |
76  * v
77  * parse(impl_type)
78  * |
79  * v
80  * create_publisher() / create_subscriber() / ...
81  * |
82  * v
83  * NodeImpl backend instance
84  * @endcode
85  *
86  * @par URL Remapping
87  * When @c VLINK_URL_USE_REMAP is enabled, the @c Protocol constructor inspects
88  * the @c VLINK_URL_REMAP environment variable and rewrites the URL before the
89  * transport is resolved. This enables transport switching without touching
90  * application code.
91  *
92  * @par Plugin loading
93  * When @c VLINK_URL_USE_PLUGIN is enabled, the complete @c VLINK_URL_PLUGINS
94  * value selects one mutually exclusive mode. A case-insensitive value of
95  * @c auto lets @c Url::load_for_plugin() load the fixed @c vlink-<module>
96  * library for a recognized, unlinked transport on first use. An empty value or
97  * case-insensitive @c none disables plugin loading. Any other non-empty value is
98  * parsed as the explicit preload list used by @c Url::init_plugins(). Explicitly
99  * listed modules are loaded process-wide even when the first caller has that
100  * backend linked, because linked availability is a property of each caller's
101  * compilation target. The value
102  * is sampled when the process-wide plugin manager is first initialized; later
103  * environment changes have no effect. Linked backends keep precedence, and
104  * @c TransportType::kUnknown is never passed to plugins, so arbitrary URL
105  * schemes cannot be added through this mechanism.
106  *
107  * @par Transport enable flags
108  * @c TransportEnableFlag is a bitmask that selects which built-in transports participate in @c global_init().
109  * Embedding environments (Android, QNX, etc.) use it to skip transports they cannot support at runtime. The
110  * legacy parameter on @c init_plugins() is retained for source compatibility but does not filter the explicit
111  * preload list selected by @c VLINK_URL_PLUGINS.
112  *
113  * @par Example
114  * @code
115  * vlink::Url url("dds://vehicle/speed?domain=1");
116  *
117  * if (url.parse(vlink::kSubscriber)) {
118  * auto impl = url.get_target() != nullptr
119  * ? std::unique_ptr<vlink::SubscriberImpl>{}
120  * : nullptr;
121  * // Public Subscriber<T> template performs this call internally.
122  * auto sub = vlink::Subscriber<MyMsg>::create_unique(url.get_str());
123  * }
124  * @endcode
125  *
126  * @note This file is the single aggregation point for the VLink impl layer; it
127  * transitively includes every transport @c *_conf.h header and every
128  * @c *_impl.h header.
129  */
130 
131 #pragma once
132 
133 #include <map>
134 #include <memory>
135 #include <string>
136 #include <utility>
137 
138 #include "../base/logger.h"
139 #include "./conf.h"
140 
141 // NOLINTBEGIN
142 #include "../modules/dds_conf.h"
143 #include "../modules/ddsc_conf.h"
144 #include "../modules/ddsr_conf.h"
145 #include "../modules/fdbus_conf.h"
146 #include "../modules/intra_conf.h"
147 #include "../modules/mqtt_conf.h"
148 #include "../modules/shm2_conf.h"
149 #include "../modules/shm_conf.h"
150 #include "../modules/someip_conf.h"
151 #include "../modules/zenoh_conf.h"
152 //
153 #include "./client_impl.h"
154 #include "./getter_impl.h"
155 #include "./publisher_impl.h"
156 #include "./server_impl.h"
157 #include "./setter_impl.h"
158 #include "./subscriber_impl.h"
159 // NOLINTEND
160 
161 namespace vlink {
162 
163 /**
164  * @struct Protocol
165  * @brief Plain-data record describing the parsed components of a VLink URL.
166  *
167  * @details
168  * Built by @c Protocol(const std::string& address), which feeds the URL through
169  * @c UrlParser, applies any @c VLINK_URL_REMAP rewriting and resolves the
170  * @c TransportType from the URI scheme. Only @c Url may construct a
171  * @c Protocol (the constructor is private and @c Url is the sole friend).
172  *
173  * @note The @c str field is the URL string after remap, not a reconstruction
174  * from the other fields.
175  */
176 struct VLINK_EXPORT Protocol final {
177  std::string str; ///< URL string after remap, if any.
178  TransportType transport; ///< Resolved transport backend identifier.
179  std::string host; ///< Hostname or IP component, if any.
180  std::string path; ///< Topic path component.
181  std::map<std::string, std::string> dictionary; ///< Query parameters parsed into a key/value dictionary.
182  std::string fragment; ///< Fragment identifier (after @c #).
183 
184  private:
185  friend struct Url;
186  explicit Protocol(const std::string& address);
187 };
188 
189 /**
190  * @struct Url
191  * @brief @c Conf subclass that routes virtual calls to the transport selected by a URL string.
192  *
193  * @details
194  * Construction parses the URL into a @c Protocol and then runs
195  * @c init_target_internal() to instantiate the matching transport @c Conf
196  * (@c target_). Every @c Conf virtual hook is forwarded to @c target_; the
197  * caller need only build one @c Url instance per topic.
198  *
199  * @par Full lifecycle
200  * @code
201  * // 1. Construct with URL string:
202  * Url url("dds://vehicle/speed");
203  * // -> Protocol("dds://vehicle/speed") -> transport == kDds
204  * // -> init_target_internal() -> target_ = make_unique<DdsConf>()
205  *
206  * // 2. Parse for a specific node role:
207  * url.parse(kSubscriber);
208  * // -> target_->parse(kSubscriber)
209  * // -> target_->parse_protocol(&protocol_)
210  *
211  * // 3. Create the transport implementation:
212  * auto impl = url.create_subscriber();
213  * // -> target_->create_subscriber()
214  * @endcode
215  */
216 struct Url final : public Conf {
217  /**
218  * @enum TransportEnableFlag
219  * @brief Bitmask that selects which transports participate in @c global_init().
220  *
221  * @details
222  * Embedding environments (e.g. Android, QNX) pass a subset of these flags to
223  * skip transports they cannot support at runtime. Bit positions are
224  * independent of the numeric @c TransportType values.
225  *
226  * | Flag | Bit position | Transport |
227  * | ---------------- | ------------ | --------------- |
228  * | @c kEnableIntra | 15 | @c intra:// |
229  * | @c kEnableShm | 14 | @c shm:// |
230  * | @c kEnableShm2 | 13 | @c shm2:// |
231  * | @c kEnableZenoh | 12 | @c zenoh:// |
232  * | @c kEnableDds | 11 | @c dds:// |
233  * | @c kEnableDdsc | 10 | @c ddsc:// |
234  * | @c kEnableDdsr | 9 | @c ddsr:// |
235  * | @c kEnableSomeip | 7 | @c someip:// |
236  * | @c kEnableMqtt | 6 | @c mqtt:// |
237  * | @c kEnableFdbus | 5 | @c fdbus:// |
238  * | @c kEnableAll | all bits set | Every transport |
239  */
240  enum TransportEnableFlag : uint16_t {
241  kEnableEmpty = 0b0000'0000'0000'0000, ///< No transport enabled.
242  kEnableIntra = 0b1000'0000'0000'0000, ///< Enable the @c intra:// transport.
243  kEnableShm = 0b0100'0000'0000'0000, ///< Enable the @c shm:// (Iceoryx) transport.
244  kEnableShm2 = 0b0010'0000'0000'0000, ///< Enable the @c shm2:// (Iceoryx2) transport.
245  kEnableZenoh = 0b0001'0000'0000'0000, ///< Enable the @c zenoh:// transport.
246  kEnableDds = 0b0000'1000'0000'0000, ///< Enable the @c dds:// (Fast-DDS) transport.
247  kEnableDdsc = 0b0000'0100'0000'0000, ///< Enable the @c ddsc:// (CycloneDDS) transport.
248  kEnableDdsr = 0b0000'0010'0000'0000, ///< Enable the @c ddsr:// (RTI DDS) transport.
249  kEnableSomeip = 0b0000'0000'1000'0000, ///< Enable the @c someip:// transport.
250  kEnableMqtt = 0b0000'0000'0100'0000, ///< Enable the @c mqtt:// transport.
251  kEnableFdbus = 0b0000'0000'0010'0000, ///< Enable the @c fdbus:// transport.
252  kEnableAll = 0b1111'1111'1111'1111, ///< Enable every transport.
253  };
254 
255  /**
256  * @brief Builds a @c Url from a transport address string.
257  *
258  * @details
259  * Parses @p str into a @c Protocol, then delegates to
260  * @c init_target_internal() to allocate the matching transport @c Conf.
261  * Triggers a fatal log entry when no transport backend matches the URL.
262  *
263  * @param str VLink URL string (e.g. @c "dds://vehicle/speed").
264  */
265  explicit Url(const std::string& str);
266 
267  /**
268  * @brief Copy constructor.
269  *
270  * @details
271  * Copies the @c Protocol from @p url and rebuilds a fresh @c target_ via
272  * @c init_target_internal(), so the two @c Url objects do not share the
273  * same transport @c Conf instance.
274  *
275  * @param url Source @c Url to copy.
276  */
277  Url(const Url& url);
278 
279  /**
280  * @brief Move constructor.
281  *
282  * @details
283  * Transfers both @c protocol_ and @c target_ from @p url; no rebuild is
284  * performed.
285  *
286  * @param url Source @c Url to move from.
287  */
288  Url(Url&& url) noexcept;
289 
290  /**
291  * @brief Destructor.
292  */
293  ~Url() override;
294 
295  /**
296  * @brief Copy assignment.
297  *
298  * @details
299  * Copies @c protocol_ and re-runs @c init_target_internal() to rebuild
300  * @c target_.
301  *
302  * @param url Source @c Url.
303  * @return Reference to @c *this.
304  */
305  Url& operator=(const Url& url);
306 
307  /**
308  * @brief Move assignment.
309  *
310  * @param url Source @c Url.
311  * @return Reference to @c *this.
312  */
313  Url& operator=(Url&& url) noexcept;
314 
315  /**
316  * @brief Returns the stored URL string (after any @c VLINK_URL_REMAP rewrite).
317  *
318  * @return Reference to the string stored inside @c Protocol::str.
319  */
320  [[nodiscard]] const std::string& get_str() const;
321 
322  /**
323  * @brief Returns the underlying transport @c Conf or @c nullptr.
324  *
325  * @details
326  * Lets callers downcast the active transport conf for transport-specific
327  * inspection (for example to a @c DdsConf for native DDS QoS).
328  *
329  * @return Pointer to the cached transport @c Conf; @c nullptr when the URL
330  * was invalid or @c init_target_internal() failed.
331  */
332  [[nodiscard]] const Conf* get_target() const;
333 
334  /**
335  * @brief Parses the URL for @p impl_type by delegating to @c target_.
336  *
337  * @details
338  * Chains @c Conf::parse(impl_type), @c target_->parse(impl_type) and
339  * @c target_->parse_protocol(); returns @c false on @c target_ being null
340  * or any step failing.
341  *
342  * @param impl_type Bitmask of @c ImplType roles to validate.
343  * @return @c true when every step succeeds; @c false otherwise.
344  */
345  bool parse(ImplType impl_type) const override;
346 
347  /**
348  * @brief Reports whether the underlying @c target_ conf is valid.
349  *
350  * @return Result of @c target_->is_valid(), or @c false when @c target_ is null.
351  */
352  [[nodiscard]] bool is_valid() const override;
353 
354  /**
355  * @brief Returns the @c ImplType cached by the most recent @c target_->parse().
356  *
357  * @return Cached @c ImplType, or @c kUnknownImplType when @c target_ is null.
358  */
359  [[nodiscard]] ImplType get_impl_type() const override;
360 
361  /**
362  * @brief Returns the transport backend identifier resolved from the URL.
363  *
364  * @return @c TransportType value, or @c TransportType::kUnknown when no transport was resolved.
365  */
366  [[nodiscard]] TransportType get_transport_type() const override;
367 
368  /**
369  * @brief Explicitly preloads recognized transport plugins from @c VLINK_URL_PLUGINS.
370  *
371  * @details
372  * Unless its complete value is the case-insensitive mode @c auto or @c none,
373  * entries in @c VLINK_URL_PLUGINS must map to existing VLink transport module
374  * names such as @c zenoh or @c ddsc; unknown names are rejected before the
375  * shared library loader is called. This API loads alternate implementations
376  * for known transports, not arbitrary new URL schemes.
377  *
378  * Explicitly listed plugins are loaded process-wide even when the first caller
379  * has the same backend linked; the inline URL dispatcher still gives a caller's
380  * linked backend precedence. The first @c Url construction triggers this call
381  * automatically; explicit invocations are only needed for unusual initialisation
382  * sequences.
383  *
384  * Explicit preload, @c auto, and @c none are mutually exclusive modes of the
385  * complete setting. Mode names are case-insensitive and cannot be combined
386  * with a module list.
387  *
388  * @param transport_enable_flags Retained for source compatibility; explicit
389  * preload selection comes from @c VLINK_URL_PLUGINS.
390  */
391  VLINK_EXPORT static void init_plugins(uint16_t transport_enable_flags = 0);
392 
393  /**
394  * @brief Resolves a transport plugin and asks it for a @c Conf matching @p type.
395  *
396  * @details
397  * Looks up a preloaded or previously auto-loaded @c ConfPluginInterface whose
398  * @c get_transport_type() returns @p type. If none is registered and the
399  * complete @c VLINK_URL_PLUGINS value equals @c auto, ignoring case, the
400  * runtime tries the fixed @c vlink-<module> library for the recognized
401  * transport, validates the plugin-reported type, and invokes @c create().
402  * Empty and case-insensitive @c none values disable plugin loading; other
403  * non-empty values select explicit preload mode. The complete setting is
404  * sampled once when the process-wide plugin manager is first initialized.
405  *
406  * @param type Transport backend to look up.
407  * @return Newly created @c Conf, or @c nullptr for an unknown transport, a
408  * disabled or failed on-demand load, or when no plugin matches.
409  */
410  [[nodiscard]] VLINK_EXPORT static std::unique_ptr<Conf> load_for_plugin(TransportType type);
411 
412  /**
413  * @brief Returns a numeric sort index for the transport backend of @p url.
414  *
415  * @details
416  * Used to order URLs by transport priority. Local transports
417  * (@c intra://, @c shm://) yield lower indices than network transports.
418  * Empty URLs return @c -1, while non-empty URLs whose transport is unknown
419  * still return @c 0 so they can participate in low-priority sorting.
420  *
421  * @param url URL string to classify.
422  * @return Sort index; lower values mean higher priority.
423  */
424  [[nodiscard]] VLINK_EXPORT static int get_sort_index(std::string_view url);
425 
426  /**
427  * @brief Returns whether @p url designates a same-machine transport.
428  *
429  * @details
430  * A URL is local when it uses @c intra://, @c shm:// or @c shm2://.
431  *
432  * @param url URL string to classify.
433  * @return @c true for local transports; @c false for network ones.
434  */
435  [[nodiscard]] VLINK_EXPORT static bool is_local_type(std::string_view url);
436 
437  /**
438  * @brief Returns whether @p url designates the @c intra:// in-process transport.
439  *
440  * @param url URL string to classify.
441  * @return @c true only for @c intra:// URLs.
442  */
443  [[nodiscard]] VLINK_EXPORT static bool is_intra_type(std::string_view url);
444 
445  /**
446  * @brief Returns whether @p url uses a shared-memory transport.
447  *
448  * @param url URL string to classify.
449  * @return @c true for both @c shm:// and @c shm2:// URLs.
450  */
451  [[nodiscard]] VLINK_EXPORT static bool is_shm_type(std::string_view url);
452 
453  /**
454  * @brief Initialises the process-wide state for every enabled transport.
455  *
456  * @details
457  * Calls @c NodeImpl::global_init() first and then each @c *Conf::global_init()
458  * whose bit appears in @p transport_enable_flags. Passing @c 0 expands to
459  * all compiled-in transports. Must run once before any @c Url is created
460  * when fine-grained transport selection is required; otherwise the
461  * transports are lazily initialised on first use.
462  *
463  * @param transport_enable_flags Bitmask of @c TransportEnableFlag values.
464  */
465  static void global_init(uint16_t transport_enable_flags = 0);
466 
467  /**
468  * @brief Returns a bitmask of all compile-time-enabled transports.
469  *
470  * @details
471  * Computed from the @c VLINK_SUPPORT_* preprocessor flags. The result can
472  * be passed to @c global_init() to initialise the available transports
473  * exactly.
474  *
475  * @return Bitmask of @c TransportEnableFlag values.
476  */
477  [[nodiscard]] static uint16_t get_transport_enable_flags();
478 
479  /**
480  * @brief Builds @c target_ for the resolved transport in @p protocol.
481  *
482  * @details
483  * Switches on @c Protocol::transport, allocates the matching @c *Conf class,
484  * and falls back to @c load_for_plugin() when no built-in backend matches.
485  * That fallback may perform opt-in on-demand loading as documented above.
486  * Logs a fatal entry when neither path succeeds.
487  *
488  * @param protocol Parsed URL information used to select the transport.
489  * @param target Output: receives the newly created @c Conf instance.
490  */
491  static void init_target_internal(const Protocol& protocol, std::unique_ptr<Conf>& target);
492 
493  private:
494  std::unique_ptr<ServerImpl> create_server() const override;
495 
496  std::unique_ptr<ClientImpl> create_client() const override;
497 
498  std::unique_ptr<PublisherImpl> create_publisher() const override;
499 
500  std::unique_ptr<SubscriberImpl> create_subscriber() const override;
501 
502  std::unique_ptr<SetterImpl> create_setter() const override;
503 
504  std::unique_ptr<GetterImpl> create_getter() const override;
505 
506  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const Url& conf) noexcept;
507 
508  mutable Protocol protocol_;
509  std::unique_ptr<Conf> target_;
511  VLINK_ALLOW_IMPL_TYPE(kServer | kClient | kPublisher | kSubscriber | kSetter | kGetter);
512 };
513 
514 ////////////////////////////////////////////////////////////////
515 /// Details
516 ////////////////////////////////////////////////////////////////
517 
518 inline Url::Url(const std::string& str) : protocol_(str) { init_target_internal(protocol_, target_); }
519 
520 // NOLINTNEXTLINE(bugprone-copy-constructor-init)
521 inline Url::Url(const Url& url) : protocol_(url.protocol_) { init_target_internal(protocol_, target_); }
522 
523 inline Url::Url(Url&& url) noexcept : protocol_(std::move(url.protocol_)), target_(std::move(url.target_)) {}
524 
525 inline Url::~Url() = default;
526 
527 inline Url& Url::operator=(const Url& url) {
528  if VUNLIKELY (this == &url) {
529  return *this;
530  }
531 
532  protocol_ = url.protocol_;
533 
534  init_target_internal(protocol_, target_);
535 
536  return *this;
537 }
538 
539 inline Url& Url::operator=(Url&& url) noexcept {
540  if VUNLIKELY (this == &url) {
541  return *this;
542  }
543 
544  protocol_ = std::move(url.protocol_);
545  target_ = std::move(url.target_);
546 
547  return *this;
548 }
549 
550 inline const std::string& Url::get_str() const { return protocol_.str; }
551 
552 inline const Conf* Url::get_target() const { return target_.get(); }
553 
554 inline bool Url::parse(ImplType impl_type) const {
555  if VUNLIKELY (!target_) {
556  return false; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
557  }
558 
559  if VUNLIKELY (!Conf::parse(impl_type) || !target_->parse(impl_type)) {
560  return false; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
561  }
562 
563  return target_->parse_protocol(&protocol_);
564 }
565 
566 inline bool Url::is_valid() const {
567  if VUNLIKELY (!target_) {
568  return false; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
569  }
570 
571  return target_->is_valid();
572 }
573 
574 inline ImplType Url::get_impl_type() const {
575  if VUNLIKELY (!target_) {
576  return kUnknownImplType; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
577  }
578 
579  return target_->get_impl_type();
580 }
581 
583  if VUNLIKELY (!target_) {
584  return TransportType::kUnknown; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
585  }
586 
587  return target_->get_transport_type();
588 }
589 
590 inline void Url::global_init(uint16_t transport_enable_flags) {
591  if (transport_enable_flags == 0) {
592  transport_enable_flags = get_transport_enable_flags(); // LCOV_EXCL_LINE GCOVR_EXCL_LINE
593  }
594 
595  (void)transport_enable_flags;
596 
598 
599 #ifndef VLINK_ENABLE_C_INTERFACE
600 
601 #ifdef VLINK_SUPPORT_INTRA
602 
603  if (transport_enable_flags & kEnableIntra) {
604  IntraConf::global_init();
605  }
606 #endif
607 
608 #ifdef VLINK_SUPPORT_SHM
609 
610  if (transport_enable_flags & kEnableShm) {
611  ShmConf::global_init(); // LCOV_EXCL_LINE GCOVR_EXCL_LINE
612  }
613 #endif
614 
615 #ifdef VLINK_SUPPORT_SHM2
616 
617  if (transport_enable_flags & kEnableShm2) {
618  Shm2Conf::global_init(); // LCOV_EXCL_LINE GCOVR_EXCL_LINE
619  }
620 #endif
621 
622 #ifdef VLINK_SUPPORT_ZENOH
623 
624  if (transport_enable_flags & kEnableZenoh) {
625  ZenohConf::global_init(); // LCOV_EXCL_LINE GCOVR_EXCL_LINE
626  }
627 #endif
628 
629 #ifdef VLINK_SUPPORT_DDS
630 
631  if (transport_enable_flags & kEnableDds) {
632  DdsConf::global_init(); // LCOV_EXCL_LINE GCOVR_EXCL_LINE
633  }
634 #endif
635 
636 #ifdef VLINK_SUPPORT_DDSC
637 
638  if (transport_enable_flags & kEnableDdsc) {
639  DdscConf::global_init(); // LCOV_EXCL_LINE GCOVR_EXCL_LINE
640  }
641 #endif
642 
643 #ifdef VLINK_SUPPORT_DDSR
644 
645  if (transport_enable_flags & kEnableDdsr) {
646  DdsrConf::global_init();
647  }
648 #endif
649 
650 #ifdef VLINK_SUPPORT_SOMEIP
651 
652  if (transport_enable_flags & kEnableSomeip) {
653  SomeipConf::global_init(); // LCOV_EXCL_LINE GCOVR_EXCL_LINE
654  }
655 #endif
656 
657 #ifdef VLINK_SUPPORT_MQTT
658 
659  if (transport_enable_flags & kEnableMqtt) {
660  MqttConf::global_init(); // LCOV_EXCL_LINE GCOVR_EXCL_LINE
661  }
662 #endif
663 
664 #ifdef VLINK_SUPPORT_FDBUS
665 
666  if (transport_enable_flags & kEnableFdbus) {
667  FdbusConf::global_init(); // LCOV_EXCL_LINE GCOVR_EXCL_LINE
668  }
669 #endif
670 
671 #endif
672 }
673 
675  uint16_t flags = 0;
676 
677 #ifdef VLINK_SUPPORT_INTRA
678  flags |= kEnableIntra;
679 #endif
680 
681 #ifdef VLINK_SUPPORT_SHM
682  flags |= kEnableShm;
683 #endif
684 
685 #ifdef VLINK_SUPPORT_SHM2
686  flags |= kEnableShm2;
687 #endif
688 
689 #ifdef VLINK_SUPPORT_ZENOH
690  flags |= kEnableZenoh;
691 #endif
692 
693 #ifdef VLINK_SUPPORT_DDS
694  flags |= kEnableDds;
695 #endif
696 
697 #ifdef VLINK_SUPPORT_DDSC
698  flags |= kEnableDdsc;
699 #endif
700 
701 #ifdef VLINK_SUPPORT_DDSR
702  flags |= kEnableDdsr;
703 #endif
704 
705 #ifdef VLINK_SUPPORT_SOMEIP
706  flags |= kEnableSomeip;
707 #endif
708 
709 #ifdef VLINK_SUPPORT_MQTT
710  flags |= kEnableMqtt;
711 #endif
712 
713 #ifdef VLINK_SUPPORT_FDBUS
714  flags |= kEnableFdbus;
715 #endif
716 
717  return flags;
718 }
719 
720 inline void Url::init_target_internal(const Protocol& protocol, std::unique_ptr<Conf>& target) {
721  static auto transport_enable_flags = get_transport_enable_flags();
722 
723  Url::init_plugins(transport_enable_flags);
724 
725  // NOLINTBEGIN
726  switch (protocol.transport) {
727 #ifdef VLINK_SUPPORT_INTRA
729  target = std::make_unique<IntraConf>();
730  break;
731 #endif
732 
733 #ifdef VLINK_SUPPORT_SHM
734  case TransportType::kShm:
735  target = std::make_unique<ShmConf>();
736  break;
737 #endif
738 
739 #ifdef VLINK_SUPPORT_SHM2
741  target = std::make_unique<Shm2Conf>();
742  break;
743 #endif
744 
745 #ifdef VLINK_SUPPORT_ZENOH
747  target = std::make_unique<ZenohConf>();
748  break;
749 #endif
750 
751 #ifdef VLINK_SUPPORT_DDS
752  case TransportType::kDds:
753  target = std::make_unique<DdsConf>();
754  break;
755 #endif
756 
757 #ifdef VLINK_SUPPORT_DDSC
759  target = std::make_unique<DdscConf>();
760  break;
761 #endif
762 
763 #ifdef VLINK_SUPPORT_DDSR
765  target = std::make_unique<DdsrConf>();
766  break;
767 #endif
768 
769 #ifdef VLINK_SUPPORT_SOMEIP
771  target = std::make_unique<SomeipConf>();
772  break;
773 #endif
774 
775 #ifdef VLINK_SUPPORT_MQTT
777  target = std::make_unique<MqttConf>();
778  break;
779 #endif
780 
781 #ifdef VLINK_SUPPORT_FDBUS
783  target = std::make_unique<FdbusConf>();
784  break;
785 #endif
786 
787  default:
788  break;
789  }
790  // NOLINTEND
791 
792  if VUNLIKELY (!target) {
793  target = Url::load_for_plugin(protocol.transport);
794  }
795 
796  if VUNLIKELY (!target) {
797  CLOG_F("Unsupported url[%s].", protocol.str.c_str());
798  }
799 }
800 
801 inline std::unique_ptr<ServerImpl> Url::create_server() const {
802  if VUNLIKELY (!target_) {
803  return nullptr; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
804  }
805 
806  return target_->create_server();
807 }
808 
809 inline std::unique_ptr<ClientImpl> Url::create_client() const {
810  if VUNLIKELY (!target_) {
811  return nullptr; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
812  }
813 
814  return target_->create_client();
815 }
816 
817 inline std::unique_ptr<PublisherImpl> Url::create_publisher() const {
818  if VUNLIKELY (!target_) {
819  return nullptr; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
820  }
821 
822  return target_->create_publisher();
823 }
824 
825 inline std::unique_ptr<SubscriberImpl> Url::create_subscriber() const {
826  if VUNLIKELY (!target_) {
827  return nullptr; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
828  }
829 
830  return target_->create_subscriber();
831 }
832 
833 inline std::unique_ptr<SetterImpl> Url::create_setter() const {
834  if VUNLIKELY (!target_) {
835  return nullptr; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
836  }
837 
838  return target_->create_setter();
839 }
840 
841 inline std::unique_ptr<GetterImpl> Url::create_getter() const {
842  if VUNLIKELY (!target_) {
843  return nullptr; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
844  }
845 
846  return target_->create_getter();
847 }
848 
849 } // namespace vlink
Transport-neutral backbone shared by every method-model client implementation.
Transport-configuration base contract and the supporting boilerplate macros.
#define VLINK_DECLARE_CONF_FRIEND()
Macro Definitions
Definition: conf.h:225
Transport-neutral base for field-model getter (latest-value reader) implementations.
#define CLOG_F(...)
Definition: logger.h:855
#define VUNLIKELY(...)
Short alias for VLINK_UNLIKELY.
Definition: macros.h:289
#define VLINK_EXPORT
Definition: macros.h:81
Transport-neutral base class for every event-model publisher implementation.
Transport-neutral base class for every method-model server implementation.
Transport-neutral base class for every field-model setter (latest-value writer).
Transport-neutral base class for every event-model subscriber implementation.