daemonconfig.h 3.8 KB
/* ****************************************************************************
 * Copyright 2019 Open Systems Development BV                                 *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *
 * DEALINGS IN THE SOFTWARE.                                                  *
 * ****************************************************************************/
#pragma once

#include <fstream>
#include <cstring>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>

#include "daemonlog.h"

// TODO: Do a better config parsing.
namespace osdev::components::daemon 
{
    struct daemonconfig
    {
        std::map<std::string, std::string> values;

        std::string get(const std::string &key) const
        {
            auto it = values.find(key);
            if (it != values.end())
            {
                return it->second;
            }
            return "";
        }

        static daemonconfig from_file(const std::string &filename)
        {
            daemonconfig cfg;
            if (filename.empty())
            {
                return cfg;
            }

            auto split = [](const std::string &str, char delim)
            {
                std::vector<std::string> parts;
                std::stringstream oss(str);
                std::string part;
                while (std::getline(oss, part, delim))
                {
                    parts.push_back(part);
                }
                return parts;
            };

            auto trim = [](std::string &s)
            {
                s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch){ return !std::isspace(ch);}));
                s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch){return !std::isspace(ch);}).base(), s.end());
            };

            std::ifstream ifs{filename};
            std::string line;

            while(std::getline(ifs, line))
            {
                trim(line);
                if (line.empty())       // skip empty lines
                {
                    continue;
                }

                if (line[0] == '#')     // skip comments
                {
                    continue;
                }

                auto parts = split(line, '=');
                std::string key = parts[0];
                std::string value = parts[1];
                trim(key);
                trim(value);
                cfg.values[key] = value;
            }
            ifs.close();
            return cfg;
        }
    };
}