/* * 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 #include #include #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 // ,. FieldTrialOptional will use nullopt if the key is provided without :. // 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(); protected: explicit FieldTrialParameterInterface(std::string key); friend void ParseFieldTrial( std::initializer_list fields, std::string raw_string); virtual bool Parse(absl::optional str_value) = 0; std::string Key() const; private: const std::string key_; }; // ParseFieldTrial function parses the given string and fills the given fields // with extrated values if available. void ParseFieldTrial( std::initializer_list fields, std::string raw_string); // Specialize this in code file for custom types. Should return absl::nullopt if // the given string cannot be properly parsed. template absl::optional ParseTypedParameter(std::string); // This class uses the ParseTypedParameter function to implement a parameter // implementation with an enforced default value. template class FieldTrialParameter : public FieldTrialParameterInterface { public: FieldTrialParameter(std::string key, T default_value) : FieldTrialParameterInterface(key), value_(default_value) {} T Get() const { return value_; } operator T() const { return Get(); } protected: bool Parse(absl::optional str_value) override { if (str_value) { absl::optional value = ParseTypedParameter(*str_value); if (value.has_value()) { value_ = value.value(); return true; } } return false; } private: T value_; }; // This class uses the ParseTypedParameter function to implement an optional // parameter implementation that can default to absl::nullopt. template class FieldTrialOptional : public FieldTrialParameterInterface { public: explicit FieldTrialOptional(std::string key) : FieldTrialParameterInterface(key) {} FieldTrialOptional(std::string key, absl::optional default_value) : FieldTrialParameterInterface(key), value_(default_value) {} absl::optional Get() const { return value_; } protected: bool Parse(absl::optional str_value) override { if (str_value) { absl::optional value = ParseTypedParameter(*str_value); if (!value.has_value()) return false; value_ = value.value(); } else { value_ = absl::nullopt; } return true; } private: absl::optional value_; }; // Equivalent to a FieldTrialParameter 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(std::string key); FieldTrialFlag(std::string key, bool default_value); bool Get() const; protected: bool Parse(absl::optional str_value) override; private: bool value_; }; // Accepts true, false, else parsed with sscanf %i, true if != 0. extern template class FieldTrialParameter; // Interpreted using sscanf %lf. extern template class FieldTrialParameter; // Interpreted using sscanf %i. extern template class FieldTrialParameter; // Using the given value as is. extern template class FieldTrialParameter; extern template class FieldTrialOptional; extern template class FieldTrialOptional; extern template class FieldTrialOptional; extern template class FieldTrialOptional; } // namespace webrtc #endif // RTC_BASE_EXPERIMENTS_FIELD_TRIAL_PARSER_H_