/* * 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/stats/rtcstats.h" #include #include "webrtc/base/stringencode.h" namespace webrtc { namespace { // Produces "{ a, b, c }". Works for non-vector |RTCStatsMemberInterface::Type| // types. template std::string VectorToString(const std::vector& vector) { if (vector.empty()) return "{}"; std::ostringstream oss; oss << "{ " << rtc::ToString(vector[0]); for (size_t i = 1; i < vector.size(); ++i) { oss << ", " << rtc::ToString(vector[i]); } oss << " }"; return oss.str(); } // Produces "{ \"a\", \"b\", \"c\" }". Works for vectors of both const char* and // std::string element types. template std::string VectorOfStringsToString(const std::vector& strings) { if (strings.empty()) return "{}"; std::ostringstream oss; oss << "{ \"" << rtc::ToString(strings[0]) << '\"'; for (size_t i = 1; i < strings.size(); ++i) { oss << ", \"" << rtc::ToString(strings[i]) << '\"'; } oss << " }"; return oss.str(); } } // namespace bool RTCStats::operator==(const RTCStats& other) const { if (type() != other.type() || id() != other.id()) return false; std::vector members = Members(); std::vector other_members = other.Members(); RTC_DCHECK_EQ(members.size(), other_members.size()); for (size_t i = 0; i < members.size(); ++i) { const RTCStatsMemberInterface* member = members[i]; const RTCStatsMemberInterface* other_member = other_members[i]; RTC_DCHECK_EQ(member->type(), other_member->type()); RTC_DCHECK_EQ(member->name(), other_member->name()); if (*member != *other_member) return false; } return true; } bool RTCStats::operator!=(const RTCStats& other) const { return !(*this == other); } std::string RTCStats::ToString() const { std::ostringstream oss; oss << type() << " {\n id: \"" << id_ << "\"\n timestamp: " << timestamp_us_ << '\n'; for (const RTCStatsMemberInterface* member : Members()) { oss << " " << member->name() << ": "; if (member->is_defined()) { if (member->is_string()) oss << '"' << member->ValueToString() << "\"\n"; else oss << member->ValueToString() << '\n'; } else { oss << "undefined\n"; } } oss << '}'; return oss.str(); } std::vector RTCStats::Members() const { return MembersOfThisObjectAndAncestors(0); } std::vector RTCStats::MembersOfThisObjectAndAncestors( size_t additional_capacity) const { std::vector members; members.reserve(additional_capacity); return members; } #define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str) \ template<> \ const RTCStatsMemberInterface::Type RTCStatsMember::kType = \ RTCStatsMemberInterface::type; \ template<> \ bool RTCStatsMember::is_sequence() const { return is_seq; } \ template<> \ bool RTCStatsMember::is_string() const { return is_str; } \ template<> \ std::string RTCStatsMember::ValueToString() const { \ RTC_DCHECK(is_defined_); \ return to_str; \ } WEBRTC_DEFINE_RTCSTATSMEMBER(bool, kBool, false, false, rtc::ToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t, kInt32, false, false, rtc::ToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t, kUint32, false, false, rtc::ToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t, kInt64, false, false, rtc::ToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t, kUint64, false, false, rtc::ToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(double, kDouble, false, false, rtc::ToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true, value_); WEBRTC_DEFINE_RTCSTATSMEMBER( std::vector, kSequenceBool, true, false, VectorToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER( std::vector, kSequenceInt32, true, false, VectorToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER( std::vector, kSequenceUint32, true, false, VectorToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER( std::vector, kSequenceInt64, true, false, VectorToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER( std::vector, kSequenceUint64, true, false, VectorToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER( std::vector, kSequenceDouble, true, false, VectorToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER( std::vector, kSequenceString, true, false, VectorOfStringsToString(value_)); } // namespace webrtc