LCOV - code coverage report
Current view: top level - modules/dds - dds_conf.cc (source / functions) Hit Total Coverage
Test: vlink Lines: 67 79 84.8 %
Date: 2026-06-27 19:56:04 Functions: 20 26 76.9 %
Branches: 105 190 55.3 %

           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 "./modules/dds_conf.h"
      25                 :            : 
      26                 :            : #include <map>
      27                 :            : #include <memory>
      28                 :            : #include <string>
      29                 :            : #include <vector>
      30                 :            : 
      31                 :            : #include "./base/helpers.h"
      32                 :            : #include "./base/logger.h"
      33                 :            : #include "./dds_client_impl.h"
      34                 :            : #include "./dds_getter_impl.h"
      35                 :            : #include "./dds_publisher_impl.h"
      36                 :            : #include "./dds_server_impl.h"
      37                 :            : #include "./dds_setter_impl.h"
      38                 :            : #include "./dds_subscriber_impl.h"
      39                 :            : #include "./impl/conf_plugin_interface.h"
      40                 :            : #include "./impl/url.h"
      41                 :            : #include "./impl/url_parser.h"
      42                 :            : 
      43                 :            : namespace vlink {
      44                 :            : 
      45                 :            : VLINK_DEFINE_GLOBAL_PROPERTY(DdsConf)
      46                 :            : 
      47                 :            : std::map<std::string, Function<void*()>> DdsConf::type_support_map_;
      48                 :            : std::map<std::string, Qos> DdsConf::qos_map_;
      49                 :            : std::shared_mutex DdsConf::mtx_;
      50                 :            : 
      51                 :            : // DdsConf
      52                 :          5 : std::vector<std::tuple<std::string, std::string>> DdsConf::get_discovered_topics(int32_t _domain) {
      53                 :          5 :   return DdsFactory::get_discovered_topics(_domain);
      54                 :            : }
      55                 :            : 
      56                 :          2 : bool DdsConf::load_global_qos_file(const std::string& filepath) { return DdsFactory::load_global_qos_file(filepath); }
      57                 :            : 
      58                 :         36 : void DdsConf::register_qos(const std::string& name, const Qos& qos) {
      59         [ +  - ]:         36 :   std::lock_guard lock(mtx_);
      60                 :            : 
      61   [ +  -  +  +  :         36 :   if VUNLIKELY (qos_map_.find(name) != qos_map_.end() || name == "part" || name == "topic" || name == "pub" ||
          -  +  +  +  -  
          +  +  +  -  +  
          +  +  -  +  +  
          +  -  +  +  +  
          -  +  +  +  +  
                +  +  + ]
      62                 :            :                 name == "sub" || name == "writer" || name == "reader" || name == "depth") {
      63   [ +  -  -  + ]:          4 :     VLOG_F("DdsConf: Invalid qos name: '", name, "' (reserved or already registered).");
      64                 :            :   }
      65                 :            : 
      66         [ +  - ]:         34 :   register_qos_internal(name, qos);
      67                 :         36 : }
      68                 :            : 
      69                 :        242 : void DdsConf::register_qos_internal(const std::string& name, const Qos& qos) { qos_map_[name] = qos; }
      70                 :            : 
      71                 :        303 : Function<void*()> DdsConf::find_type_support(const std::string& name) {
      72         [ +  - ]:        303 :   std::shared_lock lock(mtx_);
      73         [ +  - ]:        303 :   auto iter = type_support_map_.find(name);
      74                 :            : 
      75         [ -  + ]:        303 :   if (iter != type_support_map_.end()) {
      76         [ #  # ]:          0 :     return iter->second;
      77                 :            :   }
      78                 :            : 
      79                 :        303 :   return nullptr;
      80                 :        303 : }
      81                 :            : 
      82                 :         44 : const Qos& DdsConf::find_qos(const std::string& name) {
      83         [ +  - ]:         44 :   std::shared_lock lock(mtx_);
      84                 :            : 
      85         [ +  - ]:         44 :   auto iter = qos_map_.find(name);
      86                 :            : 
      87         [ +  + ]:         44 :   if VUNLIKELY (iter == qos_map_.end()) {
      88   [ +  -  +  - ]:          2 :     CLOG_E("DdsConf: Invalid qos [%s].", name.c_str());
      89                 :            :     static Qos invalid_qos;
      90                 :          1 :     return invalid_qos;
      91                 :            :   }
      92                 :            : 
      93                 :         43 :   return iter->second;
      94                 :         44 : }
      95                 :            : 
      96                 :          0 : std::string DdsConf::get_topic_for_url(const std::string& url) {
      97         [ #  # ]:          0 :   UrlParser parser(url);
      98                 :            : 
      99   [ #  #  #  # ]:          0 :   if VUNLIKELY (parser.get_host().empty()) {
     100         [ #  # ]:          0 :     return "";
     101                 :            :   }
     102                 :            : 
     103   [ #  #  #  #  :          0 :   return parser.get_host() + (parser.get_path().empty() ? "" : "/" + parser.get_path());
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     104                 :          0 : }
     105                 :            : 
     106                 :          1 : void DdsConf::global_init() { DdsFactory::get(); }
     107                 :            : 
     108                 :        138 : bool DdsConf::parse_protocol(struct Protocol* protocol) {
     109         [ -  + ]:        138 :   if VUNLIKELY (get_impl_type() == kUnknownImplType) {
     110   [ #  #  #  # ]:          0 :     VLOG_F("DdsConf: Unknown node type, cannot parse protocol.");
     111                 :            : 
     112                 :          0 :     return false;
     113                 :            :   }
     114                 :            : 
     115         [ +  + ]:        138 :   if VUNLIKELY (protocol->host.empty()) {
     116                 :          4 :     return false;
     117                 :            :   }
     118                 :            : 
     119   [ +  +  +  -  :        134 :   static int default_domain_id = DdsFactory::get_default_domain_id();
             +  -  -  - ]
     120                 :            : 
     121   [ +  +  +  -  :        134 :   topic = protocol->host + (protocol->path.empty() ? "" : "/" + protocol->path);
          +  -  +  -  +  
                +  -  - ]
     122   [ +  -  +  - ]:        134 :   domain = Helpers::to_int(protocol->dictionary["domain"], default_domain_id);
     123   [ +  -  +  - ]:        134 :   depth = Helpers::to_int(protocol->dictionary["depth"]);
     124   [ +  -  +  -  :        134 :   qos = protocol->dictionary["qos"];
                   +  - ]
     125                 :        134 :   qos_ext = protocol->dictionary;
     126   [ +  -  +  - ]:        134 :   qos_ext.erase("domain");
     127   [ +  -  +  - ]:        134 :   qos_ext.erase("depth");
     128   [ +  -  +  - ]:        134 :   qos_ext.erase("qos");
     129                 :            : 
     130         [ +  + ]:        147 :   for (const auto& [key, value] : qos_ext) {
     131   [ +  +  +  +  :         13 :     if VUNLIKELY (key != "part" && key != "topic" && key != "pub" && key != "sub" && key != "writer" &&
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                +  +  + ]
     132                 :            :                   key != "reader") {
     133   [ +  -  +  - ]:          2 :       VLOG_W("DdsConf: Unknown qos key: ", key, ".");
     134                 :            :     }
     135                 :            :   }
     136                 :            : 
     137                 :        134 :   return true;
     138                 :            : }
     139                 :            : 
     140                 :        286 : bool DdsConf::is_valid() const {
     141   [ +  +  +  +  :        286 :   if VUNLIKELY (domain < 0 || topic.empty()) {
                   +  + ]
     142                 :          4 :     return false;
     143                 :            :   }
     144                 :            : 
     145   [ +  +  +  +  :        282 :   if VUNLIKELY (!qos.empty() && !qos_ext.empty()) {
                   +  + ]
     146                 :          2 :     return false;
     147                 :            :   }
     148                 :            : 
     149                 :        280 :   return true;
     150                 :            : }
     151                 :            : 
     152                 :         37 : std::unique_ptr<ServerImpl> DdsConf::create_server() const { return std::make_unique<DdsServerImpl>(*this); }
     153                 :            : 
     154                 :         35 : std::unique_ptr<ClientImpl> DdsConf::create_client() const { return std::make_unique<DdsClientImpl>(*this); }
     155                 :            : 
     156                 :         82 : std::unique_ptr<PublisherImpl> DdsConf::create_publisher() const { return std::make_unique<DdsPublisherImpl>(*this); }
     157                 :            : 
     158                 :         73 : std::unique_ptr<SubscriberImpl> DdsConf::create_subscriber() const {
     159                 :         73 :   return std::make_unique<DdsSubscriberImpl>(*this);
     160                 :            : }
     161                 :            : 
     162                 :         24 : std::unique_ptr<SetterImpl> DdsConf::create_setter() const { return std::make_unique<DdsSetterImpl>(*this); }
     163                 :            : 
     164                 :         27 : std::unique_ptr<GetterImpl> DdsConf::create_getter() const { return std::make_unique<DdsGetterImpl>(*this); }
     165                 :            : 
     166                 :          1 : std::ostream& operator<<(std::ostream& ostream, const Conf::PropertiesMap& qos) noexcept {
     167                 :          1 :   std::ios_base::fmtflags f = ostream.flags();
     168                 :            : 
     169         [ +  + ]:          3 :   for (const auto& [key, value] : qos) {
     170                 :          2 :     ostream << "(" << key << ")" << value;
     171                 :            :   }
     172                 :            : 
     173                 :          1 :   ostream.flags(f);
     174                 :            : 
     175                 :          1 :   return ostream;
     176                 :            : }
     177                 :            : 
     178                 :          1 : std::ostream& operator<<(std::ostream& ostream, const DdsConf& conf) noexcept {
     179                 :          1 :   std::ios_base::fmtflags f = ostream.flags();
     180                 :            : 
     181                 :            :   ostream << "DdsConf:"
     182                 :          1 :           << "[type]" << +conf.get_impl_type() << "[topic]" << conf.topic << "[domain]" << conf.domain << "[depth]"
     183                 :          1 :           << conf.depth << "[qos]" << conf.qos << "[qos_ext]" << conf.qos_ext;
     184                 :            : 
     185                 :          1 :   ostream.flags(f);
     186                 :            : 
     187                 :          1 :   return ostream;
     188                 :            : }
     189                 :            : 
     190                 :            : class ConfPluginDds : public ConfPluginInterface {
     191                 :            :  protected:
     192                 :          0 :   TransportType get_transport_type() const override { return TransportType::kDds; }
     193                 :            : 
     194                 :          0 :   std::unique_ptr<Conf> create() const override { return std::make_unique<DdsConf>(); }
     195                 :            : };
     196                 :            : 
     197                 :            : #ifdef VLINK_LIBRARY
     198   [ #  #  #  #  :          0 : VLINK_PLUGIN_DECLARE(ConfPluginDds, 1, 0)
          #  #  #  #  #  
                      # ]
     199                 :            : #endif
     200                 :            : 
     201                 :            : }  // namespace vlink

Generated by: LCOV version 1.14