blob: d84c948e351cd80c79b74749e92a534d7a84c08f [file] [log] [blame]
henrike@webrtc.orgf7795df2014-05-13 18:00:26 +00001/*
2 * Copyright 2008 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
11#include "webrtc/base/optionsfile.h"
12
13#include <ctype.h>
14
15#include "webrtc/base/logging.h"
16#include "webrtc/base/stream.h"
17#include "webrtc/base/stringencode.h"
18
19namespace rtc {
20
21OptionsFile::OptionsFile(const std::string &path) : path_(path) {
22}
23
24bool OptionsFile::Load() {
25 options_.clear();
26 // Open file.
27 FileStream stream;
28 int err;
29 if (!stream.Open(path_, "r", &err)) {
30 LOG_F(LS_WARNING) << "Could not open file, err=" << err;
31 // We do not consider this an error because we expect there to be no file
32 // until the user saves a setting.
33 return true;
34 }
35 // Read in all its data.
36 std::string line;
37 StreamResult res;
38 for (;;) {
39 res = stream.ReadLine(&line);
40 if (res != SR_SUCCESS) {
41 break;
42 }
43 size_t equals_pos = line.find('=');
44 if (equals_pos == std::string::npos) {
45 // We do not consider this an error. Instead we ignore the line and
46 // keep going.
47 LOG_F(LS_WARNING) << "Ignoring malformed line in " << path_;
48 continue;
49 }
50 std::string key(line, 0, equals_pos);
51 std::string value(line, equals_pos + 1, line.length() - (equals_pos + 1));
52 options_[key] = value;
53 }
54 if (res != SR_EOS) {
55 LOG_F(LS_ERROR) << "Error when reading from file";
56 return false;
57 } else {
58 return true;
59 }
60}
61
62bool OptionsFile::Save() {
63 // Open file.
64 FileStream stream;
65 int err;
66 if (!stream.Open(path_, "w", &err)) {
67 LOG_F(LS_ERROR) << "Could not open file, err=" << err;
68 return false;
69 }
70 // Write out all the data.
71 StreamResult res = SR_SUCCESS;
72 size_t written;
73 int error;
74 for (OptionsMap::const_iterator i = options_.begin(); i != options_.end();
75 ++i) {
76 res = stream.WriteAll(i->first.c_str(), i->first.length(), &written,
77 &error);
78 if (res != SR_SUCCESS) {
79 break;
80 }
81 res = stream.WriteAll("=", 1, &written, &error);
82 if (res != SR_SUCCESS) {
83 break;
84 }
85 res = stream.WriteAll(i->second.c_str(), i->second.length(), &written,
86 &error);
87 if (res != SR_SUCCESS) {
88 break;
89 }
90 res = stream.WriteAll("\n", 1, &written, &error);
91 if (res != SR_SUCCESS) {
92 break;
93 }
94 }
95 if (res != SR_SUCCESS) {
96 LOG_F(LS_ERROR) << "Unable to write to file";
97 return false;
98 } else {
99 return true;
100 }
101}
102
103bool OptionsFile::IsLegalName(const std::string &name) {
104 for (size_t pos = 0; pos < name.length(); ++pos) {
105 if (name[pos] == '\n' || name[pos] == '\\' || name[pos] == '=') {
106 // Illegal character.
107 LOG(LS_WARNING) << "Ignoring operation for illegal option " << name;
108 return false;
109 }
110 }
111 return true;
112}
113
114bool OptionsFile::IsLegalValue(const std::string &value) {
115 for (size_t pos = 0; pos < value.length(); ++pos) {
116 if (value[pos] == '\n' || value[pos] == '\\') {
117 // Illegal character.
118 LOG(LS_WARNING) << "Ignoring operation for illegal value " << value;
119 return false;
120 }
121 }
122 return true;
123}
124
125bool OptionsFile::GetStringValue(const std::string& option,
126 std::string *out_val) const {
127 LOG(LS_VERBOSE) << "OptionsFile::GetStringValue "
128 << option;
129 if (!IsLegalName(option)) {
130 return false;
131 }
132 OptionsMap::const_iterator i = options_.find(option);
133 if (i == options_.end()) {
134 return false;
135 }
136 *out_val = i->second;
137 return true;
138}
139
140bool OptionsFile::GetIntValue(const std::string& option,
141 int *out_val) const {
142 LOG(LS_VERBOSE) << "OptionsFile::GetIntValue "
143 << option;
144 if (!IsLegalName(option)) {
145 return false;
146 }
147 OptionsMap::const_iterator i = options_.find(option);
148 if (i == options_.end()) {
149 return false;
150 }
151 return FromString(i->second, out_val);
152}
153
154bool OptionsFile::SetStringValue(const std::string& option,
155 const std::string& value) {
156 LOG(LS_VERBOSE) << "OptionsFile::SetStringValue "
157 << option << ":" << value;
158 if (!IsLegalName(option) || !IsLegalValue(value)) {
159 return false;
160 }
161 options_[option] = value;
162 return true;
163}
164
165bool OptionsFile::SetIntValue(const std::string& option,
166 int value) {
167 LOG(LS_VERBOSE) << "OptionsFile::SetIntValue "
168 << option << ":" << value;
169 if (!IsLegalName(option)) {
170 return false;
171 }
172 return ToString(value, &options_[option]);
173}
174
175bool OptionsFile::RemoveValue(const std::string& option) {
176 LOG(LS_VERBOSE) << "OptionsFile::RemoveValue " << option;
177 if (!IsLegalName(option)) {
178 return false;
179 }
180 options_.erase(option);
181 return true;
182}
183
184} // namespace rtc