tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rtc_stats.h (8491B)


      1 /*
      2 *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #ifndef API_STATS_RTC_STATS_H_
     12 #define API_STATS_RTC_STATS_H_
     13 
     14 #include <stddef.h>
     15 #include <stdint.h>
     16 
     17 #include <memory>
     18 #include <optional>
     19 #include <string>
     20 #include <vector>
     21 
     22 #include "api/stats/attribute.h"
     23 #include "api/units/timestamp.h"
     24 #include "rtc_base/checks.h"
     25 #include "rtc_base/system/rtc_export.h"
     26 
     27 namespace webrtc {
     28 
     29 // Abstract base class for RTCStats-derived dictionaries, see
     30 // https://w3c.github.io/webrtc-stats/.
     31 //
     32 // All derived classes must have the following static variable defined:
     33 //   static const char kType[];
     34 // It is used as a unique class identifier and a string representation of the
     35 // class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
     36 // Use the `WEBRTC_RTCSTATS_IMPL` macro when implementing subclasses, see macro
     37 // for details.
     38 //
     39 // Derived classes list their dictionary attributes, std::optional<T>, as
     40 // public fields, allowing the following:
     41 //
     42 // RTCFooStats foo("fooId", Timestamp::Micros(GetCurrentTime()));
     43 // foo.bar = 42;
     44 // foo.baz = std::vector<std::string>();
     45 // foo.baz->push_back("hello world");
     46 // uint32_t x = *foo.bar;
     47 //
     48 // Pointers to all the attributes are available with `Attributes()`, allowing
     49 // iteration:
     50 //
     51 // for (const auto& attribute : foo.Attributes()) {
     52 //   printf("%s = %s\n", attribute.name(), attribute.ToString().c_str());
     53 // }
     54 class RTC_EXPORT RTCStats {
     55 public:
     56  RTCStats(const std::string& id, Timestamp timestamp)
     57      : id_(id), timestamp_(timestamp) {}
     58  RTCStats(const RTCStats& other);
     59  virtual ~RTCStats();
     60 
     61  virtual std::unique_ptr<RTCStats> copy() const = 0;
     62 
     63  const std::string& id() const { return id_; }
     64  // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
     65  Timestamp timestamp() const { return timestamp_; }
     66  void set_timestamp(Timestamp timestamp) { timestamp_ = timestamp; }
     67 
     68  // Returns the static member variable `kType` of the implementing class.
     69  virtual const char* type() const = 0;
     70  // Returns all attributes of this stats object, i.e. a list of its individual
     71  // metrics as viewed via the Attribute wrapper.
     72  std::vector<Attribute> Attributes() const;
     73  template <typename T>
     74  Attribute GetAttribute(const std::optional<T>& stat) const {
     75    for (const auto& attribute : Attributes()) {
     76      if (!attribute.holds_alternative<T>()) {
     77        continue;
     78      }
     79      if (std::get<const std::optional<T>*>(attribute.as_variant()) == &stat) {
     80        return attribute;
     81      }
     82    }
     83    RTC_CHECK_NOTREACHED();
     84  }
     85  // Checks if the two stats objects are of the same type and have the same
     86  // attribute values. Timestamps are not compared. These operators are exposed
     87  // for testing.
     88  bool operator==(const RTCStats& other) const;
     89  bool operator!=(const RTCStats& other) const;
     90 
     91  // Creates a JSON readable string representation of the stats
     92  // object, listing all of its attributes (names and values).
     93  std::string ToJson() const;
     94 
     95  // Downcasts the stats object to an `RTCStats` subclass `T`. DCHECKs that the
     96  // object is of type `T`.
     97  template <typename T>
     98  const T& cast_to() const {
     99    RTC_DCHECK_EQ(type(), T::kType);
    100    return static_cast<const T&>(*this);
    101  }
    102 
    103 protected:
    104  virtual std::vector<Attribute> AttributesImpl(
    105      size_t additional_capacity) const;
    106 
    107  std::string id_;
    108  Timestamp timestamp_;
    109 };
    110 
    111 // All `RTCStats` classes should use these macros.
    112 // `WEBRTC_RTCSTATS_DECL` is placed in a public section of the class definition.
    113 // `WEBRTC_RTCSTATS_IMPL` is placed outside the class definition (in a .cc).
    114 //
    115 // These macros declare (in _DECL) and define (in _IMPL) the static `kType` and
    116 // overrides methods as required by subclasses of `RTCStats`: `copy`, `type` and
    117 // `AttributesImpl`. The |...| argument is a list of addresses to each attribute
    118 // defined in the implementing class. The list must have at least one attribute.
    119 //
    120 // (Since class names need to be known to implement these methods this cannot be
    121 // part of the base `RTCStats`. While these methods could be implemented using
    122 // templates, that would only work for immediate subclasses. Subclasses of
    123 // subclasses also have to override these methods, resulting in boilerplate
    124 // code. Using a macro avoids this and works for any `RTCStats` class, including
    125 // grandchildren.)
    126 //
    127 // Sample usage:
    128 //
    129 // rtcfoostats.h:
    130 //   class RTCFooStats : public RTCStats {
    131 //    public:
    132 //     WEBRTC_RTCSTATS_DECL();
    133 //
    134 //     RTCFooStats(const std::string& id, Timestamp timestamp);
    135 //
    136 //     std::optional<int32_t> foo;
    137 //     std::optional<int32_t> bar;
    138 //   };
    139 //
    140 // rtcfoostats.cc:
    141 //   WEBRTC_RTCSTATS_IMPL(RTCFooStats, RTCStats, "foo-stats"
    142 //       &foo,
    143 //       &bar);
    144 //
    145 //   RTCFooStats::RTCFooStats(const std::string& id, Timestamp timestamp)
    146 //       : RTCStats(id, timestamp),
    147 //         foo("foo"),
    148 //         bar("bar") {
    149 //   }
    150 //
    151 #define WEBRTC_RTCSTATS_DECL(SelfT)                                         \
    152 protected:                                                                 \
    153  std::vector<webrtc::Attribute> AttributesImpl(size_t additional_capacity) \
    154      const override;                                                       \
    155                                                                            \
    156 public:                                                                    \
    157  static const char kType[];                                                \
    158                                                                            \
    159  template <typename Sink>                                                  \
    160  friend void AbslStringify(Sink& sink, const SelfT& stats) {               \
    161    sink.Append(stats.ToJson());                                            \
    162  }                                                                         \
    163                                                                            \
    164  std::unique_ptr<webrtc::RTCStats> copy() const override;                  \
    165  const char* type() const override
    166 
    167 #define WEBRTC_RTCSTATS_IMPL(this_class, parent_class, type_str, ...)         \
    168  const char this_class::kType[] = type_str;                                  \
    169                                                                              \
    170  std::unique_ptr<webrtc::RTCStats> this_class::copy() const {                \
    171    return std::make_unique<this_class>(*this);                               \
    172  }                                                                           \
    173                                                                              \
    174  const char* this_class::type() const {                                      \
    175    return this_class::kType;                                                 \
    176  }                                                                           \
    177                                                                              \
    178  std::vector<webrtc::Attribute> this_class::AttributesImpl(                  \
    179      size_t additional_capacity) const {                                     \
    180    webrtc::AttributeInit attribute_inits[] = {__VA_ARGS__};                  \
    181    size_t attribute_inits_size =                                             \
    182        sizeof(attribute_inits) / sizeof(attribute_inits[0]);                 \
    183    std::vector<webrtc::Attribute> attributes = parent_class::AttributesImpl( \
    184        attribute_inits_size + additional_capacity);                          \
    185    for (size_t i = 0; i < attribute_inits_size; ++i) {                       \
    186      attributes.push_back(std::visit(                                        \
    187          [&](const auto* field) {                                            \
    188            return Attribute(attribute_inits[i].name, field);                 \
    189          },                                                                  \
    190          attribute_inits[i].variant));                                       \
    191    }                                                                         \
    192    return attributes;                                                        \
    193  }
    194 
    195 }  // namespace webrtc
    196 
    197 #endif  // API_STATS_RTC_STATS_H_