blob: b8e9633f460dd3dc0e356a7d4b10f6c18a4fcbfb [file] [log] [blame]
hbos615d3012016-08-24 01:33:13 -07001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "api/stats/rtc_stats.h"
hbos615d3012016-08-24 01:33:13 -070012
Steve Antona29b3a62018-12-27 15:44:25 -080013#include <cstdio>
hbos6ded1902016-11-01 01:50:46 -070014
Steve Antona29b3a62018-12-27 15:44:25 -080015#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080016#include "rtc_base/string_encode.h"
Steve Antona29b3a62018-12-27 15:44:25 -080017#include "rtc_base/strings/string_builder.h"
hbos615d3012016-08-24 01:33:13 -070018
19namespace webrtc {
20
21namespace {
22
ehmaldonado35a872c2017-07-28 07:29:12 -070023// Produces "[a,b,c]". Works for non-vector |RTCStatsMemberInterface::Type|
hbos615d3012016-08-24 01:33:13 -070024// types.
Yves Gerey665174f2018-06-19 15:03:05 +020025template <typename T>
hbos615d3012016-08-24 01:33:13 -070026std::string VectorToString(const std::vector<T>& vector) {
Steve Antona29b3a62018-12-27 15:44:25 -080027 rtc::StringBuilder sb;
28 sb << "[";
29 const char* separator = "";
30 for (const T& element : vector) {
31 sb << separator << rtc::ToString(element);
32 separator = ",";
hbos615d3012016-08-24 01:33:13 -070033 }
Steve Antona29b3a62018-12-27 15:44:25 -080034 sb << "]";
35 return sb.Release();
hbos615d3012016-08-24 01:33:13 -070036}
37
ehmaldonado35a872c2017-07-28 07:29:12 -070038// Produces "[\"a\",\"b\",\"c\"]". Works for vectors of both const char* and
hbos615d3012016-08-24 01:33:13 -070039// std::string element types.
Yves Gerey665174f2018-06-19 15:03:05 +020040template <typename T>
hbos615d3012016-08-24 01:33:13 -070041std::string VectorOfStringsToString(const std::vector<T>& strings) {
Steve Antona29b3a62018-12-27 15:44:25 -080042 rtc::StringBuilder sb;
43 sb << "[";
44 const char* separator = "";
45 for (const T& element : strings) {
46 sb << separator << "\"" << rtc::ToString(element) << "\"";
47 separator = ",";
hbos615d3012016-08-24 01:33:13 -070048 }
Steve Antona29b3a62018-12-27 15:44:25 -080049 sb << "]";
50 return sb.Release();
ehmaldonado35a872c2017-07-28 07:29:12 -070051}
52
53template <typename T>
54std::string ToStringAsDouble(const T value) {
55 // JSON represents numbers as floating point numbers with about 15 decimal
56 // digits of precision.
Steve Antona29b3a62018-12-27 15:44:25 -080057 char buf[32];
58 const int len = std::snprintf(&buf[0], arraysize(buf), "%.16g",
59 static_cast<double>(value));
60 RTC_DCHECK_LE(len, arraysize(buf));
61 return std::string(&buf[0], len);
ehmaldonado35a872c2017-07-28 07:29:12 -070062}
63
64template <typename T>
65std::string VectorToStringAsDouble(const std::vector<T>& vector) {
Steve Antona29b3a62018-12-27 15:44:25 -080066 rtc::StringBuilder sb;
67 sb << "[";
68 const char* separator = "";
69 for (const T& element : vector) {
70 sb << separator << ToStringAsDouble<T>(element);
71 separator = ",";
ehmaldonado35a872c2017-07-28 07:29:12 -070072 }
Steve Antona29b3a62018-12-27 15:44:25 -080073 sb << "]";
74 return sb.Release();
hbos615d3012016-08-24 01:33:13 -070075}
76
77} // namespace
78
hbos67c8bc42016-10-25 04:31:23 -070079bool RTCStats::operator==(const RTCStats& other) const {
hbos0583b282016-11-30 01:50:14 -080080 if (type() != other.type() || id() != other.id())
hbos67c8bc42016-10-25 04:31:23 -070081 return false;
hbos67c8bc42016-10-25 04:31:23 -070082 std::vector<const RTCStatsMemberInterface*> members = Members();
83 std::vector<const RTCStatsMemberInterface*> other_members = other.Members();
84 RTC_DCHECK_EQ(members.size(), other_members.size());
85 for (size_t i = 0; i < members.size(); ++i) {
86 const RTCStatsMemberInterface* member = members[i];
87 const RTCStatsMemberInterface* other_member = other_members[i];
88 RTC_DCHECK_EQ(member->type(), other_member->type());
89 RTC_DCHECK_EQ(member->name(), other_member->name());
90 if (*member != *other_member)
91 return false;
92 }
93 return true;
94}
95
96bool RTCStats::operator!=(const RTCStats& other) const {
97 return !(*this == other);
98}
99
ehmaldonado35a872c2017-07-28 07:29:12 -0700100std::string RTCStats::ToJson() const {
Steve Antona29b3a62018-12-27 15:44:25 -0800101 rtc::StringBuilder sb;
Jonas Olssonb2b20312020-01-14 12:11:31 +0100102 sb << "{\"type\":\"" << type()
103 << "\","
104 "\"id\":\""
105 << id_
106 << "\","
107 "\"timestamp\":"
108 << timestamp_us_;
hbos615d3012016-08-24 01:33:13 -0700109 for (const RTCStatsMemberInterface* member : Members()) {
hbos615d3012016-08-24 01:33:13 -0700110 if (member->is_defined()) {
Steve Antona29b3a62018-12-27 15:44:25 -0800111 sb << ",\"" << member->name() << "\":";
hbos615d3012016-08-24 01:33:13 -0700112 if (member->is_string())
Steve Antona29b3a62018-12-27 15:44:25 -0800113 sb << "\"" << member->ValueToJson() << "\"";
hbos615d3012016-08-24 01:33:13 -0700114 else
Steve Antona29b3a62018-12-27 15:44:25 -0800115 sb << member->ValueToJson();
hbos615d3012016-08-24 01:33:13 -0700116 }
117 }
Steve Antona29b3a62018-12-27 15:44:25 -0800118 sb << "}";
119 return sb.Release();
hbos615d3012016-08-24 01:33:13 -0700120}
121
122std::vector<const RTCStatsMemberInterface*> RTCStats::Members() const {
123 return MembersOfThisObjectAndAncestors(0);
124}
125
126std::vector<const RTCStatsMemberInterface*>
Yves Gerey665174f2018-06-19 15:03:05 +0200127RTCStats::MembersOfThisObjectAndAncestors(size_t additional_capacity) const {
hbos615d3012016-08-24 01:33:13 -0700128 std::vector<const RTCStatsMemberInterface*> members;
129 members.reserve(additional_capacity);
130 return members;
131}
132
ehmaldonado35a872c2017-07-28 07:29:12 -0700133#define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \
134 template <> \
Mirko Bonadei054f1852019-11-04 16:31:08 +0100135 RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType() { \
136 return type; \
137 } \
ehmaldonado35a872c2017-07-28 07:29:12 -0700138 template <> \
139 bool RTCStatsMember<T>::is_sequence() const { \
140 return is_seq; \
141 } \
142 template <> \
143 bool RTCStatsMember<T>::is_string() const { \
144 return is_str; \
145 } \
146 template <> \
hbos615d3012016-08-24 01:33:13 -0700147 std::string RTCStatsMember<T>::ValueToString() const { \
148 RTC_DCHECK(is_defined_); \
149 return to_str; \
ehmaldonado35a872c2017-07-28 07:29:12 -0700150 } \
151 template <> \
152 std::string RTCStatsMember<T>::ValueToJson() const { \
153 RTC_DCHECK(is_defined_); \
154 return to_json; \
Mirko Bonadei054f1852019-11-04 16:31:08 +0100155 } \
156 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember<T>
hbos615d3012016-08-24 01:33:13 -0700157
ehmaldonado35a872c2017-07-28 07:29:12 -0700158WEBRTC_DEFINE_RTCSTATSMEMBER(bool,
159 kBool,
160 false,
161 false,
162 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100163 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700164WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t,
165 kInt32,
166 false,
167 false,
168 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100169 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700170WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t,
171 kUint32,
172 false,
173 false,
174 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100175 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700176WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t,
177 kInt64,
178 false,
179 false,
180 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100181 ToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700182WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t,
183 kUint64,
184 false,
185 false,
186 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100187 ToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700188WEBRTC_DEFINE_RTCSTATSMEMBER(double,
189 kDouble,
190 false,
191 false,
192 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100193 ToStringAsDouble(value_));
194WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true, value_, value_);
ehmaldonado35a872c2017-07-28 07:29:12 -0700195WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<bool>,
196 kSequenceBool,
197 true,
198 false,
199 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100200 VectorToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700201WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int32_t>,
202 kSequenceInt32,
203 true,
204 false,
205 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100206 VectorToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700207WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint32_t>,
208 kSequenceUint32,
209 true,
210 false,
211 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100212 VectorToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700213WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int64_t>,
214 kSequenceInt64,
215 true,
216 false,
217 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100218 VectorToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700219WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint64_t>,
220 kSequenceUint64,
221 true,
222 false,
223 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100224 VectorToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700225WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<double>,
226 kSequenceDouble,
227 true,
228 false,
229 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100230 VectorToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700231WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<std::string>,
232 kSequenceString,
233 true,
234 false,
235 VectorOfStringsToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100236 VectorOfStringsToString(value_));
hbos615d3012016-08-24 01:33:13 -0700237
Mirko Bonadei759f1612019-11-13 11:18:31 +0100238template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
239 RTCNonStandardStatsMember<bool>;
240template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
241 RTCNonStandardStatsMember<int32_t>;
242template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
243 RTCNonStandardStatsMember<uint32_t>;
244template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
245 RTCNonStandardStatsMember<int64_t>;
246template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
247 RTCNonStandardStatsMember<uint64_t>;
248template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
249 RTCNonStandardStatsMember<double>;
250template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
251 RTCNonStandardStatsMember<std::string>;
252template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
253 RTCNonStandardStatsMember<std::vector<bool>>;
254template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
255 RTCNonStandardStatsMember<std::vector<int32_t>>;
256template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
257 RTCNonStandardStatsMember<std::vector<uint32_t>>;
258template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
259 RTCNonStandardStatsMember<std::vector<int64_t>>;
260template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
261 RTCNonStandardStatsMember<std::vector<uint64_t>>;
262template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
263 RTCNonStandardStatsMember<std::vector<double>>;
264template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
265 RTCNonStandardStatsMember<std::vector<std::string>>;
266
hbos615d3012016-08-24 01:33:13 -0700267} // namespace webrtc