LCOV - code coverage report
Current view: top level - src/impl - url.cc (source / functions) Hit Total Coverage
Test: vlink Lines: 192 201 95.5 %
Date: 2026-09-30 18:30:16 Functions: 30 31 96.8 %
Branches: 197 285 69.1 %

           Branch data     Line data    Source code
       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                 :            : #include "./impl/url.h"
      25                 :            : 
      26                 :            : #include <algorithm>
      27                 :            : #include <atomic>
      28                 :            : #include <cctype>
      29                 :            : #include <map>
      30                 :            : #include <memory>
      31                 :            : #include <mutex>
      32                 :            : #include <new>
      33                 :            : #include <shared_mutex>
      34                 :            : #include <string>
      35                 :            : #include <string_view>
      36                 :            : #include <unordered_map>
      37                 :            : #include <utility>
      38                 :            : 
      39                 :            : #include "./base/helpers.h"
      40                 :            : #include "./base/plugin.h"
      41                 :            : #include "./base/utils.h"
      42                 :            : #include "./extension/url_remap.h"
      43                 :            : #include "./impl/conf_plugin_interface.h"
      44                 :            : #include "./impl/url_parser.h"
      45                 :            : 
      46                 :            : #define VLINK_URL_USE_REMAP 1
      47                 :            : #define VLINK_URL_USE_PLUGIN 1
      48                 :            : 
      49                 :            : namespace vlink {
      50                 :            : 
      51                 :            : [[maybe_unused]] static constexpr uint16_t kMaxUrlLength = 120U;
      52                 :            : 
      53                 :         68 : [[maybe_unused]] inline static bool equals_ignore_case(std::string_view left, std::string_view right) noexcept {
      54   [ +  +  +  + ]:         73 :   return left.size() == right.size() &&
      55                 :          5 :          std::equal(left.begin(), left.end(), right.begin(), [](unsigned char left_char, unsigned char right_char) {
      56                 :         17 :            return std::tolower(left_char) == std::tolower(right_char);
      57                 :         68 :          });
      58                 :            : }
      59                 :            : 
      60                 :        666 : [[maybe_unused]] inline static TransportType get_transport_for_str(const std::string& str) noexcept {
      61         [ +  + ]:        666 :   if (str == "intra") {
      62                 :        288 :     return TransportType::kIntra;
      63                 :            :   }
      64                 :            : 
      65                 :            : #if !defined(__ANDROID__)
      66                 :            : 
      67         [ +  + ]:        378 :   if (str == "shm") {
      68                 :         98 :     return TransportType::kShm;
      69                 :            :   }
      70                 :            : 
      71         [ +  + ]:        280 :   if (str == "shm2") {
      72                 :          1 :     return TransportType::kShm2;
      73                 :            :   }
      74                 :            : #endif
      75                 :            : 
      76         [ +  + ]:        279 :   if (str == "zenoh") {
      77                 :          1 :     return TransportType::kZenoh;
      78                 :            :   }
      79                 :            : 
      80   [ +  +  -  +  :        278 :   if (str == "dds" || str == "ddsf") {
                   +  + ]
      81                 :        144 :     return TransportType::kDds;
      82                 :            :   }
      83                 :            : 
      84         [ +  + ]:        134 :   if (str == "ddsc") {
      85                 :         99 :     return TransportType::kDdsc;
      86                 :            :   }
      87                 :            : 
      88         [ +  + ]:         35 :   if (str == "ddsr") {
      89                 :          1 :     return TransportType::kDdsr;
      90                 :            :   }
      91                 :            : 
      92         [ +  + ]:         34 :   if (str == "someip") {
      93                 :          1 :     return TransportType::kSomeip;
      94                 :            :   }
      95                 :            : 
      96         [ +  + ]:         33 :   if (str == "mqtt") {
      97                 :          1 :     return TransportType::kMqtt;
      98                 :            :   }
      99                 :            : 
     100         [ +  + ]:         32 :   if (str == "fdbus") {
     101                 :          1 :     return TransportType::kFdbus;
     102                 :            :   }
     103                 :            : 
     104                 :         31 :   return TransportType::kUnknown;
     105                 :            : }
     106                 :            : 
     107                 :          1 : [[maybe_unused]] inline static TransportType get_dds_transport_for_str(const std::string& str) noexcept {
     108   [ +  -  -  +  :          1 :   if (str == "dds" || str == "ddsf") {
                   -  + ]
     109                 :          0 :     return TransportType::kDds;
     110                 :            :   }
     111                 :            : 
     112         [ +  - ]:          1 :   if (str == "ddsc") {
     113                 :          1 :     return TransportType::kDdsc;
     114                 :            :   }
     115                 :            : 
     116         [ #  # ]:          0 :   if (str == "ddsr") {
     117                 :          0 :     return TransportType::kDdsr;
     118                 :            :   }
     119                 :            : 
     120                 :          0 :   return TransportType::kUnknown;
     121                 :            : }
     122                 :            : 
     123                 :        659 : [[maybe_unused]] inline static bool is_dds_type(const TransportType& transport) noexcept {
     124   [ +  +  +  +  :        659 :   return transport == TransportType::kDds || transport == TransportType::kDdsc || transport == TransportType::kDdsr;
                   +  + ]
     125                 :            : }
     126                 :            : 
     127                 :         23 : [[maybe_unused]] inline static const char* get_module_for_transport(TransportType type) noexcept {
     128   [ +  +  +  +  :         23 :   switch (type) {
          +  +  +  +  +  
                   +  - ]
     129                 :          5 :     case TransportType::kIntra:
     130                 :          5 :       return "intra";
     131                 :            : 
     132                 :            : #if !defined(__ANDROID__)
     133                 :            : 
     134                 :          2 :     case TransportType::kShm:
     135                 :          2 :       return "shm";
     136                 :            : 
     137                 :          2 :     case TransportType::kShm2:
     138                 :          2 :       return "shm2";
     139                 :            : #endif
     140                 :            : 
     141                 :          2 :     case TransportType::kZenoh:
     142                 :          2 :       return "zenoh";
     143                 :            : 
     144                 :          2 :     case TransportType::kDds:
     145                 :          2 :       return "dds";
     146                 :            : 
     147                 :          2 :     case TransportType::kDdsc:
     148                 :          2 :       return "ddsc";
     149                 :            : 
     150                 :          2 :     case TransportType::kDdsr:
     151                 :          2 :       return "ddsr";
     152                 :            : 
     153                 :          2 :     case TransportType::kSomeip:
     154                 :          2 :       return "someip";
     155                 :            : 
     156                 :          2 :     case TransportType::kMqtt:
     157                 :          2 :       return "mqtt";
     158                 :            : 
     159                 :          2 :     case TransportType::kFdbus:
     160                 :          2 :       return "fdbus";
     161                 :            : 
     162                 :          0 :     default:
     163                 :            :       return nullptr;  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     164                 :            :   }
     165                 :            : }
     166                 :            : 
     167                 :         15 : [[maybe_unused]] inline static bool is_intra_url(std::string_view url) noexcept {
     168                 :         15 :   return Helpers::has_startwith(url, "intra://");
     169                 :            : }
     170                 :            : 
     171                 :         15 : [[maybe_unused]] inline static bool is_shm_url(std::string_view url) noexcept {
     172   [ +  +  +  + ]:         15 :   return Helpers::has_startwith(url, "shm://") || Helpers::has_startwith(url, "shm2://");
     173                 :            : }
     174                 :            : 
     175                 :        696 : [[maybe_unused]] inline static int get_sort_index_for_url(std::string_view url) {
     176         [ +  + ]:        696 :   if (url.empty()) {
     177                 :          3 :     return -1;
     178                 :            :   }
     179                 :            : 
     180         [ +  + ]:        693 :   if (Helpers::has_startwith(url, "intra://")) {
     181                 :        101 :     return static_cast<int>(TransportType::kIntra);
     182                 :            :   }
     183                 :            : 
     184                 :            : #if !defined(__ANDROID__)
     185                 :            : 
     186         [ +  + ]:        592 :   if (Helpers::has_startwith(url, "shm://")) {
     187                 :         41 :     return static_cast<int>(TransportType::kShm);
     188                 :            :   }
     189                 :            : 
     190         [ +  + ]:        551 :   if (Helpers::has_startwith(url, "shm2://")) {
     191                 :          2 :     return static_cast<int>(TransportType::kShm2);
     192                 :            :   }
     193                 :            : #endif
     194                 :            : 
     195         [ +  + ]:        549 :   if (Helpers::has_startwith(url, "zenoh://")) {
     196                 :          3 :     return static_cast<int>(TransportType::kZenoh);
     197                 :            :   }
     198                 :            : 
     199   [ +  +  +  +  :        546 :   if (Helpers::has_startwith(url, "dds://") || Helpers::has_startwith(url, "ddsf://")) {
                   +  + ]
     200                 :        509 :     return static_cast<int>(TransportType::kDds);
     201                 :            :   }
     202                 :            : 
     203         [ +  + ]:         37 :   if (Helpers::has_startwith(url, "ddsc://")) {
     204                 :         29 :     return static_cast<int>(TransportType::kDdsc);
     205                 :            :   }
     206                 :            : 
     207         [ +  + ]:          8 :   if (Helpers::has_startwith(url, "ddsr://")) {
     208                 :          1 :     return static_cast<int>(TransportType::kDdsr);
     209                 :            :   }
     210                 :            : 
     211         [ +  + ]:          7 :   if (Helpers::has_startwith(url, "someip://")) {
     212                 :          2 :     return static_cast<int>(TransportType::kSomeip);
     213                 :            :   }
     214                 :            : 
     215         [ +  + ]:          5 :   if (Helpers::has_startwith(url, "mqtt://")) {
     216                 :          1 :     return static_cast<int>(TransportType::kMqtt);
     217                 :            :   }
     218                 :            : 
     219         [ +  + ]:          4 :   if (Helpers::has_startwith(url, "fdbus://")) {
     220                 :          2 :     return static_cast<int>(TransportType::kFdbus);
     221                 :            :   }
     222                 :            : 
     223                 :          2 :   return 0;
     224                 :            : }
     225                 :            : 
     226                 :            : // GlobalModulesManager
     227                 :            : class GlobalModulesManager final {
     228                 :            :  public:
     229                 :        106 :   static GlobalModulesManager& get() {
     230   [ +  +  +  +  :        106 :     static GlobalModulesManager manager;
             +  -  -  - ]
     231                 :        106 :     return manager;
     232                 :            :   }
     233                 :            : 
     234                 :         45 :   std::shared_ptr<ConfPluginInterface> get_or_load_interface(TransportType type) {
     235                 :            :     {
     236         [ +  - ]:         45 :       std::shared_lock lock(mtx_);
     237                 :            : 
     238         [ +  - ]:         45 :       auto iter = ptr_map_.find(type);
     239                 :            : 
     240         [ +  + ]:         44 :       if VLIKELY (iter != ptr_map_.end()) {
     241                 :          9 :         return iter->second;
     242                 :            :       }
     243         [ +  + ]:         44 :     }
     244                 :            : 
     245         [ +  + ]:         36 :     if VLIKELY (!plugin_autoload_enabled_) {
     246                 :         13 :       return nullptr;
     247                 :            :     }
     248                 :            : 
     249                 :         23 :     const char* module_name = get_module_for_transport(type);
     250                 :            : 
     251         [ -  + ]:         23 :     if VUNLIKELY (module_name == nullptr) {
     252                 :            :       return nullptr;  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     253                 :            :     }
     254                 :            : 
     255         [ +  - ]:         23 :     std::lock_guard lock(mtx_);
     256                 :            : 
     257         [ +  - ]:         23 :     auto iter = ptr_map_.find(type);
     258                 :            : 
     259         [ +  + ]:         23 :     if VUNLIKELY (iter != ptr_map_.end()) {
     260                 :            :       return iter->second;  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     261                 :            :     }
     262                 :            : 
     263   [ +  -  +  - ]:         42 :     const std::string lib_name = std::string("vlink-") + module_name;
     264   [ +  -  +  -  :         42 :     auto ptr = plugin_.load<ConfPluginInterface>(lib_name, 1, 0);
             +  -  +  - ]
     265                 :            : 
     266         [ +  + ]:         21 :     if VUNLIKELY (!ptr) {
     267                 :         12 :       return nullptr;
     268                 :            :     }
     269                 :            : 
     270         [ +  - ]:          9 :     const auto plugin_type = ptr->get_transport_type();
     271                 :            : 
     272                 :            :     // LCOV_EXCL_START GCOVR_EXCL_START
     273                 :            :     if VUNLIKELY (plugin_type != type) {
     274                 :            :       VLOG_E("Plugin transport mismatch, libname: ", lib_name, ", expected: ", static_cast<int>(type),
     275                 :            :              ", actual: ", static_cast<int>(plugin_type), ".");
     276                 :            :       (void)plugin_.unload<ConfPluginInterface>(lib_name);
     277                 :            :       return nullptr;
     278                 :            :     }
     279                 :            :     // LCOV_EXCL_STOP GCOVR_EXCL_STOP
     280                 :            : 
     281         [ +  - ]:          9 :     return ptr_map_.emplace(type, std::move(ptr)).first->second;
     282                 :         23 :   }
     283                 :            : 
     284                 :         61 :   void init(uint16_t transport_enable_flags) {
     285                 :            :     (void)transport_enable_flags;
     286                 :            : 
     287   [ +  +  +  +  :         61 :     if VLIKELY (url_plugins_env_.empty() || plugin_autoload_enabled_ || equals_ignore_case(url_plugins_env_, "none")) {
          +  +  +  +  +  
                      + ]
     288                 :         57 :       return;
     289                 :            :     }
     290                 :            : 
     291                 :          4 :     auto plugins_list = Helpers::split_any(url_plugins_env_);
     292                 :            : 
     293         [ +  - ]:          4 :     std::lock_guard lock(mtx_);
     294                 :            : 
     295                 :            :     // plugin_.set_log_level(Logger::kWarn);
     296                 :            : 
     297   [ +  -  +  + ]:         10 :     for (auto libname : plugins_list) {
     298   [ +  -  +  - ]:          6 :       Helpers::replace_string(libname, "vlink-", "");
     299                 :            : 
     300                 :          6 :       const auto expected_type = get_transport_for_str(libname);
     301                 :            : 
     302         [ +  + ]:          6 :       if VUNLIKELY (expected_type == TransportType::kUnknown) {
     303   [ +  -  +  -  :          4 :         VLOG_E("Unsupported plugin module, libname: ", libname, ".");
                   +  - ]
     304                 :          2 :         continue;
     305                 :          2 :       }
     306                 :            : 
     307         [ +  - ]:          4 :       const std::string plugin_lib_name = "vlink-" + libname;
     308   [ +  -  +  -  :          8 :       auto ptr = plugin_.load<ConfPluginInterface>(plugin_lib_name, 1, 0);
             +  -  +  - ]
     309                 :            : 
     310         [ +  - ]:          4 :       if VLIKELY (ptr) {
     311         [ +  - ]:          4 :         const auto plugin_type = ptr->get_transport_type();
     312                 :            : 
     313                 :            :         // LCOV_EXCL_START GCOVR_EXCL_START
     314                 :            :         if VUNLIKELY (plugin_type != expected_type) {
     315                 :            :           VLOG_E("Plugin transport mismatch, libname: ", plugin_lib_name,
     316                 :            :                  ", expected: ", static_cast<int>(expected_type), ", actual: ", static_cast<int>(plugin_type), ".");
     317                 :            :           (void)plugin_.unload<ConfPluginInterface>(plugin_lib_name);
     318                 :            :           continue;
     319                 :            :         }
     320                 :            :         // LCOV_EXCL_STOP GCOVR_EXCL_STOP
     321                 :            : 
     322         [ +  - ]:          4 :         ptr_map_.emplace(expected_type, std::move(ptr));
     323                 :            :       }
     324   [ +  -  +  -  :          6 :     }
                   +  + ]
     325                 :          4 :   }
     326                 :            : 
     327                 :            :  private:
     328                 :         63 :   GlobalModulesManager()
     329   [ +  -  +  - ]:         63 :       : url_plugins_env_(Utils::get_env("VLINK_URL_PLUGINS")),
     330         [ +  - ]:         63 :         plugin_autoload_enabled_(equals_ignore_case(url_plugins_env_, "auto")) {}
     331                 :            : 
     332                 :        126 :   ~GlobalModulesManager() {
     333                 :            : #ifdef _WIN32
     334                 :            :     if (Utils::is_terminating()) {
     335                 :            :       (void)::new (std::nothrow) auto(std::move(ptr_map_));
     336                 :            :       return;
     337                 :            :     }
     338                 :            : #endif
     339                 :            : 
     340                 :         63 :     std::lock_guard lock(mtx_);
     341                 :         63 :     ptr_map_.clear();
     342                 :         63 :     plugin_.clear();
     343                 :         63 :   }
     344                 :            : 
     345                 :            :   const std::string url_plugins_env_;
     346                 :            :   const bool plugin_autoload_enabled_{false};
     347                 :            :   Plugin plugin_;
     348                 :            :   std::unordered_map<TransportType, std::shared_ptr<ConfPluginInterface>> ptr_map_;
     349                 :            :   mutable std::shared_mutex mtx_;
     350                 :            : 
     351                 :            :   VLINK_DISALLOW_COPY_AND_ASSIGN(GlobalModulesManager)
     352                 :            : };
     353                 :            : 
     354                 :            : // GlobalUrlRemap
     355                 :            : class GlobalUrlRemap final : public UrlRemap {
     356                 :            :  public:
     357                 :        662 :   static GlobalUrlRemap& get() {
     358   [ +  +  +  -  :        662 :     static GlobalUrlRemap remap;
             +  -  -  - ]
     359                 :        662 :     return remap;
     360                 :            :   }
     361                 :            : 
     362                 :        662 :   std::string convert_thread_safe(const std::string& url) noexcept {
     363                 :        662 :     std::lock_guard lock(mtx_);
     364                 :        662 :     return convert(url);
     365                 :        662 :   }
     366                 :            : 
     367                 :            :  private:
     368                 :         52 :   GlobalUrlRemap() {
     369   [ +  -  +  - ]:         52 :     const auto& url_remap_env = Utils::get_env("VLINK_URL_REMAP", "");
     370                 :            : 
     371         [ +  - ]:         52 :     if (url_remap_env.empty()) {
     372                 :         52 :       return;
     373                 :            :     }
     374                 :            : 
     375                 :          0 :     set_enable_log(true);
     376                 :            : 
     377                 :          0 :     load(url_remap_env);
     378         [ -  + ]:         52 :   }
     379                 :            : 
     380                 :         52 :   ~GlobalUrlRemap() = default;
     381                 :            : 
     382                 :            :   std::mutex mtx_;
     383                 :            : 
     384                 :            :   VLINK_DISALLOW_COPY_AND_ASSIGN(GlobalUrlRemap)
     385                 :            : };
     386                 :            : 
     387                 :            : // Protocol
     388                 :        662 : Protocol::Protocol(const std::string& address) {
     389         [ -  + ]:        662 :   if VUNLIKELY (address.length() > kMaxUrlLength) {
     390   [ #  #  #  #  :          0 :     CLOG_F("The URL length exceeds the character limit (Target length: %zu, Max length: %u).", address.length(),
                   #  # ]
     391                 :            :            kMaxUrlLength);
     392                 :          0 :     return;
     393                 :            :   }
     394                 :            : 
     395                 :            : #if VLINK_URL_USE_REMAP
     396         [ +  - ]:        662 :   std::string real_address = GlobalUrlRemap::get().convert_thread_safe(address);
     397                 :            : 
     398         [ +  + ]:        662 :   UrlParser parser(real_address);
     399                 :        659 :   str = std::move(real_address);
     400                 :            : #else
     401                 :            :   UrlParser parser(address);
     402                 :            :   str = address;
     403                 :            : #endif
     404                 :            : 
     405         [ +  - ]:        659 :   transport = get_transport_for_str(parser.get_transport());
     406                 :            : 
     407         [ +  + ]:        659 :   if (is_dds_type(transport)) {
     408   [ +  -  +  - ]:        484 :     const auto dds_bind_transport_str = Utils::get_env("VLINK_DDS_BIND", "");
     409                 :            : 
     410         [ +  + ]:        242 :     if VUNLIKELY (!dds_bind_transport_str.empty()) {
     411                 :          1 :       TransportType dds_bind_transport = get_dds_transport_for_str(dds_bind_transport_str);
     412                 :            : 
     413         [ +  - ]:          1 :       if VLIKELY (dds_bind_transport != TransportType::kUnknown) {
     414                 :            :         static std::atomic_bool dds_bind_print{false};
     415                 :            : 
     416         [ +  - ]:          1 :         if (!dds_bind_print.exchange(true, std::memory_order_relaxed)) {
     417   [ +  -  +  -  :          2 :           CLOG_I("Bind [dds] to [%s].", dds_bind_transport_str.c_str());
                   +  - ]
     418                 :            :         }
     419                 :            : 
     420                 :          1 :         transport = dds_bind_transport;
     421                 :            :       }
     422                 :            :     }
     423         [ +  + ]:        659 :   } else if (transport == TransportType::kIntra) {
     424   [ +  -  +  - ]:        570 :     const auto intra_bind_transport_str = Utils::get_env("VLINK_INTRA_BIND", "");
     425                 :            : 
     426         [ +  + ]:        285 :     if (!intra_bind_transport_str.empty()) {
     427                 :          1 :       TransportType intra_bind_transport = get_transport_for_str(intra_bind_transport_str);
     428                 :            : 
     429   [ +  -  +  -  :          1 :       if VLIKELY (intra_bind_transport != TransportType::kIntra && intra_bind_transport != TransportType::kUnknown) {
                   +  - ]
     430                 :            :         static std::atomic_bool intra_bind_print{false};
     431                 :            : 
     432         [ +  - ]:          1 :         if (!intra_bind_print.exchange(true, std::memory_order_relaxed)) {
     433   [ +  -  +  -  :          2 :           CLOG_I("Bind [intra] to [%s].", intra_bind_transport_str.c_str());
                   +  - ]
     434                 :            :         }
     435                 :            : 
     436                 :          1 :         transport = intra_bind_transport;
     437                 :            :       }
     438                 :            :     }
     439                 :        285 :   }
     440                 :            : 
     441         [ +  - ]:        659 :   host = std::move(const_cast<std::string&>(parser.get_host()));
     442         [ +  - ]:        659 :   path = std::move(const_cast<std::string&>(parser.get_path()));
     443         [ +  - ]:        659 :   dictionary = std::move(const_cast<std::map<std::string, std::string>&>(parser.get_query_dictionary()));
     444         [ +  - ]:        659 :   fragment = std::move(const_cast<std::string&>(parser.get_fragment()));
     445                 :        677 : }
     446                 :            : 
     447                 :            : // Url
     448                 :        670 : void Url::init_plugins(uint16_t transport_enable_flags) {
     449                 :            : #if VLINK_URL_USE_PLUGIN
     450   [ +  +  +  -  :        670 :   static auto& manager_instance = GlobalModulesManager::get();
             +  -  -  - ]
     451                 :            : 
     452                 :            :   static std::once_flag flag;
     453                 :            : 
     454         [ +  - ]:        731 :   std::call_once(flag, [transport_enable_flags]() { manager_instance.init(transport_enable_flags); });
     455                 :            : #else
     456                 :            :   (void)transport_enable_flags;
     457                 :            : #endif
     458                 :        670 : }
     459                 :            : 
     460                 :         76 : std::unique_ptr<Conf> Url::load_for_plugin(TransportType type) {
     461                 :            : #if VLINK_URL_USE_PLUGIN
     462         [ +  + ]:         76 :   if VUNLIKELY (type == TransportType::kUnknown) {
     463                 :         31 :     return nullptr;
     464                 :            :   }
     465                 :            : 
     466   [ +  -  +  - ]:         45 :   auto ptr = GlobalModulesManager::get().get_or_load_interface(type);
     467                 :            : 
     468         [ +  + ]:         45 :   if VUNLIKELY (!ptr) {
     469                 :         25 :     return nullptr;
     470                 :            :   }
     471                 :            : 
     472                 :            :   return ptr->create();  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     473                 :            : #else
     474                 :            :   (void)type;
     475                 :            : 
     476                 :            :   return nullptr;
     477                 :            : #endif
     478                 :         45 : }
     479                 :            : 
     480                 :        696 : int Url::get_sort_index(std::string_view url) { return get_sort_index_for_url(url); }
     481                 :            : 
     482   [ +  +  +  + ]:         10 : bool Url::is_local_type(std::string_view url) { return is_intra_url(url) || is_shm_url(url); }
     483                 :            : 
     484                 :          5 : bool Url::is_intra_type(std::string_view url) { return is_intra_url(url); }
     485                 :            : 
     486                 :          6 : bool Url::is_shm_type(std::string_view url) { return is_shm_url(url); }
     487                 :            : 
     488                 :          2 : std::ostream& operator<<(std::ostream& ostream, const Url& conf) noexcept {
     489                 :            :   ostream << "Url:"
     490                 :          2 :           << "[type]" << +conf.get_impl_type() << "[str]" << conf.protocol_.str;
     491                 :            : 
     492                 :          2 :   return ostream;
     493                 :            : }
     494                 :            : 
     495                 :            : }  // namespace vlink

Generated by: LCOV version 1.14