2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
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.
11 #include "api/stats/rtc_stats.h"
15 #include "rtc_base/arraysize.h"
16 #include "rtc_base/string_encode.h"
17 #include "rtc_base/strings/string_builder.h"
23 // Produces "[a,b,c]". Works for non-vector `RTCStatsMemberInterface::Type`
26 std::string
VectorToString(const std::vector
<T
>& vector
) {
27 rtc::StringBuilder sb
;
29 const char* separator
= "";
30 for (const T
& element
: vector
) {
31 sb
<< separator
<< rtc::ToString(element
);
38 // This overload is required because std::vector<bool> range loops don't
39 // return references but objects, causing -Wrange-loop-analysis diagnostics.
40 std::string
VectorToString(const std::vector
<bool>& vector
) {
41 rtc::StringBuilder sb
;
43 const char* separator
= "";
44 for (bool element
: vector
) {
45 sb
<< separator
<< rtc::ToString(element
);
52 // Produces "[\"a\",\"b\",\"c\"]". Works for vectors of both const char* and
53 // std::string element types.
55 std::string
VectorOfStringsToString(const std::vector
<T
>& strings
) {
56 rtc::StringBuilder sb
;
58 const char* separator
= "";
59 for (const T
& element
: strings
) {
60 sb
<< separator
<< "\"" << rtc::ToString(element
) << "\"";
68 std::string
MapToString(const std::map
<std::string
, T
>& map
) {
69 rtc::StringBuilder sb
;
71 const char* separator
= "";
72 for (const auto& element
: map
) {
73 sb
<< separator
<< rtc::ToString(element
.first
) << ":"
74 << rtc::ToString(element
.second
);
82 std::string
ToStringAsDouble(const T value
) {
83 // JSON represents numbers as floating point numbers with about 15 decimal
84 // digits of precision.
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
);
93 std::string
VectorToStringAsDouble(const std::vector
<T
>& vector
) {
94 rtc::StringBuilder sb
;
96 const char* separator
= "";
97 for (const T
& element
: vector
) {
98 sb
<< separator
<< ToStringAsDouble
<T
>(element
);
105 template <typename T
>
106 std::string
MapToStringAsDouble(const std::map
<std::string
, T
>& map
) {
107 rtc::StringBuilder sb
;
109 const char* separator
= "";
110 for (const auto& element
: map
) {
111 sb
<< separator
<< "\"" << rtc::ToString(element
.first
)
112 << "\":" << ToStringAsDouble(element
.second
);
121 bool RTCStats::operator==(const RTCStats
& other
) const {
122 if (type() != other
.type() || id() != other
.id())
124 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
)
138 bool RTCStats::operator!=(const RTCStats
& other
) const {
139 return !(*this == other
);
142 std::string
RTCStats::ToJson() const {
143 rtc::StringBuilder sb
;
144 sb
<< "{\"type\":\"" << type()
151 for (const RTCStatsMemberInterface
* member
: Members()) {
152 if (member
->is_defined()) {
153 sb
<< ",\"" << member
->name() << "\":";
154 if (member
->is_string())
155 sb
<< "\"" << member
->ValueToJson() << "\"";
157 sb
<< member
->ValueToJson();
164 std::vector
<const RTCStatsMemberInterface
*> RTCStats::Members() const {
165 return MembersOfThisObjectAndAncestors(0);
168 std::vector
<const RTCStatsMemberInterface
*>
169 RTCStats::MembersOfThisObjectAndAncestors(size_t additional_capacity
) const {
170 std::vector
<const RTCStatsMemberInterface
*> members
;
171 members
.reserve(additional_capacity
);
175 #define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \
177 RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType() { \
181 bool RTCStatsMember<T>::is_sequence() const { \
185 bool RTCStatsMember<T>::is_string() const { \
189 std::string RTCStatsMember<T>::ValueToString() const { \
190 RTC_DCHECK(value_.has_value()); \
194 std::string RTCStatsMember<T>::ValueToJson() const { \
195 RTC_DCHECK(value_.has_value()); \
198 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember<T>
200 WEBRTC_DEFINE_RTCSTATSMEMBER(bool,
204 rtc::ToString(*value_
),
205 rtc::ToString(*value_
));
206 WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t,
210 rtc::ToString(*value_
),
211 rtc::ToString(*value_
));
212 WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t,
216 rtc::ToString(*value_
),
217 rtc::ToString(*value_
));
218 WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t,
222 rtc::ToString(*value_
),
223 ToStringAsDouble(*value_
));
224 WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t,
228 rtc::ToString(*value_
),
229 ToStringAsDouble(*value_
));
230 WEBRTC_DEFINE_RTCSTATSMEMBER(double,
234 rtc::ToString(*value_
),
235 ToStringAsDouble(*value_
));
236 WEBRTC_DEFINE_RTCSTATSMEMBER(std::string
,
242 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector
<bool>,
246 VectorToString(*value_
),
247 VectorToString(*value_
));
248 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector
<int32_t>,
252 VectorToString(*value_
),
253 VectorToString(*value_
));
254 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector
<uint32_t>,
258 VectorToString(*value_
),
259 VectorToString(*value_
));
260 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector
<int64_t>,
264 VectorToString(*value_
),
265 VectorToStringAsDouble(*value_
));
266 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector
<uint64_t>,
270 VectorToString(*value_
),
271 VectorToStringAsDouble(*value_
));
272 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector
<double>,
276 VectorToString(*value_
),
277 VectorToStringAsDouble(*value_
));
278 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector
<std::string
>,
282 VectorOfStringsToString(*value_
),
283 VectorOfStringsToString(*value_
));
284 WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64
,
288 MapToString(*value_
),
289 MapToStringAsDouble(*value_
));
290 WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble
,
294 MapToString(*value_
),
295 MapToStringAsDouble(*value_
));
297 } // namespace webrtc