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 #ifndef WEBRTC_API_RTCSTATS_H_ | 11 // TODO(hbos): Remove this file once Chromium uses the correct include path. |
12 #define WEBRTC_API_RTCSTATS_H_ | |
13 | 12 |
14 #include <map> | 13 #include "webrtc/api/stats/rtcstats.h" |
15 #include <memory> | |
16 #include <string> | |
17 #include <utility> | |
18 #include <vector> | |
19 | |
20 #include "webrtc/base/checks.h" | |
21 | |
22 namespace webrtc { | |
23 | |
24 class RTCStatsMemberInterface; | |
25 | |
26 // Abstract base class for RTCStats-derived dictionaries, see | |
27 // https://w3c.github.io/webrtc-stats/. | |
28 // | |
29 // All derived classes must have the following static variable defined: | |
30 // static const char kType[]; | |
31 // It is used as a unique class identifier and a string representation of the | |
32 // class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*. | |
33 // Use the |WEBRTC_RTCSTATS_IMPL| macro when implementing subclasses, see macro | |
34 // for details. | |
35 // | |
36 // Derived classes list their dictionary members, RTCStatsMember<T>, as public | |
37 // fields, allowing the following: | |
38 // | |
39 // RTCFooStats foo("fooId", GetCurrentTime()); | |
40 // foo.bar = 42; | |
41 // foo.baz = std::vector<std::string>(); | |
42 // foo.baz->push_back("hello world"); | |
43 // uint32_t x = *foo.bar; | |
44 // | |
45 // Pointers to all the members are available with |Members|, allowing iteration: | |
46 // | |
47 // for (const RTCStatsMemberInterface* member : foo.Members()) { | |
48 // printf("%s = %s\n", member->name(), member->ValueToString().c_str()); | |
49 // } | |
50 class RTCStats { | |
51 public: | |
52 RTCStats(const std::string& id, int64_t timestamp_us) | |
53 : id_(id), timestamp_us_(timestamp_us) {} | |
54 RTCStats(std::string&& id, int64_t timestamp_us) | |
55 : id_(std::move(id)), timestamp_us_(timestamp_us) {} | |
56 virtual ~RTCStats() {} | |
57 | |
58 virtual std::unique_ptr<RTCStats> copy() const = 0; | |
59 | |
60 const std::string& id() const { return id_; } | |
61 // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds. | |
62 int64_t timestamp_us() const { return timestamp_us_; } | |
63 // Returns the static member variable |kType| of the implementing class. | |
64 virtual const char* type() const = 0; | |
65 // Returns a vector of pointers to all the RTCStatsMemberInterface members of | |
66 // this class. This allows for iteration of members. | |
67 std::vector<const RTCStatsMemberInterface*> Members() const; | |
68 | |
69 // Creates a human readable string representation of the report, listing all | |
70 // of its members (names and values). | |
71 std::string ToString() const; | |
72 | |
73 // Downcasts the stats object to an |RTCStats| subclass |T|. DCHECKs that the | |
74 // object is of type |T|. | |
75 template<typename T> | |
76 const T& cast_to() const { | |
77 RTC_DCHECK_EQ(type(), T::kType); | |
78 return static_cast<const T&>(*this); | |
79 } | |
80 | |
81 protected: | |
82 // Gets a vector of all members of this |RTCStats| object, including members | |
83 // derived from parent classes. |additional_capacity| is how many more members | |
84 // shall be reserved in the vector (so that subclasses can allocate a vector | |
85 // with room for both parent and child members without it having to resize). | |
86 virtual std::vector<const RTCStatsMemberInterface*> | |
87 MembersOfThisObjectAndAncestors( | |
88 size_t additional_capacity) const; | |
89 | |
90 std::string const id_; | |
91 int64_t timestamp_us_; | |
92 }; | |
93 | |
94 // All |RTCStats| classes should use this macro in a public section of the class | |
95 // definition. | |
96 // | |
97 // This macro declares the static |kType| and overrides methods as required by | |
98 // subclasses of |RTCStats|: |copy|, |type|, and | |
99 // |MembersOfThisObjectAndAncestors|. The |...| argument is a list of addresses | |
100 // to each member defined in the implementing class (list cannot be empty, must | |
101 // have at least one new member). | |
102 // | |
103 // (Since class names need to be known to implement these methods this cannot be | |
104 // part of the base |RTCStats|. While these methods could be implemented using | |
105 // templates, that would only work for immediate subclasses. Subclasses of | |
106 // subclasses also have to override these methods, resulting in boilerplate | |
107 // code. Using a macro avoids this and works for any |RTCStats| class, including | |
108 // grandchildren.) | |
109 // | |
110 // Sample usage: | |
111 // | |
112 // rtcfoostats.h: | |
113 // class RTCFooStats : public RTCStats { | |
114 // public: | |
115 // RTCFooStats(const std::string& id, int64_t timestamp_us) | |
116 // : RTCStats(id, timestamp_us), | |
117 // foo("foo"), | |
118 // bar("bar") { | |
119 // } | |
120 // | |
121 // WEBRTC_RTCSTATS_IMPL(RTCStats, RTCFooStats, | |
122 // &foo, | |
123 // &bar); | |
124 // | |
125 // RTCStatsMember<int32_t> foo; | |
126 // RTCStatsMember<int32_t> bar; | |
127 // }; | |
128 // | |
129 // rtcfoostats.cc: | |
130 // const char RTCFooStats::kType[] = "foo-stats"; | |
131 // | |
132 #define WEBRTC_RTCSTATS_IMPL(parent_class, this_class, ...) \ | |
133 public: \ | |
134 static const char kType[]; \ | |
135 std::unique_ptr<webrtc::RTCStats> copy() const override { \ | |
136 return std::unique_ptr<webrtc::RTCStats>(new this_class(*this)); \ | |
137 } \ | |
138 const char* type() const override { return this_class::kType; } \ | |
139 protected: \ | |
140 std::vector<const webrtc::RTCStatsMemberInterface*> \ | |
141 MembersOfThisObjectAndAncestors( \ | |
142 size_t local_var_additional_capacity) const override { \ | |
143 const webrtc::RTCStatsMemberInterface* local_var_members[] = { \ | |
144 __VA_ARGS__ \ | |
145 }; \ | |
146 size_t local_var_members_count = \ | |
147 sizeof(local_var_members) / sizeof(local_var_members[0]); \ | |
148 std::vector<const webrtc::RTCStatsMemberInterface*> local_var_members_vec =\ | |
149 parent_class::MembersOfThisObjectAndAncestors( \ | |
150 local_var_members_count + local_var_additional_capacity); \ | |
151 RTC_DCHECK_GE( \ | |
152 local_var_members_vec.capacity() - local_var_members_vec.size(), \ | |
153 local_var_members_count + local_var_additional_capacity); \ | |
154 local_var_members_vec.insert(local_var_members_vec.end(), \ | |
155 &local_var_members[0], \ | |
156 &local_var_members[local_var_members_count]); \ | |
157 return local_var_members_vec; \ | |
158 } \ | |
159 public: | |
160 | |
161 // Interface for |RTCStats| members, which have a name and a value of a type | |
162 // defined in a subclass. Only the types listed in |Type| are supported, these | |
163 // are implemented by |RTCStatsMember<T>|. The value of a member may be | |
164 // undefined, the value can only be read if |is_defined|. | |
165 class RTCStatsMemberInterface { | |
166 public: | |
167 // Member value types. | |
168 enum Type { | |
169 kInt32, // int32_t | |
170 kUint32, // uint32_t | |
171 kInt64, // int64_t | |
172 kUint64, // uint64_t | |
173 kDouble, // double | |
174 kString, // std::string | |
175 | |
176 kSequenceInt32, // std::vector<int32_t> | |
177 kSequenceUint32, // std::vector<uint32_t> | |
178 kSequenceInt64, // std::vector<int64_t> | |
179 kSequenceUint64, // std::vector<uint64_t> | |
180 kSequenceDouble, // std::vector<double> | |
181 kSequenceString, // std::vector<std::string> | |
182 }; | |
183 | |
184 virtual ~RTCStatsMemberInterface() {} | |
185 | |
186 const char* name() const { return name_; } | |
187 virtual Type type() const = 0; | |
188 virtual bool is_sequence() const = 0; | |
189 virtual bool is_string() const = 0; | |
190 bool is_defined() const { return is_defined_; } | |
191 virtual std::string ValueToString() const = 0; | |
192 | |
193 template<typename T> | |
194 const T& cast_to() const { | |
195 RTC_DCHECK_EQ(type(), T::kType); | |
196 return static_cast<const T&>(*this); | |
197 } | |
198 | |
199 protected: | |
200 RTCStatsMemberInterface(const char* name, bool is_defined) | |
201 : name_(name), is_defined_(is_defined) {} | |
202 | |
203 const char* const name_; | |
204 bool is_defined_; | |
205 }; | |
206 | |
207 // Template implementation of |RTCStatsMemberInterface|. Every possible |T| is | |
208 // specialized in rtcstats.cc, using a different |T| results in a linker error | |
209 // (undefined reference to |kType|). The supported types are the ones described | |
210 // by |RTCStatsMemberInterface::Type|. | |
211 template<typename T> | |
212 class RTCStatsMember : public RTCStatsMemberInterface { | |
213 public: | |
214 static const Type kType; | |
215 | |
216 explicit RTCStatsMember(const char* name) | |
217 : RTCStatsMemberInterface(name, false), | |
218 value_() {} | |
219 RTCStatsMember(const char* name, const T& value) | |
220 : RTCStatsMemberInterface(name, true), | |
221 value_(value) {} | |
222 RTCStatsMember(const char* name, T&& value) | |
223 : RTCStatsMemberInterface(name, true), | |
224 value_(std::move(value)) {} | |
225 explicit RTCStatsMember(const RTCStatsMember<T>& other) | |
226 : RTCStatsMemberInterface(other.name_, other.is_defined_), | |
227 value_(other.value_) {} | |
228 explicit RTCStatsMember(RTCStatsMember<T>&& other) | |
229 : RTCStatsMemberInterface(other.name_, other.is_defined_), | |
230 value_(std::move(other.value_)) {} | |
231 | |
232 Type type() const override { return kType; } | |
233 bool is_sequence() const override; | |
234 bool is_string() const override; | |
235 std::string ValueToString() const override; | |
236 | |
237 // Assignment operators. | |
238 T& operator=(const T& value) { | |
239 value_ = value; | |
240 is_defined_ = true; | |
241 return value_; | |
242 } | |
243 T& operator=(const T&& value) { | |
244 value_ = std::move(value); | |
245 is_defined_ = true; | |
246 return value_; | |
247 } | |
248 T& operator=(const RTCStatsMember<T>& other) { | |
249 RTC_DCHECK(other.is_defined_); | |
250 value_ = other.is_defined_; | |
251 is_defined_ = true; | |
252 return value_; | |
253 } | |
254 | |
255 // Value getters. | |
256 T& operator*() { | |
257 RTC_DCHECK(is_defined_); | |
258 return value_; | |
259 } | |
260 const T& operator*() const { | |
261 RTC_DCHECK(is_defined_); | |
262 return value_; | |
263 } | |
264 | |
265 // Value getters, arrow operator. | |
266 T* operator->() { | |
267 RTC_DCHECK(is_defined_); | |
268 return &value_; | |
269 } | |
270 const T* operator->() const { | |
271 RTC_DCHECK(is_defined_); | |
272 return &value_; | |
273 } | |
274 | |
275 private: | |
276 T value_; | |
277 }; | |
278 | |
279 } // namespace webrtc | |
280 | |
281 #endif // WEBRTC_API_RTCSTATS_H_ | |
OLD | NEW |