summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/rtc_base/experiments/field_trial_parser.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/rtc_base/experiments/field_trial_parser.h')
-rw-r--r--third_party/libwebrtc/rtc_base/experiments/field_trial_parser.h291
1 files changed, 291 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/experiments/field_trial_parser.h b/third_party/libwebrtc/rtc_base/experiments/field_trial_parser.h
new file mode 100644
index 0000000000..822895e70b
--- /dev/null
+++ b/third_party/libwebrtc/rtc_base/experiments/field_trial_parser.h
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2018 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.
+ */
+#ifndef RTC_BASE_EXPERIMENTS_FIELD_TRIAL_PARSER_H_
+#define RTC_BASE_EXPERIMENTS_FIELD_TRIAL_PARSER_H_
+
+#include <stdint.h>
+
+#include <initializer_list>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+
+// Field trial parser functionality. Provides funcitonality to parse field trial
+// argument strings in key:value format. Each parameter is described using
+// key:value, parameters are separated with a ,. Values can't include the comma
+// character, since there's no quote facility. For most types, white space is
+// ignored. Parameters are declared with a given type for which an
+// implementation of ParseTypedParameter should be provided. The
+// ParseTypedParameter implementation is given whatever is between the : and the
+// ,. If the key is provided without : a FieldTrialOptional will use nullopt.
+
+// Example string: "my_optional,my_int:3,my_string:hello"
+
+// For further description of usage and behavior, see the examples in the unit
+// tests.
+
+namespace webrtc {
+class FieldTrialParameterInterface {
+ public:
+ virtual ~FieldTrialParameterInterface();
+ std::string key() const { return key_; }
+
+ protected:
+ // Protected to allow implementations to provide assignment and copy.
+ FieldTrialParameterInterface(const FieldTrialParameterInterface&) = default;
+ FieldTrialParameterInterface& operator=(const FieldTrialParameterInterface&) =
+ default;
+ explicit FieldTrialParameterInterface(absl::string_view key);
+ friend void ParseFieldTrial(
+ std::initializer_list<FieldTrialParameterInterface*> fields,
+ absl::string_view trial_string);
+ void MarkAsUsed() { used_ = true; }
+ virtual bool Parse(absl::optional<std::string> str_value) = 0;
+
+ virtual void ParseDone() {}
+
+ std::vector<FieldTrialParameterInterface*> sub_parameters_;
+
+ private:
+ std::string key_;
+ bool used_ = false;
+};
+
+// ParseFieldTrial function parses the given string and fills the given fields
+// with extracted values if available.
+void ParseFieldTrial(
+ std::initializer_list<FieldTrialParameterInterface*> fields,
+ absl::string_view trial_string);
+
+// Specialize this in code file for custom types. Should return absl::nullopt if
+// the given string cannot be properly parsed.
+template <typename T>
+absl::optional<T> ParseTypedParameter(absl::string_view);
+
+// This class uses the ParseTypedParameter function to implement a parameter
+// implementation with an enforced default value.
+template <typename T>
+class FieldTrialParameter : public FieldTrialParameterInterface {
+ public:
+ FieldTrialParameter(absl::string_view key, T default_value)
+ : FieldTrialParameterInterface(key), value_(default_value) {}
+ T Get() const { return value_; }
+ operator T() const { return Get(); }
+ const T* operator->() const { return &value_; }
+
+ void SetForTest(T value) { value_ = value; }
+
+ protected:
+ bool Parse(absl::optional<std::string> str_value) override {
+ if (str_value) {
+ absl::optional<T> value = ParseTypedParameter<T>(*str_value);
+ if (value.has_value()) {
+ value_ = value.value();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private:
+ T value_;
+};
+
+// This class uses the ParseTypedParameter function to implement a parameter
+// implementation with an enforced default value and a range constraint. Values
+// outside the configured range will be ignored.
+template <typename T>
+class FieldTrialConstrained : public FieldTrialParameterInterface {
+ public:
+ FieldTrialConstrained(absl::string_view key,
+ T default_value,
+ absl::optional<T> lower_limit,
+ absl::optional<T> upper_limit)
+ : FieldTrialParameterInterface(key),
+ value_(default_value),
+ lower_limit_(lower_limit),
+ upper_limit_(upper_limit) {}
+ T Get() const { return value_; }
+ operator T() const { return Get(); }
+ const T* operator->() const { return &value_; }
+
+ protected:
+ bool Parse(absl::optional<std::string> str_value) override {
+ if (str_value) {
+ absl::optional<T> value = ParseTypedParameter<T>(*str_value);
+ if (value && (!lower_limit_ || *value >= *lower_limit_) &&
+ (!upper_limit_ || *value <= *upper_limit_)) {
+ value_ = *value;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private:
+ T value_;
+ absl::optional<T> lower_limit_;
+ absl::optional<T> upper_limit_;
+};
+
+class AbstractFieldTrialEnum : public FieldTrialParameterInterface {
+ public:
+ AbstractFieldTrialEnum(absl::string_view key,
+ int default_value,
+ std::map<std::string, int> mapping);
+ ~AbstractFieldTrialEnum() override;
+ AbstractFieldTrialEnum(const AbstractFieldTrialEnum&);
+
+ protected:
+ bool Parse(absl::optional<std::string> str_value) override;
+
+ protected:
+ int value_;
+ std::map<std::string, int> enum_mapping_;
+ std::set<int> valid_values_;
+};
+
+// The FieldTrialEnum class can be used to quickly define a parser for a
+// specific enum. It handles values provided as integers and as strings if a
+// mapping is provided.
+template <typename T>
+class FieldTrialEnum : public AbstractFieldTrialEnum {
+ public:
+ FieldTrialEnum(absl::string_view key,
+ T default_value,
+ std::map<std::string, T> mapping)
+ : AbstractFieldTrialEnum(key,
+ static_cast<int>(default_value),
+ ToIntMap(mapping)) {}
+ T Get() const { return static_cast<T>(value_); }
+ operator T() const { return Get(); }
+
+ private:
+ static std::map<std::string, int> ToIntMap(std::map<std::string, T> mapping) {
+ std::map<std::string, int> res;
+ for (const auto& it : mapping)
+ res[it.first] = static_cast<int>(it.second);
+ return res;
+ }
+};
+
+// This class uses the ParseTypedParameter function to implement an optional
+// parameter implementation that can default to absl::nullopt.
+template <typename T>
+class FieldTrialOptional : public FieldTrialParameterInterface {
+ public:
+ explicit FieldTrialOptional(absl::string_view key)
+ : FieldTrialParameterInterface(key) {}
+ FieldTrialOptional(absl::string_view key, absl::optional<T> default_value)
+ : FieldTrialParameterInterface(key), value_(default_value) {}
+ absl::optional<T> GetOptional() const { return value_; }
+ const T& Value() const { return value_.value(); }
+ const T& operator*() const { return value_.value(); }
+ const T* operator->() const { return &value_.value(); }
+ explicit operator bool() const { return value_.has_value(); }
+
+ protected:
+ bool Parse(absl::optional<std::string> str_value) override {
+ if (str_value) {
+ absl::optional<T> value = ParseTypedParameter<T>(*str_value);
+ if (!value.has_value())
+ return false;
+ value_ = value.value();
+ } else {
+ value_ = absl::nullopt;
+ }
+ return true;
+ }
+
+ private:
+ absl::optional<T> value_;
+};
+
+// Equivalent to a FieldTrialParameter<bool> in the case that both key and value
+// are present. If key is missing, evaluates to false. If key is present, but no
+// explicit value is provided, the flag evaluates to true.
+class FieldTrialFlag : public FieldTrialParameterInterface {
+ public:
+ explicit FieldTrialFlag(absl::string_view key);
+ FieldTrialFlag(absl::string_view key, bool default_value);
+ bool Get() const;
+ explicit operator bool() const;
+
+ protected:
+ bool Parse(absl::optional<std::string> str_value) override;
+
+ private:
+ bool value_;
+};
+
+template <typename T>
+absl::optional<absl::optional<T>> ParseOptionalParameter(
+ absl::string_view str) {
+ if (str.empty())
+ return absl::optional<T>();
+ auto parsed = ParseTypedParameter<T>(str);
+ if (parsed.has_value())
+ return parsed;
+ return absl::nullopt;
+}
+
+template <>
+absl::optional<bool> ParseTypedParameter<bool>(absl::string_view str);
+template <>
+absl::optional<double> ParseTypedParameter<double>(absl::string_view str);
+template <>
+absl::optional<int> ParseTypedParameter<int>(absl::string_view str);
+template <>
+absl::optional<unsigned> ParseTypedParameter<unsigned>(absl::string_view str);
+template <>
+absl::optional<std::string> ParseTypedParameter<std::string>(
+ absl::string_view str);
+
+template <>
+absl::optional<absl::optional<bool>> ParseTypedParameter<absl::optional<bool>>(
+ absl::string_view str);
+template <>
+absl::optional<absl::optional<int>> ParseTypedParameter<absl::optional<int>>(
+ absl::string_view str);
+template <>
+absl::optional<absl::optional<unsigned>>
+ParseTypedParameter<absl::optional<unsigned>>(absl::string_view str);
+template <>
+absl::optional<absl::optional<double>>
+ParseTypedParameter<absl::optional<double>>(absl::string_view str);
+
+// Accepts true, false, else parsed with sscanf %i, true if != 0.
+extern template class FieldTrialParameter<bool>;
+// Interpreted using sscanf %lf.
+extern template class FieldTrialParameter<double>;
+// Interpreted using sscanf %i.
+extern template class FieldTrialParameter<int>;
+// Interpreted using sscanf %u.
+extern template class FieldTrialParameter<unsigned>;
+// Using the given value as is.
+extern template class FieldTrialParameter<std::string>;
+
+extern template class FieldTrialConstrained<double>;
+extern template class FieldTrialConstrained<int>;
+extern template class FieldTrialConstrained<unsigned>;
+
+extern template class FieldTrialOptional<double>;
+extern template class FieldTrialOptional<int>;
+extern template class FieldTrialOptional<unsigned>;
+extern template class FieldTrialOptional<bool>;
+extern template class FieldTrialOptional<std::string>;
+
+} // namespace webrtc
+
+#endif // RTC_BASE_EXPERIMENTS_FIELD_TRIAL_PARSER_H_