blob: 4332fe6acf36c78c5a73ec438f0ac56e206fe3dd [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 <> \
hbos615d3012016-08-24 01:33:13 -0700131 const RTCStatsMemberInterface::Type RTCStatsMember<T>::kType = \
132 RTCStatsMemberInterface::type; \
ehmaldonado35a872c2017-07-28 07:29:12 -0700133 template <> \
134 bool RTCStatsMember<T>::is_sequence() const { \
135 return is_seq; \
136 } \
137 template <> \
138 bool RTCStatsMember<T>::is_string() const { \
139 return is_str; \
140 } \
141 template <> \
hbos615d3012016-08-24 01:33:13 -0700142 std::string RTCStatsMember<T>::ValueToString() const { \
143 RTC_DCHECK(is_defined_); \
144 return to_str; \
ehmaldonado35a872c2017-07-28 07:29:12 -0700145 } \
146 template <> \
147 std::string RTCStatsMember<T>::ValueToJson() const { \
148 RTC_DCHECK(is_defined_); \
149 return to_json; \
hbos615d3012016-08-24 01:33:13 -0700150 }
151
ehmaldonado35a872c2017-07-28 07:29:12 -0700152WEBRTC_DEFINE_RTCSTATSMEMBER(bool,
153 kBool,
154 false,
155 false,
156 rtc::ToString(value_),
hbosb20f3872016-10-04 14:37:11 -0700157 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700158WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t,
159 kInt32,
160 false,
161 false,
162 rtc::ToString(value_),
hbos615d3012016-08-24 01:33:13 -0700163 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700164WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t,
165 kUint32,
166 false,
167 false,
168 rtc::ToString(value_),
hbos615d3012016-08-24 01:33:13 -0700169 rtc::ToString(value_));
ehmaldonado35a872c2017-07-28 07:29:12 -0700170WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t,
171 kInt64,
172 false,
173 false,
174 rtc::ToString(value_),
175 ToStringAsDouble(value_));
176WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t,
177 kUint64,
178 false,
179 false,
180 rtc::ToString(value_),
181 ToStringAsDouble(value_));
182WEBRTC_DEFINE_RTCSTATSMEMBER(double,
183 kDouble,
184 false,
185 false,
186 rtc::ToString(value_),
187 ToStringAsDouble(value_));
Yves Gerey665174f2018-06-19 15:03:05 +0200188WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true, value_, value_);
ehmaldonado35a872c2017-07-28 07:29:12 -0700189WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<bool>,
190 kSequenceBool,
191 true,
192 false,
193 VectorToString(value_),
194 VectorToString(value_));
195WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int32_t>,
196 kSequenceInt32,
197 true,
198 false,
199 VectorToString(value_),
200 VectorToString(value_));
201WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint32_t>,
202 kSequenceUint32,
203 true,
204 false,
205 VectorToString(value_),
206 VectorToString(value_));
207WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int64_t>,
208 kSequenceInt64,
209 true,
210 false,
211 VectorToString(value_),
212 VectorToStringAsDouble(value_));
213WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint64_t>,
214 kSequenceUint64,
215 true,
216 false,
217 VectorToString(value_),
218 VectorToStringAsDouble(value_));
219WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<double>,
220 kSequenceDouble,
221 true,
222 false,
223 VectorToString(value_),
224 VectorToStringAsDouble(value_));
225WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<std::string>,
226 kSequenceString,
227 true,
228 false,
229 VectorOfStringsToString(value_),
230 VectorOfStringsToString(value_));
hbos615d3012016-08-24 01:33:13 -0700231
232} // namespace webrtc