LCOV - code coverage report
Current view: top level - datadog - parse_util.cpp (source / functions) Hit Total Coverage
Test: filtered.info Lines: 63 63 100.0 %
Date: 2024-01-03 20:30:12 Functions: 10 10 100.0 %

          Line data    Source code
       1             : #include "parse_util.h"
       2             : 
       3             : #include <algorithm>
       4             : #include <cassert>
       5             : #include <cctype>
       6             : #include <charconv>
       7             : #include <iterator>
       8             : #include <sstream>
       9             : #include <string>
      10             : 
      11             : #include "error.h"
      12             : 
      13             : namespace datadog {
      14             : namespace tracing {
      15             : namespace {
      16             : 
      17             : template <typename Integer>
      18         512 : Expected<Integer> parse_integer(StringView input, int base, StringView kind) {
      19             :   Integer value;
      20         512 :   const auto status = std::from_chars(input.begin(), input.end(), value, base);
      21         512 :   if (status.ec == std::errc::invalid_argument) {
      22          31 :     std::string message;
      23          31 :     message += "Is not a valid integer: \"";
      24          31 :     append(message, input);
      25          31 :     message += '\"';
      26          31 :     return Error{Error::INVALID_INTEGER, std::move(message)};
      27         512 :   } else if (status.ptr != input.end()) {
      28          27 :     std::string message;
      29          27 :     message += "Integer has trailing characters in: \"";
      30          27 :     append(message, input);
      31          27 :     message += '\"';
      32          27 :     return Error{Error::INVALID_INTEGER, std::move(message)};
      33         481 :   } else if (status.ec == std::errc::result_out_of_range) {
      34          16 :     std::string message;
      35          16 :     message += "Integer is not within the range of ";
      36          16 :     append(message, kind);
      37          16 :     message += ": ";
      38          16 :     append(message, input);
      39          16 :     return Error{Error::OUT_OF_RANGE_INTEGER, std::move(message)};
      40          16 :   }
      41         438 :   return value;
      42             : }
      43             : 
      44             : }  // namespace
      45             : 
      46         212 : StringView strip(StringView input) {
      47         450 :   const auto not_whitespace = [](unsigned char ch) {
      48         450 :     return !std::isspace(ch);
      49             :   };
      50             :   const char* const begin =
      51         212 :       std::find_if(input.begin(), input.end(), not_whitespace);
      52             :   const char* const end =
      53         212 :       std::find_if(input.rbegin(), std::make_reverse_iterator(begin),
      54             :                    not_whitespace)
      55         212 :           .base();
      56             : 
      57         212 :   assert(begin <= end);
      58             : 
      59         212 :   return StringView{begin, std::size_t(end - begin)};
      60             : }
      61             : 
      62         423 : Expected<std::uint64_t> parse_uint64(StringView input, int base) {
      63         423 :   return parse_integer<std::uint64_t>(input, base, "64-bit unsigned");
      64             : }
      65             : 
      66          89 : Expected<int> parse_int(StringView input, int base) {
      67          89 :   return parse_integer<int>(input, base, "int");
      68             : }
      69             : 
      70          23 : Expected<double> parse_double(StringView input) {
      71             :   // This function uses a different technique from `parse_integer`, because
      72             :   // some compilers with _partial_ support for C++17 do not implement the
      73             :   // floating point portions of `std::from_chars`:
      74             :   // <https://en.cppreference.com/w/cpp/compiler_support/17#C.2B.2B17_library_features>.
      75             :   // As an alternative, we could use either of `std::stod` or `std::istream`.
      76             :   // I choose `std::istream`.
      77             :   double value;
      78          23 :   std::stringstream stream;
      79          23 :   stream << input;
      80          23 :   stream >> value;
      81             : 
      82          23 :   if (!stream) {
      83          14 :     std::string message;
      84             :     message +=
      85             :         "Is not a valid number, or is out of the range of double precision "
      86          14 :         "floating point: \"";
      87          14 :     append(message, input);
      88          14 :     message += '\"';
      89          14 :     return Error{Error::INVALID_DOUBLE, std::move(message)};
      90          23 :   } else if (!stream.eof()) {
      91           2 :     std::string message;
      92           2 :     message += "Number has trailing characters in: \"";
      93           2 :     append(message, input);
      94           2 :     message += '\"';
      95           2 :     return Error{Error::INVALID_DOUBLE, std::move(message)};
      96           2 :   }
      97             : 
      98           7 :   return value;
      99          23 : }
     100             : 
     101       20147 : bool starts_with(StringView subject, StringView prefix) {
     102       20147 :   if (prefix.size() > subject.size()) {
     103          13 :     return false;
     104             :   }
     105             : 
     106       20134 :   return std::mismatch(subject.begin(), subject.end(), prefix.begin()).second ==
     107       20134 :          prefix.end();
     108             : }
     109             : 
     110          95 : void to_lower(std::string& text) {
     111          95 :   std::transform(text.begin(), text.end(), text.begin(),
     112         304 :                  [](unsigned char ch) { return std::tolower(ch); });
     113          95 : }
     114             : 
     115             : }  // namespace tracing
     116             : }  // namespace datadog

Generated by: LCOV version 1.16