summaryrefslogtreecommitdiff
path: root/src/CommonAPI/IniFileReader.cpp
blob: fd8adf89bd81040ebd36a794ee9f1ab68fb80b57 (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
// Copyright (C) 2015 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_INFO("Loading ini file from ", _path);

        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