tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rtc_event_definition.h (5618B)


      1 /*
      2 *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
      3 *
      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
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DEFINITION_H_
     12 #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DEFINITION_H_
     13 
     14 #include <cstdint>
     15 #include <string>
     16 #include <vector>
     17 
     18 #include "absl/strings/string_view.h"
     19 #include "api/array_view.h"
     20 #include "api/rtc_event_log/rtc_event.h"
     21 #include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
     22 #include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
     23 #include "logging/rtc_event_log/events/rtc_event_log_parse_status.h"
     24 
     25 namespace webrtc {
     26 
     27 template <typename EventType, typename LoggedType, typename T>
     28 struct RtcEventFieldDefinition {
     29  const T EventType::*event_member;
     30  T LoggedType::*logged_member;
     31  FieldParameters params;
     32 };
     33 
     34 // Base case
     35 template <typename EventType, typename LoggedType, typename... Ts>
     36 class RtcEventDefinitionImpl {
     37 public:
     38  void EncodeImpl(EventEncoder&, ArrayView<const RtcEvent*>) const {}
     39  RtcEventLogParseStatus ParseImpl(EventParser&, ArrayView<LoggedType>) const {
     40    return RtcEventLogParseStatus::Success();
     41  }
     42 };
     43 
     44 // Recursive case
     45 template <typename EventType, typename LoggedType, typename T, typename... Ts>
     46 class RtcEventDefinitionImpl<EventType, LoggedType, T, Ts...> {
     47 public:
     48  constexpr RtcEventDefinitionImpl(
     49      RtcEventFieldDefinition<EventType, LoggedType, T> field,
     50      RtcEventFieldDefinition<EventType, LoggedType, Ts>... rest)
     51      : field_(field), rest_(rest...) {}
     52 
     53  void EncodeImpl(EventEncoder& encoder,
     54                  ArrayView<const RtcEvent*> batch) const {
     55    auto values = ExtractRtcEventMember(batch, field_.event_member);
     56    encoder.EncodeField(field_.params, values);
     57    rest_.EncodeImpl(encoder, batch);
     58  }
     59 
     60  RtcEventLogParseStatus ParseImpl(EventParser& parser,
     61                                   ArrayView<LoggedType> output_batch) const {
     62    RtcEventLogParseStatusOr<ArrayView<uint64_t>> result =
     63        parser.ParseNumericField(field_.params);
     64    if (!result.ok())
     65      return result.status();
     66    auto status = PopulateRtcEventMember(result.value(), field_.logged_member,
     67                                         output_batch);
     68    if (!status.ok())
     69      return status;
     70 
     71    return rest_.ParseImpl(parser, output_batch);
     72  }
     73 
     74 private:
     75  RtcEventFieldDefinition<EventType, LoggedType, T> field_;
     76  RtcEventDefinitionImpl<EventType, LoggedType, Ts...> rest_;
     77 };
     78 
     79 // The RtcEventDefinition sets up a mapping between the fields
     80 // in an RtcEvent and the corresponding fields in the parsed struct.
     81 // For example, an RtcFoo class containing two fields; `uint32_t bar`
     82 // and `bool baz` (a log timestamp is always implicitly added)
     83 // might have a definition
     84 // RtcEventDefinition<RtcFoo, LoggedFoo, uint32_t, bool>(
     85 //   {"foo", RtcFoo::Type},
     86 //   {&RtcFoo::bar_, &LoggedFoo::bar, {"bar", 1, FieldType::kVarInt, 32}},
     87 //   {&RtcFoo::baz_, &LoggedFoo::baz, {"baz", 2, FieldType::kFixed8, 1}},
     88 // );
     89 // In addition to defining string names to aid debugging,
     90 // this specifies that
     91 // * RtcFoo::Type uniquely identifies an RtcFoo in the encoded stream
     92 // * The `bar` field has ID 1, is encoded as a VarInt
     93 //   (when not delta compressed), and wraps around after 32 bits.
     94 // * The `baz` field has ID 2, is encoded as an 8-bit field
     95 //   (when not delta compressed), and wraps around after 1 bit.
     96 // Note that the numerical field and event IDs can't be changed since
     97 // that would break compatibility with old logs.
     98 // In most cases (including all cases where wrap around isn't
     99 // expected), the wrap around should be equal to the bitwidth of
    100 // the field.
    101 template <typename EventType, typename LoggedType, typename... Ts>
    102 class RtcEventDefinition {
    103 public:
    104  constexpr RtcEventDefinition(
    105      EventParameters params,
    106      RtcEventFieldDefinition<EventType, LoggedType, Ts>... fields)
    107      : params_(params), fields_(fields...) {}
    108 
    109  std::string EncodeBatch(ArrayView<const RtcEvent*> batch) const {
    110    EventEncoder encoder(params_, batch);
    111    fields_.EncodeImpl(encoder, batch);
    112    return encoder.AsString();
    113  }
    114 
    115  RtcEventLogParseStatus ParseBatch(absl::string_view s,
    116                                    bool batched,
    117                                    std::vector<LoggedType>& output) const {
    118    EventParser parser;
    119    auto status = parser.Initialize(s, batched);
    120    if (!status.ok())
    121      return status;
    122 
    123    ArrayView<LoggedType> output_batch =
    124        ExtendLoggedBatch(output, parser.NumEventsInBatch());
    125 
    126    constexpr FieldParameters timestamp_params{"timestamp_ms",
    127                                               FieldParameters::kTimestampField,
    128                                               FieldType::kVarInt, 64};
    129    RtcEventLogParseStatusOr<ArrayView<uint64_t>> result =
    130        parser.ParseNumericField(timestamp_params);
    131    if (!result.ok())
    132      return result.status();
    133    status = PopulateRtcEventTimestamp(result.value(), &LoggedType::timestamp,
    134                                       output_batch);
    135    if (!status.ok())
    136      return status;
    137 
    138    return fields_.ParseImpl(parser, output_batch);
    139  }
    140 
    141 private:
    142  EventParameters params_;
    143  RtcEventDefinitionImpl<EventType, LoggedType, Ts...> fields_;
    144 };
    145 
    146 }  // namespace webrtc
    147 
    148 #endif  // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DEFINITION_H_