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