From 272fb3aab0a516a33735870b482c17d1a8c54790 Mon Sep 17 00:00:00 2001 From: Sven Czarnian Date: Tue, 10 Aug 2021 08:42:53 +0200 Subject: [PATCH] add the communication file format --- include/aman/config/CommunicationFileFormat.h | 61 +++++++++++ src/CMakeLists.txt | 3 + src/config/CommunicationFileFormat.cpp | 100 ++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 include/aman/config/CommunicationFileFormat.h create mode 100644 src/config/CommunicationFileFormat.cpp diff --git a/include/aman/config/CommunicationFileFormat.h b/include/aman/config/CommunicationFileFormat.h new file mode 100644 index 0000000..7b1a164 --- /dev/null +++ b/include/aman/config/CommunicationFileFormat.h @@ -0,0 +1,61 @@ +/* + * @brief Defines the communication file format + * @file aman/config/CommunicationFileFormat.h + * @author Sven Czarnian + * @copyright Copyright 2021 Sven Czarnian + * @license This project is published under the GNU General Public License v3 (GPLv3) + */ + +#pragma once + +#include +#include + +namespace aman { + /** + * @brief Defines the parser of communication configurations + * @ingroup format + * + * All configuration entries need to be stored in 'AmanCommunication.txt'. + * + * The following entries of the configuration exist: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Setting entries
NameDescriptionDefault valueUnit
URLDefines the URL to the backend.
PortDefines the port to access the backend.
UIDDefines the identifier to access the backend.
+ */ + class CommunicationFileFormat : public FileFormat { +#ifndef DOXYGEN_IGNORE + public: + /** + * @brief Initializes the communication file format + */ + CommunicationFileFormat(); + + /** + * @brief Parses the set configuration file + * @param[in] filename The path to the configuration file + * @param[out] config The resulting configuration + * @return True if the configuration file was valid, else false + */ + bool parse(const std::string& filename, Communication& config); +#endif + }; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1eeadfa..1ffc99d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,6 +15,7 @@ SET(SOURCE_FILES stdafx.h ) SET(SOURCE_CONFIG_FILES + config/CommunicationFileFormat.cpp config/FileFormat.cpp config/IdentifierFileFormat.cpp ) @@ -24,6 +25,7 @@ SET(SOURCE_FILES_RES ${CMAKE_SOURCE_DIR}/res/targetver.h ) SET(INCLUDE_CONFIG_FILES + ${CMAKE_SOURCE_DIR}/include/aman/config/CommunicationFileFormat.h ${CMAKE_SOURCE_DIR}/include/aman/config/FileFormat.h ${CMAKE_SOURCE_DIR}/include/aman/config/IdentifierFileFormat.h ) @@ -42,6 +44,7 @@ ADD_LIBRARY( ${SOURCE_FILES} ${INCLUDE_CONFIG_FILES} ${INCLUDE_HELPER_FILES} + ${INCLUDE_TYPES_FILES} ) # define the dependencies diff --git a/src/config/CommunicationFileFormat.cpp b/src/config/CommunicationFileFormat.cpp new file mode 100644 index 0000000..73e6717 --- /dev/null +++ b/src/config/CommunicationFileFormat.cpp @@ -0,0 +1,100 @@ +/* + * Author: + * Sven Czarnian + * Brief: + * Implements the communication file format + * Copyright: + * 2021 Sven Czarnian + * License: + * GNU General Public License v3 (GPLv3) + */ + +#include + +#include + +#include +#include + +using namespace aman; + +CommunicationFileFormat::CommunicationFileFormat() : + FileFormat() { } + +bool CommunicationFileFormat::parse(const std::string& filename, Communication& config) { + config.valid = true; + + std::ifstream stream(filename); + if (false == stream.is_open()) { + this->m_errorMessage = "Unable to open the configuration file: " + filename; + this->m_errorLine = 0; + config.valid = false; + return false; + } + + std::string line; + std::uint32_t lineOffset = 0; + while (std::getline(stream, line)) { + std::string value; + + lineOffset += 1; + + /* skip a new line */ + if (0 == line.length()) + continue; + + /* trimm the line and check if a comment line is used */ + std::string trimmed = String::trim(line); + if (0 == trimmed.find_first_of('#', 0)) + continue; + + auto entry = String::splitString(trimmed, "="); + if (2 > entry.size()) { + this->m_errorLine = lineOffset; + this->m_errorMessage = "Invalid configuration entry"; + config.valid = false; + return false; + } + else if (2 < entry.size()) { + for (std::size_t idx = 1; idx < entry.size() - 1; ++idx) + value += gsl::at(entry, idx) + "="; + value += entry.back(); + } + else { + value = gsl::at(entry, 1); + } + + /* found an invalid line */ + if (0 == value.length()) { + this->m_errorLine = lineOffset; + this->m_errorMessage = "Invalid entry"; + config.valid = false; + return false; + } + + if ("URL" == gsl::at(entry, 0)) { + config.url = gsl::at(entry, 1); + } + else if ("Port" == gsl::at(entry, 0)) { + config.port = static_cast(std::atoi(gsl::at(entry, 1).c_str())); + } + else if ("UID" == gsl::at(entry, 0)) { + config.identifier = gsl::at(entry, 1); + } + else { + this->m_errorLine = lineOffset; + this->m_errorMessage = "Unknown entry: " + gsl::at(entry, 0); + config.valid = false; + return false; + } + } + + if (0 == lineOffset) { + this->m_errorLine = 0; + this->m_errorMessage = "No data found in " + filename; + config.valid = false; + return false; + } + + return true; +}