blob: 94af4a72b384f22126425b2f39e580d698ef929c [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
15#include "api/optional.h"
16
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
29rtc::Optional<ValueWithUnit> ParseValueWithUnit(std::string str) {
30 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 }
43 return rtc::nullopt;
44}
45} // namespace
46
47template <>
48rtc::Optional<DataRate> ParseTypedParameter<DataRate>(std::string str) {
49 rtc::Optional<ValueWithUnit> result = ParseValueWithUnit(str);
50 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 }
57 return rtc::nullopt;
58}
59
60template <>
61rtc::Optional<DataSize> ParseTypedParameter<DataSize>(std::string str) {
62 rtc::Optional<ValueWithUnit> result = ParseValueWithUnit(str);
63 if (result) {
64 if (result->unit.empty() || result->unit == "bytes")
65 return DataSize::bytes(result->value);
66 }
67 return rtc::nullopt;
68}
69
70template <>
71rtc::Optional<TimeDelta> ParseTypedParameter<TimeDelta>(std::string str) {
72 rtc::Optional<ValueWithUnit> result = ParseValueWithUnit(str);
73 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 }
82 return rtc::nullopt;
83}
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