config: setup
Added implementation of config Manager and tests. reviewer=Ebsi review url=https://git.mediacube.at/egraether.mmt-b2009/masterproject/merge_request/3
This commit is contained in:
+36
-13
@@ -46,23 +46,32 @@ project(${PROJECT_NAME})
|
||||
# Lib --------------------------------------------------------------------------
|
||||
|
||||
add_subdirectory(src/lib)
|
||||
add_subdirectory(src/external)
|
||||
|
||||
add_library(${LIB_PROJECT_NAME} ${LIB_FILES})
|
||||
|
||||
add_library(${LIB_PROJECT_NAME} ${LIB_FILES} ${EXTERNAL_FILES})
|
||||
|
||||
create_source_groups(${LIB_FILES})
|
||||
create_source_groups(${EXTERNAL_FILES})
|
||||
|
||||
set_target_properties(
|
||||
${LIB_PROJECT_NAME}
|
||||
PROPERTIES DEBUG_OUTPUT_NAME ${PROJECT_NAME}_d
|
||||
RELEASE_OUTPUT_NAME ${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
DEBUG_OUTPUT_NAME ${PROJECT_NAME}_d
|
||||
RELEASE_OUTPUT_NAME ${PROJECT_NAME}
|
||||
)
|
||||
|
||||
set_property(
|
||||
TARGET ${LIB_PROJECT_NAME}
|
||||
PROPERTY INCLUDE_DIRECTORIES
|
||||
"${CMAKE_SOURCE_DIR}/src/lib"
|
||||
"${CMAKE_SOURCE_DIR}/src/external"
|
||||
)
|
||||
|
||||
|
||||
# App --------------------------------------------------------------------------
|
||||
|
||||
add_subdirectory(src/app)
|
||||
include_directories(src/lib src/app build/src/app)
|
||||
|
||||
|
||||
# Find includes in corresponding build directories
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
@@ -80,6 +89,15 @@ create_source_groups(${APP_FILES})
|
||||
|
||||
target_link_libraries(${APP_PROJECT_NAME} ${LIB_PROJECT_NAME})
|
||||
|
||||
set_property(
|
||||
TARGET ${APP_PROJECT_NAME}
|
||||
PROPERTY INCLUDE_DIRECTORIES
|
||||
"${CMAKE_SOURCE_DIR}/src/lib"
|
||||
"${CMAKE_SOURCE_DIR}/src/app"
|
||||
"${CMAKE_SOURCE_DIR}/build/src/app"
|
||||
"${CMAKE_SOURCE_DIR}/src/external"
|
||||
)
|
||||
|
||||
# Use the Widgets module from Qt 5.
|
||||
qt5_use_modules(${APP_PROJECT_NAME} Widgets)
|
||||
|
||||
@@ -99,13 +117,7 @@ set(CXXTEST_INCLUDE_DIR $ENV{CXX_TEST_DIR})
|
||||
set(CXXTEST_PYTHON_TESTGEN_EXECUTABLE ${CXXTEST_INCLUDE_DIR}/bin/cxxtestgen)
|
||||
set(TESTGEN_FILE ${CMAKE_CURRENT_BINARY_DIR}/test_main.cpp)
|
||||
|
||||
find_package(CxxTest)
|
||||
|
||||
if (CXXTEST_FOUND)
|
||||
|
||||
include_directories(${CXXTEST_INCLUDE_DIR})
|
||||
|
||||
endif (CXXTEST_FOUND)
|
||||
|
||||
|
||||
find_package(PythonInterp REQUIRED)
|
||||
|
||||
@@ -115,6 +127,17 @@ create_source_groups(${TEST_FILES})
|
||||
|
||||
target_link_libraries(${TEST_PROJECT_NAME} ${LIB_PROJECT_NAME})
|
||||
|
||||
find_package(CxxTest)
|
||||
if (CXXTEST_FOUND)
|
||||
set_property(
|
||||
TARGET ${TEST_PROJECT_NAME}
|
||||
PROPERTY INCLUDE_DIRECTORIES
|
||||
"${CMAKE_SOURCE_DIR}/src/lib"
|
||||
"${CXXTEST_INCLUDE_DIR}"
|
||||
"${CMAKE_SOURCE_DIR}/src/external"
|
||||
)
|
||||
endif (CXXTEST_FOUND)
|
||||
|
||||
if (WIN32)
|
||||
|
||||
add_custom_command(
|
||||
@@ -127,7 +150,7 @@ if (WIN32)
|
||||
add_custom_command(
|
||||
TARGET ${TEST_PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND $(OutDir)$(TargetName)$(TargetExt)
|
||||
COMMAND cd $(ProjectDir)../bin/\n$(OutDir)$(TargetName)$(TargetExt)
|
||||
COMMENT "Running unittest code"
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<config>
|
||||
<path>
|
||||
<to>
|
||||
<single_value>42</single_value>
|
||||
<bool_that_is_true>1</bool_that_is_true>
|
||||
<bool_that_is_false>0</bool_that_is_false>
|
||||
</to>
|
||||
</path>
|
||||
</config>
|
||||
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
add_files(
|
||||
EXTERNAL_FILES
|
||||
|
||||
tinyxml/tinystr.cpp
|
||||
tinyxml/tinystr.h
|
||||
tinyxml/tinyxml.cpp
|
||||
tinyxml/tinyxml.h
|
||||
tinyxml/tinyxmlerror.cpp
|
||||
tinyxml/tinyxmlparser.cpp
|
||||
)
|
||||
Vendored
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/tinyxml
|
||||
Original file by Yves Berquin.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TIXML_USE_STL
|
||||
|
||||
#include "tinystr.h"
|
||||
|
||||
// Error value for find primitive
|
||||
const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
|
||||
|
||||
|
||||
// Null rep.
|
||||
TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
|
||||
|
||||
|
||||
void TiXmlString::reserve (size_type cap)
|
||||
{
|
||||
if (cap > capacity())
|
||||
{
|
||||
TiXmlString tmp;
|
||||
tmp.init(length(), cap);
|
||||
memcpy(tmp.start(), data(), length());
|
||||
swap(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TiXmlString& TiXmlString::assign(const char* str, size_type len)
|
||||
{
|
||||
size_type cap = capacity();
|
||||
if (len > cap || cap > 3*(len + 8))
|
||||
{
|
||||
TiXmlString tmp;
|
||||
tmp.init(len);
|
||||
memcpy(tmp.start(), str, len);
|
||||
swap(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(start(), str, len);
|
||||
set_size(len);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
TiXmlString& TiXmlString::append(const char* str, size_type len)
|
||||
{
|
||||
size_type newsize = length() + len;
|
||||
if (newsize > capacity())
|
||||
{
|
||||
reserve (newsize + capacity());
|
||||
}
|
||||
memmove(finish(), str, len);
|
||||
set_size(newsize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
|
||||
{
|
||||
TiXmlString tmp;
|
||||
tmp.reserve(a.length() + b.length());
|
||||
tmp += a;
|
||||
tmp += b;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
TiXmlString operator + (const TiXmlString & a, const char* b)
|
||||
{
|
||||
TiXmlString tmp;
|
||||
TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
|
||||
tmp.reserve(a.length() + b_len);
|
||||
tmp += a;
|
||||
tmp.append(b, b_len);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
TiXmlString operator + (const char* a, const TiXmlString & b)
|
||||
{
|
||||
TiXmlString tmp;
|
||||
TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
|
||||
tmp.reserve(a_len + b.length());
|
||||
tmp.append(a, a_len);
|
||||
tmp += b;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
#endif // TIXML_USE_STL
|
||||
Vendored
+319
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/tinyxml
|
||||
Original file by Yves Berquin.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
|
||||
*
|
||||
* - completely rewritten. compact, clean, and fast implementation.
|
||||
* - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
|
||||
* - fixed reserve() to work as per specification.
|
||||
* - fixed buggy compares operator==(), operator<(), and operator>()
|
||||
* - fixed operator+=() to take a const ref argument, following spec.
|
||||
* - added "copy" constructor with length, and most compare operators.
|
||||
* - added swap(), clear(), size(), capacity(), operator+().
|
||||
*/
|
||||
|
||||
#ifndef TIXML_USE_STL
|
||||
|
||||
#ifndef TIXML_STRING_INCLUDED
|
||||
#define TIXML_STRING_INCLUDED
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
/* The support for explicit isn't that universal, and it isn't really
|
||||
required - it is used to check that the TiXmlString class isn't incorrectly
|
||||
used. Be nice to old compilers and macro it here:
|
||||
*/
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
|
||||
// Microsoft visual studio, version 6 and higher.
|
||||
#define TIXML_EXPLICIT explicit
|
||||
#elif defined(__GNUC__) && (__GNUC__ >= 3 )
|
||||
// GCC version 3 and higher.s
|
||||
#define TIXML_EXPLICIT explicit
|
||||
#else
|
||||
#define TIXML_EXPLICIT
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
TiXmlString is an emulation of a subset of the std::string template.
|
||||
Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
|
||||
Only the member functions relevant to the TinyXML project have been implemented.
|
||||
The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
|
||||
a string and there's no more room, we allocate a buffer twice as big as we need.
|
||||
*/
|
||||
class TiXmlString
|
||||
{
|
||||
public :
|
||||
// The size type used
|
||||
typedef size_t size_type;
|
||||
|
||||
// Error value for find primitive
|
||||
static const size_type npos; // = -1;
|
||||
|
||||
|
||||
// TiXmlString empty constructor
|
||||
TiXmlString () : rep_(&nullrep_)
|
||||
{
|
||||
}
|
||||
|
||||
// TiXmlString copy constructor
|
||||
TiXmlString ( const TiXmlString & copy) : rep_(0)
|
||||
{
|
||||
init(copy.length());
|
||||
memcpy(start(), copy.data(), length());
|
||||
}
|
||||
|
||||
// TiXmlString constructor, based on a string
|
||||
TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
|
||||
{
|
||||
init( static_cast<size_type>( strlen(copy) ));
|
||||
memcpy(start(), copy, length());
|
||||
}
|
||||
|
||||
// TiXmlString constructor, based on a string
|
||||
TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
|
||||
{
|
||||
init(len);
|
||||
memcpy(start(), str, len);
|
||||
}
|
||||
|
||||
// TiXmlString destructor
|
||||
~TiXmlString ()
|
||||
{
|
||||
quit();
|
||||
}
|
||||
|
||||
// = operator
|
||||
TiXmlString& operator = (const char * copy)
|
||||
{
|
||||
return assign( copy, (size_type)strlen(copy));
|
||||
}
|
||||
|
||||
// = operator
|
||||
TiXmlString& operator = (const TiXmlString & copy)
|
||||
{
|
||||
return assign(copy.start(), copy.length());
|
||||
}
|
||||
|
||||
|
||||
// += operator. Maps to append
|
||||
TiXmlString& operator += (const char * suffix)
|
||||
{
|
||||
return append(suffix, static_cast<size_type>( strlen(suffix) ));
|
||||
}
|
||||
|
||||
// += operator. Maps to append
|
||||
TiXmlString& operator += (char single)
|
||||
{
|
||||
return append(&single, 1);
|
||||
}
|
||||
|
||||
// += operator. Maps to append
|
||||
TiXmlString& operator += (const TiXmlString & suffix)
|
||||
{
|
||||
return append(suffix.data(), suffix.length());
|
||||
}
|
||||
|
||||
|
||||
// Convert a TiXmlString into a null-terminated char *
|
||||
const char * c_str () const { return rep_->str; }
|
||||
|
||||
// Convert a TiXmlString into a char * (need not be null terminated).
|
||||
const char * data () const { return rep_->str; }
|
||||
|
||||
// Return the length of a TiXmlString
|
||||
size_type length () const { return rep_->size; }
|
||||
|
||||
// Alias for length()
|
||||
size_type size () const { return rep_->size; }
|
||||
|
||||
// Checks if a TiXmlString is empty
|
||||
bool empty () const { return rep_->size == 0; }
|
||||
|
||||
// Return capacity of string
|
||||
size_type capacity () const { return rep_->capacity; }
|
||||
|
||||
|
||||
// single char extraction
|
||||
const char& at (size_type index) const
|
||||
{
|
||||
assert( index < length() );
|
||||
return rep_->str[ index ];
|
||||
}
|
||||
|
||||
// [] operator
|
||||
char& operator [] (size_type index) const
|
||||
{
|
||||
assert( index < length() );
|
||||
return rep_->str[ index ];
|
||||
}
|
||||
|
||||
// find a char in a string. Return TiXmlString::npos if not found
|
||||
size_type find (char lookup) const
|
||||
{
|
||||
return find(lookup, 0);
|
||||
}
|
||||
|
||||
// find a char in a string from an offset. Return TiXmlString::npos if not found
|
||||
size_type find (char tofind, size_type offset) const
|
||||
{
|
||||
if (offset >= length()) return npos;
|
||||
|
||||
for (const char* p = c_str() + offset; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == tofind) return static_cast< size_type >( p - c_str() );
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
//Lee:
|
||||
//The original was just too strange, though correct:
|
||||
// TiXmlString().swap(*this);
|
||||
//Instead use the quit & re-init:
|
||||
quit();
|
||||
init(0,0);
|
||||
}
|
||||
|
||||
/* Function to reserve a big amount of data when we know we'll need it. Be aware that this
|
||||
function DOES NOT clear the content of the TiXmlString if any exists.
|
||||
*/
|
||||
void reserve (size_type cap);
|
||||
|
||||
TiXmlString& assign (const char* str, size_type len);
|
||||
|
||||
TiXmlString& append (const char* str, size_type len);
|
||||
|
||||
void swap (TiXmlString& other)
|
||||
{
|
||||
Rep* r = rep_;
|
||||
rep_ = other.rep_;
|
||||
other.rep_ = r;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init(size_type sz) { init(sz, sz); }
|
||||
void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
|
||||
char* start() const { return rep_->str; }
|
||||
char* finish() const { return rep_->str + rep_->size; }
|
||||
|
||||
struct Rep
|
||||
{
|
||||
size_type size, capacity;
|
||||
char str[1];
|
||||
};
|
||||
|
||||
void init(size_type sz, size_type cap)
|
||||
{
|
||||
if (cap)
|
||||
{
|
||||
// Lee: the original form:
|
||||
// rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
|
||||
// doesn't work in some cases of new being overloaded. Switching
|
||||
// to the normal allocation, although use an 'int' for systems
|
||||
// that are overly picky about structure alignment.
|
||||
const size_type bytesNeeded = sizeof(Rep) + cap;
|
||||
const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );
|
||||
rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
|
||||
|
||||
rep_->str[ rep_->size = sz ] = '\0';
|
||||
rep_->capacity = cap;
|
||||
}
|
||||
else
|
||||
{
|
||||
rep_ = &nullrep_;
|
||||
}
|
||||
}
|
||||
|
||||
void quit()
|
||||
{
|
||||
if (rep_ != &nullrep_)
|
||||
{
|
||||
// The rep_ is really an array of ints. (see the allocator, above).
|
||||
// Cast it back before delete, so the compiler won't incorrectly call destructors.
|
||||
delete [] ( reinterpret_cast<int*>( rep_ ) );
|
||||
}
|
||||
}
|
||||
|
||||
Rep * rep_;
|
||||
static Rep nullrep_;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
inline bool operator == (const TiXmlString & a, const TiXmlString & b)
|
||||
{
|
||||
return ( a.length() == b.length() ) // optimization on some platforms
|
||||
&& ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare
|
||||
}
|
||||
inline bool operator < (const TiXmlString & a, const TiXmlString & b)
|
||||
{
|
||||
return strcmp(a.c_str(), b.c_str()) < 0;
|
||||
}
|
||||
|
||||
inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
|
||||
inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; }
|
||||
inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
|
||||
inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
|
||||
|
||||
inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
|
||||
inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
|
||||
inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
|
||||
inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
|
||||
|
||||
TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
|
||||
TiXmlString operator + (const TiXmlString & a, const char* b);
|
||||
TiXmlString operator + (const char* a, const TiXmlString & b);
|
||||
|
||||
|
||||
/*
|
||||
TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
|
||||
Only the operators that we need for TinyXML have been developped.
|
||||
*/
|
||||
class TiXmlOutStream : public TiXmlString
|
||||
{
|
||||
public :
|
||||
|
||||
// TiXmlOutStream << operator.
|
||||
TiXmlOutStream & operator << (const TiXmlString & in)
|
||||
{
|
||||
*this += in;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TiXmlOutStream << operator.
|
||||
TiXmlOutStream & operator << (const char * in)
|
||||
{
|
||||
*this += in;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
#endif // TIXML_STRING_INCLUDED
|
||||
#endif // TIXML_USE_STL
|
||||
Vendored
+1839
File diff suppressed because it is too large
Load Diff
Vendored
+1799
File diff suppressed because it is too large
Load Diff
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/tinyxml
|
||||
Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
#include "tinyxml.h"
|
||||
|
||||
// The goal of the seperate error file is to make the first
|
||||
// step towards localization. tinyxml (currently) only supports
|
||||
// english error messages, but the could now be translated.
|
||||
//
|
||||
// It also cleans up the code a bit.
|
||||
//
|
||||
|
||||
const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
|
||||
{
|
||||
"No error",
|
||||
"Error",
|
||||
"Failed to open file",
|
||||
"Error parsing Element.",
|
||||
"Failed to read Element name",
|
||||
"Error reading Element value.",
|
||||
"Error reading Attributes.",
|
||||
"Error: empty tag.",
|
||||
"Error reading end tag.",
|
||||
"Error parsing Unknown.",
|
||||
"Error parsing Comment.",
|
||||
"Error parsing Declaration.",
|
||||
"Error document empty.",
|
||||
"Error null (0) or unexpected EOF found in input stream.",
|
||||
"Error parsing CDATA.",
|
||||
"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
|
||||
};
|
||||
+1635
File diff suppressed because it is too large
Load Diff
@@ -1 +1,133 @@
|
||||
#include "utility/ConfigManager.h"
|
||||
#include "utility/ConfigManager.h"
|
||||
|
||||
std::shared_ptr<ConfigManager> ConfigManager::createAndLoad(const std::string& filePath)
|
||||
{
|
||||
std::shared_ptr<ConfigManager> configManager = std::shared_ptr<ConfigManager>(new ConfigManager(filePath));
|
||||
configManager->load();
|
||||
return configManager;
|
||||
}
|
||||
|
||||
bool ConfigManager::getValue(const std::string& key, std::string& value) const
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator it = m_values.find(key);
|
||||
|
||||
if(it != m_values.end())
|
||||
{
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// LOG ERROR
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigManager::getValue(const std::string& key, int& value) const
|
||||
{
|
||||
std::string valueString;
|
||||
if (getValue(key, valueString))
|
||||
{
|
||||
value = atoi(valueString.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConfigManager::getValue(const std::string& key, float& value) const
|
||||
{
|
||||
std::string valueString;
|
||||
if (getValue(key, valueString))
|
||||
{
|
||||
value = atof(valueString.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConfigManager::getValue(const std::string& key, bool& value) const
|
||||
{
|
||||
std::string valueString;
|
||||
if (getValue(key, valueString))
|
||||
{
|
||||
value = (atoi(valueString.c_str()) != 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConfigManager::setValue(const std::string& key, const std::string& value)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator it = m_values.find(key);
|
||||
|
||||
if(it != m_values.end())
|
||||
{
|
||||
it->second = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// LOG ERROR
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManager::setValue(const std::string& key, const int value)
|
||||
{
|
||||
setValue(key, std::to_string(value));
|
||||
}
|
||||
|
||||
void ConfigManager::setValue(const std::string& key, const float value)
|
||||
{
|
||||
setValue(key, std::to_string(value));
|
||||
}
|
||||
|
||||
void ConfigManager::setValue(const std::string& key, const bool value)
|
||||
{
|
||||
setValue(key, value ? "1" : "0");
|
||||
}
|
||||
|
||||
|
||||
void ConfigManager::load()
|
||||
{
|
||||
// LOG ("Loading config from file: " + m_filePath)
|
||||
|
||||
TiXmlDocument doc(m_filePath.c_str());
|
||||
if (doc.LoadFile())
|
||||
{
|
||||
TiXmlHandle docHandle(&doc);
|
||||
TiXmlNode *rootNode = docHandle.FirstChild("config").ToNode();
|
||||
for(TiXmlNode *childNode = rootNode->FirstChild(); childNode; childNode = childNode->NextSibling())
|
||||
{
|
||||
parseSubtree(childNode, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// LOG ERROR Unable to load file.
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManager::save()
|
||||
{
|
||||
// LOG ("Saving config to file: " + m_filePath)
|
||||
}
|
||||
|
||||
ConfigManager::ConfigManager(const std::string& filePath)
|
||||
: m_filePath(filePath)
|
||||
{
|
||||
}
|
||||
|
||||
void ConfigManager::parseSubtree(TiXmlNode* currentNode, const std::string& currentPath)
|
||||
{
|
||||
if (currentNode->Type() == TiXmlNode::TINYXML_TEXT)
|
||||
{
|
||||
std::string key = currentPath.substr(0, currentPath.size() - 1);
|
||||
m_values[key] = currentNode->ToText()->Value();
|
||||
}
|
||||
else
|
||||
{
|
||||
for(TiXmlNode *childNode = currentNode->FirstChild(); childNode; childNode = childNode->NextSibling())
|
||||
{
|
||||
parseSubtree(childNode, currentPath + std::string(currentNode->Value()) + "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,40 @@
|
||||
#define CONFIG_MANAGER_H
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "tinyxml/tinyxml.h"
|
||||
|
||||
|
||||
class ConfigManager
|
||||
{
|
||||
public:
|
||||
static std::shared_ptr<ConfigManager> createAndLoad(const std::string& filePath);
|
||||
|
||||
bool getValue(const std::string& key, std::string& value) const;
|
||||
bool getValue(const std::string& key, int& value) const;
|
||||
bool getValue(const std::string& key, float& value) const;
|
||||
bool getValue(const std::string& key, bool& value) const;
|
||||
|
||||
void setValue(const std::string& key, const std::string& value);
|
||||
void setValue(const std::string& key, const int value);
|
||||
void setValue(const std::string& key, const float value);
|
||||
void setValue(const std::string& key, const bool value);
|
||||
|
||||
void load();
|
||||
void save();
|
||||
|
||||
private:
|
||||
ConfigManager(const std::string& filePath);
|
||||
ConfigManager(const ConfigManager&);
|
||||
ConfigManager operator=(const ConfigManager&);
|
||||
|
||||
void parseSubtree(TiXmlNode* parentElement, const std::string& currentPath);
|
||||
|
||||
const std::string m_filePath;
|
||||
std::map<std::string, std::string> m_values;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
add_files(
|
||||
TEST_FILES
|
||||
ConfigManagerTestSuite.h
|
||||
UtilityTestSuite.h
|
||||
)
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
#include "cxxtest/TestSuite.h"
|
||||
|
||||
#include "utility/ConfigManager.h"
|
||||
|
||||
|
||||
class ConfigManagerTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_config_manager_returns_true_when_key_is_found()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad("data/test_config.xml");
|
||||
|
||||
float value;
|
||||
bool success = config->getValue("path/to/single_value", value);
|
||||
|
||||
TS_ASSERT(success);
|
||||
}
|
||||
|
||||
|
||||
void test_config_manager_returns_false_when_key_is_not_found()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad("data/test_config.xml");
|
||||
|
||||
float value;
|
||||
bool success = config->getValue("path/to/nowhere", value);
|
||||
|
||||
TS_ASSERT(!success);
|
||||
}
|
||||
|
||||
|
||||
void test_config_manager_returns_correct_string_for_key()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad("data/test_config.xml");
|
||||
|
||||
std::string value;
|
||||
config->getValue("path/to/single_value", value);
|
||||
|
||||
TS_ASSERT_EQUALS("42", value);
|
||||
}
|
||||
|
||||
|
||||
void test_config_manager_returns_correct_float_for_key()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad("data/test_config.xml");
|
||||
|
||||
float value;
|
||||
config->getValue("path/to/single_value", value);
|
||||
|
||||
TS_ASSERT_DELTA(42.0f, value, 0.0001f);
|
||||
}
|
||||
|
||||
void test_config_manager_returns_correct_bool_for_key_if_value_is_true()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad("data/test_config.xml");
|
||||
|
||||
float value;
|
||||
bool success(config->getValue("path/to/bool_that_is_true", value));
|
||||
|
||||
TS_ASSERT(success);
|
||||
TS_ASSERT(value);
|
||||
}
|
||||
|
||||
void test_config_manager_returns_correct_bool_for_key_if_value_is_false()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad("data/test_config.xml");
|
||||
|
||||
float value;
|
||||
bool success(config->getValue("path/to/bool_that_is_false", value));
|
||||
|
||||
TS_ASSERT(success);
|
||||
TS_ASSERT(!value);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user