Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: webrtc/stats/rtcstats.cc

Issue 2983243002: Make RTCStatsReport::ToString() return JSON-parseable string. (Closed)
Patch Set: Display Int64 values as doubles. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/api/stats/rtcstats.h" 11 #include "webrtc/api/stats/rtcstats.h"
12 12
13 #include <cfloat>
14 #include <iomanip>
13 #include <sstream> 15 #include <sstream>
14 16
15 #include "webrtc/rtc_base/stringencode.h" 17 #include "webrtc/rtc_base/stringencode.h"
16 18
17 namespace webrtc { 19 namespace webrtc {
18 20
19 namespace { 21 namespace {
20 22
21 // Produces "{ a, b, c }". Works for non-vector |RTCStatsMemberInterface::Type| 23 // Produces "[ a, b, c ]". Works for non-vector |RTCStatsMemberInterface::Type|
22 // types. 24 // types.
23 template<typename T> 25 template<typename T>
24 std::string VectorToString(const std::vector<T>& vector) { 26 std::string VectorToString(const std::vector<T>& vector) {
25 if (vector.empty()) 27 if (vector.empty())
26 return "{}"; 28 return "[]";
27 std::ostringstream oss; 29 std::ostringstream oss;
28 oss << "{ " << rtc::ToString<T>(vector[0]); 30 oss << "[ " << rtc::ToString<T>(vector[0]);
29 for (size_t i = 1; i < vector.size(); ++i) { 31 for (size_t i = 1; i < vector.size(); ++i) {
30 oss << ", " << rtc::ToString<T>(vector[i]); 32 oss << ", " << rtc::ToString<T>(vector[i]);
31 } 33 }
32 oss << " }"; 34 oss << " ]";
33 return oss.str(); 35 return oss.str();
34 } 36 }
35 37
36 // Produces "{ \"a\", \"b\", \"c\" }". Works for vectors of both const char* and 38 // Produces "[ \"a\", \"b\", \"c\" ]". Works for vectors of both const char* and
37 // std::string element types. 39 // std::string element types.
38 template<typename T> 40 template<typename T>
39 std::string VectorOfStringsToString(const std::vector<T>& strings) { 41 std::string VectorOfStringsToString(const std::vector<T>& strings) {
40 if (strings.empty()) 42 if (strings.empty())
41 return "{}"; 43 return "[]";
42 std::ostringstream oss; 44 std::ostringstream oss;
43 oss << "{ \"" << rtc::ToString<T>(strings[0]) << '\"'; 45 oss << "[ \"" << rtc::ToString<T>(strings[0]) << '\"';
44 for (size_t i = 1; i < strings.size(); ++i) { 46 for (size_t i = 1; i < strings.size(); ++i) {
45 oss << ", \"" << rtc::ToString<T>(strings[i]) << '\"'; 47 oss << ", \"" << rtc::ToString<T>(strings[i]) << '\"';
46 } 48 }
47 oss << " }"; 49 oss << " ]";
48 return oss.str(); 50 return oss.str();
49 } 51 }
50 52
53 template <typename T>
54 std::string ToStringAsDouble(const T value) {
55 std::ostringstream oss;
56 oss << std::setprecision(DBL_DIG + 1) << static_cast<double>(value);
hbos 2017/07/27 16:27:40 nit: Hm, maybe prefer std::numeric_limits<double>:
57 return oss.str();
58 }
59
60 template <typename T>
61 std::string VectorToStringAsDouble(const std::vector<T>& vector) {
62 if (vector.empty())
63 return "[]";
64 std::ostringstream oss;
65 oss << "[ " << ToStringAsDouble<T>(vector[0]);
66 for (size_t i = 1; i < vector.size(); ++i) {
67 oss << ", " << ToStringAsDouble<T>(vector[i]);
68 }
69 oss << " ]";
70 return oss.str();
71 }
72
51 } // namespace 73 } // namespace
52 74
53 bool RTCStats::operator==(const RTCStats& other) const { 75 bool RTCStats::operator==(const RTCStats& other) const {
54 if (type() != other.type() || id() != other.id()) 76 if (type() != other.type() || id() != other.id())
55 return false; 77 return false;
56 std::vector<const RTCStatsMemberInterface*> members = Members(); 78 std::vector<const RTCStatsMemberInterface*> members = Members();
57 std::vector<const RTCStatsMemberInterface*> other_members = other.Members(); 79 std::vector<const RTCStatsMemberInterface*> other_members = other.Members();
58 RTC_DCHECK_EQ(members.size(), other_members.size()); 80 RTC_DCHECK_EQ(members.size(), other_members.size());
59 for (size_t i = 0; i < members.size(); ++i) { 81 for (size_t i = 0; i < members.size(); ++i) {
60 const RTCStatsMemberInterface* member = members[i]; 82 const RTCStatsMemberInterface* member = members[i];
61 const RTCStatsMemberInterface* other_member = other_members[i]; 83 const RTCStatsMemberInterface* other_member = other_members[i];
62 RTC_DCHECK_EQ(member->type(), other_member->type()); 84 RTC_DCHECK_EQ(member->type(), other_member->type());
63 RTC_DCHECK_EQ(member->name(), other_member->name()); 85 RTC_DCHECK_EQ(member->name(), other_member->name());
64 if (*member != *other_member) 86 if (*member != *other_member)
65 return false; 87 return false;
66 } 88 }
67 return true; 89 return true;
68 } 90 }
69 91
70 bool RTCStats::operator!=(const RTCStats& other) const { 92 bool RTCStats::operator!=(const RTCStats& other) const {
71 return !(*this == other); 93 return !(*this == other);
72 } 94 }
73 95
74 std::string RTCStats::ToString() const { 96 std::string RTCStats::ToJson() const {
75 std::ostringstream oss; 97 std::ostringstream oss;
76 oss << type() << " {\n id: \"" << id_ << "\"\n timestamp: " 98 oss << "{\n \"type\": \"" << type() << "\",\n \"id\": \"" << id_
77 << timestamp_us_ << '\n'; 99 << "\",\n \"timestamp\": " << timestamp_us_;
78 for (const RTCStatsMemberInterface* member : Members()) { 100 for (const RTCStatsMemberInterface* member : Members()) {
79 oss << " " << member->name() << ": ";
80 if (member->is_defined()) { 101 if (member->is_defined()) {
102 oss << ",\n \"" << member->name() << "\": ";
81 if (member->is_string()) 103 if (member->is_string())
82 oss << '"' << member->ValueToString() << "\"\n"; 104 oss << '"' << member->ValueToJson() << '"';
83 else 105 else
84 oss << member->ValueToString() << '\n'; 106 oss << member->ValueToJson();
85 } else {
86 oss << "undefined\n";
87 } 107 }
88 } 108 }
89 oss << '}'; 109 oss << "\n}";
90 return oss.str(); 110 return oss.str();
91 } 111 }
92 112
93 std::vector<const RTCStatsMemberInterface*> RTCStats::Members() const { 113 std::vector<const RTCStatsMemberInterface*> RTCStats::Members() const {
94 return MembersOfThisObjectAndAncestors(0); 114 return MembersOfThisObjectAndAncestors(0);
95 } 115 }
96 116
97 std::vector<const RTCStatsMemberInterface*> 117 std::vector<const RTCStatsMemberInterface*>
98 RTCStats::MembersOfThisObjectAndAncestors( 118 RTCStats::MembersOfThisObjectAndAncestors(
99 size_t additional_capacity) const { 119 size_t additional_capacity) const {
100 std::vector<const RTCStatsMemberInterface*> members; 120 std::vector<const RTCStatsMemberInterface*> members;
101 members.reserve(additional_capacity); 121 members.reserve(additional_capacity);
102 return members; 122 return members;
103 } 123 }
104 124
105 #define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str) \ 125 #define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \
106 template<> \ 126 template <> \
107 const RTCStatsMemberInterface::Type RTCStatsMember<T>::kType = \ 127 const RTCStatsMemberInterface::Type RTCStatsMember<T>::kType = \
108 RTCStatsMemberInterface::type; \ 128 RTCStatsMemberInterface::type; \
109 template<> \ 129 template <> \
110 bool RTCStatsMember<T>::is_sequence() const { return is_seq; } \ 130 bool RTCStatsMember<T>::is_sequence() const { \
111 template<> \ 131 return is_seq; \
112 bool RTCStatsMember<T>::is_string() const { return is_str; } \ 132 } \
113 template<> \ 133 template <> \
134 bool RTCStatsMember<T>::is_string() const { \
135 return is_str; \
136 } \
137 template <> \
114 std::string RTCStatsMember<T>::ValueToString() const { \ 138 std::string RTCStatsMember<T>::ValueToString() const { \
115 RTC_DCHECK(is_defined_); \ 139 RTC_DCHECK(is_defined_); \
116 return to_str; \ 140 return to_str; \
141 } \
142 template <> \
143 std::string RTCStatsMember<T>::ValueToJson() const { \
144 RTC_DCHECK(is_defined_); \
145 return to_json; \
117 } 146 }
118 147
119 WEBRTC_DEFINE_RTCSTATSMEMBER(bool, kBool, false, false, 148 #define WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(T, type, is_seq, is_str, \
ehmaldonado_webrtc 2017/07/27 08:56:29 I ran "git cl format" and got this. Should I rever
hbos 2017/07/27 16:27:40 Let's keep it, it looks readable and people might
120 rtc::ToString(value_)); 149 to_str) \
121 WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t, kInt32, false, false, 150 WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_str)
122 rtc::ToString(value_)); 151
123 WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t, kUint32, false, false, 152 WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(bool,
124 rtc::ToString(value_)); 153 kBool,
125 WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t, kInt64, false, false, 154 false,
126 rtc::ToString(value_)); 155 false,
127 WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t, kUint64, false, false, 156 rtc::ToString(value_));
128 rtc::ToString(value_)); 157 WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(int32_t,
129 WEBRTC_DEFINE_RTCSTATSMEMBER(double, kDouble, false, false, 158 kInt32,
130 rtc::ToString(value_)); 159 false,
131 WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true, 160 false,
132 value_); 161 rtc::ToString(value_));
133 WEBRTC_DEFINE_RTCSTATSMEMBER( 162 WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(uint32_t,
134 std::vector<bool>, kSequenceBool, true, false, 163 kUint32,
135 VectorToString(value_)); 164 false,
136 WEBRTC_DEFINE_RTCSTATSMEMBER( 165 false,
137 std::vector<int32_t>, kSequenceInt32, true, false, 166 rtc::ToString(value_));
138 VectorToString(value_)); 167 WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(double,
139 WEBRTC_DEFINE_RTCSTATSMEMBER( 168 kDouble,
140 std::vector<uint32_t>, kSequenceUint32, true, false, 169 false,
141 VectorToString(value_)); 170 false,
142 WEBRTC_DEFINE_RTCSTATSMEMBER( 171 rtc::ToString(value_));
143 std::vector<int64_t>, kSequenceInt64, true, false, 172 WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(std::string,
144 VectorToString(value_)); 173 kString,
145 WEBRTC_DEFINE_RTCSTATSMEMBER( 174 false,
146 std::vector<uint64_t>, kSequenceUint64, true, false, 175 true,
147 VectorToString(value_)); 176 value_);
148 WEBRTC_DEFINE_RTCSTATSMEMBER( 177 WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(std::vector<bool>,
149 std::vector<double>, kSequenceDouble, true, false, 178 kSequenceBool,
150 VectorToString(value_)); 179 true,
151 WEBRTC_DEFINE_RTCSTATSMEMBER( 180 false,
152 std::vector<std::string>, kSequenceString, true, false, 181 VectorToString(value_));
153 VectorOfStringsToString(value_)); 182 WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(std::vector<int32_t>,
183 kSequenceInt32,
184 true,
185 false,
186 VectorToString(value_));
187 WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(std::vector<uint32_t>,
188 kSequenceUint32,
189 true,
190 false,
191 VectorToString(value_));
192 WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(std::vector<double>,
193 kSequenceDouble,
194 true,
195 false,
196 VectorToString(value_));
197 WEBRTC_DEFINE_RTCSTATSMEMBER_DEFAULT_JSON(std::vector<std::string>,
198 kSequenceString,
199 true,
200 false,
201 VectorOfStringsToString(value_));
202
203 WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t,
204 kInt64,
205 false,
206 false,
207 rtc::ToString(value_),
208 ToStringAsDouble(value_));
209 WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t,
210 kUint64,
211 false,
212 false,
213 rtc::ToString(value_),
214 ToStringAsDouble(value_));
215 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int64_t>,
216 kSequenceInt64,
217 true,
218 false,
219 VectorToString(value_),
220 VectorToStringAsDouble(value_));
221 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint64_t>,
222 kSequenceUint64,
223 true,
224 false,
225 VectorToString(value_),
226 VectorToStringAsDouble(value_));
hbos 2017/07/27 16:27:40 Can you change back the order (..., kInt32, kUint3
154 227
155 } // namespace webrtc 228 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698