blob: 9c9cf434d95347953d4fbe4f9aaefc3de7a1143b [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
Yves Gerey988cc082018-10-23 12:03:01 +020012#include <stdio.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020013
Sebastian Jansson9eb38862018-06-14 16:47:42 +020014#include <limits>
15#include <string>
16
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020017#include "absl/types/optional.h"
Sebastian Jansson9eb38862018-06-14 16:47:42 +020018
19// Large enough to fit "seconds", the longest supported unit name.
20#define RTC_TRIAL_UNIT_LENGTH_STR "7"
21#define RTC_TRIAL_UNIT_SIZE 8
22
23namespace webrtc {
24namespace {
25
26struct ValueWithUnit {
27 double value;
28 std::string unit;
29};
30
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020031absl::optional<ValueWithUnit> ParseValueWithUnit(std::string str) {
Sebastian Jansson9eb38862018-06-14 16:47:42 +020032 if (str == "inf") {
33 return ValueWithUnit{std::numeric_limits<double>::infinity(), ""};
34 } else if (str == "-inf") {
35 return ValueWithUnit{-std::numeric_limits<double>::infinity(), ""};
36 } else {
37 double double_val;
38 char unit_char[RTC_TRIAL_UNIT_SIZE];
39 unit_char[0] = 0;
40 if (sscanf(str.c_str(), "%lf%" RTC_TRIAL_UNIT_LENGTH_STR "s", &double_val,
41 unit_char) >= 1) {
42 return ValueWithUnit{double_val, unit_char};
43 }
44 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020045 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020046}
47} // namespace
48
49template <>
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020050absl::optional<DataRate> ParseTypedParameter<DataRate>(std::string str) {
51 absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020052 if (result) {
53 if (result->unit.empty() || result->unit == "kbps") {
54 return DataRate::kbps(result->value);
55 } else if (result->unit == "bps") {
56 return DataRate::bps(result->value);
57 }
58 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020059 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020060}
61
62template <>
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020063absl::optional<DataSize> ParseTypedParameter<DataSize>(std::string str) {
64 absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020065 if (result) {
66 if (result->unit.empty() || result->unit == "bytes")
67 return DataSize::bytes(result->value);
68 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020069 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020070}
71
72template <>
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020073absl::optional<TimeDelta> ParseTypedParameter<TimeDelta>(std::string str) {
74 absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020075 if (result) {
76 if (result->unit == "s" || result->unit == "seconds") {
77 return TimeDelta::seconds(result->value);
78 } else if (result->unit == "us") {
79 return TimeDelta::us(result->value);
80 } else if (result->unit.empty() || result->unit == "ms") {
81 return TimeDelta::ms(result->value);
82 }
83 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020084 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020085}
86
Sebastian Jansson55251c32019-08-08 11:14:51 +020087template <>
88absl::optional<absl::optional<DataRate>>
89ParseTypedParameter<absl::optional<DataRate>>(std::string str) {
90 return ParseOptionalParameter<DataRate>(str);
91}
92template <>
93absl::optional<absl::optional<DataSize>>
94ParseTypedParameter<absl::optional<DataSize>>(std::string str) {
95 return ParseOptionalParameter<DataSize>(str);
96}
97template <>
98absl::optional<absl::optional<TimeDelta>>
99ParseTypedParameter<absl::optional<TimeDelta>>(std::string str) {
100 return ParseOptionalParameter<TimeDelta>(str);
101}
102
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200103template class FieldTrialParameter<DataRate>;
104template class FieldTrialParameter<DataSize>;
105template class FieldTrialParameter<TimeDelta>;
106
Sebastian Janssonb22f0772018-11-19 17:44:33 +0100107template class FieldTrialConstrained<DataRate>;
108template class FieldTrialConstrained<DataSize>;
109template class FieldTrialConstrained<TimeDelta>;
110
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200111template class FieldTrialOptional<DataRate>;
112template class FieldTrialOptional<DataSize>;
113template class FieldTrialOptional<TimeDelta>;
114} // namespace webrtc