ini.cpp 5.6 KB
Newer Older
羽飞's avatar
羽飞 已提交
1
/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved.
羽飞's avatar
羽飞 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */

//
// Created by Longda on 2010
//

#include <errno.h>
#include <string.h>

#include <fstream>

#include "common/conf/ini.h"
#include "common/defs.h"
#include "common/lang/string.h"
#include "common/log/log.h"

namespace common {

const std::string Ini::DEFAULT_SECTION = std::string("");
const std::map<std::string, std::string> Ini::empty_map_;

30 31
Ini::Ini()
{}
羽飞's avatar
羽飞 已提交
32

33 34
Ini::~Ini()
{}
羽飞's avatar
羽飞 已提交
35

36 37
void Ini::insert_session(const std::string &session_name)
{
羽飞's avatar
羽飞 已提交
38
  std::map<std::string, std::string> session_map;
39 40
  std::pair<std::string, std::map<std::string, std::string>> entry =
      std::pair<std::string, std::map<std::string, std::string>>(session_name, session_map);
羽飞's avatar
羽飞 已提交
41 42 43 44

  sections_.insert(entry);
}

45 46
std::map<std::string, std::string> *Ini::switch_session(const std::string &session_name)
{
羽飞's avatar
羽飞 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
  SessionsMap::iterator it = sections_.find(session_name);
  if (it != sections_.end()) {
    return &it->second;
  }

  insert_session(session_name);

  it = sections_.find(session_name);
  if (it != sections_.end()) {
    return &it->second;
  }

  // should never go this
  return nullptr;
}

63 64
const std::map<std::string, std::string> &Ini::get(const std::string &section)
{
羽飞's avatar
羽飞 已提交
65 66 67 68 69 70 71 72
  SessionsMap::iterator it = sections_.find(section);
  if (it == sections_.end()) {
    return empty_map_;
  }

  return it->second;
}

73 74
std::string Ini::get(const std::string &key, const std::string &defaultValue, const std::string &section)
{
羽飞's avatar
羽飞 已提交
75 76 77 78 79 80 81 82 83 84
  std::map<std::string, std::string> section_map = get(section);

  std::map<std::string, std::string>::iterator it = section_map.find(key);
  if (it == section_map.end()) {
    return defaultValue;
  }

  return it->second;
}

85 86
int Ini::put(const std::string &key, const std::string &value, const std::string &section)
{
羽飞's avatar
羽飞 已提交
87 88 89 90 91 92 93
  std::map<std::string, std::string> *section_map = switch_session(section);

  section_map->insert(std::pair<std::string, std::string>(key, value));

  return 0;
}

94 95
int Ini::insert_entry(std::map<std::string, std::string> *session_map, const std::string &line)
{
羽飞's avatar
羽飞 已提交
96
  if (session_map == nullptr) {
97
    std::cerr << __FILE__ << __FUNCTION__ << " session map is null" << std::endl;
羽飞's avatar
羽飞 已提交
98 99 100 101
    return -1;
  }
  size_t equal_pos = line.find_first_of('=');
  if (equal_pos == std::string::npos) {
102
    std::cerr << __FILE__ << __FUNCTION__ << "Invalid configuration line " << line << std::endl;
羽飞's avatar
羽飞 已提交
103 104 105 106 107 108 109 110 111 112 113 114 115 116
    return -1;
  }

  std::string key = line.substr(0, equal_pos);
  std::string value = line.substr(equal_pos + 1);

  strip(key);
  strip(value);

  session_map->insert(std::pair<std::string, std::string>(key, value));

  return 0;
}

117 118
int Ini::load(const std::string &file_name)
{
羽飞's avatar
羽飞 已提交
119 120 121 122 123 124
  std::ifstream ifs;

  try {

    bool continue_last_line = false;

125
    std::map<std::string, std::string> *current_session = switch_session(DEFAULT_SECTION);
羽飞's avatar
羽飞 已提交
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149

    char line[MAX_CFG_LINE_LEN];

    std::string line_entry;

    ifs.open(file_name.c_str());
    while (ifs.good()) {

      memset(line, 0, sizeof(line));

      ifs.getline(line, sizeof(line));

      char *read_buf = strip(line);

      if (strlen(read_buf) == 0) {
        // empty line
        continue;
      }

      if (read_buf[0] == CFG_COMMENT_TAG) {
        // comments line
        continue;
      }

150
      if (read_buf[0] == CFG_SESSION_START_TAG && read_buf[strlen(read_buf) - 1] == CFG_SESSION_END_TAG) {
羽飞's avatar
羽飞 已提交
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171

        read_buf[strlen(read_buf) - 1] = '\0';
        std::string session_name = std::string(read_buf + 1);

        current_session = switch_session(session_name);

        continue;
      }

      if (continue_last_line == false) {
        // don't need continue last line
        line_entry = read_buf;
      } else {
        line_entry += read_buf;
      }

      if (read_buf[strlen(read_buf) - 1] == CFG_CONTINUE_TAG) {
        // this line isn't finished, need continue
        continue_last_line = true;

        // remove the last character
172
        line_entry = line_entry.substr(0, line_entry.size() - 1);
羽飞's avatar
羽飞 已提交
173 174 175 176 177 178 179 180 181 182 183 184 185 186
        continue;
      } else {
        continue_last_line = false;
        insert_entry(current_session, line_entry);
      }
    }
    ifs.close();

    file_names_.insert(file_name);
    std::cout << "Successfully load " << file_name << std::endl;
  } catch (...) {
    if (ifs.is_open()) {
      ifs.close();
    }
187
    std::cerr << "Failed to load " << file_name << SYS_OUTPUT_ERROR << std::endl;
羽飞's avatar
羽飞 已提交
188 189 190 191 192 193
    return -1;
  }

  return 0;
}

194 195
void Ini::to_string(std::string &output_str)
{
羽飞's avatar
羽飞 已提交
196 197 198 199
  output_str.clear();

  output_str += "Begin dump configuration\n";

200
  for (SessionsMap::iterator it = sections_.begin(); it != sections_.end(); it++) {
羽飞's avatar
羽飞 已提交
201 202 203 204 205 206 207
    output_str += CFG_SESSION_START_TAG;
    output_str += it->first;
    output_str += CFG_SESSION_END_TAG;
    output_str += "\n";

    std::map<std::string, std::string> &section_map = it->second;

208 209
    for (std::map<std::string, std::string>::iterator sub_it = section_map.begin(); sub_it != section_map.end();
         sub_it++) {
羽飞's avatar
羽飞 已提交
210 211 212 213 214 215 216 217 218 219 220 221 222 223
      output_str += sub_it->first;
      output_str += "=";
      output_str += sub_it->second;
      output_str += "\n";
    }
    output_str += "\n";
  }

  output_str += "Finish dump configuration \n";

  return;
}

//! Accessor function which wraps global properties object
224 225
Ini *&get_properties()
{
羽飞's avatar
羽飞 已提交
226 227 228 229
  static Ini *properties = new Ini();
  return properties;
}

230
}  // namespace common