LCOV - code coverage report
Current view: top level - src/tracing - trace_context_parser.cpp (source / functions) Coverage Total Hit
Test: HPActor Coverage Lines: 90.4 % 73 66
Test Date: 2026-05-20 02:24:49 Functions: 100.0 % 8 8
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : #include <hpactor/tracing/trace_context_parser.hpp>
       2                 :             : 
       3                 :             : #include <array>
       4                 :             : #include <cstring>
       5                 :             : 
       6                 :             : namespace hpactor::tracing {
       7                 :             : 
       8                 :             : namespace {
       9                 :             : 
      10                 :         230 : int hex_value(char c) noexcept {
      11                 :         230 :     if (c >= '0' && c <= '9')
      12                 :         164 :         return c - '0';
      13                 :          66 :     if (c >= 'a' && c <= 'f')
      14                 :          48 :         return c - 'a' + 10;
      15                 :          18 :     if (c >= 'A' && c <= 'F')
      16                 :          18 :         return c - 'A' + 10;
      17                 :           0 :     return -1;
      18                 :             : }
      19                 :             : 
      20                 :             : template <size_t N>
      21                 :          12 : bool parse_hex_bytes(std::string_view text, std::array<uint8_t, N>& out) noexcept {
      22                 :          12 :     if (text.size() != N * 2)
      23                 :           0 :         return false;
      24                 :         127 :     for (size_t i = 0; i < N; ++i) {
      25                 :         115 :         int hi = hex_value(text[i * 2]);
      26                 :         115 :         int lo = hex_value(text[i * 2 + 1]);
      27                 :         115 :         if (hi < 0 || lo < 0)
      28                 :           0 :             return false;
      29                 :         115 :         out[i] = static_cast<uint8_t>((hi << 4) | lo);
      30                 :             :     }
      31                 :          12 :     return true;
      32                 :             : }
      33                 :             : 
      34                 :         150 : void append_hex_byte(std::string& out, uint8_t b) {
      35                 :         150 :     constexpr char kHex[] = "0123456789abcdef";
      36                 :         150 :     out.push_back(kHex[(b >> 4) & 0x0F]);
      37                 :         150 :     out.push_back(kHex[b & 0x0F]);
      38                 :         150 : }
      39                 :             : 
      40                 :             : } // namespace
      41                 :             : 
      42                 :           7 : TraceParseResult parse_w3c_trace_context(std::string_view traceparent,
      43                 :             :                                          std::string_view tracestate,
      44                 :             :                                          uint16_t max_tracestate_len) noexcept {
      45                 :           7 :     TraceParseResult result;
      46                 :           7 :     if (traceparent.empty()) {
      47                 :           1 :         result.status_value = TraceParseStatus::kMissing;
      48                 :           1 :         return result;
      49                 :             :     }
      50                 :          11 :     if (traceparent.size() != 55 || traceparent[2] != '-' ||
      51                 :          11 :         traceparent[35] != '-' || traceparent[52] != '-') {
      52                 :           1 :         result.status_value = TraceParseStatus::kMalformed;
      53                 :           1 :         return result;
      54                 :             :     }
      55                 :           5 :     if (!traceparent.starts_with("00")) {
      56                 :           0 :         result.status_value = TraceParseStatus::kUnsupportedVersion;
      57                 :           0 :         return result;
      58                 :             :     }
      59                 :             : 
      60                 :           5 :     TraceContext ctx;
      61                 :          10 :     if (!parse_hex_bytes(traceparent.substr(3, 32), ctx.trace_id.bytes) ||
      62                 :           5 :         !ctx.trace_id.valid()) {
      63                 :           1 :         result.status_value = TraceParseStatus::kInvalidTraceId;
      64                 :           1 :         return result;
      65                 :             :     }
      66                 :           8 :     if (!parse_hex_bytes(traceparent.substr(36, 16), ctx.span_id.bytes) ||
      67                 :           4 :         !ctx.span_id.valid()) {
      68                 :           1 :         result.status_value = TraceParseStatus::kInvalidSpanId;
      69                 :           1 :         return result;
      70                 :             :     }
      71                 :             : 
      72                 :           3 :     std::array<uint8_t, 1> flags{};
      73                 :           3 :     if (!parse_hex_bytes(traceparent.substr(53, 2), flags)) {
      74                 :           0 :         result.status_value = TraceParseStatus::kMalformed;
      75                 :           0 :         return result;
      76                 :             :     }
      77                 :           3 :     ctx.flags.value = flags[0];
      78                 :             : 
      79                 :           5 :     if (tracestate.size() > max_tracestate_len ||
      80                 :           4 :         tracestate.size() > ctx.tracestate.size()) {
      81                 :           1 :         result.status_value = TraceParseStatus::kTracestateTooLarge;
      82                 :           1 :         return result;
      83                 :             :     }
      84                 :           2 :     if (!tracestate.empty()) {
      85                 :           1 :         std::memcpy(ctx.tracestate.data(), tracestate.data(), tracestate.size());
      86                 :           1 :         ctx.tracestate_len = static_cast<uint16_t>(tracestate.size());
      87                 :             :     }
      88                 :             : 
      89                 :           2 :     result.status_value = TraceParseStatus::kOk;
      90                 :           2 :     result.context = ctx;
      91                 :           2 :     return result;
      92                 :             : }
      93                 :             : 
      94                 :           6 : std::string format_traceparent(const TraceContext& context) {
      95                 :           6 :     std::string out;
      96                 :           6 :     out.reserve(55);
      97                 :           6 :     out += "00-";
      98                 :         102 :     for (uint8_t b : context.trace_id.bytes)
      99                 :          96 :         append_hex_byte(out, b);
     100                 :           6 :     out.push_back('-');
     101                 :          54 :     for (uint8_t b : context.span_id.bytes)
     102                 :          48 :         append_hex_byte(out, b);
     103                 :           6 :     out.push_back('-');
     104                 :           6 :     append_hex_byte(out, context.flags.value);
     105                 :           6 :     return out;
     106                 :             : }
     107                 :             : 
     108                 :           1 : std::string format_tracestate(const TraceContext& context) {
     109                 :           1 :     return std::string(context.tracestate_view());
     110                 :             : }
     111                 :             : 
     112                 :             : } // namespace hpactor::tracing
        

Generated by: LCOV version 2.0-1