Index: webrtc/stats/rtcstats.cc |
diff --git a/webrtc/stats/rtcstats.cc b/webrtc/stats/rtcstats.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..77782824a6441c751c15bf519ef1e87699ed9880 |
--- /dev/null |
+++ b/webrtc/stats/rtcstats.cc |
@@ -0,0 +1,343 @@ |
+/* |
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
+ * |
+ * Use of this source code is governed by a BSD-style license |
+ * that can be found in the LICENSE file in the root of the source |
+ * tree. An additional intellectual property rights grant can be found |
+ * in the file PATENTS. All contributing project authors may |
+ * be found in the AUTHORS file in the root of the source tree. |
+ */ |
+ |
+#include "webrtc/api/rtcstats.h" |
+ |
+#include "webrtc/base/stringencode.h" |
+ |
+namespace webrtc { |
+ |
+namespace { |
+ |
+// Produces "{ a, b, c }". Works for non-vector |RTCStatsMemberInterface::Type| |
+// types. |
+template<typename T> |
+std::string VectorToString(const std::vector<T>& vector) { |
+ if (vector.empty()) |
+ return "{}"; |
+ std::ostringstream oss; |
+ oss << "{ "; |
+ bool is_first = true; |
+ for (const T& element : vector) { |
+ if (!is_first) |
nisse-webrtc
2016/08/23 08:27:28
I think the is_first logic is unnecessary state.
hbos
2016/08/23 16:21:18
Done.
|
+ oss << ", "; |
+ oss << rtc::ToString<T>(element); |
+ is_first = false; |
+ } |
+ oss << " }"; |
+ return oss.str(); |
+} |
+ |
+// Produces "{ \"a\", \"b\", \"c\" }". Works for vectors of both const char* and |
+// std::string element types. |
+template<typename T> |
+std::string VectorOfStringsToString(const std::vector<T>& strings) { |
+ if (strings.empty()) |
+ return "{}"; |
+ std::ostringstream oss; |
+ oss << "{ "; |
+ bool is_first = true; |
+ for (const T& string : strings) { |
+ if (!is_first) |
+ oss << ", "; |
+ oss << '"' << string << '"'; |
+ is_first = false; |
+ } |
+ oss << " }"; |
+ return oss.str(); |
+} |
+ |
+} // namespace |
+ |
+std::string RTCStats::ToString() const { |
+ std::ostringstream oss; |
+ oss << type_name() << " {\n id: \"" << id_ << "\"\n timestamp: " |
+ << timestamp_ << '\n'; |
+ for (const RTCStatsMemberInterface* member : Members()) { |
+ oss << " " << member->name() << ": "; |
+ if (member->is_defined()) { |
+ if (member->is_string() && !member->is_sequence()) |
+ oss << '"' << member->ValueToString() << "\"\n"; |
+ else |
+ oss << member->ValueToString() << '\n'; |
+ } else { |
+ oss << "undefined\n"; |
+ } |
+ } |
+ oss << '}'; |
+ return oss.str(); |
+} |
+ |
+std::vector<const RTCStatsMemberInterface*> RTCStats::Members() const { |
+ return MembersOfThisObjectAndAncestors(0); |
+} |
+ |
+std::vector<const RTCStatsMemberInterface*> |
+RTCStats::MembersOfThisObjectAndAncestors( |
+ size_t additional_capacity) const { |
+ std::vector<const RTCStatsMemberInterface*> members; |
+ members.reserve(additional_capacity); |
+ return members; |
+} |
+ |
+// int32_t (kInt32) |
nisse-webrtc
2016/08/23 08:27:28
I'd consider using a local macro to reduce code du
hbos
2016/08/23 16:21:18
Done.
|
+template<> |
+const RTCStatsMemberInterface::Type RTCStatsMember<int32_t>::kType = |
+ RTCStatsMemberInterface::kInt32; |
+ |
+template<> |
+bool RTCStatsMember<int32_t>::is_sequence() const { return false; } |
+ |
+template<> |
+bool RTCStatsMember<int32_t>::is_string() const { return false; } |
+ |
+template<> |
+std::string RTCStatsMember<int32_t>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return rtc::ToString<int32_t>(value_); |
+} |
+ |
+// uint32_t (kUint32) |
+template<> |
+const RTCStatsMemberInterface::Type RTCStatsMember<uint32_t>::kType = |
+ RTCStatsMemberInterface::kUint32; |
+ |
+template<> |
+bool RTCStatsMember<uint32_t>::is_sequence() const { return false; } |
+ |
+template<> |
+bool RTCStatsMember<uint32_t>::is_string() const { return false; } |
+ |
+template<> |
+std::string RTCStatsMember<uint32_t>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return rtc::ToString<uint32_t>(value_); |
+} |
+ |
+// int64_t (kInt64) |
+template<> |
+const RTCStatsMemberInterface::Type RTCStatsMember<int64_t>::kType = |
+ RTCStatsMemberInterface::kInt64; |
+ |
+template<> |
+bool RTCStatsMember<int64_t>::is_sequence() const { return false; } |
+ |
+template<> |
+bool RTCStatsMember<int64_t>::is_string() const { return false; } |
+ |
+template<> |
+std::string RTCStatsMember<int64_t>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return rtc::ToString<int64_t>(value_); |
+} |
+ |
+// uint64_t (kUint64) |
+template<> |
+const RTCStatsMemberInterface::Type RTCStatsMember<uint64_t>::kType = |
+ RTCStatsMemberInterface::kUint64; |
+ |
+template<> |
+bool RTCStatsMember<uint64_t>::is_sequence() const { return false; } |
+ |
+template<> |
+bool RTCStatsMember<uint64_t>::is_string() const { return false; } |
+ |
+template<> |
+std::string RTCStatsMember<uint64_t>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return rtc::ToString<uint64_t>(value_); |
+} |
+ |
+// double (kDouble) |
+template<> |
+const RTCStatsMemberInterface::Type RTCStatsMember<double>::kType = |
+ RTCStatsMemberInterface::kDouble; |
+ |
+template<> |
+bool RTCStatsMember<double>::is_sequence() const { return false; } |
+ |
+template<> |
+bool RTCStatsMember<double>::is_string() const { return false; } |
+ |
+template<> |
+std::string RTCStatsMember<double>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return rtc::ToString<double>(value_); |
+} |
+ |
+// const char* (kStaticString) |
+template<> |
+const RTCStatsMemberInterface::Type RTCStatsMember<const char*>::kType = |
+ RTCStatsMemberInterface::kStaticString; |
+ |
+template<> |
+bool RTCStatsMember<const char*>::is_sequence() const { return false; } |
+ |
+template<> |
+bool RTCStatsMember<const char*>::is_string() const { return true; } |
+ |
+template<> |
+std::string RTCStatsMember<const char*>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return value_; |
+} |
+ |
+// std::string (kString) |
+template<> |
+const RTCStatsMemberInterface::Type RTCStatsMember<std::string>::kType = |
+ RTCStatsMemberInterface::kString; |
+ |
+template<> |
+bool RTCStatsMember<std::string>::is_sequence() const { return false; } |
+ |
+template<> |
+bool RTCStatsMember<std::string>::is_string() const { return true; } |
+ |
+template<> |
+std::string RTCStatsMember<std::string>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return value_; |
+} |
+ |
+// std::vector<int32_t> (kSequenceInt32) |
+template<> |
+const RTCStatsMemberInterface::Type |
+RTCStatsMember<std::vector<int32_t>>::kType = |
+ RTCStatsMemberInterface::kSequenceInt32; |
+ |
+template<> |
+bool RTCStatsMember<std::vector<int32_t>>::is_sequence() const { return true; } |
+ |
+template<> |
+bool RTCStatsMember<std::vector<int32_t>>::is_string() const { return false; } |
+ |
+template<> |
+std::string RTCStatsMember<std::vector<int32_t>>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return VectorToString<int32_t>(value_); |
+} |
+ |
+// std::vector<uint32_t> (kSequenceUint32) |
+template<> |
+const RTCStatsMemberInterface::Type |
+RTCStatsMember<std::vector<uint32_t>>::kType = |
+ RTCStatsMemberInterface::kSequenceUint32; |
+ |
+template<> |
+bool RTCStatsMember<std::vector<uint32_t>>::is_sequence() const { return true; } |
+ |
+template<> |
+bool RTCStatsMember<std::vector<uint32_t>>::is_string() const { return false; } |
+ |
+template<> |
+std::string RTCStatsMember<std::vector<uint32_t>>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return VectorToString<uint32_t>(value_); |
+} |
+ |
+// std::vector<int64_t> (kSequenceInt64) |
+template<> |
+const RTCStatsMemberInterface::Type |
+RTCStatsMember<std::vector<int64_t>>::kType = |
+ RTCStatsMemberInterface::kSequenceInt64; |
+ |
+template<> |
+bool RTCStatsMember<std::vector<int64_t>>::is_sequence() const { return true; } |
+ |
+template<> |
+bool RTCStatsMember<std::vector<int64_t>>::is_string() const { return false; } |
+ |
+template<> |
+std::string RTCStatsMember<std::vector<int64_t>>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return VectorToString<int64_t>(value_); |
+} |
+ |
+// std::vector<uint64_t> (kSequenceUint64) |
+template<> |
+const RTCStatsMemberInterface::Type |
+RTCStatsMember<std::vector<uint64_t>>::kType = |
+ RTCStatsMemberInterface::kSequenceUint64; |
+ |
+template<> |
+bool RTCStatsMember<std::vector<uint64_t>>::is_sequence() const { return true; } |
+ |
+template<> |
+bool RTCStatsMember<std::vector<uint64_t>>::is_string() const { return false; } |
+ |
+template<> |
+std::string RTCStatsMember<std::vector<uint64_t>>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return VectorToString<uint64_t>(value_); |
+} |
+ |
+// std::vector<double> (kSequenceDouble) |
+template<> |
+const RTCStatsMemberInterface::Type |
+RTCStatsMember<std::vector<double>>::kType = |
+ RTCStatsMemberInterface::kSequenceDouble; |
+ |
+template<> |
+bool RTCStatsMember<std::vector<double>>::is_sequence() const { return true; } |
+ |
+template<> |
+bool RTCStatsMember<std::vector<double>>::is_string() const { return false; } |
+ |
+template<> |
+std::string RTCStatsMember<std::vector<double>>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return VectorToString<double>(value_); |
+} |
+ |
+// std::vector<const char*> (kSequenceStaticString) |
+template<> |
+const RTCStatsMemberInterface::Type |
+RTCStatsMember<std::vector<const char*>>::kType = |
+ RTCStatsMemberInterface::kSequenceStaticString; |
+ |
+template<> |
+bool RTCStatsMember<std::vector<const char*>>::is_sequence() const { |
+ return true; |
+} |
+ |
+template<> |
+bool RTCStatsMember<std::vector<const char*>>::is_string() const { |
+ return true; |
+} |
+ |
+template<> |
+std::string RTCStatsMember<std::vector<const char*>>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return VectorOfStringsToString<const char*>(value_); |
+} |
+ |
+// std::vector<std::string> (kSequenceString) |
+template<> |
+const RTCStatsMemberInterface::Type |
+RTCStatsMember<std::vector<std::string>>::kType = |
+ RTCStatsMemberInterface::kSequenceString; |
+ |
+template<> |
+bool RTCStatsMember<std::vector<std::string>>::is_sequence() const { |
+ return true; |
+} |
+ |
+template<> |
+bool RTCStatsMember<std::vector<std::string>>::is_string() const { |
+ return true; |
+} |
+ |
+template<> |
+std::string RTCStatsMember<std::vector<std::string>>::ValueToString() const { |
+ RTC_DCHECK(is_defined_); |
+ return VectorOfStringsToString<std::string>(value_); |
+} |
+ |
+} // namespace webrtc |