From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- third_party/libwebrtc/stats/attribute.cc | 172 +++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 third_party/libwebrtc/stats/attribute.cc (limited to 'third_party/libwebrtc/stats/attribute.cc') diff --git a/third_party/libwebrtc/stats/attribute.cc b/third_party/libwebrtc/stats/attribute.cc new file mode 100644 index 0000000000..fab948b1bd --- /dev/null +++ b/third_party/libwebrtc/stats/attribute.cc @@ -0,0 +1,172 @@ +/* + * Copyright 2024 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "api/stats/attribute.h" + +#include + +#include "absl/types/variant.h" +#include "rtc_base/arraysize.h" +#include "rtc_base/checks.h" +#include "rtc_base/string_encode.h" +#include "rtc_base/strings/string_builder.h" + +namespace webrtc { + +namespace { + +struct VisitIsSequence { + // Any type of vector is a sequence. + template + bool operator()(const RTCStatsMember>* attribute) { + return true; + } + // Any other type is not. + template + bool operator()(const RTCStatsMember* attribute) { + return false; + } +}; + +// Converts the attribute to string in a JSON-compatible way. +struct VisitToString { + template || std::is_same_v || + std::is_same_v || std::is_same_v, + bool> = true> + std::string ValueToString(const T& value) { + return rtc::ToString(value); + } + // Convert 64-bit integers to doubles before converting to string because JSON + // represents all numbers as floating points with ~15 digits of precision. + template || + std::is_same_v || + std::is_same_v, + bool> = true> + std::string ValueToString(const T& value) { + char buf[32]; + const int len = std::snprintf(&buf[0], arraysize(buf), "%.16g", + static_cast(value)); + RTC_DCHECK_LE(len, arraysize(buf)); + return std::string(&buf[0], len); + } + + // Vector attributes. + template + std::string operator()(const RTCStatsMember>* attribute) { + rtc::StringBuilder sb; + sb << "["; + const char* separator = ""; + constexpr bool element_is_string = std::is_same::value; + for (const T& element : attribute->value()) { + sb << separator; + if (element_is_string) { + sb << "\""; + } + sb << ValueToString(element); + if (element_is_string) { + sb << "\""; + } + separator = ","; + } + sb << "]"; + return sb.Release(); + } + // Map attributes. + template + std::string operator()( + const RTCStatsMember>* attribute) { + rtc::StringBuilder sb; + sb << "{"; + const char* separator = ""; + constexpr bool element_is_string = std::is_same::value; + for (const auto& pair : attribute->value()) { + sb << separator; + sb << "\"" << pair.first << "\":"; + if (element_is_string) { + sb << "\""; + } + sb << ValueToString(pair.second); + if (element_is_string) { + sb << "\""; + } + separator = ","; + } + sb << "}"; + return sb.Release(); + } + // Simple attributes. + template + std::string operator()(const RTCStatsMember* attribute) { + return ValueToString(attribute->value()); + } +}; + +struct VisitIsEqual { + template + bool operator()(const RTCStatsMember* attribute) { + if (!other.holds_alternative()) { + return false; + } + absl::optional attribute_as_optional = + attribute->has_value() ? absl::optional(attribute->value()) + : absl::nullopt; + return attribute_as_optional == other.as_optional(); + } + + const Attribute& other; +}; + +} // namespace + +const char* Attribute::name() const { + return name_; +} + +const Attribute::StatVariant& Attribute::as_variant() const { + return attribute_; +} + +bool Attribute::has_value() const { + return absl::visit([](const auto* attr) { return attr->has_value(); }, + attribute_); +} + +bool Attribute::is_sequence() const { + return absl::visit(VisitIsSequence(), attribute_); +} + +bool Attribute::is_string() const { + return absl::holds_alternative*>( + attribute_); +} + +std::string Attribute::ToString() const { + if (!has_value()) { + return "null"; + } + return absl::visit(VisitToString(), attribute_); +} + +bool Attribute::operator==(const Attribute& other) const { + return absl::visit(VisitIsEqual{.other = other}, attribute_); +} + +bool Attribute::operator!=(const Attribute& other) const { + return !(*this == other); +} + +AttributeInit::AttributeInit(const char* name, + const Attribute::StatVariant& variant) + : name(name), variant(variant) {} + +} // namespace webrtc -- cgit v1.2.3