Home | History | Annotate | Download | only in base
      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 
     21 OptionsFile::OptionsFile(const std::string &path) : path_(path) {
     22 }
     23 
     24 bool 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 
     62 bool 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 
    103 bool 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 
    114 bool 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 
    125 bool 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 
    140 bool 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 
    154 bool 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 
    165 bool 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 
    175 bool 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
    185