blob: 8c201a6ee7ec75d2d90c2b905ceb1244d8cbd048 [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>
Sebastian Jansson9eb38862018-06-14 16:47:42 +020013#include <limits>
14#include <string>
15
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020016#include "absl/types/optional.h"
Sebastian Jansson9eb38862018-06-14 16:47:42 +020017
18// Large enough to fit "seconds", the longest supported unit name.
19#define RTC_TRIAL_UNIT_LENGTH_STR "7"
20#define RTC_TRIAL_UNIT_SIZE 8
21
22namespace webrtc {
23namespace {
24
25struct ValueWithUnit {
26 double value;
27 std::string unit;
28};
29
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020030absl::optional<ValueWithUnit> ParseValueWithUnit(std::string str) {
Sebastian Jansson9eb38862018-06-14 16:47:42 +020031 if (str == "inf") {
32 return ValueWithUnit{std::numeric_limits<double>::infinity(), ""};
33 } else if (str == "-inf") {
34 return ValueWithUnit{-std::numeric_limits<double>::infinity(), ""};
35 } else {
36 double double_val;
37 char unit_char[RTC_TRIAL_UNIT_SIZE];
38 unit_char[0] = 0;
39 if (sscanf(str.c_str(), "%lf%" RTC_TRIAL_UNIT_LENGTH_STR "s", &double_val,
40 unit_char) >= 1) {
41 return ValueWithUnit{double_val, unit_char};
42 }
43 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020044 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020045}
46} // namespace
47
48template <>
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020049absl::optional<DataRate> ParseTypedParameter<DataRate>(std::string str) {
50 absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020051 if (result) {
52 if (result->unit.empty() || result->unit == "kbps") {
53 return DataRate::kbps(result->value);
54 } else if (result->unit == "bps") {
55 return DataRate::bps(result->value);
56 }
57 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020058 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020059}
60
61template <>
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020062absl::optional<DataSize> ParseTypedParameter<DataSize>(std::string str) {
63 absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020064 if (result) {
65 if (result->unit.empty() || result->unit == "bytes")
66 return DataSize::bytes(result->value);
67 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020068 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020069}
70
71template <>
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020072absl::optional<TimeDelta> ParseTypedParameter<TimeDelta>(std::string str) {
73 absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020074 if (result) {
75 if (result->unit == "s" || result->unit == "seconds") {
76 return TimeDelta::seconds(result->value);
77 } else if (result->unit == "us") {
78 return TimeDelta::us(result->value);
79 } else if (result->unit.empty() || result->unit == "ms") {
80 return TimeDelta::ms(result->value);
81 }
82 }
Danil Chapovalov0a1d1892018-06-21 11:48:25 +020083 return absl::nullopt;
Sebastian Jansson9eb38862018-06-14 16:47:42 +020084}
85
86template class FieldTrialParameter<DataRate>;
87template class FieldTrialParameter<DataSize>;
88template class FieldTrialParameter<TimeDelta>;
89
90template class FieldTrialOptional<DataRate>;
91template class FieldTrialOptional<DataSize>;
92template class FieldTrialOptional<TimeDelta>;
93} // namespace webrtc