blob: 92f64e46549d7c03074d0edf798291116a18474e [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;
102 sb << "{\"type\":\"" << type() << "\","
103 << "\"id\":\"" << id_ << "\","
104 << "\"timestamp\":" << timestamp_us_;
hbos615d3012016-08-24 01:33:13 -0700105 for (const RTCStatsMemberInterface* member : Members()) {
hbos615d3012016-08-24 01:33:13 -0700106 if (member->is_defined()) {
Steve Antona29b3a62018-12-27 15:44:25 -0800107 sb << ",\"" << member->name() << "\":";
hbos615d3012016-08-24 01:33:13 -0700108 if (member->is_string())
Steve Antona29b3a62018-12-27 15:44:25 -0800109 sb << "\"" << member->ValueToJson() << "\"";
hbos615d3012016-08-24 01:33:13 -0700110 else
Steve Antona29b3a62018-12-27 15:44:25 -0800111 sb << member->ValueToJson();
hbos615d3012016-08-24 01:33:13 -0700112 }
113 }
Steve Antona29b3a62018-12-27 15:44:25 -0800114 sb << "}";
115 return sb.Release();
hbos615d3012016-08-24 01:33:13 -0700116}
117
118std::vector<const RTCStatsMemberInterface*> RTCStats::Members() const {
119 return MembersOfThisObjectAndAncestors(0);
120}
121
122std::vector<const RTCStatsMemberInterface*>
Yves Gerey665174f2018-06-19 15:03:05 +0200123RTCStats::MembersOfThisObjectAndAncestors(size_t additional_capacity) const {
hbos615d3012016-08-24 01:33:13 -0700124 std::vector<const RTCStatsMemberInterface*> members;
125 members.reserve(additional_capacity);
126 return members;
127}
128
ehmaldonado35a872c2017-07-28 07:29:12 -0700129#define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \
130 template <> \
Mirko Bonadei054f1852019-11-04 16:31:08 +0100131 RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType() { \
132 return type; \
133 } \
ehmaldonado35a872c2017-07-28 07:29:12 -0700134 template <> \
135 bool RTCStatsMember<T>::is_sequence() const { \
136 return is_seq; \
137 } \
138 template <> \
139 bool RTCStatsMember<T>::is_string() const { \
140 return is_str; \
141 } \
142 template <> \
hbos615d3012016-08-24 01:33:13 -0700143 std::string RTCStatsMember<T>::ValueToString() const { \
144 RTC_DCHECK(is_defined_); \
145 return to_str; \
ehmaldonado35a872c2017-07-28 07:29:12 -0700146 } \
147 template <> \
148 std::string RTCStatsMember<T>::ValueToJson() const { \
149 RTC_DCHECK(is_defined_); \
150 return to_json; \
Mirko Bonadei054f1852019-11-04 16:31:08 +0100151 } \
152 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember<T>
hbos615d3012016-08-24 01:33:13 -0700153
ehmaldonado35a872c2017-07-28 07:29:12 -0700154WEBRTC_DEFINE_RTCSTATSMEMBER(bool,
155 kBool,
156 false,
157 false,
158 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100159 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700160WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t,
161 kInt32,
162 false,
163 false,
164 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100165 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700166WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t,
167 kUint32,
168 false,
169 false,
170 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100171 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700172WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t,
173 kInt64,
174 false,
175 false,
176 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100177 ToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700178WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t,
179 kUint64,
180 false,
181 false,
182 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100183 ToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700184WEBRTC_DEFINE_RTCSTATSMEMBER(double,
185 kDouble,
186 false,
187 false,
188 rtc::ToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100189 ToStringAsDouble(value_));
190WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true, value_, value_);
ehmaldonado35a872c2017-07-28 07:29:12 -0700191WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<bool>,
192 kSequenceBool,
193 true,
194 false,
195 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100196 VectorToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700197WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int32_t>,
198 kSequenceInt32,
199 true,
200 false,
201 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100202 VectorToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700203WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint32_t>,
204 kSequenceUint32,
205 true,
206 false,
207 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100208 VectorToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700209WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int64_t>,
210 kSequenceInt64,
211 true,
212 false,
213 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100214 VectorToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700215WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint64_t>,
216 kSequenceUint64,
217 true,
218 false,
219 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100220 VectorToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700221WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<double>,
222 kSequenceDouble,
223 true,
224 false,
225 VectorToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100226 VectorToStringAsDouble(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700227WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<std::string>,
228 kSequenceString,
229 true,
230 false,
231 VectorOfStringsToString(value_),
Mirko Bonadei054f1852019-11-04 16:31:08 +0100232 VectorOfStringsToString(value_));
hbos615d3012016-08-24 01:33:13 -0700233
234} // namespace webrtc