LCOV - code coverage report
Current view: top level - src/impl - types.cc (source / functions) Hit Total Coverage
Test: vlink Lines: 91 102 89.2 %
Date: 2026-07-26 14:05:51 Functions: 16 16 100.0 %
Branches: 90 124 72.6 %

           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/types.h"
      25                 :            : 
      26                 :            : #include <charconv>
      27                 :            : #include <sstream>
      28                 :            : #include <string>
      29                 :            : 
      30                 :            : namespace vlink {
      31                 :            : 
      32                 :            : // SampleLostInfo
      33                 :          3 : std::ostream& operator<<(std::ostream& ostream, const SampleLostInfo& info) noexcept {
      34                 :            :   ostream << "SampleLostInfo:"
      35                 :          3 :           << "[total]" << info.total << "[lost]" << info.lost;
      36                 :            : 
      37                 :          3 :   return ostream;
      38                 :            : }
      39                 :            : 
      40                 :            : // SchemaData
      41                 :       3028 : bool SchemaData::is_valid_type(SchemaType schema_type) noexcept {
      42         [ +  - ]:       3028 :   switch (schema_type) {
      43                 :       3028 :     case SchemaType::kUnknown:
      44                 :            :     case SchemaType::kProtobuf:
      45                 :            :     case SchemaType::kFlatbuffers:
      46                 :            :     case SchemaType::kRaw:
      47                 :            :     case SchemaType::kZeroCopy:
      48                 :            :     case SchemaType::kCdr:
      49                 :       3028 :       return true;
      50                 :            :     default:         // LCOV_EXCL_LINE GCOVR_EXCL_LINE
      51                 :            :       return false;  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
      52                 :            :   }
      53                 :            : }
      54                 :            : 
      55                 :        109 : bool SchemaData::is_real_type(SchemaType schema_type) noexcept {
      56         [ +  + ]:        109 :   switch (schema_type) {
      57                 :         86 :     case SchemaType::kProtobuf:
      58                 :            :     case SchemaType::kFlatbuffers:
      59                 :            :     case SchemaType::kZeroCopy:
      60                 :         86 :       return true;
      61                 :         23 :     default:
      62                 :         23 :       return false;
      63                 :            :   }
      64                 :            : }
      65                 :            : 
      66                 :       1799 : std::string_view SchemaData::convert_type(SchemaType schema_type) noexcept {
      67   [ +  +  +  -  :       1799 :   switch (schema_type) {
                   -  + ]
      68                 :        463 :     case SchemaType::kProtobuf:
      69                 :        463 :       return "protobuf";
      70                 :          4 :     case SchemaType::kFlatbuffers:
      71                 :          4 :       return "flatbuffers";
      72                 :       1207 :     case SchemaType::kRaw:
      73                 :       1207 :       return "raw";
      74                 :          0 :     case SchemaType::kZeroCopy:
      75                 :          0 :       return "zerocopy";
      76                 :          0 :     case SchemaType::kCdr:
      77                 :          0 :       return "cdr";
      78                 :        125 :     default:
      79                 :        125 :       return "";
      80                 :            :   }
      81                 :            : }
      82                 :            : 
      83                 :        991 : SchemaType SchemaData::convert_encoding(std::string_view encoding) noexcept {
      84                 :        778 :   constexpr auto kIsAsciiSpace = [](char ch) noexcept {
      85   [ +  -  +  -  :        778 :     return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\f' || ch == '\v';
          +  -  +  -  +  
                -  -  + ]
      86                 :            :   };
      87                 :            : 
      88                 :       3950 :   constexpr auto kAsciiLower = [](char ch) noexcept {
      89   [ +  -  -  + ]:       3950 :     return ch >= 'A' && ch <= 'Z' ? static_cast<char>(ch - 'A' + 'a') : ch;
      90                 :            :   };
      91                 :            : 
      92                 :      12377 :   const auto iequals = [kAsciiLower](std::string_view lhs, std::string_view rhs) noexcept {
      93         [ +  + ]:      12377 :     if (lhs.size() != rhs.size()) {
      94                 :      11706 :       return false;
      95                 :            :     }
      96                 :            : 
      97         [ +  + ]:       2358 :     for (size_t i = 0; i < lhs.size(); ++i) {
      98         [ +  + ]:       1975 :       if (kAsciiLower(lhs[i]) != kAsciiLower(rhs[i])) {
      99                 :        288 :         return false;
     100                 :            :       }
     101                 :            :     }
     102                 :            : 
     103                 :        383 :     return true;
     104                 :            :   };
     105                 :            : 
     106   [ +  +  -  +  :        991 :   while (!encoding.empty() && kIsAsciiSpace(encoding.front())) {
                   -  + ]
     107                 :          0 :     encoding.remove_prefix(1);
     108                 :            :   }
     109                 :            : 
     110   [ +  +  -  +  :        991 :   while (!encoding.empty() && kIsAsciiSpace(encoding.back())) {
                   -  + ]
     111                 :          0 :     encoding.remove_suffix(1);
     112                 :            :   }
     113                 :            : 
     114   [ +  +  -  +  :        991 :   if (iequals(encoding, "protobuf") || iequals(encoding, "proto")) {
                   +  + ]
     115                 :        107 :     return SchemaType::kProtobuf;
     116                 :            :   }
     117                 :            : 
     118   [ +  -  +  -  :       1768 :   if (iequals(encoding, "flatbuffers") || iequals(encoding, "flatbuffer") || iequals(encoding, "fbs") ||
             +  -  +  + ]
     119         [ +  + ]:       1768 :       iequals(encoding, "bfbs")) {
     120                 :          1 :     return SchemaType::kFlatbuffers;
     121                 :            :   }
     122                 :            : 
     123   [ +  +  +  -  :        883 :   if (iequals(encoding, "raw") || iequals(encoding, "json") || iequals(encoding, "text") || iequals(encoding, "blob")) {
          +  -  +  +  +  
                      + ]
     124                 :        275 :     return SchemaType::kRaw;
     125                 :            :   }
     126                 :            : 
     127   [ +  -  +  -  :       1216 :   if (iequals(encoding, "string") || iequals(encoding, "std::string") || iequals(encoding, "application/json") ||
             +  -  -  + ]
     128         [ -  + ]:       1216 :       iequals(encoding, "text/json")) {
     129                 :          0 :     return SchemaType::kRaw;
     130                 :            :   }
     131                 :            : 
     132   [ +  -  -  +  :        608 :   if (iequals(encoding, "zerocopy") || iequals(encoding, "vlink_msg")) {
                   -  + ]
     133                 :          0 :     return SchemaType::kZeroCopy;
     134                 :            :   }
     135                 :            : 
     136         [ -  + ]:        608 :   if (iequals(encoding, "cdr")) {
     137                 :          0 :     return SchemaType::kCdr;
     138                 :            :   }
     139                 :            : 
     140                 :        608 :   return SchemaType::kUnknown;
     141                 :            : }
     142                 :            : 
     143                 :       2652 : SchemaType SchemaData::resolve_type(SchemaType schema_type, std::string_view ser_type,
     144                 :            :                                     std::string_view encoding) noexcept {
     145         [ +  - ]:       2652 :   const auto normalized_schema_type = is_valid_type(schema_type) ? schema_type : SchemaType::kUnknown;
     146                 :            : 
     147         [ +  + ]:       2652 :   if (normalized_schema_type != SchemaType::kUnknown) {
     148                 :       2037 :     return normalized_schema_type;
     149                 :            :   }
     150                 :            : 
     151                 :        615 :   const auto inferred_encoding_type = convert_encoding(encoding);
     152                 :            : 
     153         [ +  + ]:        615 :   if (inferred_encoding_type != SchemaType::kUnknown) {
     154                 :         48 :     return inferred_encoding_type;
     155                 :            :   }
     156                 :            : 
     157                 :        567 :   return infer_ser_type(ser_type);
     158                 :            : }
     159                 :            : 
     160                 :            : // Version
     161                 :       1025 : bool Version::operator==(const Version& target) const noexcept {
     162   [ +  +  +  -  :       1025 :   return major == target.major && minor == target.minor && patch == target.patch;
                   +  + ]
     163                 :            : }
     164                 :            : 
     165                 :       1023 : bool Version::operator!=(const Version& target) const noexcept { return !(*this == target); }
     166                 :            : 
     167                 :         15 : bool Version::operator<(const Version& target) const noexcept {
     168         [ +  + ]:         15 :   if (major != target.major) {
     169                 :          6 :     return major < target.major;
     170                 :            :   }
     171                 :            : 
     172         [ +  + ]:          9 :   if (minor != target.minor) {
     173                 :          3 :     return minor < target.minor;
     174                 :            :   }
     175                 :            : 
     176                 :          6 :   return patch < target.patch;
     177                 :            : }
     178                 :            : 
     179                 :          3 : bool Version::operator>(const Version& target) const noexcept { return target < *this; }
     180                 :            : 
     181                 :        123 : Version Version::from_string(const std::string& version_str) noexcept {
     182                 :        123 :   Version version;
     183                 :            : 
     184         [ +  + ]:        123 :   thread_local std::stringstream ss;
     185                 :        123 :   ss.clear();
     186                 :        123 :   ss.str(version_str);
     187                 :            : 
     188                 :        123 :   std::string token;
     189                 :            : 
     190         [ +  + ]:        123 :   if (std::getline(ss, token, '.')) {
     191                 :        122 :     const auto* end = token.data() + token.size();
     192                 :        122 :     auto result = std::from_chars(token.data(), end, version.major);
     193                 :            : 
     194         [ +  + ]:        122 :     if VUNLIKELY (result.ptr != end) {
     195                 :          1 :       version.major = -1;
     196                 :            :     }
     197                 :            :   }
     198                 :            : 
     199         [ +  + ]:        123 :   if (std::getline(ss, token, '.')) {
     200                 :        120 :     const auto* end = token.data() + token.size();
     201                 :        120 :     auto result = std::from_chars(token.data(), end, version.minor);
     202                 :            : 
     203         [ -  + ]:        120 :     if VUNLIKELY (result.ptr != end) {
     204                 :          0 :       version.minor = -1;
     205                 :            :     }
     206                 :            :   }
     207                 :            : 
     208         [ +  + ]:        123 :   if (std::getline(ss, token, '.')) {
     209                 :        119 :     const auto* end = token.data() + token.size();
     210                 :        119 :     auto result = std::from_chars(token.data(), end, version.patch);
     211                 :            : 
     212         [ -  + ]:        119 :     if VUNLIKELY (result.ptr != end) {
     213                 :          0 :       version.patch = -1;
     214                 :            :     }
     215                 :            :   }
     216                 :            : 
     217                 :        246 :   return version;
     218                 :        123 : }
     219                 :            : 
     220                 :         44 : std::string Version::to_string() const noexcept {
     221                 :         44 :   return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(patch);
     222                 :            : }
     223                 :            : 
     224   [ +  +  +  +  :        107 : bool Version::is_valid() const noexcept { return major >= 0 && minor >= 0 && patch >= 0; }
                   +  + ]
     225                 :            : 
     226                 :            : }  // namespace vlink

Generated by: LCOV version 1.14