Line data Source code
1 : #include "trace_id.h" 2 : 3 : #include "hex.h" 4 : #include "parse_util.h" 5 : 6 : namespace datadog { 7 : namespace tracing { 8 : 9 165810 : TraceID::TraceID() : low(0), high(0) {} 10 : 11 372 : TraceID::TraceID(std::uint64_t low) : low(low), high(0) {} 12 : 13 33 : TraceID::TraceID(std::uint64_t low, std::uint64_t high) 14 33 : : low(low), high(high) {} 15 : 16 37 : std::string TraceID::hex_padded() const { 17 37 : std::string result; 18 37 : if (high) { 19 9 : result += ::datadog::tracing::hex_padded(high); 20 : } else { 21 28 : result.append(16, '0'); 22 : } 23 37 : result += ::datadog::tracing::hex_padded(low); 24 37 : return result; 25 0 : } 26 : 27 86 : Expected<TraceID> TraceID::parse_hex(StringView input) { 28 : const auto parse_hex_piece = 29 143 : [input](StringView piece) -> Expected<std::uint64_t> { 30 143 : auto result = parse_uint64(piece, 16); 31 143 : if (auto *error = result.if_error()) { 32 10 : std::string prefix = "Unable to parse trace ID from \""; 33 10 : append(prefix, input); 34 10 : prefix += "\": "; 35 10 : return error->with_prefix(prefix); 36 10 : } 37 133 : return result; 38 143 : }; 39 : 40 : // A 64-bit integer is at most 16 hex characters. If the input is no 41 : // longer than that, then it will all fit in `TraceID::low`. 42 86 : if (input.size() <= 16) { 43 28 : auto result = parse_hex_piece(input); 44 28 : if (auto *error = result.if_error()) { 45 4 : return std::move(*error); 46 : } 47 24 : return TraceID(*result); 48 28 : } 49 : 50 : // Parse the lower part and the higher part separately. 51 58 : const auto divider = input.begin() + (input.size() - 16); 52 58 : const auto high_hex = range(input.begin(), divider); 53 58 : const auto low_hex = range(divider, input.end()); 54 58 : TraceID trace_id; 55 : 56 58 : auto result = parse_hex_piece(low_hex); 57 58 : if (auto *error = result.if_error()) { 58 1 : return std::move(*error); 59 : } 60 57 : trace_id.low = *result; 61 : 62 57 : result = parse_hex_piece(high_hex); 63 57 : if (auto *error = result.if_error()) { 64 5 : return std::move(*error); 65 : } 66 52 : trace_id.high = *result; 67 : 68 52 : return trace_id; 69 58 : } 70 : 71 206 : bool operator==(TraceID left, TraceID right) { 72 206 : return left.low == right.low && left.high == right.high; 73 : } 74 : 75 42 : bool operator!=(TraceID left, TraceID right) { 76 42 : return left.low != right.low || left.high != right.high; 77 : } 78 : 79 171 : bool operator==(TraceID left, std::uint64_t right) { 80 171 : return left == TraceID{right}; 81 : } 82 : 83 36 : bool operator!=(TraceID left, std::uint64_t right) { 84 36 : return left != TraceID{right}; 85 : } 86 : 87 18 : bool operator==(std::uint64_t left, TraceID right) { return right == left; } 88 : 89 18 : bool operator!=(std::uint64_t left, TraceID right) { return right != left; } 90 : 91 : } // namespace tracing 92 : } // namespace datadog