blob: f53978b21153d4fd5024e1c99564d57ebf91adf7 [file] [log] [blame]
Sebastian Jansson9eb38862018-06-14 16:47:42 +02001/*
2 * Copyright 2018 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#include "rtc_base/experiments/field_trial_units.h"
11
12#include <limits>
13#include <string>
14
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020015#include "absl/types/optional.h"
Sebastian Jansson9eb38862018-06-14 16:47:42 +020016
17// Large enough to fit "seconds", the longest supported unit name.
18#define RTC_TRIAL_UNIT_LENGTH_STR "7"
19#define RTC_TRIAL_UNIT_SIZE 8
20
21namespace webrtc {
22namespace {
23
24struct ValueWithUnit {
25 double value;
26 std::string unit;
27};
28
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020029absl::optional<ValueWithUnit> ParseValueWithUnit(std::string str) {
Sebastian Jansson9eb38862018-06-14 16:47:42 +020030 if (str == "inf") {
31 return ValueWithUnit{std::numeric_limits<double>::infinity(), ""};
32 } else if (str == "-inf") {
33 return ValueWithUnit{-std::numeric_limits<double>::infinity(), ""};
34 } else {
35 double double_val;
36 char unit_char[RTC_TRIAL_UNIT_SIZE];
37 unit_char[0] = 0;
38 if (sscanf(str.c_str(), "%lf%" RTC_TRIAL_UNIT_LENGTH_STR "s", &double_val,
39 unit_char) >= 1) {
40 return ValueWithUnit{double_val, unit_char};
41 }
42 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020043 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020044}
45} // namespace
46
47template <>
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020048absl::optional<DataRate> ParseTypedParameter<DataRate>(std::string str) {
49 absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020050 if (result) {
51 if (result->unit.empty() || result->unit == "kbps") {
52 return DataRate::kbps(result->value);
53 } else if (result->unit == "bps") {
54 return DataRate::bps(result->value);
55 }
56 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020057 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020058}
59
60template <>
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020061absl::optional<DataSize> ParseTypedParameter<DataSize>(std::string str) {
62 absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020063 if (result) {
64 if (result->unit.empty() || result->unit == "bytes")
65 return DataSize::bytes(result->value);
66 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020067 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020068}
69
70template <>
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020071absl::optional<TimeDelta> ParseTypedParameter<TimeDelta>(std::string str) {
72 absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020073 if (result) {
74 if (result->unit == "s" || result->unit == "seconds") {
75 return TimeDelta::seconds(result->value);
76 } else if (result->unit == "us") {
77 return TimeDelta::us(result->value);
78 } else if (result->unit.empty() || result->unit == "ms") {
79 return TimeDelta::ms(result->value);
80 }
81 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020082 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020083}
84
85template class FieldTrialParameter<DataRate>;
86template class FieldTrialParameter<DataSize>;
87template class FieldTrialParameter<TimeDelta>;
88
89template class FieldTrialOptional<DataRate>;
90template class FieldTrialOptional<DataSize>;
91template class FieldTrialOptional<TimeDelta>;
92} // namespace webrtc