- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / base / optionsfile.cc
1 /*
2  * libjingle
3  * Copyright 2008, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "talk/base/optionsfile.h"
29
30 #include <ctype.h>
31
32 #include "talk/base/logging.h"
33 #include "talk/base/stream.h"
34 #include "talk/base/stringencode.h"
35
36 namespace talk_base {
37
38 OptionsFile::OptionsFile(const std::string &path) : path_(path) {
39 }
40
41 bool OptionsFile::Load() {
42   options_.clear();
43   // Open file.
44   FileStream stream;
45   int err;
46   if (!stream.Open(path_, "r", &err)) {
47     LOG_F(LS_WARNING) << "Could not open file, err=" << err;
48     // We do not consider this an error because we expect there to be no file
49     // until the user saves a setting.
50     return true;
51   }
52   // Read in all its data.
53   std::string line;
54   StreamResult res;
55   for (;;) {
56     res = stream.ReadLine(&line);
57     if (res != SR_SUCCESS) {
58       break;
59     }
60     size_t equals_pos = line.find('=');
61     if (equals_pos == std::string::npos) {
62       // We do not consider this an error. Instead we ignore the line and
63       // keep going.
64       LOG_F(LS_WARNING) << "Ignoring malformed line in " << path_;
65       continue;
66     }
67     std::string key(line, 0, equals_pos);
68     std::string value(line, equals_pos + 1, line.length() - (equals_pos + 1));
69     options_[key] = value;
70   }
71   if (res != SR_EOS) {
72     LOG_F(LS_ERROR) << "Error when reading from file";
73     return false;
74   } else {
75     return true;
76   }
77 }
78
79 bool OptionsFile::Save() {
80   // Open file.
81   FileStream stream;
82   int err;
83   if (!stream.Open(path_, "w", &err)) {
84     LOG_F(LS_ERROR) << "Could not open file, err=" << err;
85     return false;
86   }
87   // Write out all the data.
88   StreamResult res = SR_SUCCESS;
89   size_t written;
90   int error;
91   for (OptionsMap::const_iterator i = options_.begin(); i != options_.end();
92        ++i) {
93     res = stream.WriteAll(i->first.c_str(), i->first.length(), &written,
94         &error);
95     if (res != SR_SUCCESS) {
96       break;
97     }
98     res = stream.WriteAll("=", 1, &written, &error);
99     if (res != SR_SUCCESS) {
100       break;
101     }
102     res = stream.WriteAll(i->second.c_str(), i->second.length(), &written,
103         &error);
104     if (res != SR_SUCCESS) {
105       break;
106     }
107     res = stream.WriteAll("\n", 1, &written, &error);
108     if (res != SR_SUCCESS) {
109       break;
110     }
111   }
112   if (res != SR_SUCCESS) {
113     LOG_F(LS_ERROR) << "Unable to write to file";
114     return false;
115   } else {
116     return true;
117   }
118 }
119
120 bool OptionsFile::IsLegalName(const std::string &name) {
121   for (size_t pos = 0; pos < name.length(); ++pos) {
122     if (name[pos] == '\n' || name[pos] == '\\' || name[pos] == '=') {
123       // Illegal character.
124       LOG(LS_WARNING) << "Ignoring operation for illegal option " << name;
125       return false;
126     }
127   }
128   return true;
129 }
130
131 bool OptionsFile::IsLegalValue(const std::string &value) {
132   for (size_t pos = 0; pos < value.length(); ++pos) {
133     if (value[pos] == '\n' || value[pos] == '\\') {
134       // Illegal character.
135       LOG(LS_WARNING) << "Ignoring operation for illegal value " << value;
136       return false;
137     }
138   }
139   return true;
140 }
141
142 bool OptionsFile::GetStringValue(const std::string& option,
143                                  std::string *out_val) const {
144   LOG(LS_VERBOSE) << "OptionsFile::GetStringValue "
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   *out_val = i->second;
154   return true;
155 }
156
157 bool OptionsFile::GetIntValue(const std::string& option,
158                               int *out_val) const {
159   LOG(LS_VERBOSE) << "OptionsFile::GetIntValue "
160                   << option;
161   if (!IsLegalName(option)) {
162     return false;
163   }
164   OptionsMap::const_iterator i = options_.find(option);
165   if (i == options_.end()) {
166     return false;
167   }
168   return FromString(i->second, out_val);
169 }
170
171 bool OptionsFile::SetStringValue(const std::string& option,
172                                  const std::string& value) {
173   LOG(LS_VERBOSE) << "OptionsFile::SetStringValue "
174                   << option << ":" << value;
175   if (!IsLegalName(option) || !IsLegalValue(value)) {
176     return false;
177   }
178   options_[option] = value;
179   return true;
180 }
181
182 bool OptionsFile::SetIntValue(const std::string& option,
183                               int value) {
184   LOG(LS_VERBOSE) << "OptionsFile::SetIntValue "
185                   << option << ":" << value;
186   if (!IsLegalName(option)) {
187     return false;
188   }
189   return ToString(value, &options_[option]);
190 }
191
192 bool OptionsFile::RemoveValue(const std::string& option) {
193   LOG(LS_VERBOSE) << "OptionsFile::RemoveValue " << option;
194   if (!IsLegalName(option)) {
195     return false;
196   }
197   options_.erase(option);
198   return true;
199 }
200
201 }  // namespace talk_base