webrtc_m130/api/stats/rtc_stats_member.h
Henrik Boström 7209548090 Reland "[Stats] Attribute::ToString(), to replace member ValueToString/ToJson."
This is a reland of commit 54be7084e0861a0179a5fccd0b27edf7d7994bbb

Previously reverted due to an importer issue (b/320646178) and later a
dependency on RTCStatsMember<T>::ValueToString().

In this reland, we add Attribute::ToString() but we don't delete the
RTCStatsMember<T> stringifier methods, allowing downstream to migrate
before they are deleted.

Original change's description:
> [Stats] Attribute::ToString(), to replace member ValueToString/ToJson.
>
> Delete RTCStatsMember<T>::ValueToString() and ValueToJson() in favor of
> Attribute::ToString().
>
> The difference between "ToString" and "ToJson" is that the "ToJson"
> version converts 64-bit integers and doubles to floating points with no
> more than ~15 digits of precision as to not exceed JSON's precision
> limitations. So only in edge cases of really large numbers or numbers
> with a silly number of digits will the two methods produce different
> results. Also JSON puts '\"' around map key names, e.g. "{\"foo\":123}"
> as opposed to "{foo:123}".
>
> Going forward we see no reason to maintain two different string
> converted paths that are this similar, so we only implement one
> Attribute::ToString() method which does what "ToJson" did.
>
> In the next CL we can delete RTCStatsMember<T>.
>
> Bug: webrtc:15164
> Change-Id: Iaa8cf3bf14b40dc44664f75989832469603131c5
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/334640
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Reviewed-by: Evan Shrubsole <eshr@google.com>
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#41544}

Bug: webrtc:15164
Change-Id: I281ccf5b23d8f194b5ce00186a32846c757b46fc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/334860
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41575}
2024-01-19 14:42:10 +00:00

194 lines
6.5 KiB
C++

/*
* 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() {}
virtual Type type() const = 0;
virtual bool is_sequence() const = 0;
virtual bool is_string() const = 0;
virtual bool has_value() 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 const RTCStatsMemberInterface* member_ptr() const { return this; }
template <typename T>
const T& cast_to() const {
RTC_DCHECK_EQ(type(), T::StaticType());
return static_cast<const T&>(*member_ptr());
}
protected:
virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0;
};
// Template implementation of `RTCStatsMemberInterface`.
// The supported types are the ones described by
// `RTCStatsMemberInterface::Type`.
template <typename T>
class RTCStatsMember : public RTCStatsMemberInterface {
public:
RTCStatsMember() {}
explicit RTCStatsMember(const T& value) : value_(value) {}
static Type StaticType();
Type type() const override { return StaticType(); }
bool is_sequence() const override;
bool is_string() const override;
// TODO(https://crbug.com/webrtc/15164): Delete both in favor of
// Attribute::ToString().
std::string ValueToString() const;
std::string ValueToJson() const;
template <typename U>
inline T value_or(U default_value) const {
return value_.value_or(default_value);
}
// TODO(https://crbug.com/webrtc/15164): Migrate to value_or() and delete.
template <typename U>
inline T ValueOrDefault(U default_value) const {
return 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 override { 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_);
}
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_