From c064b4409c0bfbc1054f5f1b3aec508fe2edfcf4 Mon Sep 17 00:00:00 2001 From: Sven Luethi Date: Tue, 11 Jun 2024 21:50:21 +0200 Subject: [PATCH] new file: lib/mini-yaml/yaml.hpp modified: src/core/CMakeLists.txt modified: src/core/ConfigManager.cpp --- lib/mini-yaml/yaml.hpp | 656 +++++++++++++++++++++++++++++++++++++ src/core/CMakeLists.txt | 1 + src/core/ConfigManager.cpp | 1 + 3 files changed, 658 insertions(+) create mode 100644 lib/mini-yaml/yaml.hpp diff --git a/lib/mini-yaml/yaml.hpp b/lib/mini-yaml/yaml.hpp new file mode 100644 index 0000000..586657f --- /dev/null +++ b/lib/mini-yaml/yaml.hpp @@ -0,0 +1,656 @@ +/* +* MIT License +* +* Copyright(c) 2018 Jimmie Bergmann +* +* 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. +* +*/ + +/* +YAML documentation: +http://yaml.org/spec/1.0/index.html +https://www.codeproject.com/Articles/28720/YAML-Parser-in-C +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +/** +* @breif Namespace wrapping mini-yaml classes. +* +*/ +namespace Yaml +{ + + /** + * @breif Forward declarations. + * + */ + class Node; + + + /** + * @breif Helper classes and functions + * + */ + namespace impl + { + + /** + * @breif Helper functionality, converting string to any data type. + * Strings are left untouched. + * + */ + template + struct StringConverter + { + static T Get(const std::string & data) + { + T type; + std::stringstream ss(data); + ss >> type; + return type; + } + + static T Get(const std::string & data, const T & defaultValue) + { + T type; + std::stringstream ss(data); + ss >> type; + + if(ss.fail()) + { + return defaultValue; + } + + return type; + } + }; + template<> + struct StringConverter + { + static std::string Get(const std::string & data) + { + return data; + } + + static std::string Get(const std::string & data, const std::string & defaultValue) + { + if(data.size() == 0) + { + return defaultValue; + } + return data; + } + }; + + template<> + struct StringConverter + { + static bool Get(const std::string & data) + { + std::string tmpData = data; + std::transform(tmpData.begin(), tmpData.end(), tmpData.begin(), ::tolower); + if(tmpData == "true" || tmpData == "yes" || tmpData == "1") + { + return true; + } + + return false; + } + + static bool Get(const std::string & data, const bool & defaultValue) + { + if(data.size() == 0) + { + return defaultValue; + } + + return Get(data); + } + }; + + } + + + /** + * @breif Exception class. + * + */ + class Exception : public std::runtime_error + { + + public: + + /** + * @breif Enumeration of exception types. + * + */ + enum eType + { + InternalError, ///< Internal error. + ParsingError, ///< Invalid parsing data. + OperationError ///< User operation error. + }; + + /** + * @breif Constructor. + * + * @param message Exception message. + * @param type Type of exception. + * + */ + Exception(const std::string & message, const eType type); + + /** + * @breif Get type of exception. + * + */ + eType Type() const; + + /** + * @breif Get message of exception. + * + */ + const char * Message() const; + + private: + + eType m_Type; ///< Type of exception. + + }; + + + /** + * @breif Internal exception class. + * + * @see Exception + * + */ + class InternalException : public Exception + { + + public: + + /** + * @breif Constructor. + * + * @param message Exception message. + * + */ + InternalException(const std::string & message); + + }; + + + /** + * @breif Parsing exception class. + * + * @see Exception + * + */ + class ParsingException : public Exception + { + + public: + + /** + * @breif Constructor. + * + * @param message Exception message. + * + */ + ParsingException(const std::string & message); + + }; + + + /** + * @breif Operation exception class. + * + * @see Exception + * + */ + class OperationException : public Exception + { + + public: + + /** + * @breif Constructor. + * + * @param message Exception message. + * + */ + OperationException(const std::string & message); + + }; + + + /** + * @breif Iterator class. + * + */ + class Iterator + { + + public: + + friend class Node; + + /** + * @breif Default constructor. + * + */ + Iterator(); + + /** + * @breif Copy constructor. + * + */ + Iterator(const Iterator & it); + + /** + * @breif Assignment operator. + * + */ + Iterator & operator = (const Iterator & it); + + /** + * @breif Destructor. + * + */ + ~Iterator(); + + /** + * @breif Get node of iterator. + * First pair item is the key of map value, empty if type is sequence. + * + */ + std::pair operator *(); + + /** + * @breif Post-increment operator. + * + */ + Iterator & operator ++ (int); + + /** + * @breif Post-decrement operator. + * + */ + Iterator & operator -- (int); + + /** + * @breif Check if iterator is equal to other iterator. + * + */ + bool operator == (const Iterator & it); + + /** + * @breif Check if iterator is not equal to other iterator. + * + */ + bool operator != (const Iterator & it); + + private: + + enum eType + { + None, + SequenceType, + MapType + }; + + eType m_Type; ///< Type of iterator. + void * m_pImp; ///< Implementation of iterator class. + + }; + + + /** + * @breif Constant iterator class. + * + */ + class ConstIterator + { + + public: + + friend class Node; + + /** + * @breif Default constructor. + * + */ + ConstIterator(); + + /** + * @breif Copy constructor. + * + */ + ConstIterator(const ConstIterator & it); + + /** + * @breif Assignment operator. + * + */ + ConstIterator & operator = (const ConstIterator & it); + + /** + * @breif Destructor. + * + */ + ~ConstIterator(); + + /** + * @breif Get node of iterator. + * First pair item is the key of map value, empty if type is sequence. + * + */ + std::pair operator *(); + + /** + * @breif Post-increment operator. + * + */ + ConstIterator & operator ++ (int); + + /** + * @breif Post-decrement operator. + * + */ + ConstIterator & operator -- (int); + + /** + * @breif Check if iterator is equal to other iterator. + * + */ + bool operator == (const ConstIterator & it); + + /** + * @breif Check if iterator is not equal to other iterator. + * + */ + bool operator != (const ConstIterator & it); + + private: + + enum eType + { + None, + SequenceType, + MapType + }; + + eType m_Type; ///< Type of iterator. + void * m_pImp; ///< Implementation of constant iterator class. + + }; + + + /** + * @breif Node class. + * + */ + class Node + { + + public: + + friend class Iterator; + + /** + * @breif Enumeration of node types. + * + */ + enum eType + { + None, + SequenceType, + MapType, + ScalarType + }; + + /** + * @breif Default constructor. + * + */ + Node(); + + /** + * @breif Copy constructor. + * + */ + Node(const Node & node); + + /** + * @breif Assignment constructors. + * Converts node to scalar type if needed. + * + */ + Node(const std::string & value); + Node(const char * value); + + /** + * @breif Destructor. + * + */ + ~Node(); + + /** + * @breif Functions for checking type of node. + * + */ + eType Type() const; + bool IsNone() const; + bool IsSequence() const; + bool IsMap() const; + bool IsScalar() const; + + /** + * @breif Completely clear node. + * + */ + void Clear(); + + /** + * @breif Get node as given template type. + * + */ + template + T As() const + { + return impl::StringConverter::Get(AsString()); + } + + /** + * @breif Get node as given template type. + * + */ + template + T As(const T & defaultValue) const + { + return impl::StringConverter::Get(AsString(), defaultValue); + } + + /** + * @breif Get size of node. + * Nodes of type None or Scalar will return 0. + * + */ + size_t Size() const; + + // Sequence operators + + /** + * @breif Insert sequence item at given index. + * Converts node to sequence type if needed. + * Adding new item to end of sequence if index is larger than sequence size. + * + */ + Node & Insert(const size_t index); + + /** + * @breif Add new sequence index to back. + * Converts node to sequence type if needed. + * + */ + Node & PushFront(); + + /** + * @breif Add new sequence index to front. + * Converts node to sequence type if needed. + * + */ + Node & PushBack(); + + /** + * @breif Get sequence/map item. + * Converts node to sequence/map type if needed. + * + * @param index Sequence index. Returns None type Node if index is unknown. + * @param key Map key. Creates a new node if key is unknown. + * + */ + Node & operator [] (const size_t index); + Node & operator [] (const std::string & key); + + /** + * @breif Erase item. + * No action if node is not a sequence or map. + * + */ + void Erase(const size_t index); + void Erase(const std::string & key); + + /** + * @breif Assignment operators. + * + */ + Node & operator = (const Node & node); + Node & operator = (const std::string & value); + Node & operator = (const char * value); + + /** + * @breif Get start iterator. + * + */ + Iterator Begin(); + ConstIterator Begin() const; + + /** + * @breif Get end iterator. + * + */ + Iterator End(); + ConstIterator End() const; + + + private: + + /** + * @breif Get as string. If type is scalar, else empty. + * + */ + const std::string & AsString() const; + + void * m_pImp; ///< Implementation of node class. + + }; + + + /** + * @breif Parsing functions. + * Population given root node with deserialized data. + * + * @param root Root node to populate. + * @param filename Path of input file. + * @param stream Input stream. + * @param string String of input data. + * @param buffer Char array of input data. + * @param size Buffer size. + * + * @throw InternalException An internal error occurred. + * @throw ParsingException Invalid input YAML data. + * @throw OperationException If filename or buffer pointer is invalid. + * + */ + void Parse(Node & root, const char * filename); + void Parse(Node & root, std::iostream & stream); + void Parse(Node & root, const std::string & string); + void Parse(Node & root, const char * buffer, const size_t size); + + + /** + * @breif Serialization configuration structure, + * describing output behavior. + * + */ + struct SerializeConfig + { + + /** + * @breif Constructor. + * + * @param spaceIndentation Number of spaces per indentation. + * @param scalarMaxLength Maximum length of scalars. Serialized as folder scalars if exceeded. + * Ignored if equal to 0. + * @param sequenceMapNewline Put maps on a new line if parent node is a sequence. + * @param mapScalarNewline Put scalars on a new line if parent node is a map. + * + */ + SerializeConfig(const size_t spaceIndentation = 2, + const size_t scalarMaxLength = 64, + const bool sequenceMapNewline = false, + const bool mapScalarNewline = false); + + size_t SpaceIndentation; ///< Number of spaces per indentation. + size_t ScalarMaxLength; ///< Maximum length of scalars. Serialized as folder scalars if exceeded. + bool SequenceMapNewline; ///< Put maps on a new line if parent node is a sequence. + bool MapScalarNewline; ///< Put scalars on a new line if parent node is a map. + }; + + + /** + * @breif Serialization functions. + * + * @param root Root node to serialize. + * @param filename Path of output file. + * @param stream Output stream. + * @param string String of output data. + * @param config Serialization configurations. + * + * @throw InternalException An internal error occurred. + * @throw OperationException If filename or buffer pointer is invalid. + * If config is invalid. + * + */ + void Serialize(const Node & root, const char * filename, const SerializeConfig & config = {2, 64, false, false}); + void Serialize(const Node & root, std::iostream & stream, const SerializeConfig & config = {2, 64, false, false}); + void Serialize(const Node & root, std::string & string, const SerializeConfig & config = {2, 64, false, false}); + +} diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 640b0f2..e943fb0 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -3,3 +3,4 @@ add_library(Core OBJECT EventBus.cpp ConfigManager.cpp Logger.cpp Exception.cpp) target_include_directories(Core PUBLIC include) +target_link_libraries(Core PRIVATE MiniYAML) diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp index d7d5ca7..2de63ba 100644 --- a/src/core/ConfigManager.cpp +++ b/src/core/ConfigManager.cpp @@ -1,6 +1,7 @@ #include "ConfigManager.hpp" #include #include +#include "yaml.hpp" namespace Plains { namespace Core {