LCOV - code coverage report
Current view: top level - src/net - frame_protobuf.cpp (source / functions) Coverage Total Hit
Test: HPActor Coverage Lines: 72.7 % 99 72
Test Date: 2026-05-20 02:24:49 Functions: 82.4 % 17 14
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright 2026 HPActor Contributors
       2                 :             : #include <hpactor/net/frame.hpp>
       3                 :             : 
       4                 :             : #include <hpactor/common.pb.h>
       5                 :             : #include <hpactor/frame.pb.h>
       6                 :             : 
       7                 :             : namespace hpactor {
       8                 :             : namespace net {
       9                 :             : 
      10                 :             : // Helper: convert HPActor Ipv4Endpoint to protobuf PbIpv4Endpoint
      11                 :             : static void
      12                 :           6 : to_proto(::hpactor::PbIpv4Endpoint* pb_ep, const ::hpactor::Ipv4Endpoint& ep) {
      13                 :           6 :     pb_ep->set_addr(ep.addr); // Network byte order
      14                 :           6 :     pb_ep->set_port(ep.port_nw);
      15                 :           6 : }
      16                 :             : 
      17                 :             : // Helper: convert HPActor Ipv6Endpoint to protobuf PbIpv6Endpoint
      18                 :             : static void
      19                 :           2 : to_proto(::hpactor::PbIpv6Endpoint* pb_ep, const ::hpactor::Ipv6Endpoint& ep) {
      20                 :           4 :     pb_ep->set_addr(ep.addr.data(), ep.addr.size());
      21                 :           2 :     pb_ep->set_port(ep.port_nw);
      22                 :           2 : }
      23                 :             : 
      24                 :             : // Helper: convert HPActor EndPoint to protobuf PbEndpoint
      25                 :             : static void
      26                 :           8 : to_proto(::hpactor::PbEndpoint* pb_endpoint, const ::hpactor::EndPoint& ep) {
      27                 :           8 :     if (const auto* ipv4 = std::get_if<::hpactor::Ipv4Endpoint>(&ep)) {
      28                 :           6 :         to_proto(pb_endpoint->mutable_ipv4(), *ipv4);
      29                 :           2 :     } else if (const auto* ipv6 = std::get_if<::hpactor::Ipv6Endpoint>(&ep)) {
      30                 :           2 :         to_proto(pb_endpoint->mutable_ipv6(), *ipv6);
      31                 :             :     }
      32                 :           8 : }
      33                 :             : 
      34                 :             : // Helper: fill PbLocalActorAddress from C++ ActorAddress fields
      35                 :             : static void
      36                 :          36 : fill_local_addr(::hpactor::PbLocalActorAddress* local, const ActorAddress& addr) {
      37                 :          36 :     local->set_actor_type(addr.type);
      38                 :          36 :     local->set_actor_id(addr.id.value());
      39                 :          36 :     local->set_incarnation(addr.incarnation);
      40                 :          36 : }
      41                 :             : 
      42                 :             : // Helper: fill PbGlobalActorAddress from C++ ActorAddress fields
      43                 :           8 : static void fill_global_addr(::hpactor::PbGlobalActorAddress* global,
      44                 :             :                              const ActorAddress& addr) {
      45                 :           8 :     to_proto(global->mutable_endpoint(), addr.endpoint);
      46                 :           8 :     fill_local_addr(global->mutable_local_addr(), addr);
      47                 :           8 : }
      48                 :             : 
      49                 :             : // Returns true if the endpoint is the default localhost:0 (no real endpoint).
      50                 :          36 : static bool is_default_local_endpoint(const EndPoint& ep) {
      51                 :          36 :     if (const auto* ipv4 = std::get_if<Ipv4Endpoint>(&ep)) {
      52                 :          34 :         return ipv4->is_loopback() && ipv4->port() == 0;
      53                 :             :     }
      54                 :           2 :     if (const auto* ipv6 = std::get_if<Ipv6Endpoint>(&ep)) {
      55                 :           2 :         return ipv6->is_loopback() && ipv6->port() == 0;
      56                 :             :     }
      57                 :           0 :     return false;
      58                 :             : }
      59                 :             : 
      60                 :             : // Helper: convert C++ ActorAddress to protobuf PbActorAddress
      61                 :             : // Uses local_addr only for the default localhost:0 endpoint;
      62                 :             : // all other addresses (including IPv6 loopback) use global_addr
      63                 :             : // to preserve full endpoint information.
      64                 :          36 : void to_proto(::hpactor::PbActorAddress* pb_addr, const ActorAddress& addr) {
      65                 :          36 :     if (is_default_local_endpoint(addr.endpoint) || !addr) {
      66                 :          28 :         fill_local_addr(pb_addr->mutable_local_addr(), addr);
      67                 :             :     } else {
      68                 :           8 :         fill_global_addr(pb_addr->mutable_global_addr(), addr);
      69                 :             :     }
      70                 :          36 : }
      71                 :             : 
      72                 :             : // Helper: convert C++ ActorAddress to protobuf PbActorRef (same structure)
      73                 :           0 : void to_proto(::hpactor::PbActorRef* pb_ref, const ActorAddress& addr) {
      74                 :           0 :     if (is_default_local_endpoint(addr.endpoint) || !addr) {
      75                 :           0 :         fill_local_addr(pb_ref->mutable_local_addr(), addr);
      76                 :             :     } else {
      77                 :           0 :         fill_global_addr(pb_ref->mutable_global_addr(), addr);
      78                 :             :     }
      79                 :           0 : }
      80                 :             : 
      81                 :             : // Helper: convert protobuf PbIpv4Endpoint to HPActor Ipv4Endpoint
      82                 :           6 : static ::hpactor::Ipv4Endpoint from_proto(const ::hpactor::PbIpv4Endpoint& pb_ep) {
      83                 :          12 :     return ::hpactor::Ipv4Endpoint{pb_ep.addr(),
      84                 :          12 :                                    static_cast<uint16_t>(pb_ep.port())};
      85                 :             : }
      86                 :             : 
      87                 :             : // Helper: convert protobuf PbIpv6Endpoint to HPActor Ipv6Endpoint
      88                 :           1 : static ::hpactor::Ipv6Endpoint from_proto(const ::hpactor::PbIpv6Endpoint& pb_ep) {
      89                 :           1 :     std::array<uint8_t, 16> addr{};
      90                 :           1 :     std::memcpy(addr.data(), pb_ep.addr().data(), addr.size());
      91                 :           1 :     return ::hpactor::Ipv6Endpoint{addr, static_cast<uint16_t>(pb_ep.port())};
      92                 :             : }
      93                 :             : 
      94                 :             : // Helper: convert protobuf PbEndpoint to HPActor EndPoint
      95                 :           7 : static ::hpactor::EndPoint from_proto(const ::hpactor::PbEndpoint& pb_endpoint) {
      96                 :           7 :     if (pb_endpoint.has_ipv4()) {
      97                 :           6 :         return from_proto(pb_endpoint.ipv4());
      98                 :             :     }
      99                 :           1 :     if (pb_endpoint.has_ipv6()) {
     100                 :           1 :         return from_proto(pb_endpoint.ipv6());
     101                 :             :     }
     102                 :           0 :     return ::hpactor::Ipv4Endpoint{};
     103                 :             : }
     104                 :             : 
     105                 :             : // Helper: build ActorAddress from PbLocalActorAddress fields
     106                 :           0 : static ActorAddress from_local_addr(const ::hpactor::PbLocalActorAddress& local) {
     107                 :           0 :     return ActorAddress{Ipv4Endpoint{0x7F000001, 0},
     108                 :           0 :                         static_cast<ActorType>(local.actor_type()),
     109                 :           0 :                         ActorId{local.actor_id()}, local.incarnation()};
     110                 :             : }
     111                 :             : 
     112                 :             : // Helper: build ActorAddress from PbGlobalActorAddress fields
     113                 :             : static ActorAddress
     114                 :           7 : from_global_addr(const ::hpactor::PbGlobalActorAddress& global) {
     115                 :           7 :     const auto& local = global.local_addr();
     116                 :           7 :     return ActorAddress{from_proto(global.endpoint()),
     117                 :           7 :                         static_cast<ActorType>(local.actor_type()),
     118                 :           7 :                         ActorId{local.actor_id()}, local.incarnation()};
     119                 :             : }
     120                 :             : 
     121                 :             : // Helper: convert protobuf PbActorAddress to HPActor ActorAddress
     122                 :           7 : ActorAddress from_proto(const ::hpactor::PbActorAddress& pb_addr) {
     123                 :           7 :     if (pb_addr.has_local_addr()) {
     124                 :           0 :         return from_local_addr(pb_addr.local_addr());
     125                 :             :     }
     126                 :           7 :     if (pb_addr.has_global_addr()) {
     127                 :           7 :         return from_global_addr(pb_addr.global_addr());
     128                 :             :     }
     129                 :           0 :     return ActorAddress{};
     130                 :             : }
     131                 :             : 
     132                 :             : // Helper: convert protobuf PbActorRef to HPActor ActorAddress
     133                 :           0 : ActorAddress from_proto(const ::hpactor::PbActorRef& pb_ref) {
     134                 :           0 :     if (pb_ref.has_local_addr()) {
     135                 :           0 :         return from_local_addr(pb_ref.local_addr());
     136                 :             :     }
     137                 :           0 :     if (pb_ref.has_global_addr()) {
     138                 :           0 :         return from_global_addr(pb_ref.global_addr());
     139                 :             :     }
     140                 :           0 :     return ActorAddress{};
     141                 :             : }
     142                 :             : 
     143                 :           1 : void to_proto(::hpactor::net::PbTraceContext* pb, const TraceContext& context) {
     144                 :           2 :     pb->set_trace_id(reinterpret_cast<const char*>(context.trace_id.bytes.data()),
     145                 :             :                      context.trace_id.bytes.size());
     146                 :           2 :     pb->set_span_id(reinterpret_cast<const char*>(context.span_id.bytes.data()),
     147                 :             :                     context.span_id.bytes.size());
     148                 :           1 :     pb->set_flags(context.flags.value);
     149                 :           1 :     if (context.tracestate_len > 0) {
     150                 :           0 :         pb->set_tracestate(context.tracestate.data(), context.tracestate_len);
     151                 :             :     }
     152                 :           1 : }
     153                 :             : 
     154                 :             : result<TraceContext>
     155                 :           1 : trace_context_from_proto(const ::hpactor::net::PbTraceContext& pb,
     156                 :             :                          uint16_t max_tracestate_len) {
     157                 :           1 :     TraceContext ctx;
     158                 :           2 :     if (pb.trace_id().size() != ctx.trace_id.bytes.size()) {
     159                 :           0 :         return result<TraceContext>::make(error(errors::invalid_argument));
     160                 :             :     }
     161                 :           2 :     if (pb.span_id().size() != ctx.span_id.bytes.size()) {
     162                 :           0 :         return result<TraceContext>::make(error(errors::invalid_argument));
     163                 :             :     }
     164                 :           2 :     std::memcpy(ctx.trace_id.bytes.data(), pb.trace_id().data(),
     165                 :             :                 ctx.trace_id.bytes.size());
     166                 :           1 :     std::memcpy(ctx.span_id.bytes.data(), pb.span_id().data(),
     167                 :             :                 ctx.span_id.bytes.size());
     168                 :           1 :     if (!ctx.trace_id.valid() || !ctx.span_id.valid()) {
     169                 :           0 :         return result<TraceContext>::make(error(errors::invalid_argument));
     170                 :             :     }
     171                 :           1 :     ctx.flags.value = static_cast<uint8_t>(pb.flags() & 0xFF);
     172                 :           2 :     if (pb.tracestate().size() > max_tracestate_len ||
     173                 :           2 :         pb.tracestate().size() > ctx.tracestate.size()) {
     174                 :           0 :         return result<TraceContext>::make(error(errors::invalid_argument));
     175                 :             :     }
     176                 :           1 :     if (!pb.tracestate().empty()) {
     177                 :           0 :         std::memcpy(ctx.tracestate.data(), pb.tracestate().data(),
     178                 :           0 :                     pb.tracestate().size());
     179                 :           0 :         ctx.tracestate_len = static_cast<uint16_t>(pb.tracestate().size());
     180                 :             :     }
     181                 :           1 :     return result<TraceContext>::make(std::move(ctx));
     182                 :             : }
     183                 :             : 
     184                 :             : } // namespace net
     185                 :             : } // namespace hpactor
        

Generated by: LCOV version 2.0-1