Move RTCStatsMember+Interface to a separate file.
Pure move CL. Avoids circular dependency in a future CL. Bug: webrtc:15164 Change-Id: Ide423be95db30b7f3cfaea946e18e12980175f2b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/333920 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/main@{#41496}
This commit is contained in:
parent
a742df24fd
commit
98b0da181b
@ -773,6 +773,7 @@ rtc_source_set("rtc_stats_api") {
|
||||
sources = [
|
||||
"stats/rtc_stats.h",
|
||||
"stats/rtc_stats_collector_callback.h",
|
||||
"stats/rtc_stats_member.h",
|
||||
"stats/rtc_stats_report.h",
|
||||
"stats/rtcstats_objects.h",
|
||||
]
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/stats/rtc_stats_member.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
@ -28,8 +28,6 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RTCStatsMemberInterface;
|
||||
|
||||
// Abstract base class for RTCStats-derived dictionaries, see
|
||||
// https://w3c.github.io/webrtc-stats/.
|
||||
//
|
||||
@ -206,185 +204,6 @@ class RTC_EXPORT RTCStats {
|
||||
return parent_class::MembersOfThisObjectAndAncestors(0); \
|
||||
}
|
||||
|
||||
// Interface for `RTCStats` members, which have a name and a value of a type
|
||||
// defined in a subclass. Only the types listed in `Type` are supported, these
|
||||
// are implemented by `RTCStatsMember<T>`. The value of a member may be
|
||||
// undefined, the value can only be read if `is_defined`.
|
||||
class RTCStatsMemberInterface {
|
||||
public:
|
||||
// Member value types.
|
||||
enum Type {
|
||||
kBool, // bool
|
||||
kInt32, // int32_t
|
||||
kUint32, // uint32_t
|
||||
kInt64, // int64_t
|
||||
kUint64, // uint64_t
|
||||
kDouble, // double
|
||||
kString, // std::string
|
||||
|
||||
kSequenceBool, // std::vector<bool>
|
||||
kSequenceInt32, // std::vector<int32_t>
|
||||
kSequenceUint32, // std::vector<uint32_t>
|
||||
kSequenceInt64, // std::vector<int64_t>
|
||||
kSequenceUint64, // std::vector<uint64_t>
|
||||
kSequenceDouble, // std::vector<double>
|
||||
kSequenceString, // std::vector<std::string>
|
||||
|
||||
kMapStringUint64, // std::map<std::string, uint64_t>
|
||||
kMapStringDouble, // std::map<std::string, double>
|
||||
};
|
||||
|
||||
virtual ~RTCStatsMemberInterface() {}
|
||||
|
||||
const char* name() const { return name_; }
|
||||
virtual Type type() const = 0;
|
||||
virtual bool is_sequence() const = 0;
|
||||
virtual bool is_string() const = 0;
|
||||
virtual bool is_defined() const = 0;
|
||||
// Type and value comparator. The names are not compared. These operators are
|
||||
// exposed for testing.
|
||||
bool operator==(const RTCStatsMemberInterface& other) const {
|
||||
return IsEqual(other);
|
||||
}
|
||||
bool operator!=(const RTCStatsMemberInterface& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
virtual std::string ValueToString() const = 0;
|
||||
// This is the same as ValueToString except for kInt64 and kUint64 types,
|
||||
// where the value is represented as a double instead of as an integer.
|
||||
// Since JSON stores numbers as floating point numbers, very large integers
|
||||
// cannot be accurately represented, so we prefer to display them as doubles
|
||||
// instead.
|
||||
virtual std::string ValueToJson() const = 0;
|
||||
|
||||
template <typename T>
|
||||
const T& cast_to() const {
|
||||
RTC_DCHECK_EQ(type(), T::StaticType());
|
||||
return static_cast<const T&>(*this);
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit RTCStatsMemberInterface(const char* name) : name_(name) {}
|
||||
|
||||
virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0;
|
||||
|
||||
const char* const name_;
|
||||
};
|
||||
|
||||
// Template implementation of `RTCStatsMemberInterface`.
|
||||
// The supported types are the ones described by
|
||||
// `RTCStatsMemberInterface::Type`.
|
||||
template <typename T>
|
||||
class RTCStatsMember : public RTCStatsMemberInterface {
|
||||
public:
|
||||
explicit RTCStatsMember(const char* name)
|
||||
: RTCStatsMemberInterface(name), value_() {}
|
||||
RTCStatsMember(const char* name, const T& value)
|
||||
: RTCStatsMemberInterface(name), value_(value) {}
|
||||
RTCStatsMember(const char* name, T&& value)
|
||||
: RTCStatsMemberInterface(name), value_(std::move(value)) {}
|
||||
explicit RTCStatsMember(const RTCStatsMember<T>& other)
|
||||
: RTCStatsMemberInterface(other.name_), value_(other.value_) {}
|
||||
explicit RTCStatsMember(RTCStatsMember<T>&& other)
|
||||
: RTCStatsMemberInterface(other.name_), value_(std::move(other.value_)) {}
|
||||
|
||||
static Type StaticType();
|
||||
Type type() const override { return StaticType(); }
|
||||
bool is_sequence() const override;
|
||||
bool is_string() const override;
|
||||
bool is_defined() const override { return value_.has_value(); }
|
||||
std::string ValueToString() const override;
|
||||
std::string ValueToJson() const override;
|
||||
|
||||
template <typename U>
|
||||
inline T ValueOrDefault(U default_value) const {
|
||||
return value_.value_or(default_value);
|
||||
}
|
||||
|
||||
// Assignment operators.
|
||||
T& operator=(const T& value) {
|
||||
value_ = value;
|
||||
return value_.value();
|
||||
}
|
||||
T& operator=(const T&& value) {
|
||||
value_ = std::move(value);
|
||||
return value_.value();
|
||||
}
|
||||
|
||||
// Getter methods that look the same as absl::optional<T>. Please prefer these
|
||||
// in order to unblock replacing RTCStatsMember<T> with absl::optional<T> in
|
||||
// the future (https://crbug.com/webrtc/15164).
|
||||
bool has_value() const { return value_.has_value(); }
|
||||
const T& value() const { return value_.value(); }
|
||||
T& value() { return value_.value(); }
|
||||
T& operator*() {
|
||||
RTC_DCHECK(value_);
|
||||
return *value_;
|
||||
}
|
||||
const T& operator*() const {
|
||||
RTC_DCHECK(value_);
|
||||
return *value_;
|
||||
}
|
||||
T* operator->() {
|
||||
RTC_DCHECK(value_);
|
||||
return &(*value_);
|
||||
}
|
||||
const T* operator->() const {
|
||||
RTC_DCHECK(value_);
|
||||
return &(*value_);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool IsEqual(const RTCStatsMemberInterface& other) const override {
|
||||
if (type() != other.type())
|
||||
return false;
|
||||
const RTCStatsMember<T>& other_t =
|
||||
static_cast<const RTCStatsMember<T>&>(other);
|
||||
return value_ == other_t.value_;
|
||||
}
|
||||
|
||||
private:
|
||||
absl::optional<T> value_;
|
||||
};
|
||||
|
||||
namespace rtc_stats_internal {
|
||||
|
||||
typedef std::map<std::string, uint64_t> MapStringUint64;
|
||||
typedef std::map<std::string, double> MapStringDouble;
|
||||
|
||||
} // namespace rtc_stats_internal
|
||||
|
||||
#define WEBRTC_DECLARE_RTCSTATSMEMBER(T) \
|
||||
template <> \
|
||||
RTC_EXPORT RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType(); \
|
||||
template <> \
|
||||
RTC_EXPORT bool RTCStatsMember<T>::is_sequence() const; \
|
||||
template <> \
|
||||
RTC_EXPORT bool RTCStatsMember<T>::is_string() const; \
|
||||
template <> \
|
||||
RTC_EXPORT std::string RTCStatsMember<T>::ValueToString() const; \
|
||||
template <> \
|
||||
RTC_EXPORT std::string RTCStatsMember<T>::ValueToJson() const; \
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT) \
|
||||
RTCStatsMember<T>
|
||||
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(bool);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(double);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::string);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<bool>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int32_t>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint32_t>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int64_t>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint64_t>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<double>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<std::string>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_STATS_RTC_STATS_H_
|
||||
|
||||
207
api/stats/rtc_stats_member.h
Normal file
207
api/stats/rtc_stats_member.h
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright 2023 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.
|
||||
*/
|
||||
|
||||
#ifndef API_STATS_RTC_STATS_MEMBER_H_
|
||||
#define API_STATS_RTC_STATS_MEMBER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
#include "rtc_base/system/rtc_export_template.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Interface for `RTCStats` members, which have a name and a value of a type
|
||||
// defined in a subclass. Only the types listed in `Type` are supported, these
|
||||
// are implemented by `RTCStatsMember<T>`. The value of a member may be
|
||||
// undefined, the value can only be read if `is_defined`.
|
||||
class RTCStatsMemberInterface {
|
||||
public:
|
||||
// Member value types.
|
||||
enum Type {
|
||||
kBool, // bool
|
||||
kInt32, // int32_t
|
||||
kUint32, // uint32_t
|
||||
kInt64, // int64_t
|
||||
kUint64, // uint64_t
|
||||
kDouble, // double
|
||||
kString, // std::string
|
||||
|
||||
kSequenceBool, // std::vector<bool>
|
||||
kSequenceInt32, // std::vector<int32_t>
|
||||
kSequenceUint32, // std::vector<uint32_t>
|
||||
kSequenceInt64, // std::vector<int64_t>
|
||||
kSequenceUint64, // std::vector<uint64_t>
|
||||
kSequenceDouble, // std::vector<double>
|
||||
kSequenceString, // std::vector<std::string>
|
||||
|
||||
kMapStringUint64, // std::map<std::string, uint64_t>
|
||||
kMapStringDouble, // std::map<std::string, double>
|
||||
};
|
||||
|
||||
virtual ~RTCStatsMemberInterface() {}
|
||||
|
||||
const char* name() const { return name_; }
|
||||
virtual Type type() const = 0;
|
||||
virtual bool is_sequence() const = 0;
|
||||
virtual bool is_string() const = 0;
|
||||
virtual bool is_defined() const = 0;
|
||||
// Type and value comparator. The names are not compared. These operators are
|
||||
// exposed for testing.
|
||||
bool operator==(const RTCStatsMemberInterface& other) const {
|
||||
return IsEqual(other);
|
||||
}
|
||||
bool operator!=(const RTCStatsMemberInterface& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
virtual std::string ValueToString() const = 0;
|
||||
// This is the same as ValueToString except for kInt64 and kUint64 types,
|
||||
// where the value is represented as a double instead of as an integer.
|
||||
// Since JSON stores numbers as floating point numbers, very large integers
|
||||
// cannot be accurately represented, so we prefer to display them as doubles
|
||||
// instead.
|
||||
virtual std::string ValueToJson() const = 0;
|
||||
|
||||
template <typename T>
|
||||
const T& cast_to() const {
|
||||
RTC_DCHECK_EQ(type(), T::StaticType());
|
||||
return static_cast<const T&>(*this);
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit RTCStatsMemberInterface(const char* name) : name_(name) {}
|
||||
|
||||
virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0;
|
||||
|
||||
const char* const name_;
|
||||
};
|
||||
|
||||
// Template implementation of `RTCStatsMemberInterface`.
|
||||
// The supported types are the ones described by
|
||||
// `RTCStatsMemberInterface::Type`.
|
||||
template <typename T>
|
||||
class RTCStatsMember : public RTCStatsMemberInterface {
|
||||
public:
|
||||
explicit RTCStatsMember(const char* name)
|
||||
: RTCStatsMemberInterface(name), value_() {}
|
||||
RTCStatsMember(const char* name, const T& value)
|
||||
: RTCStatsMemberInterface(name), value_(value) {}
|
||||
RTCStatsMember(const char* name, T&& value)
|
||||
: RTCStatsMemberInterface(name), value_(std::move(value)) {}
|
||||
explicit RTCStatsMember(const RTCStatsMember<T>& other)
|
||||
: RTCStatsMemberInterface(other.name_), value_(other.value_) {}
|
||||
explicit RTCStatsMember(RTCStatsMember<T>&& other)
|
||||
: RTCStatsMemberInterface(other.name_), value_(std::move(other.value_)) {}
|
||||
|
||||
static Type StaticType();
|
||||
Type type() const override { return StaticType(); }
|
||||
bool is_sequence() const override;
|
||||
bool is_string() const override;
|
||||
bool is_defined() const override { return value_.has_value(); }
|
||||
std::string ValueToString() const override;
|
||||
std::string ValueToJson() const override;
|
||||
|
||||
template <typename U>
|
||||
inline T ValueOrDefault(U default_value) const {
|
||||
return value_.value_or(default_value);
|
||||
}
|
||||
|
||||
// Assignment operators.
|
||||
T& operator=(const T& value) {
|
||||
value_ = value;
|
||||
return value_.value();
|
||||
}
|
||||
T& operator=(const T&& value) {
|
||||
value_ = std::move(value);
|
||||
return value_.value();
|
||||
}
|
||||
|
||||
// Getter methods that look the same as absl::optional<T>. Please prefer these
|
||||
// in order to unblock replacing RTCStatsMember<T> with absl::optional<T> in
|
||||
// the future (https://crbug.com/webrtc/15164).
|
||||
bool has_value() const { return value_.has_value(); }
|
||||
const T& value() const { return value_.value(); }
|
||||
T& value() { return value_.value(); }
|
||||
T& operator*() {
|
||||
RTC_DCHECK(value_);
|
||||
return *value_;
|
||||
}
|
||||
const T& operator*() const {
|
||||
RTC_DCHECK(value_);
|
||||
return *value_;
|
||||
}
|
||||
T* operator->() {
|
||||
RTC_DCHECK(value_);
|
||||
return &(*value_);
|
||||
}
|
||||
const T* operator->() const {
|
||||
RTC_DCHECK(value_);
|
||||
return &(*value_);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool IsEqual(const RTCStatsMemberInterface& other) const override {
|
||||
if (type() != other.type())
|
||||
return false;
|
||||
const RTCStatsMember<T>& other_t =
|
||||
static_cast<const RTCStatsMember<T>&>(other);
|
||||
return value_ == other_t.value_;
|
||||
}
|
||||
|
||||
private:
|
||||
absl::optional<T> value_;
|
||||
};
|
||||
|
||||
namespace rtc_stats_internal {
|
||||
|
||||
typedef std::map<std::string, uint64_t> MapStringUint64;
|
||||
typedef std::map<std::string, double> MapStringDouble;
|
||||
|
||||
} // namespace rtc_stats_internal
|
||||
|
||||
#define WEBRTC_DECLARE_RTCSTATSMEMBER(T) \
|
||||
template <> \
|
||||
RTC_EXPORT RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType(); \
|
||||
template <> \
|
||||
RTC_EXPORT bool RTCStatsMember<T>::is_sequence() const; \
|
||||
template <> \
|
||||
RTC_EXPORT bool RTCStatsMember<T>::is_string() const; \
|
||||
template <> \
|
||||
RTC_EXPORT std::string RTCStatsMember<T>::ValueToString() const; \
|
||||
template <> \
|
||||
RTC_EXPORT std::string RTCStatsMember<T>::ValueToJson() const; \
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT) \
|
||||
RTCStatsMember<T>
|
||||
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(bool);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(double);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::string);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<bool>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int32_t>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint32_t>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int64_t>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint64_t>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<double>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<std::string>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_STATS_RTC_STATS_MEMBER_H_
|
||||
@ -17,6 +17,7 @@ rtc_library("rtc_stats") {
|
||||
cflags = []
|
||||
sources = [
|
||||
"rtc_stats.cc",
|
||||
"rtc_stats_member.cc",
|
||||
"rtc_stats_report.cc",
|
||||
"rtcstats_objects.cc",
|
||||
]
|
||||
|
||||
@ -12,112 +12,10 @@
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "rtc_base/arraysize.h"
|
||||
#include "rtc_base/string_encode.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
// Produces "[a,b,c]". Works for non-vector `RTCStatsMemberInterface::Type`
|
||||
// types.
|
||||
template <typename T>
|
||||
std::string VectorToString(const std::vector<T>& vector) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "[";
|
||||
const char* separator = "";
|
||||
for (const T& element : vector) {
|
||||
sb << separator << rtc::ToString(element);
|
||||
separator = ",";
|
||||
}
|
||||
sb << "]";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
// This overload is required because std::vector<bool> range loops don't
|
||||
// return references but objects, causing -Wrange-loop-analysis diagnostics.
|
||||
std::string VectorToString(const std::vector<bool>& vector) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "[";
|
||||
const char* separator = "";
|
||||
for (bool element : vector) {
|
||||
sb << separator << rtc::ToString(element);
|
||||
separator = ",";
|
||||
}
|
||||
sb << "]";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
// Produces "[\"a\",\"b\",\"c\"]". Works for vectors of both const char* and
|
||||
// std::string element types.
|
||||
template <typename T>
|
||||
std::string VectorOfStringsToString(const std::vector<T>& strings) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "[";
|
||||
const char* separator = "";
|
||||
for (const T& element : strings) {
|
||||
sb << separator << "\"" << rtc::ToString(element) << "\"";
|
||||
separator = ",";
|
||||
}
|
||||
sb << "]";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string MapToString(const std::map<std::string, T>& map) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "{";
|
||||
const char* separator = "";
|
||||
for (const auto& element : map) {
|
||||
sb << separator << rtc::ToString(element.first) << ":"
|
||||
<< rtc::ToString(element.second);
|
||||
separator = ",";
|
||||
}
|
||||
sb << "}";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string ToStringAsDouble(const T value) {
|
||||
// JSON represents numbers as floating point numbers with about 15 decimal
|
||||
// digits of precision.
|
||||
char buf[32];
|
||||
const int len = std::snprintf(&buf[0], arraysize(buf), "%.16g",
|
||||
static_cast<double>(value));
|
||||
RTC_DCHECK_LE(len, arraysize(buf));
|
||||
return std::string(&buf[0], len);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string VectorToStringAsDouble(const std::vector<T>& vector) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "[";
|
||||
const char* separator = "";
|
||||
for (const T& element : vector) {
|
||||
sb << separator << ToStringAsDouble<T>(element);
|
||||
separator = ",";
|
||||
}
|
||||
sb << "]";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string MapToStringAsDouble(const std::map<std::string, T>& map) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "{";
|
||||
const char* separator = "";
|
||||
for (const auto& element : map) {
|
||||
sb << separator << "\"" << rtc::ToString(element.first)
|
||||
<< "\":" << ToStringAsDouble(element.second);
|
||||
separator = ",";
|
||||
}
|
||||
sb << "}";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool RTCStats::operator==(const RTCStats& other) const {
|
||||
if (type() != other.type() || id() != other.id())
|
||||
return false;
|
||||
@ -172,126 +70,4 @@ RTCStats::MembersOfThisObjectAndAncestors(size_t additional_capacity) const {
|
||||
return members;
|
||||
}
|
||||
|
||||
#define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \
|
||||
template <> \
|
||||
RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType() { \
|
||||
return type; \
|
||||
} \
|
||||
template <> \
|
||||
bool RTCStatsMember<T>::is_sequence() const { \
|
||||
return is_seq; \
|
||||
} \
|
||||
template <> \
|
||||
bool RTCStatsMember<T>::is_string() const { \
|
||||
return is_str; \
|
||||
} \
|
||||
template <> \
|
||||
std::string RTCStatsMember<T>::ValueToString() const { \
|
||||
RTC_DCHECK(value_.has_value()); \
|
||||
return to_str; \
|
||||
} \
|
||||
template <> \
|
||||
std::string RTCStatsMember<T>::ValueToJson() const { \
|
||||
RTC_DCHECK(value_.has_value()); \
|
||||
return to_json; \
|
||||
} \
|
||||
template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember<T>
|
||||
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(bool,
|
||||
kBool,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
rtc::ToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t,
|
||||
kInt32,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
rtc::ToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t,
|
||||
kUint32,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
rtc::ToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t,
|
||||
kInt64,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
ToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t,
|
||||
kUint64,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
ToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(double,
|
||||
kDouble,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
ToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::string,
|
||||
kString,
|
||||
false,
|
||||
true,
|
||||
*value_,
|
||||
*value_);
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<bool>,
|
||||
kSequenceBool,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int32_t>,
|
||||
kSequenceInt32,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint32_t>,
|
||||
kSequenceUint32,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int64_t>,
|
||||
kSequenceInt64,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint64_t>,
|
||||
kSequenceUint64,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<double>,
|
||||
kSequenceDouble,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<std::string>,
|
||||
kSequenceString,
|
||||
true,
|
||||
false,
|
||||
VectorOfStringsToString(*value_),
|
||||
VectorOfStringsToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64,
|
||||
kMapStringUint64,
|
||||
false,
|
||||
false,
|
||||
MapToString(*value_),
|
||||
MapToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble,
|
||||
kMapStringDouble,
|
||||
false,
|
||||
false,
|
||||
MapToString(*value_),
|
||||
MapToStringAsDouble(*value_));
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
240
stats/rtc_stats_member.cc
Normal file
240
stats/rtc_stats_member.cc
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright 2023 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/rtc_stats_member.h"
|
||||
|
||||
#include "rtc_base/arraysize.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
// Produces "[a,b,c]". Works for non-vector `RTCStatsMemberInterface::Type`
|
||||
// types.
|
||||
template <typename T>
|
||||
std::string VectorToString(const std::vector<T>& vector) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "[";
|
||||
const char* separator = "";
|
||||
for (const T& element : vector) {
|
||||
sb << separator << rtc::ToString(element);
|
||||
separator = ",";
|
||||
}
|
||||
sb << "]";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
// This overload is required because std::vector<bool> range loops don't
|
||||
// return references but objects, causing -Wrange-loop-analysis diagnostics.
|
||||
std::string VectorToString(const std::vector<bool>& vector) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "[";
|
||||
const char* separator = "";
|
||||
for (bool element : vector) {
|
||||
sb << separator << rtc::ToString(element);
|
||||
separator = ",";
|
||||
}
|
||||
sb << "]";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
// Produces "[\"a\",\"b\",\"c\"]". Works for vectors of both const char* and
|
||||
// std::string element types.
|
||||
template <typename T>
|
||||
std::string VectorOfStringsToString(const std::vector<T>& strings) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "[";
|
||||
const char* separator = "";
|
||||
for (const T& element : strings) {
|
||||
sb << separator << "\"" << rtc::ToString(element) << "\"";
|
||||
separator = ",";
|
||||
}
|
||||
sb << "]";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string MapToString(const std::map<std::string, T>& map) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "{";
|
||||
const char* separator = "";
|
||||
for (const auto& element : map) {
|
||||
sb << separator << rtc::ToString(element.first) << ":"
|
||||
<< rtc::ToString(element.second);
|
||||
separator = ",";
|
||||
}
|
||||
sb << "}";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string ToStringAsDouble(const T value) {
|
||||
// JSON represents numbers as floating point numbers with about 15 decimal
|
||||
// digits of precision.
|
||||
char buf[32];
|
||||
const int len = std::snprintf(&buf[0], arraysize(buf), "%.16g",
|
||||
static_cast<double>(value));
|
||||
RTC_DCHECK_LE(len, arraysize(buf));
|
||||
return std::string(&buf[0], len);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string VectorToStringAsDouble(const std::vector<T>& vector) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "[";
|
||||
const char* separator = "";
|
||||
for (const T& element : vector) {
|
||||
sb << separator << ToStringAsDouble<T>(element);
|
||||
separator = ",";
|
||||
}
|
||||
sb << "]";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string MapToStringAsDouble(const std::map<std::string, T>& map) {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "{";
|
||||
const char* separator = "";
|
||||
for (const auto& element : map) {
|
||||
sb << separator << "\"" << rtc::ToString(element.first)
|
||||
<< "\":" << ToStringAsDouble(element.second);
|
||||
separator = ",";
|
||||
}
|
||||
sb << "}";
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \
|
||||
template <> \
|
||||
RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType() { \
|
||||
return type; \
|
||||
} \
|
||||
template <> \
|
||||
bool RTCStatsMember<T>::is_sequence() const { \
|
||||
return is_seq; \
|
||||
} \
|
||||
template <> \
|
||||
bool RTCStatsMember<T>::is_string() const { \
|
||||
return is_str; \
|
||||
} \
|
||||
template <> \
|
||||
std::string RTCStatsMember<T>::ValueToString() const { \
|
||||
RTC_DCHECK(value_.has_value()); \
|
||||
return to_str; \
|
||||
} \
|
||||
template <> \
|
||||
std::string RTCStatsMember<T>::ValueToJson() const { \
|
||||
RTC_DCHECK(value_.has_value()); \
|
||||
return to_json; \
|
||||
} \
|
||||
template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember<T>
|
||||
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(bool,
|
||||
kBool,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
rtc::ToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t,
|
||||
kInt32,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
rtc::ToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t,
|
||||
kUint32,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
rtc::ToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t,
|
||||
kInt64,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
ToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t,
|
||||
kUint64,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
ToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(double,
|
||||
kDouble,
|
||||
false,
|
||||
false,
|
||||
rtc::ToString(*value_),
|
||||
ToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::string,
|
||||
kString,
|
||||
false,
|
||||
true,
|
||||
*value_,
|
||||
*value_);
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<bool>,
|
||||
kSequenceBool,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int32_t>,
|
||||
kSequenceInt32,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint32_t>,
|
||||
kSequenceUint32,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int64_t>,
|
||||
kSequenceInt64,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint64_t>,
|
||||
kSequenceUint64,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<double>,
|
||||
kSequenceDouble,
|
||||
true,
|
||||
false,
|
||||
VectorToString(*value_),
|
||||
VectorToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<std::string>,
|
||||
kSequenceString,
|
||||
true,
|
||||
false,
|
||||
VectorOfStringsToString(*value_),
|
||||
VectorOfStringsToString(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64,
|
||||
kMapStringUint64,
|
||||
false,
|
||||
false,
|
||||
MapToString(*value_),
|
||||
MapToStringAsDouble(*value_));
|
||||
WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble,
|
||||
kMapStringDouble,
|
||||
false,
|
||||
false,
|
||||
MapToString(*value_),
|
||||
MapToStringAsDouble(*value_));
|
||||
|
||||
} // namespace webrtc
|
||||
Loading…
x
Reference in New Issue
Block a user