OLD | NEW |
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 <iomanip> |
13 #include <sstream> | 14 #include <sstream> |
14 | 15 |
15 #include "webrtc/rtc_base/stringencode.h" | 16 #include "webrtc/rtc_base/stringencode.h" |
16 | 17 |
17 namespace webrtc { | 18 namespace webrtc { |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 // Produces "{ a, b, c }". Works for non-vector |RTCStatsMemberInterface::Type| | 22 // Produces "[a,b,c]". Works for non-vector |RTCStatsMemberInterface::Type| |
22 // types. | 23 // types. |
23 template<typename T> | 24 template<typename T> |
24 std::string VectorToString(const std::vector<T>& vector) { | 25 std::string VectorToString(const std::vector<T>& vector) { |
25 if (vector.empty()) | 26 if (vector.empty()) |
26 return "{}"; | 27 return "[]"; |
27 std::ostringstream oss; | 28 std::ostringstream oss; |
28 oss << "{ " << rtc::ToString<T>(vector[0]); | 29 oss << "[" << rtc::ToString<T>(vector[0]); |
29 for (size_t i = 1; i < vector.size(); ++i) { | 30 for (size_t i = 1; i < vector.size(); ++i) { |
30 oss << ", " << rtc::ToString<T>(vector[i]); | 31 oss << "," << rtc::ToString<T>(vector[i]); |
31 } | 32 } |
32 oss << " }"; | 33 oss << "]"; |
33 return oss.str(); | 34 return oss.str(); |
34 } | 35 } |
35 | 36 |
36 // Produces "{ \"a\", \"b\", \"c\" }". Works for vectors of both const char* and | 37 // Produces "[\"a\",\"b\",\"c\"]". Works for vectors of both const char* and |
37 // std::string element types. | 38 // std::string element types. |
38 template<typename T> | 39 template<typename T> |
39 std::string VectorOfStringsToString(const std::vector<T>& strings) { | 40 std::string VectorOfStringsToString(const std::vector<T>& strings) { |
40 if (strings.empty()) | 41 if (strings.empty()) |
41 return "{}"; | 42 return "[]"; |
42 std::ostringstream oss; | 43 std::ostringstream oss; |
43 oss << "{ \"" << rtc::ToString<T>(strings[0]) << '\"'; | 44 oss << "[\"" << rtc::ToString<T>(strings[0]) << '\"'; |
44 for (size_t i = 1; i < strings.size(); ++i) { | 45 for (size_t i = 1; i < strings.size(); ++i) { |
45 oss << ", \"" << rtc::ToString<T>(strings[i]) << '\"'; | 46 oss << ",\"" << rtc::ToString<T>(strings[i]) << '\"'; |
46 } | 47 } |
47 oss << " }"; | 48 oss << "]"; |
48 return oss.str(); | 49 return oss.str(); |
49 } | 50 } |
50 | 51 |
| 52 template <typename T> |
| 53 std::string ToStringAsDouble(const T value) { |
| 54 // JSON represents numbers as floating point numbers with about 15 decimal |
| 55 // digits of precision. |
| 56 const int JSON_PRECISION = 16; |
| 57 std::ostringstream oss; |
| 58 oss << std::setprecision(JSON_PRECISION) << static_cast<double>(value); |
| 59 return oss.str(); |
| 60 } |
| 61 |
| 62 template <typename T> |
| 63 std::string VectorToStringAsDouble(const std::vector<T>& vector) { |
| 64 if (vector.empty()) |
| 65 return "[]"; |
| 66 std::ostringstream oss; |
| 67 oss << "[" << ToStringAsDouble<T>(vector[0]); |
| 68 for (size_t i = 1; i < vector.size(); ++i) { |
| 69 oss << "," << ToStringAsDouble<T>(vector[i]); |
| 70 } |
| 71 oss << "]"; |
| 72 return oss.str(); |
| 73 } |
| 74 |
51 } // namespace | 75 } // namespace |
52 | 76 |
53 bool RTCStats::operator==(const RTCStats& other) const { | 77 bool RTCStats::operator==(const RTCStats& other) const { |
54 if (type() != other.type() || id() != other.id()) | 78 if (type() != other.type() || id() != other.id()) |
55 return false; | 79 return false; |
56 std::vector<const RTCStatsMemberInterface*> members = Members(); | 80 std::vector<const RTCStatsMemberInterface*> members = Members(); |
57 std::vector<const RTCStatsMemberInterface*> other_members = other.Members(); | 81 std::vector<const RTCStatsMemberInterface*> other_members = other.Members(); |
58 RTC_DCHECK_EQ(members.size(), other_members.size()); | 82 RTC_DCHECK_EQ(members.size(), other_members.size()); |
59 for (size_t i = 0; i < members.size(); ++i) { | 83 for (size_t i = 0; i < members.size(); ++i) { |
60 const RTCStatsMemberInterface* member = members[i]; | 84 const RTCStatsMemberInterface* member = members[i]; |
61 const RTCStatsMemberInterface* other_member = other_members[i]; | 85 const RTCStatsMemberInterface* other_member = other_members[i]; |
62 RTC_DCHECK_EQ(member->type(), other_member->type()); | 86 RTC_DCHECK_EQ(member->type(), other_member->type()); |
63 RTC_DCHECK_EQ(member->name(), other_member->name()); | 87 RTC_DCHECK_EQ(member->name(), other_member->name()); |
64 if (*member != *other_member) | 88 if (*member != *other_member) |
65 return false; | 89 return false; |
66 } | 90 } |
67 return true; | 91 return true; |
68 } | 92 } |
69 | 93 |
70 bool RTCStats::operator!=(const RTCStats& other) const { | 94 bool RTCStats::operator!=(const RTCStats& other) const { |
71 return !(*this == other); | 95 return !(*this == other); |
72 } | 96 } |
73 | 97 |
74 std::string RTCStats::ToString() const { | 98 std::string RTCStats::ToJson() const { |
75 std::ostringstream oss; | 99 std::ostringstream oss; |
76 oss << type() << " {\n id: \"" << id_ << "\"\n timestamp: " | 100 oss << "{\"type\":\"" << type() << "\"," |
77 << timestamp_us_ << '\n'; | 101 << "\"id\":\"" << id_ << "\"," |
| 102 << "\"timestamp\":" << timestamp_us_; |
78 for (const RTCStatsMemberInterface* member : Members()) { | 103 for (const RTCStatsMemberInterface* member : Members()) { |
79 oss << " " << member->name() << ": "; | |
80 if (member->is_defined()) { | 104 if (member->is_defined()) { |
| 105 oss << ",\"" << member->name() << "\":"; |
81 if (member->is_string()) | 106 if (member->is_string()) |
82 oss << '"' << member->ValueToString() << "\"\n"; | 107 oss << '"' << member->ValueToJson() << '"'; |
83 else | 108 else |
84 oss << member->ValueToString() << '\n'; | 109 oss << member->ValueToJson(); |
85 } else { | |
86 oss << "undefined\n"; | |
87 } | 110 } |
88 } | 111 } |
89 oss << '}'; | 112 oss << "}"; |
90 return oss.str(); | 113 return oss.str(); |
91 } | 114 } |
92 | 115 |
93 std::vector<const RTCStatsMemberInterface*> RTCStats::Members() const { | 116 std::vector<const RTCStatsMemberInterface*> RTCStats::Members() const { |
94 return MembersOfThisObjectAndAncestors(0); | 117 return MembersOfThisObjectAndAncestors(0); |
95 } | 118 } |
96 | 119 |
97 std::vector<const RTCStatsMemberInterface*> | 120 std::vector<const RTCStatsMemberInterface*> |
98 RTCStats::MembersOfThisObjectAndAncestors( | 121 RTCStats::MembersOfThisObjectAndAncestors( |
99 size_t additional_capacity) const { | 122 size_t additional_capacity) const { |
100 std::vector<const RTCStatsMemberInterface*> members; | 123 std::vector<const RTCStatsMemberInterface*> members; |
101 members.reserve(additional_capacity); | 124 members.reserve(additional_capacity); |
102 return members; | 125 return members; |
103 } | 126 } |
104 | 127 |
105 #define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str) \ | 128 #define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \ |
106 template<> \ | 129 template <> \ |
107 const RTCStatsMemberInterface::Type RTCStatsMember<T>::kType = \ | 130 const RTCStatsMemberInterface::Type RTCStatsMember<T>::kType = \ |
108 RTCStatsMemberInterface::type; \ | 131 RTCStatsMemberInterface::type; \ |
109 template<> \ | 132 template <> \ |
110 bool RTCStatsMember<T>::is_sequence() const { return is_seq; } \ | 133 bool RTCStatsMember<T>::is_sequence() const { \ |
111 template<> \ | 134 return is_seq; \ |
112 bool RTCStatsMember<T>::is_string() const { return is_str; } \ | 135 } \ |
113 template<> \ | 136 template <> \ |
| 137 bool RTCStatsMember<T>::is_string() const { \ |
| 138 return is_str; \ |
| 139 } \ |
| 140 template <> \ |
114 std::string RTCStatsMember<T>::ValueToString() const { \ | 141 std::string RTCStatsMember<T>::ValueToString() const { \ |
115 RTC_DCHECK(is_defined_); \ | 142 RTC_DCHECK(is_defined_); \ |
116 return to_str; \ | 143 return to_str; \ |
| 144 } \ |
| 145 template <> \ |
| 146 std::string RTCStatsMember<T>::ValueToJson() const { \ |
| 147 RTC_DCHECK(is_defined_); \ |
| 148 return to_json; \ |
117 } | 149 } |
118 | 150 |
119 WEBRTC_DEFINE_RTCSTATSMEMBER(bool, kBool, false, false, | 151 WEBRTC_DEFINE_RTCSTATSMEMBER(bool, |
| 152 kBool, |
| 153 false, |
| 154 false, |
| 155 rtc::ToString(value_), |
120 rtc::ToString(value_)); | 156 rtc::ToString(value_)); |
121 WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t, kInt32, false, false, | 157 WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t, |
| 158 kInt32, |
| 159 false, |
| 160 false, |
| 161 rtc::ToString(value_), |
122 rtc::ToString(value_)); | 162 rtc::ToString(value_)); |
123 WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t, kUint32, false, false, | 163 WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t, |
| 164 kUint32, |
| 165 false, |
| 166 false, |
| 167 rtc::ToString(value_), |
124 rtc::ToString(value_)); | 168 rtc::ToString(value_)); |
125 WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t, kInt64, false, false, | 169 WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t, |
126 rtc::ToString(value_)); | 170 kInt64, |
127 WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t, kUint64, false, false, | 171 false, |
128 rtc::ToString(value_)); | 172 false, |
129 WEBRTC_DEFINE_RTCSTATSMEMBER(double, kDouble, false, false, | 173 rtc::ToString(value_), |
130 rtc::ToString(value_)); | 174 ToStringAsDouble(value_)); |
131 WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true, | 175 WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t, |
| 176 kUint64, |
| 177 false, |
| 178 false, |
| 179 rtc::ToString(value_), |
| 180 ToStringAsDouble(value_)); |
| 181 WEBRTC_DEFINE_RTCSTATSMEMBER(double, |
| 182 kDouble, |
| 183 false, |
| 184 false, |
| 185 rtc::ToString(value_), |
| 186 ToStringAsDouble(value_)); |
| 187 WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, |
| 188 kString, |
| 189 false, |
| 190 true, |
| 191 value_, |
132 value_); | 192 value_); |
133 WEBRTC_DEFINE_RTCSTATSMEMBER( | 193 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<bool>, |
134 std::vector<bool>, kSequenceBool, true, false, | 194 kSequenceBool, |
135 VectorToString(value_)); | 195 true, |
136 WEBRTC_DEFINE_RTCSTATSMEMBER( | 196 false, |
137 std::vector<int32_t>, kSequenceInt32, true, false, | 197 VectorToString(value_), |
138 VectorToString(value_)); | 198 VectorToString(value_)); |
139 WEBRTC_DEFINE_RTCSTATSMEMBER( | 199 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int32_t>, |
140 std::vector<uint32_t>, kSequenceUint32, true, false, | 200 kSequenceInt32, |
141 VectorToString(value_)); | 201 true, |
142 WEBRTC_DEFINE_RTCSTATSMEMBER( | 202 false, |
143 std::vector<int64_t>, kSequenceInt64, true, false, | 203 VectorToString(value_), |
144 VectorToString(value_)); | 204 VectorToString(value_)); |
145 WEBRTC_DEFINE_RTCSTATSMEMBER( | 205 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint32_t>, |
146 std::vector<uint64_t>, kSequenceUint64, true, false, | 206 kSequenceUint32, |
147 VectorToString(value_)); | 207 true, |
148 WEBRTC_DEFINE_RTCSTATSMEMBER( | 208 false, |
149 std::vector<double>, kSequenceDouble, true, false, | 209 VectorToString(value_), |
150 VectorToString(value_)); | 210 VectorToString(value_)); |
151 WEBRTC_DEFINE_RTCSTATSMEMBER( | 211 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int64_t>, |
152 std::vector<std::string>, kSequenceString, true, false, | 212 kSequenceInt64, |
153 VectorOfStringsToString(value_)); | 213 true, |
| 214 false, |
| 215 VectorToString(value_), |
| 216 VectorToStringAsDouble(value_)); |
| 217 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint64_t>, |
| 218 kSequenceUint64, |
| 219 true, |
| 220 false, |
| 221 VectorToString(value_), |
| 222 VectorToStringAsDouble(value_)); |
| 223 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<double>, |
| 224 kSequenceDouble, |
| 225 true, |
| 226 false, |
| 227 VectorToString(value_), |
| 228 VectorToStringAsDouble(value_)); |
| 229 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<std::string>, |
| 230 kSequenceString, |
| 231 true, |
| 232 false, |
| 233 VectorOfStringsToString(value_), |
| 234 VectorOfStringsToString(value_)); |
154 | 235 |
155 } // namespace webrtc | 236 } // namespace webrtc |
OLD | NEW |