blob: b08fed457f8b11dc491ac33fc84b91c8a315c9cd [file] [log] [blame]
Avi Drissmand6cdf9b2022-09-15 19:52:531// Copyright 2016 The Chromium Authors
zijiehe21d8d3912016-11-18 20:14:212// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Zijie Hec18adab82017-11-17 21:08:475#include "remoting/base/session_options.h"
zijiehe21d8d3912016-11-18 20:14:216
7#include <vector>
8
9#include "base/logging.h"
zijiehee892fa92017-05-08 19:49:5510#include "base/strings/string_number_conversions.h"
zijiehe21d8d3912016-11-18 20:14:2111#include "base/strings/string_split.h"
12#include "base/strings/string_util.h"
13
14namespace remoting {
zijiehe21d8d3912016-11-18 20:14:2115
16namespace {
17
18static constexpr char kSeparator = ',';
19static constexpr char kKeyValueSeparator = ':';
20
Zijie Hec18adab82017-11-17 21:08:4721// Whether |value| is good to be added to SessionOptions as a value.
zijiehe21d8d3912016-11-18 20:14:2122bool ValueIsValid(const std::string& value) {
23 return value.find(kSeparator) == std::string::npos &&
24 value.find(kKeyValueSeparator) == std::string::npos &&
25 base::IsStringASCII(value);
26}
27
Zijie Hec18adab82017-11-17 21:08:4728// Whether |key| is good to be added to SessionOptions as a key.
zijiehe21d8d3912016-11-18 20:14:2129bool KeyIsValid(const std::string& key) {
30 return !key.empty() && ValueIsValid(key);
31}
32
33} // namespace
34
Zijie Hec18adab82017-11-17 21:08:4735SessionOptions::SessionOptions() = default;
Zijie Heba571512017-11-20 20:22:2336SessionOptions::SessionOptions(const SessionOptions& other) = default;
37SessionOptions::SessionOptions(SessionOptions&& other) = default;
zijiehe21d8d3912016-11-18 20:14:2138
Zijie Hec18adab82017-11-17 21:08:4739SessionOptions::SessionOptions(const std::string& parameter) {
zijiehef38c9722017-02-08 02:05:2940 Import(parameter);
41}
42
Zijie Heba571512017-11-20 20:22:2343SessionOptions::~SessionOptions() = default;
44
Joe Downingbc8bf50a2023-01-11 20:18:3545SessionOptions& SessionOptions::operator=(const SessionOptions& other) =
46 default;
Zijie Heba571512017-11-20 20:22:2347SessionOptions& SessionOptions::operator=(SessionOptions&& other) = default;
48
Joe Downingbc8bf50a2023-01-11 20:18:3549void SessionOptions::Append(const std::string& key, const std::string& value) {
zijiehe21d8d3912016-11-18 20:14:2150 DCHECK(KeyIsValid(key));
51 DCHECK(ValueIsValid(value));
52 options_[key] = value;
53}
54
Anton Bikineev11eb7ff2021-05-15 18:21:2855absl::optional<std::string> SessionOptions::Get(const std::string& key) const {
zijiehe21d8d3912016-11-18 20:14:2156 auto it = options_.find(key);
57 if (it == options_.end()) {
Anton Bikineev11eb7ff2021-05-15 18:21:2858 return absl::nullopt;
zijiehe21d8d3912016-11-18 20:14:2159 }
60 return it->second;
61}
62
Anton Bikineev11eb7ff2021-05-15 18:21:2863absl::optional<bool> SessionOptions::GetBool(const std::string& key) const {
64 absl::optional<std::string> value = Get(key);
zijiehee892fa92017-05-08 19:49:5565 if (!value) {
Anton Bikineev11eb7ff2021-05-15 18:21:2866 return absl::nullopt;
zijiehee892fa92017-05-08 19:49:5567 }
68
69 const std::string lowercase_value = base::ToLowerASCII(*value);
Joe Downingbc8bf50a2023-01-11 20:18:3570 if (lowercase_value.empty() || lowercase_value == "true" ||
zijiehee892fa92017-05-08 19:49:5571 lowercase_value == "1") {
72 return true;
73 }
74 if (lowercase_value == "false" || lowercase_value == "0") {
75 return false;
76 }
77 LOG(WARNING) << "Unexpected option received " << *value
78 << " which cannot be converted to bool.";
Anton Bikineev11eb7ff2021-05-15 18:21:2879 return absl::nullopt;
zijiehee892fa92017-05-08 19:49:5580}
81
Yuwei Huangdabd8ea2020-04-28 00:44:3182bool SessionOptions::GetBoolValue(const std::string& key) const {
83 return GetBool(key).value_or(false);
84}
85
Anton Bikineev11eb7ff2021-05-15 18:21:2886absl::optional<int> SessionOptions::GetInt(const std::string& key) const {
87 absl::optional<std::string> value = Get(key);
zijiehee892fa92017-05-08 19:49:5588 if (!value) {
Anton Bikineev11eb7ff2021-05-15 18:21:2889 return absl::nullopt;
zijiehee892fa92017-05-08 19:49:5590 }
91
92 int result;
93 if (base::StringToInt(*value, &result)) {
94 return result;
95 }
96 LOG(WARNING) << "Unexpected option received " << *value
97 << " which cannot be converted to integer.";
Anton Bikineev11eb7ff2021-05-15 18:21:2898 return absl::nullopt;
zijiehee892fa92017-05-08 19:49:5599}
100
Zijie Hec18adab82017-11-17 21:08:47101std::string SessionOptions::Export() const {
zijiehe21d8d3912016-11-18 20:14:21102 std::string result;
103 for (const auto& pair : options_) {
104 if (!result.empty()) {
105 result += kSeparator;
106 }
107 if (!pair.first.empty()) {
108 result += pair.first;
109 result.push_back(kKeyValueSeparator);
110 result += pair.second;
111 }
112 }
113 return result;
114}
115
Zijie Hec18adab82017-11-17 21:08:47116void SessionOptions::Import(const std::string& parameter) {
zijiehe21d8d3912016-11-18 20:14:21117 options_.clear();
118 std::vector<std::pair<std::string, std::string>> result;
Joe Downingbc8bf50a2023-01-11 20:18:35119 base::SplitStringIntoKeyValuePairs(parameter, kKeyValueSeparator, kSeparator,
zijiehe21d8d3912016-11-18 20:14:21120 &result);
121 for (const auto& pair : result) {
122 if (KeyIsValid(pair.first) && ValueIsValid(pair.second)) {
123 Append(pair.first, pair.second);
124 }
125 }
126}
127
zijiehe21d8d3912016-11-18 20:14:21128} // namespace remoting