blob: e6eb51e55c35e97761f63c4b2245b5245e867288 [file] [log] [blame]
hbos615d3012016-08-24 08:33:131/*
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 17:11:0011#include "api/stats/rtc_stats.h"
hbos615d3012016-08-24 08:33:1312
Steve Antona29b3a62018-12-27 23:44:2513#include <cstdio>
hbos6ded1902016-11-01 08:50:4614
Steve Antona29b3a62018-12-27 23:44:2515#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 17:11:0016#include "rtc_base/string_encode.h"
Steve Antona29b3a62018-12-27 23:44:2517#include "rtc_base/strings/string_builder.h"
hbos615d3012016-08-24 08:33:1318
19namespace webrtc {
20
21namespace {
22
Artem Titovcfea2182021-08-09 23:22:3123// Produces "[a,b,c]". Works for non-vector `RTCStatsMemberInterface::Type`
hbos615d3012016-08-24 08:33:1324// types.
Yves Gerey665174f2018-06-19 13:03:0525template <typename T>
hbos615d3012016-08-24 08:33:1326std::string VectorToString(const std::vector<T>& vector) {
Steve Antona29b3a62018-12-27 23:44:2527 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 08:33:1333 }
Steve Antona29b3a62018-12-27 23:44:2534 sb << "]";
35 return sb.Release();
hbos615d3012016-08-24 08:33:1336}
37
Mirko Bonadei85fae2a2020-11-05 15:08:1338// This overload is required because std::vector<bool> range loops don't
39// return references but objects, causing -Wrange-loop-analysis diagnostics.
40std::string VectorToString(const std::vector<bool>& vector) {
41 rtc::StringBuilder sb;
42 sb << "[";
43 const char* separator = "";
44 for (bool element : vector) {
45 sb << separator << rtc::ToString(element);
46 separator = ",";
47 }
48 sb << "]";
49 return sb.Release();
50}
51
ehmaldonado35a872c2017-07-28 14:29:1252// Produces "[\"a\",\"b\",\"c\"]". Works for vectors of both const char* and
hbos615d3012016-08-24 08:33:1353// std::string element types.
Yves Gerey665174f2018-06-19 13:03:0554template <typename T>
hbos615d3012016-08-24 08:33:1355std::string VectorOfStringsToString(const std::vector<T>& strings) {
Steve Antona29b3a62018-12-27 23:44:2556 rtc::StringBuilder sb;
57 sb << "[";
58 const char* separator = "";
59 for (const T& element : strings) {
60 sb << separator << "\"" << rtc::ToString(element) << "\"";
61 separator = ",";
hbos615d3012016-08-24 08:33:1362 }
Steve Antona29b3a62018-12-27 23:44:2563 sb << "]";
64 return sb.Release();
ehmaldonado35a872c2017-07-28 14:29:1265}
66
67template <typename T>
Byoungchan Lee0a52ede2021-05-21 23:41:0268std::string MapToString(const std::map<std::string, T>& map) {
69 rtc::StringBuilder sb;
70 sb << "{";
71 const char* separator = "";
72 for (const auto& element : map) {
73 sb << separator << rtc::ToString(element.first) << ":"
74 << rtc::ToString(element.second);
75 separator = ",";
76 }
77 sb << "}";
78 return sb.Release();
79}
80
81template <typename T>
ehmaldonado35a872c2017-07-28 14:29:1282std::string ToStringAsDouble(const T value) {
83 // JSON represents numbers as floating point numbers with about 15 decimal
84 // digits of precision.
Steve Antona29b3a62018-12-27 23:44:2585 char buf[32];
86 const int len = std::snprintf(&buf[0], arraysize(buf), "%.16g",
87 static_cast<double>(value));
88 RTC_DCHECK_LE(len, arraysize(buf));
89 return std::string(&buf[0], len);
ehmaldonado35a872c2017-07-28 14:29:1290}
91
92template <typename T>
93std::string VectorToStringAsDouble(const std::vector<T>& vector) {
Steve Antona29b3a62018-12-27 23:44:2594 rtc::StringBuilder sb;
95 sb << "[";
96 const char* separator = "";
97 for (const T& element : vector) {
98 sb << separator << ToStringAsDouble<T>(element);
99 separator = ",";
ehmaldonado35a872c2017-07-28 14:29:12100 }
Steve Antona29b3a62018-12-27 23:44:25101 sb << "]";
102 return sb.Release();
hbos615d3012016-08-24 08:33:13103}
104
Byoungchan Lee0a52ede2021-05-21 23:41:02105template <typename T>
106std::string MapToStringAsDouble(const std::map<std::string, T>& map) {
107 rtc::StringBuilder sb;
108 sb << "{";
109 const char* separator = "";
110 for (const auto& element : map) {
111 sb << separator << "\"" << rtc::ToString(element.first)
112 << "\":" << ToStringAsDouble(element.second);
113 separator = ",";
114 }
115 sb << "}";
116 return sb.Release();
117}
118
hbos615d3012016-08-24 08:33:13119} // namespace
120
hbos67c8bc42016-10-25 11:31:23121bool RTCStats::operator==(const RTCStats& other) const {
hbos0583b282016-11-30 09:50:14122 if (type() != other.type() || id() != other.id())
hbos67c8bc42016-10-25 11:31:23123 return false;
hbos67c8bc42016-10-25 11:31:23124 std::vector<const RTCStatsMemberInterface*> members = Members();
125 std::vector<const RTCStatsMemberInterface*> other_members = other.Members();
126 RTC_DCHECK_EQ(members.size(), other_members.size());
127 for (size_t i = 0; i < members.size(); ++i) {
128 const RTCStatsMemberInterface* member = members[i];
129 const RTCStatsMemberInterface* other_member = other_members[i];
130 RTC_DCHECK_EQ(member->type(), other_member->type());
131 RTC_DCHECK_EQ(member->name(), other_member->name());
132 if (*member != *other_member)
133 return false;
134 }
135 return true;
136}
137
138bool RTCStats::operator!=(const RTCStats& other) const {
139 return !(*this == other);
140}
141
ehmaldonado35a872c2017-07-28 14:29:12142std::string RTCStats::ToJson() const {
Steve Antona29b3a62018-12-27 23:44:25143 rtc::StringBuilder sb;
Jonas Olssonb2b20312020-01-14 11:11:31144 sb << "{\"type\":\"" << type()
145 << "\","
146 "\"id\":\""
147 << id_
148 << "\","
149 "\"timestamp\":"
150 << timestamp_us_;
hbos615d3012016-08-24 08:33:13151 for (const RTCStatsMemberInterface* member : Members()) {
hbos615d3012016-08-24 08:33:13152 if (member->is_defined()) {
Steve Antona29b3a62018-12-27 23:44:25153 sb << ",\"" << member->name() << "\":";
hbos615d3012016-08-24 08:33:13154 if (member->is_string())
Steve Antona29b3a62018-12-27 23:44:25155 sb << "\"" << member->ValueToJson() << "\"";
hbos615d3012016-08-24 08:33:13156 else
Steve Antona29b3a62018-12-27 23:44:25157 sb << member->ValueToJson();
hbos615d3012016-08-24 08:33:13158 }
159 }
Steve Antona29b3a62018-12-27 23:44:25160 sb << "}";
161 return sb.Release();
hbos615d3012016-08-24 08:33:13162}
163
164std::vector<const RTCStatsMemberInterface*> RTCStats::Members() const {
165 return MembersOfThisObjectAndAncestors(0);
166}
167
168std::vector<const RTCStatsMemberInterface*>
Yves Gerey665174f2018-06-19 13:03:05169RTCStats::MembersOfThisObjectAndAncestors(size_t additional_capacity) const {
hbos615d3012016-08-24 08:33:13170 std::vector<const RTCStatsMemberInterface*> members;
171 members.reserve(additional_capacity);
172 return members;
173}
174
ehmaldonado35a872c2017-07-28 14:29:12175#define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \
176 template <> \
Mirko Bonadei054f1852019-11-04 15:31:08177 RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType() { \
178 return type; \
179 } \
ehmaldonado35a872c2017-07-28 14:29:12180 template <> \
181 bool RTCStatsMember<T>::is_sequence() const { \
182 return is_seq; \
183 } \
184 template <> \
185 bool RTCStatsMember<T>::is_string() const { \
186 return is_str; \
187 } \
188 template <> \
hbos615d3012016-08-24 08:33:13189 std::string RTCStatsMember<T>::ValueToString() const { \
190 RTC_DCHECK(is_defined_); \
191 return to_str; \
ehmaldonado35a872c2017-07-28 14:29:12192 } \
193 template <> \
194 std::string RTCStatsMember<T>::ValueToJson() const { \
195 RTC_DCHECK(is_defined_); \
196 return to_json; \
Mirko Bonadei054f1852019-11-04 15:31:08197 } \
198 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember<T>
hbos615d3012016-08-24 08:33:13199
ehmaldonado35a872c2017-07-28 14:29:12200WEBRTC_DEFINE_RTCSTATSMEMBER(bool,
201 kBool,
202 false,
203 false,
204 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08205 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 14:29:12206WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t,
207 kInt32,
208 false,
209 false,
210 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08211 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 14:29:12212WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t,
213 kUint32,
214 false,
215 false,
216 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08217 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 14:29:12218WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t,
219 kInt64,
220 false,
221 false,
222 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08223 ToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 14:29:12224WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t,
225 kUint64,
226 false,
227 false,
228 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08229 ToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 14:29:12230WEBRTC_DEFINE_RTCSTATSMEMBER(double,
231 kDouble,
232 false,
233 false,
234 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08235 ToStringAsDouble(value_));
236WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true, value_, value_);
ehmaldonado35a872c2017-07-28 14:29:12237WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<bool>,
238 kSequenceBool,
239 true,
240 false,
241 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08242 VectorToString(value_));
ehmaldonado35a872c2017-07-28 14:29:12243WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int32_t>,
244 kSequenceInt32,
245 true,
246 false,
247 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08248 VectorToString(value_));
ehmaldonado35a872c2017-07-28 14:29:12249WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint32_t>,
250 kSequenceUint32,
251 true,
252 false,
253 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08254 VectorToString(value_));
ehmaldonado35a872c2017-07-28 14:29:12255WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int64_t>,
256 kSequenceInt64,
257 true,
258 false,
259 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08260 VectorToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 14:29:12261WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint64_t>,
262 kSequenceUint64,
263 true,
264 false,
265 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08266 VectorToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 14:29:12267WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<double>,
268 kSequenceDouble,
269 true,
270 false,
271 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08272 VectorToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 14:29:12273WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<std::string>,
274 kSequenceString,
275 true,
276 false,
277 VectorOfStringsToString(value_),
Mirko Bonadei054f1852019-11-04 15:31:08278 VectorOfStringsToString(value_));
Byoungchan Lee0a52ede2021-05-21 23:41:02279WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64,
280 kMapStringUint64,
281 false,
282 false,
283 MapToString(value_),
284 MapToStringAsDouble(value_));
285WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble,
286 kMapStringDouble,
287 false,
288 false,
289 MapToString(value_),
290 MapToStringAsDouble(value_));
hbos615d3012016-08-24 08:33:13291
Mirko Bonadei759f1612019-11-13 10:18:31292template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
293 RTCNonStandardStatsMember<bool>;
294template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
295 RTCNonStandardStatsMember<int32_t>;
296template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
297 RTCNonStandardStatsMember<uint32_t>;
298template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
299 RTCNonStandardStatsMember<int64_t>;
300template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
301 RTCNonStandardStatsMember<uint64_t>;
302template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
303 RTCNonStandardStatsMember<double>;
304template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
305 RTCNonStandardStatsMember<std::string>;
306template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
307 RTCNonStandardStatsMember<std::vector<bool>>;
308template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
309 RTCNonStandardStatsMember<std::vector<int32_t>>;
310template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
311 RTCNonStandardStatsMember<std::vector<uint32_t>>;
312template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
313 RTCNonStandardStatsMember<std::vector<int64_t>>;
314template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
315 RTCNonStandardStatsMember<std::vector<uint64_t>>;
316template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
317 RTCNonStandardStatsMember<std::vector<double>>;
318template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
319 RTCNonStandardStatsMember<std::vector<std::string>>;
320
hbos615d3012016-08-24 08:33:13321} // namespace webrtc