summaryrefslogtreecommitdiff
path: root/src/CommonAPI/IniFileReader.cpp
blob: 94057e0ee3b07ff2ef54f227c4c814af805f459a (plain)
1
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <fstream>
#include <sstream>

#include <CommonAPI/IniFileReader.hpp>
#include <CommonAPI/Logger.hpp>
#include <CommonAPI/Utils.hpp>

namespace CommonAPI {

const std::map<std::string, std::string> &
IniFileReader::Section::getMappings() const {
    return mappings_;
}

std::string
IniFileReader::Section::getValue(const std::string &_key) const {
    auto it = mappings_.find(_key);
    if (it != mappings_.end()) {
        return it->second;
    }
    return ("");
}

bool
IniFileReader::load(const std::string &_path) {
    std::ifstream configStream(_path);
    if (!configStream.is_open()) {
        COMMONAPI_ERROR("Failed to load ini file: ", _path);
        return false;
    }

    int lineCounter(0);
    std::string currentSectionName;
    std::shared_ptr<Section> currentSection;

    while (!configStream.eof()) {
        std::string line;
        std::getline(configStream, line);
        lineCounter++;

        trim(line);

        std::size_t start = line.find('[');
        if (start == 0) {
            std::size_t end = line.find(']');
            if (end != line.npos) {
                currentSectionName = line.substr(++start, --end);
                if (sections_.end() == sections_.find(currentSectionName)) {
                    currentSection = std::make_shared<Section>();
                    if (currentSection) {
                        sections_[currentSectionName] = currentSection;
                    }
                } else {
                    COMMONAPI_ERROR("Double definition of section \'",
                                    currentSectionName,
                                    "\' ignoring definition (line ",
                                    lineCounter,
                                    ")");
                    currentSection = nullptr;
                }
            } else {
                COMMONAPI_ERROR("Missing \']\' in section definition (line ",
                                lineCounter, ")");
            }
        } else if (currentSection) {
            std::size_t pos = line.find('=');
            if (pos != line.npos) {
                std::string key = line.substr(0, pos);
                trim(key);
                if (currentSection->mappings_.end()
                    != currentSection->mappings_.find(key)) {
                    COMMONAPI_ERROR("Double definition for key \'",
                                    key,
                                    "'\' in section \'",
                                    currentSectionName,
                                    "\' (line ",
                                    lineCounter,
                                    ")");
                } else {
                    std::string value = line.substr(pos+1);
                    trim(value);
                    currentSection->mappings_[key] = value;
                }
            } else if (line.size() > 0) {
                COMMONAPI_ERROR("Missing \'=\' in key=value definition (line ",
                                lineCounter, ")");
            }
        }
    }
    return true;
}

const std::map<std::string, std::shared_ptr<IniFileReader::Section>> &
IniFileReader::getSections() const {
    return sections_;
}

std::shared_ptr<IniFileReader::Section>
IniFileReader::getSection(const std::string &_name) const {
    std::shared_ptr<IniFileReader::Section> section;

    auto sectionIterator = sections_.find(_name);
    if (sectionIterator != sections_.end()) {
        section = sectionIterator->second;
    }

    return section;
}

} // namespace CommonAPI