Apply clang-format

This commit is contained in:
Martchus 2017-05-01 03:13:11 +02:00
parent 7e49d3994f
commit 59e20b1043
53 changed files with 1309 additions and 1465 deletions

File diff suppressed because it is too large Load Diff

View File

@ -3,11 +3,11 @@
#include "../global.h" #include "../global.h"
#include <vector>
#include <initializer_list>
#include <functional> #include <functional>
#include <initializer_list>
#include <vector>
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
# include <cassert> #include <cassert>
#endif #endif
class ArgumentParserTests; class ArgumentParserTests;
@ -27,11 +27,9 @@ CPP_UTILITIES_EXPORT extern std::initializer_list<const char *> dependencyVersio
* \remarks Reads those data from the config header so "config.h" must be included. * \remarks Reads those data from the config header so "config.h" must be included.
*/ */
#ifndef APP_STATICALLY_LINKED #ifndef APP_STATICALLY_LINKED
#define SET_DEPENDENCY_INFO \ #define SET_DEPENDENCY_INFO ::ApplicationUtilities::dependencyVersions = DEPENCENCY_VERSIONS
::ApplicationUtilities::dependencyVersions = DEPENCENCY_VERSIONS
#else #else
#define SET_DEPENDENCY_INFO \ #define SET_DEPENDENCY_INFO ::ApplicationUtilities::dependencyVersions = STATIC_DEPENCENCY_VERSIONS
::ApplicationUtilities::dependencyVersions = STATIC_DEPENCENCY_VERSIONS
#endif #endif
/*! /*!
@ -39,14 +37,14 @@ CPP_UTILITIES_EXPORT extern std::initializer_list<const char *> dependencyVersio
* \brief Sets application meta data (including SET_DEPENDENCY_INFO) used by ArgumentParser::printHelp(). * \brief Sets application meta data (including SET_DEPENDENCY_INFO) used by ArgumentParser::printHelp().
* \remarks Reads those data from the config header so "config.h" must be included. * \remarks Reads those data from the config header so "config.h" must be included.
*/ */
#define SET_APPLICATION_INFO \ #define SET_APPLICATION_INFO \
::ApplicationUtilities::applicationName = APP_NAME; \ ::ApplicationUtilities::applicationName = APP_NAME; \
::ApplicationUtilities::applicationAuthor = APP_AUTHOR; \ ::ApplicationUtilities::applicationAuthor = APP_AUTHOR; \
::ApplicationUtilities::applicationVersion = APP_VERSION; \ ::ApplicationUtilities::applicationVersion = APP_VERSION; \
::ApplicationUtilities::applicationUrl = APP_URL; \ ::ApplicationUtilities::applicationUrl = APP_URL; \
SET_DEPENDENCY_INFO \ SET_DEPENDENCY_INFO
CPP_UTILITIES_EXPORT extern void(*exitFunction)(int); CPP_UTILITIES_EXPORT extern void (*exitFunction)(int);
class Argument; class Argument;
class ArgumentParser; class ArgumentParser;
@ -54,14 +52,13 @@ class ArgumentReader;
typedef std::initializer_list<Argument *> ArgumentInitializerList; typedef std::initializer_list<Argument *> ArgumentInitializerList;
typedef std::vector<Argument *> ArgumentVector; typedef std::vector<Argument *> ArgumentVector;
typedef std::function<bool (Argument *)> ArgumentPredicate; typedef std::function<bool(Argument *)> ArgumentPredicate;
/*! /*!
* \brief The UnknownArgumentBehavior enum specifies the behavior of the argument parser when an unknown * \brief The UnknownArgumentBehavior enum specifies the behavior of the argument parser when an unknown
* argument is detected. * argument is detected.
*/ */
enum class UnknownArgumentBehavior enum class UnknownArgumentBehavior {
{
Ignore, /**< Unknown arguments are ignored without warnings. */ Ignore, /**< Unknown arguments are ignored without warnings. */
Warn, /**< A warning is printed to std::cerr if an unknown argument is detected. */ Warn, /**< A warning is printed to std::cerr if an unknown argument is detected. */
Fail /**< Further parsing is aborted and an ApplicationUtilities::Failure instance with an error message is thrown. */ Fail /**< Further parsing is aborted and an ApplicationUtilities::Failure instance with an error message is thrown. */
@ -70,8 +67,7 @@ enum class UnknownArgumentBehavior
/*! /*!
* \brief The ValueCompletionBehavior enum specifies the items to be considered when generating completion for an argument value. * \brief The ValueCompletionBehavior enum specifies the items to be considered when generating completion for an argument value.
*/ */
enum class ValueCompletionBehavior : unsigned char enum class ValueCompletionBehavior : unsigned char {
{
None = 0, /**< no auto-completion */ None = 0, /**< no auto-completion */
PreDefinedValues = 2, /**< values assigned with Argument::setPreDefinedCompletionValues() */ PreDefinedValues = 2, /**< values assigned with Argument::setPreDefinedCompletionValues() */
Files = 4, /**< files */ Files = 4, /**< files */
@ -97,8 +93,7 @@ Argument CPP_UTILITIES_EXPORT *firstPresentUncombinableArg(const ArgumentVector
/*! /*!
* \brief The ArgumentOccurrence struct holds argument values for an occurrence of an argument. * \brief The ArgumentOccurrence struct holds argument values for an occurrence of an argument.
*/ */
struct CPP_UTILITIES_EXPORT ArgumentOccurrence struct CPP_UTILITIES_EXPORT ArgumentOccurrence {
{
ArgumentOccurrence(std::size_t index); ArgumentOccurrence(std::size_t index);
ArgumentOccurrence(std::size_t index, const std::vector<Argument *> parentPath, Argument *parent); ArgumentOccurrence(std::size_t index, const std::vector<Argument *> parentPath, Argument *parent);
@ -122,9 +117,10 @@ struct CPP_UTILITIES_EXPORT ArgumentOccurrence
/*! /*!
* \brief Constructs an argument occurrence for the specified \a index. * \brief Constructs an argument occurrence for the specified \a index.
*/ */
inline ArgumentOccurrence::ArgumentOccurrence(std::size_t index) : inline ArgumentOccurrence::ArgumentOccurrence(std::size_t index)
index(index) : index(index)
{} {
}
/*! /*!
* \brief Constructs an argument occurrence. * \brief Constructs an argument occurrence.
@ -134,22 +130,21 @@ inline ArgumentOccurrence::ArgumentOccurrence(std::size_t index) :
* *
* The path of the new occurrence is built from the specified \a parentPath and \a parent. * The path of the new occurrence is built from the specified \a parentPath and \a parent.
*/ */
inline ArgumentOccurrence::ArgumentOccurrence(std::size_t index, const std::vector<Argument *> parentPath, Argument *parent) : inline ArgumentOccurrence::ArgumentOccurrence(std::size_t index, const std::vector<Argument *> parentPath, Argument *parent)
index(index), : index(index)
path(parentPath) , path(parentPath)
{ {
if(parent) { if (parent) {
path.push_back(parent); path.push_back(parent);
} }
} }
class CPP_UTILITIES_EXPORT Argument class CPP_UTILITIES_EXPORT Argument {
{
friend ArgumentParser; friend ArgumentParser;
friend ArgumentReader; friend ArgumentReader;
public: public:
typedef std::function <void (const ArgumentOccurrence &)> CallbackFunction; typedef std::function<void(const ArgumentOccurrence &)> CallbackFunction;
Argument(const char *name, char abbreviation = '\0', const char *description = nullptr, const char *example = nullptr); Argument(const char *name, char abbreviation = '\0', const char *description = nullptr, const char *example = nullptr);
~Argument(); ~Argument();
@ -227,8 +222,7 @@ private:
const char *m_preDefinedCompletionValues; const char *m_preDefinedCompletionValues;
}; };
class CPP_UTILITIES_EXPORT ArgumentParser class CPP_UTILITIES_EXPORT ArgumentParser {
{
friend ArgumentParserTests; friend ArgumentParserTests;
friend ArgumentReader; friend ArgumentReader;
@ -254,7 +248,7 @@ public:
private: private:
IF_DEBUG_BUILD(void verifyArgs(const ArgumentVector &args, std::vector<char> abbreviations, std::vector<const char *> names);) IF_DEBUG_BUILD(void verifyArgs(const ArgumentVector &args, std::vector<char> abbreviations, std::vector<const char *> names);)
void printBashCompletion(int argc, const char * const *argv, unsigned int cursorPos, const ArgumentReader &reader); void printBashCompletion(int argc, const char *const *argv, unsigned int cursorPos, const ArgumentReader &reader);
void checkConstraints(const ArgumentVector &args); void checkConstraints(const ArgumentVector &args);
void invokeCallbacks(const ArgumentVector &args); void invokeCallbacks(const ArgumentVector &args);
@ -285,9 +279,9 @@ inline const char *Argument::name() const
inline void Argument::setName(const char *name) inline void Argument::setName(const char *name)
{ {
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
if(name && *name) { if (name && *name) {
assert(*name != '-'); assert(*name != '-');
for(const char *c = name; *c; ++c) { for (const char *c = name; *c; ++c) {
assert(*c != ' ' && *c != '=' && *c != '\'' && *c != '\"' && *c != '\n' && *c != '\r'); assert(*c != ' ' && *c != '=' && *c != '\'' && *c != '\"' && *c != '\n' && *c != '\r');
} }
} }
@ -314,8 +308,8 @@ inline char Argument::abbreviation() const
*/ */
inline void Argument::setAbbreviation(char abbreviation) inline void Argument::setAbbreviation(char abbreviation)
{ {
IF_DEBUG_BUILD(assert(abbreviation != ' ' && abbreviation != '=' && abbreviation != '-' IF_DEBUG_BUILD(assert(abbreviation != ' ' && abbreviation != '=' && abbreviation != '-' && abbreviation != '\'' && abbreviation != '"'
&& abbreviation != '\'' && abbreviation != '"' && abbreviation != '\n' && abbreviation != '\r')); && abbreviation != '\n' && abbreviation != '\r'));
m_abbreviation = abbreviation; m_abbreviation = abbreviation;
} }
@ -470,7 +464,7 @@ inline void Argument::appendValueName(const char *valueName)
inline bool Argument::allRequiredValuesPresent(std::size_t occurrence) const inline bool Argument::allRequiredValuesPresent(std::size_t occurrence) const
{ {
return m_requiredValueCount == static_cast<std::size_t>(-1) return m_requiredValueCount == static_cast<std::size_t>(-1)
|| (m_occurrences[occurrence].values.size() >= static_cast<std::size_t>(m_requiredValueCount)); || (m_occurrences[occurrence].values.size() >= static_cast<std::size_t>(m_requiredValueCount));
} }
/*! /*!
@ -577,8 +571,8 @@ inline bool Argument::isRequired() const
*/ */
inline void Argument::setRequired(bool required) inline void Argument::setRequired(bool required)
{ {
if(required) { if (required) {
if(!m_minOccurrences) { if (!m_minOccurrences) {
m_minOccurrences = 1; m_minOccurrences = 1;
} }
} else { } else {
@ -816,41 +810,39 @@ inline void ArgumentParser::invokeCallbacks()
invokeCallbacks(m_mainArgs); invokeCallbacks(m_mainArgs);
} }
class CPP_UTILITIES_EXPORT HelpArgument : public Argument class CPP_UTILITIES_EXPORT HelpArgument : public Argument {
{
public: public:
HelpArgument(ArgumentParser &parser); HelpArgument(ArgumentParser &parser);
}; };
class CPP_UTILITIES_EXPORT OperationArgument : public Argument class CPP_UTILITIES_EXPORT OperationArgument : public Argument {
{
public: public:
OperationArgument(const char *name, char abbreviation = '\0', const char *description = nullptr, const char *example = nullptr); OperationArgument(const char *name, char abbreviation = '\0', const char *description = nullptr, const char *example = nullptr);
}; };
inline OperationArgument::OperationArgument(const char *name, char abbreviation, const char *description, const char *example) : inline OperationArgument::OperationArgument(const char *name, char abbreviation, const char *description, const char *example)
Argument(name, abbreviation, description, example) : Argument(name, abbreviation, description, example)
{ {
setDenotesOperation(true); setDenotesOperation(true);
} }
class CPP_UTILITIES_EXPORT ConfigValueArgument : public Argument class CPP_UTILITIES_EXPORT ConfigValueArgument : public Argument {
{
public: public:
ConfigValueArgument(const char *name, char abbreviation = '\0', const char *description = nullptr, std::initializer_list<const char *> valueNames = std::initializer_list<const char *>()); ConfigValueArgument(const char *name, char abbreviation = '\0', const char *description = nullptr,
std::initializer_list<const char *> valueNames = std::initializer_list<const char *>());
}; };
/*! /*!
* \brief Constructs a new ConfigValueArgument with the specified parameter. The initial value of requiredValueCount() is set to size of specified \a valueNames. * \brief Constructs a new ConfigValueArgument with the specified parameter. The initial value of requiredValueCount() is set to size of specified \a valueNames.
*/ */
inline ConfigValueArgument::ConfigValueArgument(const char *name, char abbreviation, const char *description, std::initializer_list<const char *> valueNames) : inline ConfigValueArgument::ConfigValueArgument(
Argument(name, abbreviation, description) const char *name, char abbreviation, const char *description, std::initializer_list<const char *> valueNames)
: Argument(name, abbreviation, description)
{ {
setCombinable(true); setCombinable(true);
setRequiredValueCount(valueNames.size()); setRequiredValueCount(valueNames.size());
setValueNames(valueNames); setValueNames(valueNames);
} }
} }
#endif // APPLICATION_UTILITIES_ARGUMENTPARSER_H #endif // APPLICATION_UTILITIES_ARGUMENTPARSER_H

View File

@ -3,8 +3,7 @@
namespace ApplicationUtilities { namespace ApplicationUtilities {
struct CPP_UTILITIES_EXPORT ArgumentReader struct CPP_UTILITIES_EXPORT ArgumentReader {
{
ArgumentReader(ArgumentParser &parser, const char *const *argv, const char *const *end, bool completionMode = false); ArgumentReader(ArgumentParser &parser, const char *const *argv, const char *const *end, bool completionMode = false);
ApplicationUtilities::ArgumentReader &reset(const char *const *argv, const char *const *end); ApplicationUtilities::ArgumentReader &reset(const char *const *argv, const char *const *end);
void read(); void read();
@ -31,7 +30,6 @@ struct CPP_UTILITIES_EXPORT ArgumentReader
/// \brief Whether completion mode is enabled. In this case reading args will be continued even if an denotation is unknown (regardless of unknownArgumentBehavior()). /// \brief Whether completion mode is enabled. In this case reading args will be continued even if an denotation is unknown (regardless of unknownArgumentBehavior()).
bool completionMode; bool completionMode;
}; };
} }
#endif // APPLICATION_UTILITIES_ARGUMENTPARSER_PRIVATE_H #endif // APPLICATION_UTILITIES_ARGUMENTPARSER_PRIVATE_H

View File

@ -1,11 +1,11 @@
#include "./commandlineutils.h" #include "./commandlineutils.h"
#include <string>
#include <iostream> #include <iostream>
#include <string>
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# include <windows.h> #include <fcntl.h>
# include <fcntl.h> #include <windows.h>
#endif #endif
using namespace std; using namespace std;
@ -23,11 +23,11 @@ bool confirmPrompt(const char *message, Response defaultResponse)
cout << '/' << (defaultResponse == Response::No ? 'N' : 'n'); cout << '/' << (defaultResponse == Response::No ? 'N' : 'n');
cout << ']' << ' '; cout << ']' << ' ';
cout.flush(); cout.flush();
for(string line; ;) { for (string line;;) {
getline(cin, line); getline(cin, line);
if(line == "y" || line == "Y" || (defaultResponse == Response::Yes && line.empty())) { if (line == "y" || line == "Y" || (defaultResponse == Response::Yes && line.empty())) {
return true; return true;
} else if(line == "n" || line == "N" || (defaultResponse == Response::No && line.empty())) { } else if (line == "n" || line == "N" || (defaultResponse == Response::No && line.empty())) {
return false; return false;
} else { } else {
cout << "Please enter [y] or [n]: "; cout << "Please enter [y] or [n]: ";
@ -46,7 +46,7 @@ void stopConsole()
fclose(stdout); fclose(stdout);
fclose(stdin); fclose(stdin);
fclose(stderr); fclose(stderr);
if(auto *consoleWindow = GetConsoleWindow()) { if (auto *consoleWindow = GetConsoleWindow()) {
PostMessage(consoleWindow, WM_KEYUP, VK_RETURN, 0); PostMessage(consoleWindow, WM_KEYUP, VK_RETURN, 0);
FreeConsole(); FreeConsole();
} }
@ -61,7 +61,7 @@ void stopConsole()
*/ */
void startConsole() void startConsole()
{ {
if(!AttachConsole(ATTACH_PARENT_PROCESS) && !AllocConsole()) { if (!AttachConsole(ATTACH_PARENT_PROCESS) && !AllocConsole()) {
return; return;
} }
// redirect stdout // redirect stdout
@ -104,21 +104,21 @@ pair<vector<unique_ptr<char[]> >, vector<char *> > convertArgsToUtf8()
int argc; int argc;
LPWSTR *argv_w = CommandLineToArgvW(GetCommandLineW(), &argc); LPWSTR *argv_w = CommandLineToArgvW(GetCommandLineW(), &argc);
if(!argv_w || argc <= 0) { if (!argv_w || argc <= 0) {
return res; return res;
} }
res.first.reserve(static_cast<size_t>(argc)); res.first.reserve(static_cast<size_t>(argc));
res.second.reserve(static_cast<size_t>(argc)); res.second.reserve(static_cast<size_t>(argc));
for(LPWSTR *i = argv_w, *end = argv_w + argc; i != end; ++i) { for (LPWSTR *i = argv_w, *end = argv_w + argc; i != end; ++i) {
int requiredSize = WideCharToMultiByte(CP_UTF8, 0, *i, -1, nullptr, 0, 0, 0); int requiredSize = WideCharToMultiByte(CP_UTF8, 0, *i, -1, nullptr, 0, 0, 0);
if(requiredSize <= 0) { if (requiredSize <= 0) {
break; // just stop on error break; // just stop on error
} }
auto argv = make_unique<char[]>(static_cast<size_t>(requiredSize)); auto argv = make_unique<char[]>(static_cast<size_t>(requiredSize));
requiredSize = WideCharToMultiByte(CP_UTF8, 0, *i, -1, argv.get(), requiredSize, 0, 0); requiredSize = WideCharToMultiByte(CP_UTF8, 0, *i, -1, argv.get(), requiredSize, 0, 0);
if(requiredSize <= 0) { if (requiredSize <= 0) {
break; break;
} }

View File

@ -6,8 +6,8 @@
#include <ostream> #include <ostream>
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# include <memory> #include <memory>
# include <vector> #include <vector>
#endif #endif
namespace ApplicationUtilities { namespace ApplicationUtilities {
@ -15,41 +15,35 @@ namespace ApplicationUtilities {
/*! /*!
* \brief The Response enum is used to specify the default response for the confirmPrompt() method. * \brief The Response enum is used to specify the default response for the confirmPrompt() method.
*/ */
enum class Response enum class Response { None, Yes, No };
{
None,
Yes,
No
};
bool CPP_UTILITIES_EXPORT confirmPrompt(const char *message, Response defaultResponse = Response::None); bool CPP_UTILITIES_EXPORT confirmPrompt(const char *message, Response defaultResponse = Response::None);
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
void CPP_UTILITIES_EXPORT startConsole(); void CPP_UTILITIES_EXPORT startConsole();
std::pair<std::vector<std::unique_ptr<char[]> >, std::vector<char *> > CPP_UTILITIES_EXPORT convertArgsToUtf8(); std::pair<std::vector<std::unique_ptr<char[]> >, std::vector<char *> > CPP_UTILITIES_EXPORT convertArgsToUtf8();
# define CMD_UTILS_START_CONSOLE \ #define CMD_UTILS_START_CONSOLE ::ApplicationUtilities::startConsole();
::ApplicationUtilities::startConsole(); #define CMD_UTILS_CONVERT_ARGS_TO_UTF8 \
# define CMD_UTILS_CONVERT_ARGS_TO_UTF8 \ auto utf8Args = ::ApplicationUtilities::convertArgsToUtf8(); \
auto utf8Args = ::ApplicationUtilities::convertArgsToUtf8(); \ argv = utf8Args.second.data(); \
argv = utf8Args.second.data(); \
argc = static_cast<int>(utf8Args.second.size()); argc = static_cast<int>(utf8Args.second.size());
#else #else
# define CMD_UTILS_START_CONSOLE #define CMD_UTILS_START_CONSOLE
# define CMD_UTILS_CONVERT_ARGS_TO_UTF8 #define CMD_UTILS_CONVERT_ARGS_TO_UTF8
#endif #endif
/*! /*!
* \brief The Indentation class allows printing indentation conveniently, eg. cout << Indentation(4) << ... * \brief The Indentation class allows printing indentation conveniently, eg. cout << Indentation(4) << ...
*/ */
class CPP_UTILITIES_EXPORT Indentation class CPP_UTILITIES_EXPORT Indentation {
{
public: public:
Indentation(unsigned char level = 4, char character = ' ') : Indentation(unsigned char level = 4, char character = ' ')
level(level), : level(level)
character(character) , character(character)
{} {
}
Indentation operator +(unsigned char level) Indentation operator+(unsigned char level)
{ {
return Indentation(this->level + level, character); return Indentation(this->level + level, character);
} }
@ -58,9 +52,9 @@ public:
char character; char character;
}; };
inline CPP_UTILITIES_EXPORT std::ostream &operator<< (std::ostream &out, Indentation indentation) inline CPP_UTILITIES_EXPORT std::ostream &operator<<(std::ostream &out, Indentation indentation)
{ {
for(unsigned char i = 0; i < indentation.level; ++i) { for (unsigned char i = 0; i < indentation.level; ++i) {
out << indentation.character; out << indentation.character;
} }
return out; return out;

View File

@ -12,23 +12,26 @@ namespace ApplicationUtilities {
/*! /*!
* Constructs a new Failure. * Constructs a new Failure.
*/ */
Failure::Failure() : Failure::Failure()
m_what("unspecified parsing exception") : m_what("unspecified parsing exception")
{} {
}
/*! /*!
* Constructs a new Failure. \a what is a std::string * Constructs a new Failure. \a what is a std::string
* describing the cause of the Failure. * describing the cause of the Failure.
*/ */
Failure::Failure(const std::string &what) : Failure::Failure(const std::string &what)
m_what(what) : m_what(what)
{} {
}
/*! /*!
* Destroys the Failure. * Destroys the Failure.
*/ */
Failure::~Failure() USE_NOTHROW Failure::~Failure() USE_NOTHROW
{} {
}
/*! /*!
* Returns a C-style character string describing the cause * Returns a C-style character string describing the cause
@ -38,7 +41,4 @@ const char *Failure::what() const USE_NOTHROW
{ {
return m_what.c_str(); return m_what.c_str();
} }
} }

View File

@ -8,8 +8,7 @@
namespace ApplicationUtilities { namespace ApplicationUtilities {
class CPP_UTILITIES_EXPORT Failure : public std::exception class CPP_UTILITIES_EXPORT Failure : public std::exception {
{
public: public:
Failure(); Failure();
Failure(const std::string &what); Failure(const std::string &what);
@ -20,7 +19,6 @@ public:
private: private:
std::string m_what; std::string m_what;
}; };
} }
#endif // APPLICATION_UTILITIES_FAILURE_H #endif // APPLICATION_UTILITIES_FAILURE_H

View File

@ -11,10 +11,12 @@ namespace ApplicationUtilities {
/*! /*!
* \brief Constructs new fake Qt-config arguments. * \brief Constructs new fake Qt-config arguments.
*/ */
FakeQtConfigArguments::FakeQtConfigArguments() : FakeQtConfigArguments::FakeQtConfigArguments()
m_qtWidgetsGuiArg("qt-widgets-gui", 'g', "shows a Qt widgets based graphical user interface (the application has not been built with Qt widgets support)"), : m_qtWidgetsGuiArg(
m_qtQuickGuiArg("qt-quick-gui", 'q', "shows a Qt quick based graphical user interface (the application has not been built with Qt quick support)") "qt-widgets-gui", 'g', "shows a Qt widgets based graphical user interface (the application has not been built with Qt widgets support)")
{} , m_qtQuickGuiArg(
"qt-quick-gui", 'q', "shows a Qt quick based graphical user interface (the application has not been built with Qt quick support)")
{
}
} // namespace ApplicationUtilities } // namespace ApplicationUtilities

View File

@ -5,8 +5,7 @@
namespace ApplicationUtilities { namespace ApplicationUtilities {
class CPP_UTILITIES_EXPORT FakeQtConfigArguments class CPP_UTILITIES_EXPORT FakeQtConfigArguments {
{
public: public:
FakeQtConfigArguments(); FakeQtConfigArguments();
@ -47,7 +46,7 @@ inline bool FakeQtConfigArguments::areQtGuiArgsPresent() const
} // namespace ApplicationUtilities } // namespace ApplicationUtilities
#ifndef QT_CONFIG_ARGUMENTS #ifndef QT_CONFIG_ARGUMENTS
# define QT_CONFIG_ARGUMENTS ApplicationUtilities::FakeQtConfigArguments #define QT_CONFIG_ARGUMENTS ApplicationUtilities::FakeQtConfigArguments
#endif #endif
#endif // APPLICATIONUTILITIES_FAKEQTCONFIGARGUMENTS_H #endif // APPLICATIONUTILITIES_FAKEQTCONFIGARGUMENTS_H

View File

@ -2,59 +2,59 @@
#define APPLICATION_UTILITIES_GLOBAL_H #define APPLICATION_UTILITIES_GLOBAL_H
#if defined(_WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) #if defined(_WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
# ifndef PLATFORM_WINDOWS #ifndef PLATFORM_WINDOWS
/// \brief Defined when compiling for Windows. /// \brief Defined when compiling for Windows.
# define PLATFORM_WINDOWS #define PLATFORM_WINDOWS
# endif #endif
#endif #endif
#if defined(__CYGWIN__) #if defined(__CYGWIN__)
# ifndef PLATFORM_CYGWIN #ifndef PLATFORM_CYGWIN
/// \brief Defined when compiling for Cygwin. /// \brief Defined when compiling for Cygwin.
# define PLATFORM_CYGWIN #define PLATFORM_CYGWIN
# endif
#endif #endif
# if defined(__MINGW32__) || defined(__MINGW64__) #endif
# ifndef PLATFORM_MINGW #if defined(__MINGW32__) || defined(__MINGW64__)
#ifndef PLATFORM_MINGW
/// \brief Defined when compiling with mingw(-w64). /// \brief Defined when compiling with mingw(-w64).
# define PLATFORM_MINGW #define PLATFORM_MINGW
# endif #endif
# endif #endif
#if defined(__linux__) || defined(__linux) || defined(__gnu_linux__) #if defined(__linux__) || defined(__linux) || defined(__gnu_linux__)
# ifndef PLATFORM_LINUX #ifndef PLATFORM_LINUX
/// \brief Defined when compiling for Linux. /// \brief Defined when compiling for Linux.
# define PLATFORM_LINUX #define PLATFORM_LINUX
# endif #endif
# if defined(__ANDROID__) || defined(ANDROID) #if defined(__ANDROID__) || defined(ANDROID)
# ifndef PLATFORM_ANDROID #ifndef PLATFORM_ANDROID
/// \brief Defined when compiling for Android. /// \brief Defined when compiling for Android.
# define PLATFORM_ANDROID #define PLATFORM_ANDROID
# endif #endif
# endif #endif
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
# include <TargetConditionals.h> #include <TargetConditionals.h>
# if defined(TARGET_OS_MAC) && TARGET_OS_MAC #if defined(TARGET_OS_MAC) && TARGET_OS_MAC
# ifndef PLATFORM_MAC #ifndef PLATFORM_MAC
/// \brief Defined when compiling for Mac/Darwin. /// \brief Defined when compiling for Mac/Darwin.
# define PLATFORM_MAC #define PLATFORM_MAC
# endif #endif
# ifndef PLATFORM_BSD4 #ifndef PLATFORM_BSD4
/// \brief Defined when compiling for BSD 4. /// \brief Defined when compiling for BSD 4.
# define PLATFORM_BSD4 #define PLATFORM_BSD4
# endif #endif
# endif #endif
#endif #endif
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
# ifndef PLATFORM_FREE_BSD #ifndef PLATFORM_FREE_BSD
/// \brief Defined when compiling for FreeBSD /// \brief Defined when compiling for FreeBSD
# define PLATFORM_FREE_BSD #define PLATFORM_FREE_BSD
# endif #endif
#endif #endif
#if defined(__unix__) || defined(PLATFORM_LINUX) || defined(PLATFORM_FREE_BSD) || defined(PLATFORM_MAC) #if defined(__unix__) || defined(PLATFORM_LINUX) || defined(PLATFORM_FREE_BSD) || defined(PLATFORM_MAC)
# ifndef PLATFORM_UNIX #ifndef PLATFORM_UNIX
/// \brief Defined when compiling for any UNIX (like) system. /// \brief Defined when compiling for any UNIX (like) system.
# define PLATFORM_UNIX #define PLATFORM_UNIX
# endif #endif
#endif #endif
/*! /*!
@ -75,13 +75,13 @@
*/ */
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# define LIB_EXPORT __declspec(dllexport) #define LIB_EXPORT __declspec(dllexport)
# define LIB_IMPORT __declspec(dllimport) #define LIB_IMPORT __declspec(dllimport)
# define LIB_HIDDEN #define LIB_HIDDEN
#else #else
# define LIB_EXPORT __attribute__((visibility("default"))) #define LIB_EXPORT __attribute__((visibility("default")))
# define LIB_IMPORT __attribute__((visibility("default"))) #define LIB_IMPORT __attribute__((visibility("default")))
# define LIB_HIDDEN __attribute__((visibility("hidden"))) #define LIB_HIDDEN __attribute__((visibility("hidden")))
#endif #endif
/*! /*!
@ -91,11 +91,11 @@
*/ */
#ifndef USE_NOTHROW #ifndef USE_NOTHROW
# if __cplusplus >= 201103L #if __cplusplus >= 201103L
# define USE_NOTHROW noexcept #define USE_NOTHROW noexcept
# else #else
# define USE_NOTHROW throw() #define USE_NOTHROW throw()
# endif #endif
#endif #endif
/*! /*!
@ -125,9 +125,9 @@
*/ */
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
# define IF_DEBUG_BUILD(x) x #define IF_DEBUG_BUILD(x) x
#else #else
# define IF_DEBUG_BUILD(x) #define IF_DEBUG_BUILD(x)
#endif #endif
/*! /*!
@ -137,9 +137,9 @@
*/ */
#ifdef __clang__ #ifdef __clang__
# define FALLTHROUGH [[clang::fallthrough]] #define FALLTHROUGH [[clang::fallthrough]]
# else #else
# define FALLTHROUGH #define FALLTHROUGH
#endif #endif
#endif // APPLICATION_UTILITIES_GLOBAL_H #endif // APPLICATION_UTILITIES_GLOBAL_H

View File

@ -1,14 +1,14 @@
#include "./datetime.h" #include "./datetime.h"
#include "../conversion/stringconversion.h"
#include "../conversion/stringbuilder.h" #include "../conversion/stringbuilder.h"
#include "../conversion/stringconversion.h"
#include <sstream>
#include <iomanip> #include <iomanip>
#include <sstream>
#include <stdexcept> #include <stdexcept>
#if defined(PLATFORM_UNIX) #if defined(PLATFORM_UNIX)
# include <time.h> #include <time.h>
#endif #endif
using namespace std; using namespace std;
@ -22,21 +22,19 @@ const int DateTime::m_daysPer400Years = 146097;
const int DateTime::m_daysTo1601 = 584388; const int DateTime::m_daysTo1601 = 584388;
const int DateTime::m_daysTo1899 = 693593; const int DateTime::m_daysTo1899 = 693593;
const int DateTime::m_daysTo10000 = 3652059; const int DateTime::m_daysTo10000 = 3652059;
const int DateTime::m_daysToMonth365[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; const int DateTime::m_daysToMonth365[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
const int DateTime::m_daysToMonth366[13] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}; const int DateTime::m_daysToMonth366[13] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
const int DateTime::m_daysInMonth365[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int DateTime::m_daysInMonth365[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
const int DateTime::m_daysInMonth366[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int DateTime::m_daysInMonth366[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
template<typename num1, typename num2, typename num3> template <typename num1, typename num2, typename num3> inline bool inRangeInclMax(num1 val, num2 min, num3 max)
inline bool inRangeInclMax(num1 val, num2 min, num3 max)
{ {
return (val) >= (min) && (val) <= (max); return (val) >= (min) && (val) <= (max);
} }
template<typename num1, typename num2, typename num3> template <typename num1, typename num2, typename num3> inline bool inRangeExclMax(num1 val, num2 min, num3 max)
inline bool inRangeExclMax(num1 val, num2 min, num3 max)
{ {
return (val) >= (min) && (val) < (max); return (val) >= (min) && (val) < (max);
} }
/*! /*!
@ -57,10 +55,10 @@ inline bool inRangeExclMax(num1 val, num2 min, num3 max)
*/ */
DateTime DateTime::fromTimeStamp(time_t timeStamp) DateTime DateTime::fromTimeStamp(time_t timeStamp)
{ {
if(timeStamp) { if (timeStamp) {
struct tm *timeinfo = localtime(&timeStamp); struct tm *timeinfo = localtime(&timeStamp);
return DateTime::fromDateAndTime(timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, return DateTime::fromDateAndTime(timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min,
timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec < 60 ? timeinfo->tm_sec : 59, 0); timeinfo->tm_sec < 60 ? timeinfo->tm_sec : 59, 0);
} else { } else {
return DateTime(); return DateTime();
} }
@ -79,30 +77,30 @@ DateTime DateTime::fromTimeStampGmt(time_t timeStamp)
*/ */
DateTime DateTime::fromString(const char *str) DateTime DateTime::fromString(const char *str)
{ {
int values[6] = {0}; int values[6] = { 0 };
int *const dayIndex = values + 2; int *const dayIndex = values + 2;
int *const secondsIndex = values + 5; int *const secondsIndex = values + 5;
int *valueIndex = values; int *valueIndex = values;
int *const valuesEnd = values + 7; int *const valuesEnd = values + 7;
double miliSecondsFact = 100.0, miliSeconds = 0.0; double miliSecondsFact = 100.0, miliSeconds = 0.0;
for(const char *strIndex = str; ; ++strIndex) { for (const char *strIndex = str;; ++strIndex) {
const char c = *strIndex; const char c = *strIndex;
if(c <= '9' && c >= '0') { if (c <= '9' && c >= '0') {
if(valueIndex > secondsIndex) { if (valueIndex > secondsIndex) {
miliSeconds += (c - '0') * miliSecondsFact; miliSeconds += (c - '0') * miliSecondsFact;
miliSecondsFact /= 10; miliSecondsFact /= 10;
} else { } else {
*valueIndex *= 10; *valueIndex *= 10;
*valueIndex += c - '0'; *valueIndex += c - '0';
} }
} else if((c == '-' || c == ':' || c == '/') || (c == '.' && (valueIndex == secondsIndex)) || (c == ' ' && (valueIndex == dayIndex))) { } else if ((c == '-' || c == ':' || c == '/') || (c == '.' && (valueIndex == secondsIndex)) || (c == ' ' && (valueIndex == dayIndex))) {
if(++valueIndex == valuesEnd) { if (++valueIndex == valuesEnd) {
break; // just ignore further values for now break; // just ignore further values for now
} }
} else if(c == '\0') { } else if (c == '\0') {
break; break;
} else { } else {
throw ConversionException("unexpected "s + c); throw ConversionException(argsToString("unexpected ", c));
} }
} }
return DateTime::fromDateAndTime(values[0], values[1], *dayIndex, values[3], values[4], *secondsIndex, miliSeconds); return DateTime::fromDateAndTime(values[0], values[1], *dayIndex, values[3], values[4], *secondsIndex, miliSeconds);
@ -117,7 +115,7 @@ DateTime DateTime::fromString(const char *str)
*/ */
std::pair<DateTime, TimeSpan> DateTime::fromIsoString(const char *str) std::pair<DateTime, TimeSpan> DateTime::fromIsoString(const char *str)
{ {
int values[9] = {0}; int values[9] = { 0 };
int *const dayIndex = values + 2; int *const dayIndex = values + 2;
int *const hourIndex = values + 3; int *const hourIndex = values + 3;
int *const secondsIndex = values + 5; int *const secondsIndex = values + 5;
@ -126,52 +124,53 @@ std::pair<DateTime, TimeSpan> DateTime::fromIsoString(const char *str)
int *valueIndex = values; int *valueIndex = values;
bool deltaNegative = false; bool deltaNegative = false;
double miliSecondsFact = 100.0, miliSeconds = 0.0; double miliSecondsFact = 100.0, miliSeconds = 0.0;
for(const char *strIndex = str; ; ++strIndex) { for (const char *strIndex = str;; ++strIndex) {
const char c = *strIndex; const char c = *strIndex;
if(c <= '9' && c >= '0') { if (c <= '9' && c >= '0') {
if(valueIndex == miliSecondsIndex) { if (valueIndex == miliSecondsIndex) {
miliSeconds += (c - '0') * miliSecondsFact; miliSeconds += (c - '0') * miliSecondsFact;
miliSecondsFact /= 10; miliSecondsFact /= 10;
} else { } else {
*valueIndex *= 10; *valueIndex *= 10;
*valueIndex += c - '0'; *valueIndex += c - '0';
} }
} else if(c == 'T') { } else if (c == 'T') {
if(++valueIndex != hourIndex) { if (++valueIndex != hourIndex) {
throw ConversionException("\"T\" expected before hour"); throw ConversionException("\"T\" expected before hour");
} }
} else if(c == '-') { } else if (c == '-') {
if(valueIndex < dayIndex) { if (valueIndex < dayIndex) {
++valueIndex; ++valueIndex;
} else { } else {
throw ConversionException("unexpected \"-\" after day"); throw ConversionException("unexpected \"-\" after day");
} }
} else if(c == '.') { } else if (c == '.') {
if(valueIndex != secondsIndex) { if (valueIndex != secondsIndex) {
throw ConversionException("unexpected \".\""); throw ConversionException("unexpected \".\"");
} else { } else {
++valueIndex; ++valueIndex;
} }
} else if(c == ':') { } else if (c == ':') {
if(valueIndex < hourIndex) { if (valueIndex < hourIndex) {
throw ConversionException("unexpected \":\" before hour"); throw ConversionException("unexpected \":\" before hour");
} else if(valueIndex == secondsIndex) { } else if (valueIndex == secondsIndex) {
throw ConversionException("unexpected \":\" after second"); throw ConversionException("unexpected \":\" after second");
} else { } else {
++valueIndex; ++valueIndex;
} }
} else if((c == '+') && (++valueIndex == deltaHourIndex)) { } else if ((c == '+') && (++valueIndex == deltaHourIndex)) {
deltaNegative = false; deltaNegative = false;
} else if((c == '-') && (++valueIndex == deltaHourIndex)) { } else if ((c == '-') && (++valueIndex == deltaHourIndex)) {
deltaNegative = true; deltaNegative = true;
} else if(c == '\0') { } else if (c == '\0') {
break; break;
} else { } else {
throw ConversionException("unexpected \""s % c + '\"'); throw ConversionException(argsToString("unexpected \"", c, '\"'));
} }
} }
deltaNegative && (*deltaHourIndex = -*deltaHourIndex); deltaNegative && (*deltaHourIndex = -*deltaHourIndex);
return make_pair(DateTime::fromDateAndTime(values[0], values[1], *dayIndex, *hourIndex, values[4], *secondsIndex, miliSeconds), TimeSpan::fromMinutes(*deltaHourIndex * 60 + values[8])); return make_pair(DateTime::fromDateAndTime(values[0], values[1], *dayIndex, *hourIndex, values[4], *secondsIndex, miliSeconds),
TimeSpan::fromMinutes(*deltaHourIndex * 60 + values[8]));
} }
/*! /*!
@ -195,25 +194,19 @@ void DateTime::toString(string &result, DateTimeOutputFormat format, bool noMill
{ {
stringstream s(stringstream::in | stringstream::out); stringstream s(stringstream::in | stringstream::out);
s << setfill('0'); s << setfill('0');
if(format == DateTimeOutputFormat::DateTimeAndWeekday if (format == DateTimeOutputFormat::DateTimeAndWeekday || format == DateTimeOutputFormat::DateTimeAndShortWeekday)
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday)
s << printDayOfWeek(dayOfWeek(), format == DateTimeOutputFormat::DateTimeAndShortWeekday) << ' '; s << printDayOfWeek(dayOfWeek(), format == DateTimeOutputFormat::DateTimeAndShortWeekday) << ' ';
if(format == DateTimeOutputFormat::DateOnly if (format == DateTimeOutputFormat::DateOnly || format == DateTimeOutputFormat::DateAndTime || format == DateTimeOutputFormat::DateTimeAndWeekday
|| format == DateTimeOutputFormat::DateAndTime || format == DateTimeOutputFormat::DateTimeAndShortWeekday)
|| format == DateTimeOutputFormat::DateTimeAndWeekday
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday)
s << setw(4) << year() << '-' << setw(2) << month() << '-' << setw(2) << day(); s << setw(4) << year() << '-' << setw(2) << month() << '-' << setw(2) << day();
if(format == DateTimeOutputFormat::DateAndTime if (format == DateTimeOutputFormat::DateAndTime || format == DateTimeOutputFormat::DateTimeAndWeekday
|| format == DateTimeOutputFormat::DateTimeAndWeekday || format == DateTimeOutputFormat::DateTimeAndShortWeekday)
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday)
s << " "; s << " ";
if(format == DateTimeOutputFormat::TimeOnly if (format == DateTimeOutputFormat::TimeOnly || format == DateTimeOutputFormat::DateAndTime || format == DateTimeOutputFormat::DateTimeAndWeekday
|| format == DateTimeOutputFormat::DateAndTime || format == DateTimeOutputFormat::DateTimeAndShortWeekday) {
|| format == DateTimeOutputFormat::DateTimeAndWeekday
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday) {
s << setw(2) << hour() << ':' << setw(2) << minute() << ':' << setw(2) << second(); s << setw(2) << hour() << ':' << setw(2) << minute() << ':' << setw(2) << second();
int ms = millisecond(); int ms = millisecond();
if(!noMilliseconds && ms > 0) { if (!noMilliseconds && ms > 0) {
s << '.' << setw(3) << ms; s << '.' << setw(3) << ms;
} }
} }
@ -228,9 +221,9 @@ string DateTime::toIsoString(TimeSpan timeZoneDelta) const
{ {
stringstream s(stringstream::in | stringstream::out); stringstream s(stringstream::in | stringstream::out);
s << setfill('0'); s << setfill('0');
s << setw(4) << year() << '-' << setw(2) << month() << '-' << setw(2) << day() s << setw(4) << year() << '-' << setw(2) << month() << '-' << setw(2) << day() << 'T' << setw(2) << hour() << ':' << setw(2) << minute() << ':'
<< 'T' << setw(2) << hour() << ':' << setw(2) << minute() << ':' << setw(2) << second() << '.' << setw(3) << millisecond(); << setw(2) << second() << '.' << setw(3) << millisecond();
if(!timeZoneDelta.isNull()) { if (!timeZoneDelta.isNull()) {
s << (timeZoneDelta.isNegative() ? '-' : '+'); s << (timeZoneDelta.isNegative() ? '-' : '+');
s << setw(2) << timeZoneDelta.hours() << ':' << setw(2) << timeZoneDelta.minutes(); s << setw(2) << timeZoneDelta.hours() << ':' << setw(2) << timeZoneDelta.minutes();
} }
@ -246,8 +239,8 @@ string DateTime::toIsoString(TimeSpan timeZoneDelta) const
*/ */
const char *DateTime::printDayOfWeek(DayOfWeek dayOfWeek, bool abbreviation) const char *DateTime::printDayOfWeek(DayOfWeek dayOfWeek, bool abbreviation)
{ {
if(abbreviation) { if (abbreviation) {
switch(dayOfWeek) { switch (dayOfWeek) {
case DayOfWeek::Monday: case DayOfWeek::Monday:
return "Mon"; return "Mon";
case DayOfWeek::Tuesday: case DayOfWeek::Tuesday:
@ -264,7 +257,7 @@ const char *DateTime::printDayOfWeek(DayOfWeek dayOfWeek, bool abbreviation)
return "Sun"; return "Sun";
} }
} else { } else {
switch(dayOfWeek) { switch (dayOfWeek) {
case DayOfWeek::Monday: case DayOfWeek::Monday:
return "Monday"; return "Monday";
case DayOfWeek::Tuesday: case DayOfWeek::Tuesday:
@ -293,7 +286,8 @@ DateTime DateTime::exactGmtNow()
{ {
struct timespec t; struct timespec t;
clock_gettime(CLOCK_REALTIME, &t); clock_gettime(CLOCK_REALTIME, &t);
return DateTime(DateTime::unixEpochStart().totalTicks() + static_cast<uint64>(t.tv_sec) * TimeSpan::ticksPerSecond + static_cast<uint64>(t.tv_nsec) / 100); return DateTime(
DateTime::unixEpochStart().totalTicks() + static_cast<uint64>(t.tv_sec) * TimeSpan::ticksPerSecond + static_cast<uint64>(t.tv_nsec) / 100);
} }
#endif #endif
@ -302,14 +296,15 @@ DateTime DateTime::exactGmtNow()
*/ */
uint64 DateTime::dateToTicks(int year, int month, int day) uint64 DateTime::dateToTicks(int year, int month, int day)
{ {
if(inRangeInclMax(year, 1, 9999)) { if (inRangeInclMax(year, 1, 9999)) {
if(inRangeInclMax(month, 1, 12)) { if (inRangeInclMax(month, 1, 12)) {
const int *daysToMonth = isLeapYear(year) ? m_daysToMonth366 : m_daysToMonth365; const int *daysToMonth = isLeapYear(year) ? m_daysToMonth366 : m_daysToMonth365;
int passedMonth = month - 1; int passedMonth = month - 1;
if(inRangeInclMax(day, 1, daysToMonth[month] - daysToMonth[passedMonth])) { if (inRangeInclMax(day, 1, daysToMonth[month] - daysToMonth[passedMonth])) {
int passedYears = year - 1; int passedYears = year - 1;
int passedDays = day - 1; int passedDays = day - 1;
return (passedYears * m_daysPerYear + passedYears / 4 - passedYears / 100 + passedYears / 400 + daysToMonth[passedMonth] + passedDays) * TimeSpan::ticksPerDay; return (passedYears * m_daysPerYear + passedYears / 4 - passedYears / 100 + passedYears / 400 + daysToMonth[passedMonth] + passedDays)
* TimeSpan::ticksPerDay;
} else { } else {
throw ConversionException("day is out of range"); throw ConversionException("day is out of range");
} }
@ -327,19 +322,20 @@ uint64 DateTime::dateToTicks(int year, int month, int day)
*/ */
uint64 DateTime::timeToTicks(int hour, int minute, int second, double millisecond) uint64 DateTime::timeToTicks(int hour, int minute, int second, double millisecond)
{ {
if(!inRangeExclMax(hour, 0, 24)) { if (!inRangeExclMax(hour, 0, 24)) {
throw ConversionException("hour is out of range"); throw ConversionException("hour is out of range");
} }
if(!inRangeExclMax(minute, 0, 60)) { if (!inRangeExclMax(minute, 0, 60)) {
throw ConversionException("minute is out of range"); throw ConversionException("minute is out of range");
} }
if(!inRangeExclMax(second, 0, 60)) { if (!inRangeExclMax(second, 0, 60)) {
throw ConversionException("second is out of range"); throw ConversionException("second is out of range");
} }
if(!inRangeExclMax(millisecond, 0.0, 1000.0)) { if (!inRangeExclMax(millisecond, 0.0, 1000.0)) {
throw ConversionException("millisecond is out of range"); throw ConversionException("millisecond is out of range");
} }
return (hour * TimeSpan::ticksPerHour) + (minute * TimeSpan::ticksPerMinute) + (second * TimeSpan::ticksPerSecond) + (uint64)(millisecond * (double)TimeSpan::ticksPerMillisecond); return (hour * TimeSpan::ticksPerHour) + (minute * TimeSpan::ticksPerMinute) + (second * TimeSpan::ticksPerSecond)
+ (uint64)(millisecond * (double)TimeSpan::ticksPerMillisecond);
} }
/*! /*!
@ -352,31 +348,31 @@ int DateTime::getDatePart(DatePart part) const
int full400YearBlocks = fullDays / m_daysPer400Years; int full400YearBlocks = fullDays / m_daysPer400Years;
int daysMinusFull400YearBlocks = fullDays - full400YearBlocks * m_daysPer400Years; int daysMinusFull400YearBlocks = fullDays - full400YearBlocks * m_daysPer400Years;
int full100YearBlocks = daysMinusFull400YearBlocks / m_daysPer100Years; int full100YearBlocks = daysMinusFull400YearBlocks / m_daysPer100Years;
if(full100YearBlocks == 4) { if (full100YearBlocks == 4) {
full100YearBlocks = 3; full100YearBlocks = 3;
} }
int daysMinusFull100YearBlocks = daysMinusFull400YearBlocks - full100YearBlocks * m_daysPer100Years; int daysMinusFull100YearBlocks = daysMinusFull400YearBlocks - full100YearBlocks * m_daysPer100Years;
int full4YearBlocks = daysMinusFull100YearBlocks / m_daysPer4Years; int full4YearBlocks = daysMinusFull100YearBlocks / m_daysPer4Years;
int daysMinusFull4YearBlocks = daysMinusFull100YearBlocks - full4YearBlocks * m_daysPer4Years; int daysMinusFull4YearBlocks = daysMinusFull100YearBlocks - full4YearBlocks * m_daysPer4Years;
int full1YearBlocks = daysMinusFull4YearBlocks / m_daysPerYear; int full1YearBlocks = daysMinusFull4YearBlocks / m_daysPerYear;
if(full1YearBlocks == 4) { if (full1YearBlocks == 4) {
full1YearBlocks = 3; full1YearBlocks = 3;
} }
if(part == DatePart::Year) { if (part == DatePart::Year) {
return full400YearBlocks * 400 + full100YearBlocks * 100 + full4YearBlocks * 4 + full1YearBlocks + 1; return full400YearBlocks * 400 + full100YearBlocks * 100 + full4YearBlocks * 4 + full1YearBlocks + 1;
} }
int restDays = daysMinusFull4YearBlocks - full1YearBlocks * m_daysPerYear; int restDays = daysMinusFull4YearBlocks - full1YearBlocks * m_daysPerYear;
if(part == DatePart::DayOfYear) { // day if (part == DatePart::DayOfYear) { // day
return restDays + 1; return restDays + 1;
} }
const int *daysToMonth = (full1YearBlocks == 3 && (full4YearBlocks != 24 || full100YearBlocks == 3)) ? m_daysToMonth366 : m_daysToMonth365; const int *daysToMonth = (full1YearBlocks == 3 && (full4YearBlocks != 24 || full100YearBlocks == 3)) ? m_daysToMonth366 : m_daysToMonth365;
int month = 1; int month = 1;
while(restDays >= daysToMonth[month]) { while (restDays >= daysToMonth[month]) {
++month; ++month;
} }
if(part == DatePart::Month) { if (part == DatePart::Month) {
return month; return month;
} else if(part == DatePart::Day) { } else if (part == DatePart::Day) {
return restDays - daysToMonth[month - 1] + 1; return restDays - daysToMonth[month - 1] + 1;
} }
return 0; return 0;

View File

@ -5,19 +5,17 @@
#include "../conversion/types.h" #include "../conversion/types.h"
#include <string>
#include <limits>
#include <ctime> #include <ctime>
#include <limits>
#include <string>
namespace ChronoUtilities namespace ChronoUtilities {
{
/*! /*!
* \brief Specifies the output format. * \brief Specifies the output format.
* \sa DateTime::toString() * \sa DateTime::toString()
*/ */
enum class DateTimeOutputFormat enum class DateTimeOutputFormat {
{
DateAndTime, /**< date and time */ DateAndTime, /**< date and time */
DateOnly, /**< date only */ DateOnly, /**< date only */
TimeOnly, /**< time only */ TimeOnly, /**< time only */
@ -29,8 +27,7 @@ enum class DateTimeOutputFormat
* \brief Specifies the day of the week. * \brief Specifies the day of the week.
* \sa DateTime::dayOfWeek() * \sa DateTime::dayOfWeek()
*/ */
enum class DayOfWeek enum class DayOfWeek {
{
Monday, /**< Monday */ Monday, /**< Monday */
Tuesday, /**< Tuesday */ Tuesday, /**< Tuesday */
Wednesday, /**< Wednesday */ Wednesday, /**< Wednesday */
@ -44,16 +41,14 @@ enum class DayOfWeek
* \brief Specifies the date part. * \brief Specifies the date part.
* \sa DateTime::getDatePart() * \sa DateTime::getDatePart()
*/ */
enum class DatePart enum class DatePart {
{
Year, /**< year */ Year, /**< year */
Month, /**< month */ Month, /**< month */
DayOfYear, /**< day of year */ DayOfYear, /**< day of year */
Day /**< day */ Day /**< day */
}; };
class CPP_UTILITIES_EXPORT DateTime class CPP_UTILITIES_EXPORT DateTime {
{
public: public:
explicit constexpr DateTime(); explicit constexpr DateTime();
explicit constexpr DateTime(uint64 ticks); explicit constexpr DateTime(uint64 ticks);
@ -98,18 +93,18 @@ public:
constexpr static bool isLeapYear(int year); constexpr static bool isLeapYear(int year);
static int daysInMonth(int year, int month); static int daysInMonth(int year, int month);
constexpr bool operator ==(const DateTime &other) const; constexpr bool operator==(const DateTime &other) const;
constexpr bool operator !=(const DateTime &other) const; constexpr bool operator!=(const DateTime &other) const;
constexpr bool operator <(const DateTime &other) const; constexpr bool operator<(const DateTime &other) const;
constexpr bool operator >(const DateTime &other) const; constexpr bool operator>(const DateTime &other) const;
constexpr bool operator <=(const DateTime &other) const; constexpr bool operator<=(const DateTime &other) const;
constexpr bool operator >=(const DateTime &other) const; constexpr bool operator>=(const DateTime &other) const;
constexpr DateTime operator +(const TimeSpan &timeSpan) const; constexpr DateTime operator+(const TimeSpan &timeSpan) const;
constexpr DateTime operator -(const TimeSpan &timeSpan) const; constexpr DateTime operator-(const TimeSpan &timeSpan) const;
constexpr TimeSpan operator +(const DateTime &other) const; constexpr TimeSpan operator+(const DateTime &other) const;
constexpr TimeSpan operator -(const DateTime &other) const; constexpr TimeSpan operator-(const DateTime &other) const;
DateTime &operator +=(const TimeSpan &timeSpan); DateTime &operator+=(const TimeSpan &timeSpan);
DateTime &operator -=(const TimeSpan &timeSpan); DateTime &operator-=(const TimeSpan &timeSpan);
private: private:
static uint64 dateToTicks(int year, int month, int day); static uint64 dateToTicks(int year, int month, int day);
@ -130,21 +125,21 @@ private:
static const int m_daysInMonth366[12]; static const int m_daysInMonth366[12];
}; };
/*! /*!
* \brief Constructs a DateTime. * \brief Constructs a DateTime.
*/ */
constexpr inline DateTime::DateTime() : constexpr inline DateTime::DateTime()
m_ticks(0) : m_ticks(0)
{} {
}
/*! /*!
* \brief Constructs a DateTime with the specified number of \a ticks. * \brief Constructs a DateTime with the specified number of \a ticks.
*/ */
constexpr inline DateTime::DateTime(uint64 ticks) : constexpr inline DateTime::DateTime(uint64 ticks)
m_ticks(ticks) : m_ticks(ticks)
{} {
}
/*! /*!
* \brief Constructs a DateTime to the specified \a year, \a month, and \a day. * \brief Constructs a DateTime to the specified \a year, \a month, and \a day.
@ -167,7 +162,7 @@ inline DateTime DateTime::fromTime(int hour, int minute, int second, double mill
*/ */
inline DateTime DateTime::fromDateAndTime(int year, int month, int day, int hour, int minute, int second, double millisecond) inline DateTime DateTime::fromDateAndTime(int year, int month, int day, int hour, int minute, int second, double millisecond)
{ {
if(uint64 ticks = dateToTicks(year, month, day)) { if (uint64 ticks = dateToTicks(year, month, day)) {
return DateTime(ticks + timeToTicks(hour, minute, second, millisecond)); return DateTime(ticks + timeToTicks(hour, minute, second, millisecond));
} }
return DateTime(); return DateTime();
@ -321,11 +316,7 @@ constexpr inline bool DateTime::isEternity() const
*/ */
constexpr inline bool DateTime::isLeapYear(int year) constexpr inline bool DateTime::isLeapYear(int year)
{ {
return (year % 4 != 0) return (year % 4 != 0) ? false : ((year % 100 == 0) ? (year % 400 == 0) : true);
? false
: ((year % 100 == 0)
? (year % 400 == 0)
: true);
} }
/*! /*!
@ -333,11 +324,7 @@ constexpr inline bool DateTime::isLeapYear(int year)
*/ */
inline int DateTime::daysInMonth(int year, int month) inline int DateTime::daysInMonth(int year, int month)
{ {
return (month >= 1 && month <= 12) return (month >= 1 && month <= 12) ? (isLeapYear(year) ? m_daysInMonth366[month - 1] : m_daysInMonth365[month - 1]) : (0);
? (isLeapYear(year)
? m_daysInMonth366[month - 1]
: m_daysInMonth365[month - 1])
: (0);
} }
/*! /*!
@ -385,7 +372,7 @@ inline DateTime DateTime::gmtNow()
/*! /*!
* \brief Indicates whether two DateTime instances are equal. * \brief Indicates whether two DateTime instances are equal.
*/ */
constexpr inline bool DateTime::operator ==(const DateTime &other) const constexpr inline bool DateTime::operator==(const DateTime &other) const
{ {
return m_ticks == other.m_ticks; return m_ticks == other.m_ticks;
} }
@ -393,7 +380,7 @@ constexpr inline bool DateTime::operator ==(const DateTime &other) const
/*! /*!
* \brief Indicates whether two DateTime instances are not equal. * \brief Indicates whether two DateTime instances are not equal.
*/ */
constexpr inline bool DateTime::operator !=(const DateTime &other) const constexpr inline bool DateTime::operator!=(const DateTime &other) const
{ {
return m_ticks != other.m_ticks; return m_ticks != other.m_ticks;
} }
@ -401,7 +388,7 @@ constexpr inline bool DateTime::operator !=(const DateTime &other) const
/*! /*!
* \brief Indicates whether a specified DateTime is less than another specified DateTime. * \brief Indicates whether a specified DateTime is less than another specified DateTime.
*/ */
constexpr inline bool DateTime::operator <(const DateTime &other) const constexpr inline bool DateTime::operator<(const DateTime &other) const
{ {
return m_ticks < other.m_ticks; return m_ticks < other.m_ticks;
} }
@ -409,7 +396,7 @@ constexpr inline bool DateTime::operator <(const DateTime &other) const
/*! /*!
* \brief Indicates whether a specified DateTime is greater than another specified DateTime. * \brief Indicates whether a specified DateTime is greater than another specified DateTime.
*/ */
constexpr inline bool DateTime::operator >(const DateTime &other) const constexpr inline bool DateTime::operator>(const DateTime &other) const
{ {
return m_ticks > other.m_ticks; return m_ticks > other.m_ticks;
} }
@ -417,7 +404,7 @@ constexpr inline bool DateTime::operator >(const DateTime &other) const
/*! /*!
* \brief Indicates whether a specified DateTime is less or equal than another specified DateTime. * \brief Indicates whether a specified DateTime is less or equal than another specified DateTime.
*/ */
constexpr inline bool DateTime::operator <=(const DateTime &other) const constexpr inline bool DateTime::operator<=(const DateTime &other) const
{ {
return m_ticks <= other.m_ticks; return m_ticks <= other.m_ticks;
} }
@ -425,7 +412,7 @@ constexpr inline bool DateTime::operator <=(const DateTime &other) const
/*! /*!
* \brief Indicates whether a specified DateTime is greater or equal than another specified DateTime. * \brief Indicates whether a specified DateTime is greater or equal than another specified DateTime.
*/ */
constexpr inline bool DateTime::operator >=(const DateTime &other) const constexpr inline bool DateTime::operator>=(const DateTime &other) const
{ {
return m_ticks >= other.m_ticks; return m_ticks >= other.m_ticks;
} }
@ -434,7 +421,7 @@ constexpr inline bool DateTime::operator >=(const DateTime &other) const
* \brief Adds another instance. * \brief Adds another instance.
* \returns The result is another DateTime. * \returns The result is another DateTime.
*/ */
constexpr inline DateTime DateTime::operator +(const TimeSpan &timeSpan) const constexpr inline DateTime DateTime::operator+(const TimeSpan &timeSpan) const
{ {
return DateTime(m_ticks + timeSpan.m_ticks); return DateTime(m_ticks + timeSpan.m_ticks);
} }
@ -443,7 +430,7 @@ constexpr inline DateTime DateTime::operator +(const TimeSpan &timeSpan) const
* \brief Substracts another instance. * \brief Substracts another instance.
* \returns The result is another DateTime. * \returns The result is another DateTime.
*/ */
constexpr inline DateTime DateTime::operator -(const TimeSpan &timeSpan) const constexpr inline DateTime DateTime::operator-(const TimeSpan &timeSpan) const
{ {
return DateTime(m_ticks - timeSpan.m_ticks); return DateTime(m_ticks - timeSpan.m_ticks);
} }
@ -452,7 +439,7 @@ constexpr inline DateTime DateTime::operator -(const TimeSpan &timeSpan) const
* \brief Adds two instances. * \brief Adds two instances.
* \returns The result is a TimeSpan. * \returns The result is a TimeSpan.
*/ */
constexpr inline TimeSpan DateTime::operator +(const DateTime &other) const constexpr inline TimeSpan DateTime::operator+(const DateTime &other) const
{ {
return TimeSpan(m_ticks + other.m_ticks); return TimeSpan(m_ticks + other.m_ticks);
} }
@ -461,7 +448,7 @@ constexpr inline TimeSpan DateTime::operator +(const DateTime &other) const
* \brief Substracts two DateTime instances. * \brief Substracts two DateTime instances.
* \returns The result is a TimeSpan. * \returns The result is a TimeSpan.
*/ */
constexpr inline TimeSpan DateTime::operator -(const DateTime &other) const constexpr inline TimeSpan DateTime::operator-(const DateTime &other) const
{ {
return TimeSpan(m_ticks - other.m_ticks); return TimeSpan(m_ticks - other.m_ticks);
} }
@ -469,7 +456,7 @@ constexpr inline TimeSpan DateTime::operator -(const DateTime &other) const
/*! /*!
* \brief Adds a TimeSpan to the current instance. * \brief Adds a TimeSpan to the current instance.
*/ */
inline DateTime &DateTime::operator +=(const TimeSpan &timeSpan) inline DateTime &DateTime::operator+=(const TimeSpan &timeSpan)
{ {
m_ticks += timeSpan.m_ticks; m_ticks += timeSpan.m_ticks;
return *this; return *this;
@ -478,20 +465,18 @@ inline DateTime &DateTime::operator +=(const TimeSpan &timeSpan)
/*! /*!
* \brief Substracts a TimeSpan from the current instance. * \brief Substracts a TimeSpan from the current instance.
*/ */
inline DateTime &DateTime::operator -=(const TimeSpan &timeSpan) inline DateTime &DateTime::operator-=(const TimeSpan &timeSpan)
{ {
m_ticks -= timeSpan.m_ticks; m_ticks -= timeSpan.m_ticks;
return *this; return *this;
} }
} }
namespace std { namespace std {
template<> struct hash<ChronoUtilities::DateTime> template <> struct hash<ChronoUtilities::DateTime> {
{
inline size_t operator()(const ChronoUtilities::DateTime &dateTime) const inline size_t operator()(const ChronoUtilities::DateTime &dateTime) const
{ {
return hash<decltype (dateTime.totalTicks())>()(dateTime.totalTicks()); return hash<decltype(dateTime.totalTicks())>()(dateTime.totalTicks());
} }
}; };
} }

View File

@ -5,12 +5,12 @@
#include <ostream> #include <ostream>
inline std::ostream &operator<< (std::ostream &out, const ChronoUtilities::DateTime &value) inline std::ostream &operator<<(std::ostream &out, const ChronoUtilities::DateTime &value)
{ {
return out << value.toString(ChronoUtilities::DateTimeOutputFormat::DateAndTime, false); return out << value.toString(ChronoUtilities::DateTimeOutputFormat::DateAndTime, false);
} }
inline std::ostream &operator<< (std::ostream &out, const ChronoUtilities::TimeSpan &value) inline std::ostream &operator<<(std::ostream &out, const ChronoUtilities::TimeSpan &value)
{ {
return out << value.toString(ChronoUtilities::TimeSpanOutputFormat::Normal, false); return out << value.toString(ChronoUtilities::TimeSpanOutputFormat::Normal, false);
} }

View File

@ -27,7 +27,4 @@ Period::Period(const DateTime &beg, const DateTime &end)
--m_years; --m_years;
} }
} }
} }

View File

@ -5,13 +5,13 @@
namespace ChronoUtilities { namespace ChronoUtilities {
class CPP_UTILITIES_EXPORT Period class CPP_UTILITIES_EXPORT Period {
{
public: public:
Period(const DateTime &beg, const DateTime &end); Period(const DateTime &beg, const DateTime &end);
int years() const; int years() const;
int months() const; int months() const;
int days() const; int days() const;
private: private:
int m_years; int m_years;
int m_months; int m_months;
@ -41,7 +41,6 @@ inline int Period::days() const
{ {
return m_days; return m_days;
} }
} }
#endif // CHRONO_UTILITIES_PERIOD_H #endif // CHRONO_UTILITIES_PERIOD_H

View File

@ -2,9 +2,9 @@
#include "../conversion/stringconversion.h" #include "../conversion/stringconversion.h"
#include <sstream>
#include <cmath> #include <cmath>
#include <iomanip> #include <iomanip>
#include <sstream>
#include <vector> #include <vector>
using namespace std; using namespace std;
@ -24,16 +24,16 @@ TimeSpan TimeSpan::fromString(const char *str, char separator)
{ {
vector<double> parts; vector<double> parts;
size_t partsSize = 1; size_t partsSize = 1;
for(const char *i = str; *i; ++i) { for (const char *i = str; *i; ++i) {
*i == separator && ++partsSize; *i == separator && ++partsSize;
} }
parts.reserve(partsSize); parts.reserve(partsSize);
for(const char *i = str; ;) { for (const char *i = str;;) {
if(*i == separator) { if (*i == separator) {
parts.emplace_back(stringToNumber<double>(string(str, i))); parts.emplace_back(stringToNumber<double>(string(str, i)));
str = ++i; str = ++i;
} else if(*i == '\0') { } else if (*i == '\0') {
parts.emplace_back(stringToNumber<double>(string(str, i))); parts.emplace_back(stringToNumber<double>(string(str, i)));
break; break;
} else { } else {
@ -41,7 +41,7 @@ TimeSpan TimeSpan::fromString(const char *str, char separator)
} }
} }
switch(parts.size()) { switch (parts.size()) {
case 0: case 0:
return TimeSpan(); return TimeSpan();
case 1: case 1:
@ -79,31 +79,31 @@ string TimeSpan::toString(TimeSpanOutputFormat format, bool noMilliseconds) cons
void TimeSpan::toString(string &result, TimeSpanOutputFormat format, bool noMilliseconds) const void TimeSpan::toString(string &result, TimeSpanOutputFormat format, bool noMilliseconds) const
{ {
stringstream s(stringstream::in | stringstream::out); stringstream s(stringstream::in | stringstream::out);
if(isNegative()) if (isNegative())
s << "- "; s << "- ";
switch(format) { switch (format) {
case TimeSpanOutputFormat::Normal: case TimeSpanOutputFormat::Normal:
s << setfill('0') << setw(2) << floor(fabs(totalHours())) << ":" << setw(2) << minutes() << ":" << setw(2) << seconds() << " "; s << setfill('0') << setw(2) << floor(fabs(totalHours())) << ":" << setw(2) << minutes() << ":" << setw(2) << seconds() << " ";
break; break;
case TimeSpanOutputFormat::WithMeasures: case TimeSpanOutputFormat::WithMeasures:
if(isNull()) { if (isNull()) {
s << "0 s "; s << "0 s ";
} else if(totalMilliseconds() < 1.0) { } else if (totalMilliseconds() < 1.0) {
s << setprecision(2) << (m_ticks / 10.0) << " µs "; s << setprecision(2) << (m_ticks / 10.0) << " µs ";
} else { } else {
if(days()) { if (days()) {
s << days() << " d "; s << days() << " d ";
} }
if(hours()) { if (hours()) {
s << hours() << " h "; s << hours() << " h ";
} }
if(minutes()) { if (minutes()) {
s << minutes() << " min "; s << minutes() << " min ";
} }
if(seconds()) { if (seconds()) {
s << seconds() << " s "; s << seconds() << " s ";
} }
if(!noMilliseconds && milliseconds()) { if (!noMilliseconds && milliseconds()) {
s << milliseconds() << " ms "; s << milliseconds() << " ms ";
} }
} }
@ -111,5 +111,3 @@ void TimeSpan::toString(string &result, TimeSpanOutputFormat format, bool noMill
} }
result = s.str().substr(0, static_cast<string::size_type>(s.tellp()) - 1); result = s.str().substr(0, static_cast<string::size_type>(s.tellp()) - 1);
} }

View File

@ -1,17 +1,16 @@
#ifndef CHRONO_UTILITIES_TIMESPAN_H #ifndef CHRONO_UTILITIES_TIMESPAN_H
#define CHRONO_UTILITIES_TIMESPAN_H #define CHRONO_UTILITIES_TIMESPAN_H
#include "../global.h"
#include "../conversion/types.h" #include "../conversion/types.h"
#include "../global.h"
#include <string>
#include <limits> #include <limits>
#include <string>
/*! /*!
* \brief Contains classes providing a means for handling date and time information. * \brief Contains classes providing a means for handling date and time information.
*/ */
namespace ChronoUtilities namespace ChronoUtilities {
{
class DateTime; class DateTime;
@ -19,15 +18,14 @@ class DateTime;
* \brief Specifies the output format. * \brief Specifies the output format.
* \sa TimeSpan::toString() * \sa TimeSpan::toString()
*/ */
enum class TimeSpanOutputFormat enum class TimeSpanOutputFormat {
{
Normal, /**< the normal form of specifing a time interval: hh:mm:ss */ Normal, /**< the normal form of specifing a time interval: hh:mm:ss */
WithMeasures /**< measures are used, eg.: 34 d 5 h 10 min 7 s 31 ms */ WithMeasures /**< measures are used, eg.: 34 d 5 h 10 min 7 s 31 ms */
}; };
class CPP_UTILITIES_EXPORT TimeSpan class CPP_UTILITIES_EXPORT TimeSpan {
{
friend class DateTime; friend class DateTime;
public: public:
explicit constexpr TimeSpan(); explicit constexpr TimeSpan();
explicit constexpr TimeSpan(int64 ticks); explicit constexpr TimeSpan(int64 ticks);
@ -86,14 +84,18 @@ private:
/*! /*!
* \brief Constructs a new instance of the TimeSpan class with zero ticks. * \brief Constructs a new instance of the TimeSpan class with zero ticks.
*/ */
constexpr inline TimeSpan::TimeSpan() : m_ticks(0) constexpr inline TimeSpan::TimeSpan()
{} : m_ticks(0)
{
}
/*! /*!
* \brief Constructs a new instance of the TimeSpan class with the specified number of ticks. * \brief Constructs a new instance of the TimeSpan class with the specified number of ticks.
*/ */
constexpr inline TimeSpan::TimeSpan(int64 ticks) : m_ticks(ticks) constexpr inline TimeSpan::TimeSpan(int64 ticks)
{} : m_ticks(ticks)
{
}
/*! /*!
* \brief Constructs a new instance of the TimeSpan class with the specified number of miliseconds. * \brief Constructs a new instance of the TimeSpan class with the specified number of miliseconds.
@ -250,7 +252,7 @@ constexpr inline int TimeSpan::days() const
/*! /*!
* \brief Indicates whether two TimeSpan instances are equal. * \brief Indicates whether two TimeSpan instances are equal.
*/ */
constexpr inline bool TimeSpan::operator ==(const TimeSpan &other) const constexpr inline bool TimeSpan::operator==(const TimeSpan &other) const
{ {
return m_ticks == other.m_ticks; return m_ticks == other.m_ticks;
} }
@ -258,7 +260,7 @@ constexpr inline bool TimeSpan::operator ==(const TimeSpan &other) const
/*! /*!
* \brief Indicates whether two TimeSpan instances are not equal. * \brief Indicates whether two TimeSpan instances are not equal.
*/ */
constexpr inline bool TimeSpan::operator !=(const TimeSpan &other) const constexpr inline bool TimeSpan::operator!=(const TimeSpan &other) const
{ {
return m_ticks != other.m_ticks; return m_ticks != other.m_ticks;
} }
@ -266,7 +268,7 @@ constexpr inline bool TimeSpan::operator !=(const TimeSpan &other) const
/*! /*!
* \brief Indicates whether a specified TimeSpan is less than another specified TimeSpan. * \brief Indicates whether a specified TimeSpan is less than another specified TimeSpan.
*/ */
constexpr inline bool TimeSpan::operator <(const TimeSpan &other) const constexpr inline bool TimeSpan::operator<(const TimeSpan &other) const
{ {
return m_ticks < other.m_ticks; return m_ticks < other.m_ticks;
} }
@ -274,7 +276,7 @@ constexpr inline bool TimeSpan::operator <(const TimeSpan &other) const
/*! /*!
* \brief Indicates whether a specified TimeSpan is greater than another specified TimeSpan. * \brief Indicates whether a specified TimeSpan is greater than another specified TimeSpan.
*/ */
constexpr inline bool TimeSpan::operator >(const TimeSpan &other) const constexpr inline bool TimeSpan::operator>(const TimeSpan &other) const
{ {
return m_ticks > other.m_ticks; return m_ticks > other.m_ticks;
} }
@ -282,7 +284,7 @@ constexpr inline bool TimeSpan::operator >(const TimeSpan &other) const
/*! /*!
* \brief Indicates whether a specified TimeSpan is less or equal than another specified TimeSpan. * \brief Indicates whether a specified TimeSpan is less or equal than another specified TimeSpan.
*/ */
constexpr inline bool TimeSpan::operator <=(const TimeSpan &other) const constexpr inline bool TimeSpan::operator<=(const TimeSpan &other) const
{ {
return m_ticks <= other.m_ticks; return m_ticks <= other.m_ticks;
} }
@ -290,7 +292,7 @@ constexpr inline bool TimeSpan::operator <=(const TimeSpan &other) const
/*! /*!
* \brief Indicates whether a specified TimeSpan is greater or equal than another specified TimeSpan. * \brief Indicates whether a specified TimeSpan is greater or equal than another specified TimeSpan.
*/ */
constexpr inline bool TimeSpan::operator >=(const TimeSpan &other) const constexpr inline bool TimeSpan::operator>=(const TimeSpan &other) const
{ {
return m_ticks >= other.m_ticks; return m_ticks >= other.m_ticks;
} }
@ -298,7 +300,7 @@ constexpr inline bool TimeSpan::operator >=(const TimeSpan &other) const
/*! /*!
* \brief Adds two TimeSpan instances. * \brief Adds two TimeSpan instances.
*/ */
constexpr inline TimeSpan TimeSpan::operator +(const TimeSpan &other) const constexpr inline TimeSpan TimeSpan::operator+(const TimeSpan &other) const
{ {
return TimeSpan(m_ticks + other.m_ticks); return TimeSpan(m_ticks + other.m_ticks);
} }
@ -306,7 +308,7 @@ constexpr inline TimeSpan TimeSpan::operator +(const TimeSpan &other) const
/*! /*!
* \brief Substracts two TimeSpan instances. * \brief Substracts two TimeSpan instances.
*/ */
constexpr inline TimeSpan TimeSpan::operator -(const TimeSpan &other) const constexpr inline TimeSpan TimeSpan::operator-(const TimeSpan &other) const
{ {
return TimeSpan(m_ticks - other.m_ticks); return TimeSpan(m_ticks - other.m_ticks);
} }
@ -314,7 +316,7 @@ constexpr inline TimeSpan TimeSpan::operator -(const TimeSpan &other) const
/*! /*!
* \brief Adds another TimeSpan to the current instance. * \brief Adds another TimeSpan to the current instance.
*/ */
inline TimeSpan &TimeSpan::operator +=(const TimeSpan &other) inline TimeSpan &TimeSpan::operator+=(const TimeSpan &other)
{ {
m_ticks += other.m_ticks; m_ticks += other.m_ticks;
return *this; return *this;
@ -323,7 +325,7 @@ inline TimeSpan &TimeSpan::operator +=(const TimeSpan &other)
/*! /*!
* \brief Substracts another TimeSpan from the current instance. * \brief Substracts another TimeSpan from the current instance.
*/ */
inline TimeSpan &TimeSpan::operator -=(const TimeSpan &other) inline TimeSpan &TimeSpan::operator-=(const TimeSpan &other)
{ {
m_ticks -= other.m_ticks; m_ticks -= other.m_ticks;
return *this; return *this;
@ -360,15 +362,13 @@ constexpr inline bool TimeSpan::isInfinity() const
{ {
return m_ticks == std::numeric_limits<decltype(m_ticks)>::max(); return m_ticks == std::numeric_limits<decltype(m_ticks)>::max();
} }
} }
namespace std { namespace std {
template<> struct hash<ChronoUtilities::TimeSpan> template <> struct hash<ChronoUtilities::TimeSpan> {
{
inline size_t operator()(const ChronoUtilities::TimeSpan &timeSpan) const inline size_t operator()(const ChronoUtilities::TimeSpan &timeSpan) const
{ {
return hash<decltype (timeSpan.totalTicks())>()(timeSpan.totalTicks()); return hash<decltype(timeSpan.totalTicks())>()(timeSpan.totalTicks());
} }
}; };
} }

View File

@ -6,63 +6,63 @@
#include "../global.h" #include "../global.h"
#ifdef __BYTE_ORDER__ #ifdef __BYTE_ORDER__
# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false #define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN true #define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN true
# define CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN #define CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN
# elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ #elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false #define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false #define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
# define CONVERSION_UTILITIES_BYTE_ORDER_MIDDLE_ENDIAN #define CONVERSION_UTILITIES_BYTE_ORDER_MIDDLE_ENDIAN
# elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN true #define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN true
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false #define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
# define CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN #define CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN
# endif #endif
#endif #endif
#ifdef __FLOAT_WORD_ORDER__ #ifdef __FLOAT_WORD_ORDER__
# if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_BIG_ENDIAN #define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_BIG_ENDIAN
# elif __FLOAT_WORD_ORDER__ == __ORDER_PDP_ENDIAN__ #elif __FLOAT_WORD_ORDER__ == __ORDER_PDP_ENDIAN__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_MIDDLE_ENDIAN #define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_MIDDLE_ENDIAN
# elif __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ #elif __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_LITTLE_ENDIAN #define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_LITTLE_ENDIAN
# endif #endif
#endif #endif
#if defined(__BYTE_ORDER__) && defined(__FLOAT_WORD_ORDER__) #if defined(__BYTE_ORDER__) && defined(__FLOAT_WORD_ORDER__)
#else #else
# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) || defined(__LITTLE_ENDIAN__) || defined(_little_endian__) || defined(_LITTLE_ENDIAN) || defined(_WIN32_WCE) || defined(WINAPI_FAMILY) #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) \
# ifndef __BYTE_ORDER__ || defined(__LITTLE_ENDIAN__) || defined(_little_endian__) || defined(_LITTLE_ENDIAN) || defined(_WIN32_WCE) || defined(WINAPI_FAMILY)
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN true #ifndef __BYTE_ORDER__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false #define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN true
# define CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN #define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
# endif #define CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN
# ifndef __FLOAT_WORD_ORDER__ #endif
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_LITTLE_ENDIAN #ifndef __FLOAT_WORD_ORDER__
# endif #define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_LITTLE_ENDIAN
# elif defined(__MIPSEB__) || defined(__s390__) || defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN) #endif
# ifndef __BYTE_ORDER__ #elif defined(__MIPSEB__) || defined(__s390__) || defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN)
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false #ifndef __BYTE_ORDER__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN true #define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
# define CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN #define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN true
# endif #define CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN
# ifndef __FLOAT_WORD_ORDER__ #endif
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_BIG_ENDIAN #ifndef __FLOAT_WORD_ORDER__
# endif #define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_BIG_ENDIAN
# else #endif
# error "Unable to determine byte order!" #else
# endif #error "Unable to determine byte order!"
#endif
#endif #endif
#if defined(CONVERSION_UTILITIES_BYTE_ORDER_MIDDLE_ENDIAN) #if defined(CONVERSION_UTILITIES_BYTE_ORDER_MIDDLE_ENDIAN)
# error "Middle endian byte order is not supported!" #error "Middle endian byte order is not supported!"
#endif #endif
#if defined(CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_MIDDLE_ENDIAN) #if defined(CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_MIDDLE_ENDIAN)
# error "Middle endian byte order is not supported!" #error "Middle endian byte order is not supported!"
#endif #endif
namespace ConversionUtilities namespace ConversionUtilities {
{
/*! /*!
* \brief Encapsulates binary conversion functions using the big endian byte order. * \brief Encapsulates binary conversion functions using the big endian byte order.
@ -71,13 +71,12 @@ namespace ConversionUtilities
namespace BE { namespace BE {
#if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN) #if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 0 #define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 0
#elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN) #elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 1 #define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 1
#endif #endif
#include "./binaryconversionprivate.h" #include "./binaryconversionprivate.h"
#undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL #undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
} }
/*! /*!
@ -87,13 +86,12 @@ namespace BE {
namespace LE { namespace LE {
#if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN) #if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 1 #define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 1
#elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN) #elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 0 #define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 0
#endif #endif
#include "./binaryconversionprivate.h" #include "./binaryconversionprivate.h"
#undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL #undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
} }
/*! /*!
@ -135,10 +133,7 @@ CPP_UTILITIES_EXPORT constexpr float32 toFloat32(uint32 fixed16value)
*/ */
CPP_UTILITIES_EXPORT constexpr uint32 toSynchsafeInt(uint32 normalInt) CPP_UTILITIES_EXPORT constexpr uint32 toSynchsafeInt(uint32 normalInt)
{ {
return ((normalInt & 0x0000007fu) ) return ((normalInt & 0x0000007fu)) | ((normalInt & 0x00003f80u) << 1) | ((normalInt & 0x001fc000u) << 2) | ((normalInt & 0x0fe00000u) << 3);
| ((normalInt & 0x00003f80u) << 1)
| ((normalInt & 0x001fc000u) << 2)
| ((normalInt & 0x0fe00000u) << 3);
} }
/*! /*!
@ -148,10 +143,8 @@ CPP_UTILITIES_EXPORT constexpr uint32 toSynchsafeInt(uint32 normalInt)
*/ */
CPP_UTILITIES_EXPORT constexpr uint32 toNormalInt(uint32 synchsafeInt) CPP_UTILITIES_EXPORT constexpr uint32 toNormalInt(uint32 synchsafeInt)
{ {
return ((synchsafeInt & 0x0000007fu) ) return ((synchsafeInt & 0x0000007fu)) | ((synchsafeInt & 0x00007f00u) >> 1) | ((synchsafeInt & 0x007f0000u) >> 2)
| ((synchsafeInt & 0x00007f00u) >> 1) | ((synchsafeInt & 0x7f000000u) >> 3);
| ((synchsafeInt & 0x007f0000u) >> 2)
| ((synchsafeInt & 0x7f000000u) >> 3);
} }
/*! /*!
@ -167,10 +160,7 @@ CPP_UTILITIES_EXPORT constexpr uint16 swapOrder(uint16 value)
*/ */
CPP_UTILITIES_EXPORT constexpr uint32 swapOrder(uint32 value) CPP_UTILITIES_EXPORT constexpr uint32 swapOrder(uint32 value)
{ {
return (value >> 24) return (value >> 24) | ((value & 0x00FF0000) >> 8) | ((value & 0x0000FF00) << 8) | (value << 24);
| ((value & 0x00FF0000) >> 8)
| ((value & 0x0000FF00) << 8)
| (value << 24);
} }
/*! /*!
@ -178,16 +168,10 @@ CPP_UTILITIES_EXPORT constexpr uint32 swapOrder(uint32 value)
*/ */
CPP_UTILITIES_EXPORT constexpr uint64 swapOrder(uint64 value) CPP_UTILITIES_EXPORT constexpr uint64 swapOrder(uint64 value)
{ {
return(value >> (7 * 8)) return (value >> (7 * 8)) | ((value & 0x00FF000000000000) >> (5 * 8)) | ((value & 0x0000FF0000000000) >> (3 * 8))
| ((value & 0x00FF000000000000) >> (5 * 8)) | ((value & 0x000000FF00000000) >> (1 * 8)) | ((value & 0x00000000FF000000) << (1 * 8)) | ((value & 0x0000000000FF0000) << (3 * 8))
| ((value & 0x0000FF0000000000) >> (3 * 8)) | ((value & 0x000000000000FF00) << (5 * 8)) | ((value) << (7 * 8));
| ((value & 0x000000FF00000000) >> (1 * 8))
| ((value & 0x00000000FF000000) << (1 * 8))
| ((value & 0x0000000000FF0000) << (3 * 8))
| ((value & 0x000000000000FF00) << (5 * 8))
| ((value) << (7 * 8));
} }
} }
#endif // CONVERSION_UTILITIES_BINARY_CONVERSION_H #endif // CONVERSION_UTILITIES_BINARY_CONVERSION_H

View File

@ -1,5 +1,5 @@
#ifndef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL #ifndef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
# error "Do not include binaryconversionprivate.h directly." #error "Do not include binaryconversionprivate.h directly."
#else #else
#include "./types.h" #include "./types.h"
@ -12,11 +12,9 @@
CPP_UTILITIES_EXPORT inline int16 toInt16(const char *value) CPP_UTILITIES_EXPORT inline int16 toInt16(const char *value)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<int16>(value[0]) << 8 & 0xFF00) return (static_cast<int16>(value[0]) << 8 & 0xFF00) | (static_cast<int16>(value[1]) & 0x00FF);
| (static_cast<int16>(value[1]) & 0x00FF);
#else #else
return (static_cast<int16>(value[1]) << 8 & 0xFF00) return (static_cast<int16>(value[1]) << 8 & 0xFF00) | (static_cast<int16>(value[0]) & 0x00FF);
| (static_cast<int16>(value[0]) & 0x00FF);
#endif #endif
} }
@ -26,11 +24,9 @@ CPP_UTILITIES_EXPORT inline int16 toInt16(const char *value)
CPP_UTILITIES_EXPORT inline uint16 toUInt16(const char *value) CPP_UTILITIES_EXPORT inline uint16 toUInt16(const char *value)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<uint16>(value[0]) << 8 & 0xFF00) return (static_cast<uint16>(value[0]) << 8 & 0xFF00) | (static_cast<uint16>(value[1]) & 0x00FF);
| (static_cast<uint16>(value[1]) & 0x00FF);
#else #else
return (static_cast<uint16>(value[1]) << 8 & 0xFF00) return (static_cast<uint16>(value[1]) << 8 & 0xFF00) | (static_cast<uint16>(value[0]) & 0x00FF);
| (static_cast<uint16>(value[0]) & 0x00FF);
#endif #endif
} }
@ -40,15 +36,11 @@ CPP_UTILITIES_EXPORT inline uint16 toUInt16(const char *value)
CPP_UTILITIES_EXPORT inline int32 toInt32(const char *value) CPP_UTILITIES_EXPORT inline int32 toInt32(const char *value)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<int32>(value[0]) << 24 & 0xFF000000) return (static_cast<int32>(value[0]) << 24 & 0xFF000000) | (static_cast<int32>(value[1]) << 16 & 0x00FF0000)
| (static_cast<int32>(value[1]) << 16 & 0x00FF0000) | (static_cast<int32>(value[2]) << 8 & 0x0000FF00) | (static_cast<int32>(value[3]) & 0x000000FF);
| (static_cast<int32>(value[2]) << 8 & 0x0000FF00)
| (static_cast<int32>(value[3]) & 0x000000FF);
#else #else
return (static_cast<int32>(value[3]) << 24 & 0xFF000000) return (static_cast<int32>(value[3]) << 24 & 0xFF000000) | (static_cast<int32>(value[2]) << 16 & 0x00FF0000)
| (static_cast<int32>(value[2]) << 16 & 0x00FF0000) | (static_cast<int32>(value[1]) << 8 & 0x0000FF00) | (static_cast<int32>(value[0]) & 0x000000FF);
| (static_cast<int32>(value[1]) << 8 & 0x0000FF00)
| (static_cast<int32>(value[0]) & 0x000000FF);
#endif #endif
} }
@ -58,13 +50,11 @@ CPP_UTILITIES_EXPORT inline int32 toInt32(const char *value)
CPP_UTILITIES_EXPORT inline uint32 toUInt24(const char *value) CPP_UTILITIES_EXPORT inline uint32 toUInt24(const char *value)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<uint32>(value[0]) << 16 & 0x00FF0000) return (static_cast<uint32>(value[0]) << 16 & 0x00FF0000) | (static_cast<uint32>(value[1]) << 8 & 0x0000FF00)
| (static_cast<uint32>(value[1]) << 8 & 0x0000FF00) | (static_cast<uint32>(value[2]) & 0x000000FF);
| (static_cast<uint32>(value[2]) & 0x000000FF);
#else #else
return (static_cast<uint32>(value[2]) << 16 & 0x00FF0000) return (static_cast<uint32>(value[2]) << 16 & 0x00FF0000) | (static_cast<uint32>(value[1]) << 8 & 0x0000FF00)
| (static_cast<uint32>(value[1]) << 8 & 0x0000FF00) | (static_cast<uint32>(value[0]) & 0x000000FF);
| (static_cast<uint32>(value[0]) & 0x000000FF);
#endif #endif
} }
@ -74,15 +64,11 @@ CPP_UTILITIES_EXPORT inline uint32 toUInt24(const char *value)
CPP_UTILITIES_EXPORT inline uint32 toUInt32(const char *value) CPP_UTILITIES_EXPORT inline uint32 toUInt32(const char *value)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<uint32>(value[0]) << 24 & 0xFF000000) return (static_cast<uint32>(value[0]) << 24 & 0xFF000000) | (static_cast<uint32>(value[1]) << 16 & 0x00FF0000)
| (static_cast<uint32>(value[1]) << 16 & 0x00FF0000) | (static_cast<uint32>(value[2]) << 8 & 0x0000FF00) | (static_cast<uint32>(value[3]) & 0x000000FF);
| (static_cast<uint32>(value[2]) << 8 & 0x0000FF00)
| (static_cast<uint32>(value[3]) & 0x000000FF);
#else #else
return (static_cast<uint32>(value[3]) << 24 & 0xFF000000) return (static_cast<uint32>(value[3]) << 24 & 0xFF000000) | (static_cast<uint32>(value[2]) << 16 & 0x00FF0000)
| (static_cast<uint32>(value[2]) << 16 & 0x00FF0000) | (static_cast<uint32>(value[1]) << 8 & 0x0000FF00) | (static_cast<uint32>(value[0]) & 0x000000FF);
| (static_cast<uint32>(value[1]) << 8 & 0x0000FF00)
| (static_cast<uint32>(value[0]) & 0x000000FF);
#endif #endif
} }
@ -92,23 +78,15 @@ CPP_UTILITIES_EXPORT inline uint32 toUInt32(const char *value)
CPP_UTILITIES_EXPORT inline int64 toInt64(const char *value) CPP_UTILITIES_EXPORT inline int64 toInt64(const char *value)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<int64>(value[0]) << 56 & 0xFF00000000000000) return (static_cast<int64>(value[0]) << 56 & 0xFF00000000000000) | (static_cast<int64>(value[1]) << 48 & 0x00FF000000000000)
| (static_cast<int64>(value[1]) << 48 & 0x00FF000000000000) | (static_cast<int64>(value[2]) << 40 & 0x0000FF0000000000) | (static_cast<int64>(value[3]) << 32 & 0x000000FF00000000)
| (static_cast<int64>(value[2]) << 40 & 0x0000FF0000000000) | (static_cast<int64>(value[4]) << 24 & 0x00000000FF000000) | (static_cast<int64>(value[5]) << 16 & 0x0000000000FF0000)
| (static_cast<int64>(value[3]) << 32 & 0x000000FF00000000) | (static_cast<int64>(value[6]) << 8 & 0x000000000000FF00) | (static_cast<int64>(value[7]) & 0x00000000000000FF);
| (static_cast<int64>(value[4]) << 24 & 0x00000000FF000000)
| (static_cast<int64>(value[5]) << 16 & 0x0000000000FF0000)
| (static_cast<int64>(value[6]) << 8 & 0x000000000000FF00)
| (static_cast<int64>(value[7]) & 0x00000000000000FF);
#else #else
return (static_cast<int64>(value[7]) << 56 & 0xFF00000000000000) return (static_cast<int64>(value[7]) << 56 & 0xFF00000000000000) | (static_cast<int64>(value[6]) << 48 & 0x00FF000000000000)
| (static_cast<int64>(value[6]) << 48 & 0x00FF000000000000) | (static_cast<int64>(value[5]) << 40 & 0x0000FF0000000000) | (static_cast<int64>(value[4]) << 32 & 0x000000FF00000000)
| (static_cast<int64>(value[5]) << 40 & 0x0000FF0000000000) | (static_cast<int64>(value[3]) << 24 & 0x00000000FF000000) | (static_cast<int64>(value[2]) << 16 & 0x0000000000FF0000)
| (static_cast<int64>(value[4]) << 32 & 0x000000FF00000000) | (static_cast<int64>(value[1]) << 8 & 0x000000000000FF00) | (static_cast<int64>(value[0]) & 0x00000000000000FF);
| (static_cast<int64>(value[3]) << 24 & 0x00000000FF000000)
| (static_cast<int64>(value[2]) << 16 & 0x0000000000FF0000)
| (static_cast<int64>(value[1]) << 8 & 0x000000000000FF00)
| (static_cast<int64>(value[0]) & 0x00000000000000FF);
#endif #endif
} }
@ -118,23 +96,15 @@ CPP_UTILITIES_EXPORT inline int64 toInt64(const char *value)
CPP_UTILITIES_EXPORT inline uint64 toUInt64(const char *value) CPP_UTILITIES_EXPORT inline uint64 toUInt64(const char *value)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<uint64>(value[0]) << 56 & 0xFF00000000000000) return (static_cast<uint64>(value[0]) << 56 & 0xFF00000000000000) | (static_cast<uint64>(value[1]) << 48 & 0x00FF000000000000)
| (static_cast<uint64>(value[1]) << 48 & 0x00FF000000000000) | (static_cast<uint64>(value[2]) << 40 & 0x0000FF0000000000) | (static_cast<uint64>(value[3]) << 32 & 0x000000FF00000000)
| (static_cast<uint64>(value[2]) << 40 & 0x0000FF0000000000) | (static_cast<uint64>(value[4]) << 24 & 0x00000000FF000000) | (static_cast<uint64>(value[5]) << 16 & 0x0000000000FF0000)
| (static_cast<uint64>(value[3]) << 32 & 0x000000FF00000000) | (static_cast<uint64>(value[6]) << 8 & 0x000000000000FF00) | (static_cast<uint64>(value[7]) & 0x00000000000000FF);
| (static_cast<uint64>(value[4]) << 24 & 0x00000000FF000000)
| (static_cast<uint64>(value[5]) << 16 & 0x0000000000FF0000)
| (static_cast<uint64>(value[6]) << 8 & 0x000000000000FF00)
| (static_cast<uint64>(value[7]) & 0x00000000000000FF);
#else #else
return (static_cast<uint64>(value[7]) << 56 & 0xFF00000000000000) return (static_cast<uint64>(value[7]) << 56 & 0xFF00000000000000) | (static_cast<uint64>(value[6]) << 48 & 0x00FF000000000000)
| (static_cast<uint64>(value[6]) << 48 & 0x00FF000000000000) | (static_cast<uint64>(value[5]) << 40 & 0x0000FF0000000000) | (static_cast<uint64>(value[4]) << 32 & 0x000000FF00000000)
| (static_cast<uint64>(value[5]) << 40 & 0x0000FF0000000000) | (static_cast<uint64>(value[3]) << 24 & 0x00000000FF000000) | (static_cast<uint64>(value[2]) << 16 & 0x0000000000FF0000)
| (static_cast<uint64>(value[4]) << 32 & 0x000000FF00000000) | (static_cast<uint64>(value[1]) << 8 & 0x000000000000FF00) | (static_cast<uint64>(value[0]) & 0x00000000000000FF);
| (static_cast<uint64>(value[3]) << 24 & 0x00000000FF000000)
| (static_cast<uint64>(value[2]) << 16 & 0x0000000000FF0000)
| (static_cast<uint64>(value[1]) << 8 & 0x000000000000FF00)
| (static_cast<uint64>(value[0]) & 0x00000000000000FF);
#endif #endif
} }
@ -162,7 +132,7 @@ CPP_UTILITIES_EXPORT inline float64 toFloat64(const char *value)
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
int64 val = toInt64(value); int64 val = toInt64(value);
char *c = reinterpret_cast<char *>(&val); char *c = reinterpret_cast<char *>(&val);
return *reinterpret_cast<float64*>(c); return *reinterpret_cast<float64 *>(c);
#else #else
int64 val = toInt64(value); int64 val = toInt64(value);
char *c = reinterpret_cast<char *>(&val); char *c = reinterpret_cast<char *>(&val);
@ -177,10 +147,10 @@ CPP_UTILITIES_EXPORT inline void getBytes(int16 value, char *outputbuffer)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[0] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[1] = static_cast<char>((value ) & 0xFF); outputbuffer[1] = static_cast<char>((value)&0xFF);
#else #else
outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[0] = static_cast<char>((value ) & 0xFF); outputbuffer[0] = static_cast<char>((value)&0xFF);
#endif #endif
} }
@ -191,10 +161,10 @@ CPP_UTILITIES_EXPORT inline void getBytes(uint16 value, char *outputbuffer)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[0] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[1] = static_cast<char>((value ) & 0xFF); outputbuffer[1] = static_cast<char>((value)&0xFF);
#else #else
outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[0] = static_cast<char>((value ) & 0xFF); outputbuffer[0] = static_cast<char>((value)&0xFF);
#endif #endif
} }
@ -206,12 +176,12 @@ CPP_UTILITIES_EXPORT inline void getBytes24(uint32 value, char *outputbuffer)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 16) & 0xFF); outputbuffer[0] = static_cast<char>((value >> 16) & 0xFF);
outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[2] = static_cast<char>((value ) & 0xFF); outputbuffer[2] = static_cast<char>((value)&0xFF);
#else #else
outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF); outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF);
outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[0] = static_cast<char>((value ) & 0xFF); outputbuffer[0] = static_cast<char>((value)&0xFF);
#endif #endif
} }
@ -223,13 +193,13 @@ CPP_UTILITIES_EXPORT inline void getBytes(int32 value, char *outputbuffer)
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 24) & 0xFF); outputbuffer[0] = static_cast<char>((value >> 24) & 0xFF);
outputbuffer[1] = static_cast<char>((value >> 16) & 0xFF); outputbuffer[1] = static_cast<char>((value >> 16) & 0xFF);
outputbuffer[2] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[2] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[3] = static_cast<char>((value ) & 0xFF); outputbuffer[3] = static_cast<char>((value)&0xFF);
#else #else
outputbuffer[3] = static_cast<char>((value >> 24) & 0xFF); outputbuffer[3] = static_cast<char>((value >> 24) & 0xFF);
outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF); outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF);
outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[0] = static_cast<char>((value ) & 0xFF); outputbuffer[0] = static_cast<char>((value)&0xFF);
#endif #endif
} }
@ -241,13 +211,13 @@ CPP_UTILITIES_EXPORT inline void getBytes(uint32 value, char *outputbuffer)
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 24) & 0xFF); outputbuffer[0] = static_cast<char>((value >> 24) & 0xFF);
outputbuffer[1] = static_cast<char>((value >> 16) & 0xFF); outputbuffer[1] = static_cast<char>((value >> 16) & 0xFF);
outputbuffer[2] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[2] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[3] = static_cast<char>((value ) & 0xFF); outputbuffer[3] = static_cast<char>((value)&0xFF);
#else #else
outputbuffer[3] = static_cast<char>((value >> 24) & 0xFF); outputbuffer[3] = static_cast<char>((value >> 24) & 0xFF);
outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF); outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF);
outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[0] = static_cast<char>((value ) & 0xFF); outputbuffer[0] = static_cast<char>((value)&0xFF);
#endif #endif
} }
@ -263,8 +233,8 @@ CPP_UTILITIES_EXPORT inline void getBytes(int64 value, char *outputbuffer)
outputbuffer[3] = static_cast<char>((value >> 32) & 0xFF); outputbuffer[3] = static_cast<char>((value >> 32) & 0xFF);
outputbuffer[4] = static_cast<char>((value >> 24) & 0xFF); outputbuffer[4] = static_cast<char>((value >> 24) & 0xFF);
outputbuffer[5] = static_cast<char>((value >> 16) & 0xFF); outputbuffer[5] = static_cast<char>((value >> 16) & 0xFF);
outputbuffer[6] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[6] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[7] = static_cast<char>((value ) & 0xFF); outputbuffer[7] = static_cast<char>((value)&0xFF);
#else #else
outputbuffer[7] = static_cast<char>((value >> 56) & 0xFF); outputbuffer[7] = static_cast<char>((value >> 56) & 0xFF);
outputbuffer[6] = static_cast<char>((value >> 48) & 0xFF); outputbuffer[6] = static_cast<char>((value >> 48) & 0xFF);
@ -272,8 +242,8 @@ CPP_UTILITIES_EXPORT inline void getBytes(int64 value, char *outputbuffer)
outputbuffer[4] = static_cast<char>((value >> 32) & 0xFF); outputbuffer[4] = static_cast<char>((value >> 32) & 0xFF);
outputbuffer[3] = static_cast<char>((value >> 24) & 0xFF); outputbuffer[3] = static_cast<char>((value >> 24) & 0xFF);
outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF); outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF);
outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[0] = static_cast<char>((value ) & 0xFF); outputbuffer[0] = static_cast<char>((value)&0xFF);
#endif #endif
} }
@ -289,8 +259,8 @@ CPP_UTILITIES_EXPORT inline void getBytes(uint64 value, char *outputbuffer)
outputbuffer[3] = static_cast<char>((value >> 32) & 0xFF); outputbuffer[3] = static_cast<char>((value >> 32) & 0xFF);
outputbuffer[4] = static_cast<char>((value >> 24) & 0xFF); outputbuffer[4] = static_cast<char>((value >> 24) & 0xFF);
outputbuffer[5] = static_cast<char>((value >> 16) & 0xFF); outputbuffer[5] = static_cast<char>((value >> 16) & 0xFF);
outputbuffer[6] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[6] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[7] = static_cast<char>((value ) & 0xFF); outputbuffer[7] = static_cast<char>((value)&0xFF);
#else #else
outputbuffer[7] = static_cast<char>((value >> 56) & 0xFF); outputbuffer[7] = static_cast<char>((value >> 56) & 0xFF);
outputbuffer[6] = static_cast<char>((value >> 48) & 0xFF); outputbuffer[6] = static_cast<char>((value >> 48) & 0xFF);
@ -298,8 +268,8 @@ CPP_UTILITIES_EXPORT inline void getBytes(uint64 value, char *outputbuffer)
outputbuffer[4] = static_cast<char>((value >> 32) & 0xFF); outputbuffer[4] = static_cast<char>((value >> 32) & 0xFF);
outputbuffer[3] = static_cast<char>((value >> 24) & 0xFF); outputbuffer[3] = static_cast<char>((value >> 24) & 0xFF);
outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF); outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF);
outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF); outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF);
outputbuffer[0] = static_cast<char>((value ) & 0xFF); outputbuffer[0] = static_cast<char>((value)&0xFF);
#endif #endif
} }

View File

@ -11,22 +11,22 @@ namespace ConversionUtilities {
/*! /*!
* \brief Constructs a new ConversionException. * \brief Constructs a new ConversionException.
*/ */
ConversionException::ConversionException() USE_NOTHROW : ConversionException::ConversionException() USE_NOTHROW : runtime_error("unable to convert")
runtime_error("unable to convert") {
{} }
/*! /*!
* \brief Constructs a new ConversionException. \a what is a std::string * \brief Constructs a new ConversionException. \a what is a std::string
* describing the cause of the ConversionException. * describing the cause of the ConversionException.
*/ */
ConversionException::ConversionException(const std::string &what) USE_NOTHROW : ConversionException::ConversionException(const std::string &what) USE_NOTHROW : runtime_error(what)
runtime_error(what) {
{} }
/*! /*!
* \brief Destroys the ConversionException. * \brief Destroys the ConversionException.
*/ */
ConversionException::~ConversionException() USE_NOTHROW ConversionException::~ConversionException() USE_NOTHROW
{} {
}
} }

View File

@ -8,14 +8,12 @@
namespace ConversionUtilities { namespace ConversionUtilities {
class CPP_UTILITIES_EXPORT ConversionException : public std::runtime_error class CPP_UTILITIES_EXPORT ConversionException : public std::runtime_error {
{
public: public:
ConversionException() USE_NOTHROW; ConversionException() USE_NOTHROW;
ConversionException(const std::string &what) USE_NOTHROW; ConversionException(const std::string &what) USE_NOTHROW;
~ConversionException() USE_NOTHROW; ~ConversionException() USE_NOTHROW;
}; };
} }
#endif // CONVERSION_UTILITIES_CONVERSIONEXCEPTION_H #endif // CONVERSION_UTILITIES_CONVERSIONEXCEPTION_H

View File

@ -1,96 +1,97 @@
#ifndef CONVERSION_UTILITIES_STRINGBUILDER_H #ifndef CONVERSION_UTILITIES_STRINGBUILDER_H
#define CONVERSION_UTILITIES_STRINGBUILDER_H #define CONVERSION_UTILITIES_STRINGBUILDER_H
#include "./stringconversion.h"
#include "../misc/traits.h" #include "../misc/traits.h"
#include "./stringconversion.h"
#include <string> #include <string>
#include <tuple> #include <tuple>
namespace ConversionUtilities namespace ConversionUtilities {
{
/// \cond /// \cond
namespace Helper { namespace Helper {
template<class StringType, Traits::EnableIf<std::is_class<StringType> >...> template <class StringType, Traits::EnableIf<std::is_class<StringType> >...> std::size_t computeTupleElementSize(const StringType *str)
std::size_t computeTupleElementSize(const StringType *str)
{ {
return str->size(); return str->size();
} }
template<class StringType, Traits::EnableIf<std::is_class<StringType> >...> template <class StringType, Traits::EnableIf<std::is_class<StringType> >...> std::size_t computeTupleElementSize(const StringType &str)
std::size_t computeTupleElementSize(const StringType &str)
{ {
return str.size(); return str.size();
} }
template<class StringType, class CharType, Traits::EnableIf<std::is_same<typename StringType::value_type, CharType> >...> template <class StringType, class CharType, Traits::EnableIf<std::is_same<typename StringType::value_type, CharType> >...>
std::size_t computeTupleElementSize(const CharType *str) std::size_t computeTupleElementSize(const CharType *str)
{ {
return std::char_traits<CharType>::length(str); return std::char_traits<CharType>::length(str);
} }
template<class StringType, class CharType, Traits::EnableIf<std::is_same<typename StringType::value_type, CharType> >...> template <class StringType, class CharType, Traits::EnableIf<std::is_same<typename StringType::value_type, CharType> >...>
constexpr std::size_t computeTupleElementSize(CharType) constexpr std::size_t computeTupleElementSize(CharType)
{ {
return 1; return 1;
} }
template <class StringType, typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<typename StringType::value_type, IntegralType> >, std::is_integral<IntegralType>, std::is_unsigned<IntegralType> >...> template <class StringType, typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<typename StringType::value_type, IntegralType> >,
std::is_integral<IntegralType>, std::is_unsigned<IntegralType> >...>
std::size_t computeTupleElementSize(IntegralType number, typename StringType::value_type base = 10) std::size_t computeTupleElementSize(IntegralType number, typename StringType::value_type base = 10)
{ {
std::size_t size = 0; std::size_t size = 0;
for(auto n = number; n; n /= base, ++size); for (auto n = number; n; n /= base, ++size)
;
return size; return size;
} }
template <class StringType, typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<typename StringType::value_type, IntegralType> >, std::is_integral<IntegralType>, std::is_signed<IntegralType> >...> template <class StringType, typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<typename StringType::value_type, IntegralType> >,
std::is_integral<IntegralType>, std::is_signed<IntegralType> >...>
std::size_t computeTupleElementSize(IntegralType number, typename StringType::value_type base = 10) std::size_t computeTupleElementSize(IntegralType number, typename StringType::value_type base = 10)
{ {
std::size_t size = number < 0 ? 1 : 0; std::size_t size = number < 0 ? 1 : 0;
for(auto n = number; n; n /= base, ++size); for (auto n = number; n; n /= base, ++size)
;
return size; return size;
} }
template<class StringType, Traits::EnableIf<std::is_class<StringType> >...> template <class StringType, Traits::EnableIf<std::is_class<StringType> >...> void append(StringType &target, const StringType *str)
void append(StringType &target, const StringType *str)
{ {
target.append(*str); target.append(*str);
} }
template<class StringType, Traits::EnableIf<std::is_class<StringType> >...> template <class StringType, Traits::EnableIf<std::is_class<StringType> >...> void append(StringType &target, const StringType &str)
void append(StringType &target, const StringType &str)
{ {
target.append(str); target.append(str);
} }
template<class StringType, class CharType, Traits::EnableIf<std::is_same<typename StringType::value_type, CharType> >...> template <class StringType, class CharType, Traits::EnableIf<std::is_same<typename StringType::value_type, CharType> >...>
void append(StringType &target, const CharType *str) void append(StringType &target, const CharType *str)
{ {
target.append(str); target.append(str);
} }
template<class StringType, class CharType, Traits::EnableIf<std::is_same<typename StringType::value_type, CharType> >...> template <class StringType, class CharType, Traits::EnableIf<std::is_same<typename StringType::value_type, CharType> >...>
void append(StringType &target, CharType c) void append(StringType &target, CharType c)
{ {
target += c; target += c;
} }
template <class StringType, typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<typename StringType::value_type, IntegralType> >, std::is_integral<IntegralType>, std::is_unsigned<IntegralType> >...> template <class StringType, typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<typename StringType::value_type, IntegralType> >,
std::is_integral<IntegralType>, std::is_unsigned<IntegralType> >...>
void append(StringType &target, IntegralType number, typename StringType::value_type base = 10) void append(StringType &target, IntegralType number, typename StringType::value_type base = 10)
{ {
const auto start = target.begin() + target.size(); const auto start = target.begin() + target.size();
do { do {
target.insert(start, digitToChar<typename StringType::value_type>(number % base)); target.insert(start, digitToChar<typename StringType::value_type>(number % base));
number /= base; number /= base;
} while(number); } while (number);
} }
template <class StringType, typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<typename StringType::value_type, IntegralType> >, std::is_integral<IntegralType>, std::is_signed<IntegralType> >...> template <class StringType, typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<typename StringType::value_type, IntegralType> >,
std::is_integral<IntegralType>, std::is_signed<IntegralType> >...>
void append(StringType &target, IntegralType number, typename StringType::value_type base = 10) void append(StringType &target, IntegralType number, typename StringType::value_type base = 10)
{ {
if(number < 0) { if (number < 0) {
target += '-'; target += '-';
number = -number; number = -number;
} }
@ -98,25 +99,23 @@ void append(StringType &target, IntegralType number, typename StringType::value_
do { do {
target.insert(start, digitToChar<typename StringType::value_type>(number % base)); target.insert(start, digitToChar<typename StringType::value_type>(number % base));
number /= base; number /= base;
} while(number); } while (number);
} }
template<class StringType, class Tuple, std::size_t N> template <class StringType, class Tuple, std::size_t N> struct TupleToString {
struct TupleToString {
static std::size_t precomputeSize(const Tuple &tuple) static std::size_t precomputeSize(const Tuple &tuple)
{ {
return TupleToString<StringType, Tuple, N-1>::precomputeSize(tuple) + computeTupleElementSize<StringType>(std::get<N-1>(tuple)); return TupleToString<StringType, Tuple, N - 1>::precomputeSize(tuple) + computeTupleElementSize<StringType>(std::get<N - 1>(tuple));
} }
static void append(const Tuple &tuple, StringType &str) static void append(const Tuple &tuple, StringType &str)
{ {
TupleToString<StringType, Tuple, N-1>::append(tuple, str); TupleToString<StringType, Tuple, N - 1>::append(tuple, str);
Helper::append(str, std::get<N-1>(tuple)); Helper::append(str, std::get<N - 1>(tuple));
} }
}; };
template<class StringType, class Tuple> template <class StringType, class Tuple> struct TupleToString<StringType, Tuple, 1> {
struct TupleToString<StringType, Tuple, 1> {
static std::size_t precomputeSize(const Tuple &tuple) static std::size_t precomputeSize(const Tuple &tuple)
{ {
return computeTupleElementSize<StringType>(std::get<0>(tuple)); return computeTupleElementSize<StringType>(std::get<0>(tuple));
@ -127,15 +126,13 @@ struct TupleToString<StringType, Tuple, 1> {
Helper::append(str, std::get<0>(tuple)); Helper::append(str, std::get<0>(tuple));
} }
}; };
} }
/// \endcond /// \endcond
/*! /*!
* \brief Concatenates all strings hold by the specified \a tuple. * \brief Concatenates all strings hold by the specified \a tuple.
*/ */
template<class StringType = std::string, class... Args> template <class StringType = std::string, class... Args> StringType tupleToString(const std::tuple<Args...> &tuple)
StringType tupleToString(const std::tuple<Args...> &tuple)
{ {
StringType res; StringType res;
res.reserve(Helper::TupleToString<StringType, decltype(tuple), sizeof...(Args)>::precomputeSize(tuple)); res.reserve(Helper::TupleToString<StringType, decltype(tuple), sizeof...(Args)>::precomputeSize(tuple));
@ -143,8 +140,7 @@ StringType tupleToString(const std::tuple<Args...> &tuple)
return res; return res;
} }
template<class StringType = std::string, class... Args> template <class StringType = std::string, class... Args> constexpr StringType argsToString(Args &&... args)
constexpr StringType argsToString(Args&&... args)
{ {
return tupleToString(std::make_tuple(args...)); return tupleToString(std::make_tuple(args...));
} }
@ -152,8 +148,7 @@ constexpr StringType argsToString(Args&&... args)
/*! /*!
* \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3. * \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3.
*/ */
template<class Tuple> template <class Tuple> constexpr auto operator%(const Tuple &lhs, const std::string &rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(&rhs)))
constexpr auto operator %(const Tuple &lhs, const std::string &rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(&rhs)))
{ {
return std::tuple_cat(lhs, std::make_tuple(&rhs)); return std::tuple_cat(lhs, std::make_tuple(&rhs));
} }
@ -161,8 +156,7 @@ constexpr auto operator %(const Tuple &lhs, const std::string &rhs) -> decltype(
/*! /*!
* \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3. * \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3.
*/ */
template<class Tuple> template <class Tuple> constexpr auto operator%(const Tuple &lhs, const char *rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
constexpr auto operator %(const Tuple &lhs, const char *rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
{ {
return std::tuple_cat(lhs, std::make_tuple(rhs)); return std::tuple_cat(lhs, std::make_tuple(rhs));
} }
@ -170,8 +164,8 @@ constexpr auto operator %(const Tuple &lhs, const char *rhs) -> decltype(std::tu
/*! /*!
* \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3. * \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3.
*/ */
template<class Tuple, typename IntegralType, Traits::EnableIf<std::is_integral<IntegralType> >...> template <class Tuple, typename IntegralType, Traits::EnableIf<std::is_integral<IntegralType> >...>
constexpr auto operator %(const Tuple &lhs, IntegralType rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(rhs))) constexpr auto operator%(const Tuple &lhs, IntegralType rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
{ {
return std::tuple_cat(lhs, std::make_tuple(rhs)); return std::tuple_cat(lhs, std::make_tuple(rhs));
} }
@ -179,7 +173,7 @@ constexpr auto operator %(const Tuple &lhs, IntegralType rhs) -> decltype(std::t
/*! /*!
* \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3. * \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3.
*/ */
constexpr auto operator %(const std::string &lhs, const std::string &rhs) -> decltype(std::make_tuple(&lhs, &rhs)) constexpr auto operator%(const std::string &lhs, const std::string &rhs) -> decltype(std::make_tuple(&lhs, &rhs))
{ {
return std::make_tuple(&lhs, &rhs); return std::make_tuple(&lhs, &rhs);
} }
@ -187,7 +181,7 @@ constexpr auto operator %(const std::string &lhs, const std::string &rhs) -> dec
/*! /*!
* \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3. * \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3.
*/ */
constexpr auto operator %(const char *lhs, const std::string &rhs) -> decltype(std::make_tuple(lhs, &rhs)) constexpr auto operator%(const char *lhs, const std::string &rhs) -> decltype(std::make_tuple(lhs, &rhs))
{ {
return std::make_tuple(lhs, &rhs); return std::make_tuple(lhs, &rhs);
} }
@ -195,7 +189,7 @@ constexpr auto operator %(const char *lhs, const std::string &rhs) -> decltype(s
/*! /*!
* \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3. * \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3.
*/ */
constexpr auto operator %(const std::string &lhs, const char *rhs) -> decltype(std::make_tuple(&lhs, rhs)) constexpr auto operator%(const std::string &lhs, const char *rhs) -> decltype(std::make_tuple(&lhs, rhs))
{ {
return std::make_tuple(&lhs, rhs); return std::make_tuple(&lhs, rhs);
} }
@ -203,7 +197,7 @@ constexpr auto operator %(const std::string &lhs, const char *rhs) -> decltype(s
/*! /*!
* \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3. * \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3.
*/ */
constexpr auto operator %(const std::string &lhs, char rhs) -> decltype(std::make_tuple(&lhs, rhs)) constexpr auto operator%(const std::string &lhs, char rhs) -> decltype(std::make_tuple(&lhs, rhs))
{ {
return std::make_tuple(&lhs, rhs); return std::make_tuple(&lhs, rhs);
} }
@ -211,7 +205,7 @@ constexpr auto operator %(const std::string &lhs, char rhs) -> decltype(std::mak
/*! /*!
* \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3. * \brief Allows construction of string-tuples via %-operator, eg. string1 % "string2" % string3.
*/ */
constexpr auto operator %(char lhs, const std::string &rhs) -> decltype(std::make_tuple(lhs, &rhs)) constexpr auto operator%(char lhs, const std::string &rhs) -> decltype(std::make_tuple(lhs, &rhs))
{ {
return std::make_tuple(lhs, &rhs); return std::make_tuple(lhs, &rhs);
} }
@ -225,8 +219,8 @@ constexpr auto operator %(char lhs, const std::string &rhs) -> decltype(std::mak
* printVelocity("velocity: " % numberToString(velocityExample) % " km/h (" % numberToString(velocityExample / 3.6) + " m/s)")); * printVelocity("velocity: " % numberToString(velocityExample) % " km/h (" % numberToString(velocityExample / 3.6) + " m/s)"));
* ``` * ```
*/ */
template<class Tuple, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple> >...> template <class Tuple, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple> >...>
inline std::string operator +(const Tuple &lhs, const std::string &rhs) inline std::string operator+(const Tuple &lhs, const std::string &rhs)
{ {
return tupleToString(std::tuple_cat(lhs, std::make_tuple(&rhs))); return tupleToString(std::tuple_cat(lhs, std::make_tuple(&rhs)));
} }
@ -240,8 +234,8 @@ inline std::string operator +(const Tuple &lhs, const std::string &rhs)
* printVelocity("velocity: " % numberToString(velocityExample) % " km/h (" % numberToString(velocityExample / 3.6) + " m/s)")); * printVelocity("velocity: " % numberToString(velocityExample) % " km/h (" % numberToString(velocityExample / 3.6) + " m/s)"));
* ``` * ```
*/ */
template<class Tuple, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple> >...> template <class Tuple, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple> >...>
inline std::string operator +(const Tuple &lhs, const char *rhs) inline std::string operator+(const Tuple &lhs, const char *rhs)
{ {
return tupleToString(std::tuple_cat(lhs, std::make_tuple(rhs))); return tupleToString(std::tuple_cat(lhs, std::make_tuple(rhs)));
} }
@ -255,12 +249,11 @@ inline std::string operator +(const Tuple &lhs, const char *rhs)
* printVelocity("velocity: " % numberToString(velocityExample) % " km/h (" % numberToString(velocityExample / 3.6) + " m/s)")); * printVelocity("velocity: " % numberToString(velocityExample) % " km/h (" % numberToString(velocityExample / 3.6) + " m/s)"));
* ``` * ```
*/ */
template<class Tuple, typename IntegralType, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple>, std::is_integral<IntegralType> >...> template <class Tuple, typename IntegralType, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple>, std::is_integral<IntegralType> >...>
inline std::string operator +(const Tuple &lhs, IntegralType rhs) inline std::string operator+(const Tuple &lhs, IntegralType rhs)
{ {
return tupleToString(std::tuple_cat(lhs, std::make_tuple(rhs))); return tupleToString(std::tuple_cat(lhs, std::make_tuple(rhs)));
} }
} }
#endif // CONVERSION_UTILITIES_STRINGBUILDER_H #endif // CONVERSION_UTILITIES_STRINGBUILDER_H

View File

@ -1,12 +1,12 @@
#include "./stringconversion.h" #include "./stringconversion.h"
#include <cstdlib>
#include <iomanip>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include <iomanip>
#include <cstdlib>
#include <iconv.h>
#include <errno.h> #include <errno.h>
#include <iconv.h>
using namespace std; using namespace std;
@ -17,38 +17,54 @@ using namespace std;
* binaryconversion.h declares functions which convert base data types to an array of bytes and vice versa. * binaryconversion.h declares functions which convert base data types to an array of bytes and vice versa.
* stringconversion.h declares different functions around string conversion such as converting a number to a string and vice versa. * stringconversion.h declares different functions around string conversion such as converting a number to a string and vice versa.
*/ */
namespace ConversionUtilities namespace ConversionUtilities {
{
/// \cond /// \cond
struct Keep { size_t operator()(size_t value) { return value; } }; struct Keep {
struct Double { size_t operator()(size_t value) { return value + value; } }; size_t operator()(size_t value)
struct Half { size_t operator()(size_t value) { return value / 2; } }; {
return value;
}
};
struct Double {
size_t operator()(size_t value)
{
return value + value;
}
};
struct Half {
size_t operator()(size_t value)
{
return value / 2;
}
};
struct Factor { struct Factor {
Factor(float factor) : factor(factor) {}; Factor(float factor)
size_t operator()(size_t value) { return value * factor; } : factor(factor){};
size_t operator()(size_t value)
{
return value * factor;
}
float factor; float factor;
}; };
template<class OutputSizeHint> template <class OutputSizeHint> class ConversionDescriptor {
class ConversionDescriptor
{
public: public:
ConversionDescriptor(const char *fromCharset, const char *toCharset) : ConversionDescriptor(const char *fromCharset, const char *toCharset)
m_ptr(iconv_open(toCharset, fromCharset)), : m_ptr(iconv_open(toCharset, fromCharset))
m_outputSizeHint(OutputSizeHint()) , m_outputSizeHint(OutputSizeHint())
{ {
if(m_ptr == reinterpret_cast<iconv_t>(-1)) { if (m_ptr == reinterpret_cast<iconv_t>(-1)) {
throw ConversionException("Unable to allocate descriptor for character set conversion."); throw ConversionException("Unable to allocate descriptor for character set conversion.");
} }
} }
ConversionDescriptor(const char *fromCharset, const char *toCharset, OutputSizeHint outputSizeHint) : ConversionDescriptor(const char *fromCharset, const char *toCharset, OutputSizeHint outputSizeHint)
m_ptr(iconv_open(toCharset, fromCharset)), : m_ptr(iconv_open(toCharset, fromCharset))
m_outputSizeHint(outputSizeHint) , m_outputSizeHint(outputSizeHint)
{ {
if(m_ptr == reinterpret_cast<iconv_t>(-1)) { if (m_ptr == reinterpret_cast<iconv_t>(-1)) {
throw ConversionException("Unable to allocate descriptor for character set conversion."); throw ConversionException("Unable to allocate descriptor for character set conversion.");
} }
} }
@ -69,14 +85,14 @@ public:
size_t bytesWritten; size_t bytesWritten;
char *currentOutputOffset = outputBuffer; char *currentOutputOffset = outputBuffer;
for(; ; currentOutputOffset = outputBuffer + bytesWritten) { for (;; currentOutputOffset = outputBuffer + bytesWritten) {
bytesWritten = iconv(m_ptr, const_cast<char **>(&inputBuffer), &inputBytesLeft, &currentOutputOffset, &outputBytesLeft); bytesWritten = iconv(m_ptr, const_cast<char **>(&inputBuffer), &inputBytesLeft, &currentOutputOffset, &outputBytesLeft);
if(bytesWritten == static_cast<size_t>(-1)) { if (bytesWritten == static_cast<size_t>(-1)) {
if(errno == EINVAL) { if (errno == EINVAL) {
// ignore incomplete multibyte sequence in the input // ignore incomplete multibyte sequence in the input
bytesWritten = currentOutputOffset - outputBuffer; bytesWritten = currentOutputOffset - outputBuffer;
break; break;
} else if(errno == E2BIG) { } else if (errno == E2BIG) {
// output buffer has no more room for next converted character // output buffer has no more room for next converted character
bytesWritten = currentOutputOffset - outputBuffer; bytesWritten = currentOutputOffset - outputBuffer;
outputBytesLeft = (outputSize += m_outputSizeHint(inputBytesLeft)) - bytesWritten; outputBytesLeft = (outputSize += m_outputSizeHint(inputBytesLeft)) - bytesWritten;
@ -110,7 +126,8 @@ private:
* to reduce buffer reallocations during the conversion (eg. for the conversion from Latin-1 to UTF-16 * to reduce buffer reallocations during the conversion (eg. for the conversion from Latin-1 to UTF-16
* the factor would be 2, for the conversion from UTF-16 to Latin-1 the factor would be 0.5). * the factor would be 2, for the conversion from UTF-16 to Latin-1 the factor would be 0.5).
*/ */
StringData convertString(const char *fromCharset, const char *toCharset, const char *inputBuffer, std::size_t inputBufferSize, float outputBufferSizeFactor) StringData convertString(
const char *fromCharset, const char *toCharset, const char *inputBuffer, std::size_t inputBufferSize, float outputBufferSizeFactor)
{ {
return ConversionDescriptor<Factor>(fromCharset, toCharset, outputBufferSizeFactor).convertString(inputBuffer, inputBufferSize); return ConversionDescriptor<Factor>(fromCharset, toCharset, outputBufferSizeFactor).convertString(inputBuffer, inputBufferSize);
} }
@ -176,7 +193,7 @@ StringData convertUtf8ToLatin1(const char *inputBuffer, std::size_t inputBufferS
void truncateString(string &str, char terminationChar) void truncateString(string &str, char terminationChar)
{ {
string::size_type firstNullByte = str.find(terminationChar); string::size_type firstNullByte = str.find(terminationChar);
if(firstNullByte != string::npos) { if (firstNullByte != string::npos) {
str.resize(firstNullByte); str.resize(firstNullByte);
} }
} }
@ -202,7 +219,7 @@ string dataSizeToString(uint64 sizeInByte, bool includeByte)
} else { } else {
res << (static_cast<double>(sizeInByte) / 1099511627776.0) << " TiB"; res << (static_cast<double>(sizeInByte) / 1099511627776.0) << " TiB";
} }
if(includeByte && sizeInByte > 1024LL) { if (includeByte && sizeInByte > 1024LL) {
res << ' ' << '(' << sizeInByte << " byte)"; res << ' ' << '(' << sizeInByte << " byte)";
} }
return res.str(); return res.str();
@ -260,16 +277,16 @@ string encodeBase64(const byte *data, uint32 dataSize)
byte mod = dataSize % 3; byte mod = dataSize % 3;
encoded.reserve(((dataSize / 3) + (mod > 0)) * 4); encoded.reserve(((dataSize / 3) + (mod > 0)) * 4);
uint32 temp; uint32 temp;
for(const byte *end = --data + dataSize - mod; data != end; ) { for (const byte *end = --data + dataSize - mod; data != end;) {
temp = *++data << 16; temp = *++data << 16;
temp |= *++data << 8; temp |= *++data << 8;
temp |= *++data; temp |= *++data;
encoded.push_back(base64Chars[(temp & 0x00FC0000) >> 18]); encoded.push_back(base64Chars[(temp & 0x00FC0000) >> 18]);
encoded.push_back(base64Chars[(temp & 0x0003F000) >> 12]); encoded.push_back(base64Chars[(temp & 0x0003F000) >> 12]);
encoded.push_back(base64Chars[(temp & 0x00000FC0) >> 6 ]); encoded.push_back(base64Chars[(temp & 0x00000FC0) >> 6]);
encoded.push_back(base64Chars[(temp & 0x0000003F) ]); encoded.push_back(base64Chars[(temp & 0x0000003F)]);
} }
switch(mod) { switch (mod) {
case 1: case 1:
temp = *++data << 16; temp = *++data << 16;
encoded.push_back(base64Chars[(temp & 0x00FC0000) >> 18]); encoded.push_back(base64Chars[(temp & 0x00FC0000) >> 18]);
@ -282,7 +299,7 @@ string encodeBase64(const byte *data, uint32 dataSize)
temp |= *++data << 8; temp |= *++data << 8;
encoded.push_back(base64Chars[(temp & 0x00FC0000) >> 18]); encoded.push_back(base64Chars[(temp & 0x00FC0000) >> 18]);
encoded.push_back(base64Chars[(temp & 0x0003F000) >> 12]); encoded.push_back(base64Chars[(temp & 0x0003F000) >> 12]);
encoded.push_back(base64Chars[(temp & 0x00000FC0) >> 6 ]); encoded.push_back(base64Chars[(temp & 0x00000FC0) >> 6]);
encoded.push_back(base64Pad); encoded.push_back(base64Pad);
break; break;
} }
@ -295,40 +312,40 @@ string encodeBase64(const byte *data, uint32 dataSize)
*/ */
pair<unique_ptr<byte[]>, uint32> decodeBase64(const char *encodedStr, const uint32 strSize) pair<unique_ptr<byte[]>, uint32> decodeBase64(const char *encodedStr, const uint32 strSize)
{ {
if(strSize % 4) { if (strSize % 4) {
throw ConversionException("invalid size of base64"); throw ConversionException("invalid size of base64");
} }
uint32 decodedSize = (strSize / 4) * 3; uint32 decodedSize = (strSize / 4) * 3;
const char *const end = encodedStr + strSize; const char *const end = encodedStr + strSize;
if(strSize) { if (strSize) {
if(*(end - 1) == base64Pad) { if (*(end - 1) == base64Pad) {
--decodedSize; --decodedSize;
} }
if(*(end - 2) == base64Pad) { if (*(end - 2) == base64Pad) {
--decodedSize; --decodedSize;
} }
} }
auto buffer = make_unique<byte[]>(decodedSize); auto buffer = make_unique<byte[]>(decodedSize);
auto *iter = buffer.get() - 1; auto *iter = buffer.get() - 1;
while(encodedStr < end) { while (encodedStr < end) {
uint32 temp = 0; uint32 temp = 0;
for(byte quantumPos = 0; quantumPos < 4; ++quantumPos, ++encodedStr) { for (byte quantumPos = 0; quantumPos < 4; ++quantumPos, ++encodedStr) {
temp <<= 6; temp <<= 6;
if(*encodedStr >= 'A' && *encodedStr <= 'Z') { if (*encodedStr >= 'A' && *encodedStr <= 'Z') {
temp |= *encodedStr - 'A'; temp |= *encodedStr - 'A';
} else if(*encodedStr >= 'a' && *encodedStr <= 'z') { } else if (*encodedStr >= 'a' && *encodedStr <= 'z') {
temp |= *encodedStr - 'a' + 26; temp |= *encodedStr - 'a' + 26;
} else if(*encodedStr >= '0' && *encodedStr <= '9') { } else if (*encodedStr >= '0' && *encodedStr <= '9') {
temp |= *encodedStr - '0' + 2 * 26; temp |= *encodedStr - '0' + 2 * 26;
} else if(*encodedStr == '+') { } else if (*encodedStr == '+') {
temp |= 2 * 26 + 10; temp |= 2 * 26 + 10;
} else if(*encodedStr == '/') { } else if (*encodedStr == '/') {
temp |= 2 * 26 + 10 + 1; temp |= 2 * 26 + 10 + 1;
} else if(*encodedStr == base64Pad) { } else if (*encodedStr == base64Pad) {
switch(end - encodedStr) { switch (end - encodedStr) {
case 1: case 1:
*++iter = (temp >> 16) & 0xFF; *++iter = (temp >> 16) & 0xFF;
*++iter = (temp >> 8) & 0xFF; *++iter = (temp >> 8) & 0xFF;
return make_pair(move(buffer), decodedSize); return make_pair(move(buffer), decodedSize);
case 2: case 2:
*++iter = (temp >> 10) & 0xFF; *++iter = (temp >> 10) & 0xFF;
@ -341,10 +358,9 @@ pair<unique_ptr<byte[]>, uint32> decodeBase64(const char *encodedStr, const uint
} }
} }
*++iter = (temp >> 16) & 0xFF; *++iter = (temp >> 16) & 0xFF;
*++iter = (temp >> 8) & 0xFF; *++iter = (temp >> 8) & 0xFF;
*++iter = (temp ) & 0xFF; *++iter = (temp)&0xFF;
} }
return make_pair(move(buffer), decodedSize); return make_pair(move(buffer), decodedSize);
} }
} }

View File

@ -1,22 +1,21 @@
#ifndef CONVERSION_UTILITIES_STRINGCONVERSION_H #ifndef CONVERSION_UTILITIES_STRINGCONVERSION_H
#define CONVERSION_UTILITIES_STRINGCONVERSION_H #define CONVERSION_UTILITIES_STRINGCONVERSION_H
#include "./conversionexception.h"
#include "./binaryconversion.h" #include "./binaryconversion.h"
#include "./conversionexception.h"
#include "../misc/traits.h" #include "../misc/traits.h"
#include <string>
#include <cstring> #include <cstring>
#include <sstream>
#include <iomanip>
#include <initializer_list> #include <initializer_list>
#include <iomanip>
#include <list> #include <list>
#include <vector>
#include <memory> #include <memory>
#include <sstream>
#include <string>
#include <vector>
namespace ConversionUtilities namespace ConversionUtilities {
{
/*! /*!
* \brief The StringDataDeleter struct deletes the data of a StringData instance. * \brief The StringDataDeleter struct deletes the data of a StringData instance.
@ -28,7 +27,7 @@ struct CPP_UTILITIES_EXPORT StringDataDeleter {
*/ */
void operator()(char *stringData) void operator()(char *stringData)
{ {
std::free(stringData); std::free(stringData);
} }
}; };
@ -38,7 +37,8 @@ struct CPP_UTILITIES_EXPORT StringDataDeleter {
typedef std::pair<std::unique_ptr<char[], StringDataDeleter>, std::size_t> StringData; typedef std::pair<std::unique_ptr<char[], StringDataDeleter>, std::size_t> StringData;
//typedef std::pair<std::unique_ptr<char>, std::size_t> StringData; // might work too //typedef std::pair<std::unique_ptr<char>, std::size_t> StringData; // might work too
CPP_UTILITIES_EXPORT StringData convertString(const char *fromCharset, const char *toCharset, const char *inputBuffer, std::size_t inputBufferSize, float outputBufferSizeFactor = 1.0f); CPP_UTILITIES_EXPORT StringData convertString(
const char *fromCharset, const char *toCharset, const char *inputBuffer, std::size_t inputBufferSize, float outputBufferSizeFactor = 1.0f);
CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16LE(const char *inputBuffer, std::size_t inputBufferSize); CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16LE(const char *inputBuffer, std::size_t inputBufferSize);
CPP_UTILITIES_EXPORT StringData convertUtf16LEToUtf8(const char *inputBuffer, std::size_t inputBufferSize); CPP_UTILITIES_EXPORT StringData convertUtf16LEToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16BE(const char *inputBuffer, std::size_t inputBufferSize); CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16BE(const char *inputBuffer, std::size_t inputBufferSize);
@ -62,23 +62,26 @@ CPP_UTILITIES_EXPORT void truncateString(std::string &str, char terminationChar
* \returns Returns the joined string. * \returns Returns the joined string.
*/ */
template <class Container = std::initializer_list<std::string> > template <class Container = std::initializer_list<std::string> >
typename Container::value_type joinStrings(const Container &strings, const typename Container::value_type &delimiter = typename Container::value_type(), bool omitEmpty = false, const typename Container::value_type &leftClosure = typename Container::value_type(), const typename Container::value_type &rightClosure = typename Container::value_type()) typename Container::value_type joinStrings(const Container &strings,
const typename Container::value_type &delimiter = typename Container::value_type(), bool omitEmpty = false,
const typename Container::value_type &leftClosure = typename Container::value_type(),
const typename Container::value_type &rightClosure = typename Container::value_type())
{ {
typename Container::value_type res; typename Container::value_type res;
if(strings.size()) { if (strings.size()) {
size_t entries = 0, size = 0; size_t entries = 0, size = 0;
for(const auto &str : strings) { for (const auto &str : strings) {
if(!omitEmpty || !str.empty()) { if (!omitEmpty || !str.empty()) {
size += str.size(); size += str.size();
++entries; ++entries;
} }
} }
if(entries) { if (entries) {
size += (entries * leftClosure.size()) + (entries * rightClosure.size()) + ((entries - 1) * delimiter.size()); size += (entries * leftClosure.size()) + (entries * rightClosure.size()) + ((entries - 1) * delimiter.size());
res.reserve(size); res.reserve(size);
for(const auto &str : strings) { for (const auto &str : strings) {
if(!omitEmpty || !str.empty()) { if (!omitEmpty || !str.empty()) {
if(!res.empty()) { if (!res.empty()) {
res.append(delimiter); res.append(delimiter);
} }
res.append(leftClosure); res.append(leftClosure);
@ -94,8 +97,7 @@ typename Container::value_type joinStrings(const Container &strings, const typen
/*! /*!
* \brief Specifies the role of empty parts when splitting strings. * \brief Specifies the role of empty parts when splitting strings.
*/ */
enum class EmptyPartsTreat enum class EmptyPartsTreat {
{
Keep, /**< empty parts are kept */ Keep, /**< empty parts are kept */
Omit, /**< empty parts are omitted */ Omit, /**< empty parts are omitted */
Merge /**< empty parts are omitted but cause the adjacent parts being joined using the delimiter */ Merge /**< empty parts are omitted but cause the adjacent parts being joined using the delimiter */
@ -111,35 +113,36 @@ enum class EmptyPartsTreat
* \returns Returns the parts. * \returns Returns the parts.
*/ */
template <class Container = std::list<std::string> > template <class Container = std::list<std::string> >
Container splitString(const typename Container::value_type &string, const typename Container::value_type &delimiter, EmptyPartsTreat emptyPartsRole = EmptyPartsTreat::Keep, int maxParts = -1) Container splitString(const typename Container::value_type &string, const typename Container::value_type &delimiter,
EmptyPartsTreat emptyPartsRole = EmptyPartsTreat::Keep, int maxParts = -1)
{ {
--maxParts; --maxParts;
Container res; Container res;
bool merge = false; bool merge = false;
for(typename Container::value_type::size_type i = 0, end = string.size(), delimPos; i < end; i = delimPos + delimiter.size()) { for (typename Container::value_type::size_type i = 0, end = string.size(), delimPos; i < end; i = delimPos + delimiter.size()) {
delimPos = string.find(delimiter, i); delimPos = string.find(delimiter, i);
if(!merge && maxParts >= 0 && res.size() == static_cast<typename Container::value_type::size_type>(maxParts)) { if (!merge && maxParts >= 0 && res.size() == static_cast<typename Container::value_type::size_type>(maxParts)) {
if(delimPos == i && emptyPartsRole == EmptyPartsTreat::Merge) { if (delimPos == i && emptyPartsRole == EmptyPartsTreat::Merge) {
if(!res.empty()) { if (!res.empty()) {
merge = true; merge = true;
continue; continue;
} }
} }
delimPos = Container::value_type::npos; delimPos = Container::value_type::npos;
} }
if(delimPos == Container::value_type::npos) { if (delimPos == Container::value_type::npos) {
delimPos = string.size(); delimPos = string.size();
} }
if(emptyPartsRole == EmptyPartsTreat::Keep || i != delimPos) { if (emptyPartsRole == EmptyPartsTreat::Keep || i != delimPos) {
if(merge) { if (merge) {
res.back().append(delimiter); res.back().append(delimiter);
res.back().append(string.substr(i, delimPos - i)); res.back().append(string.substr(i, delimPos - i));
merge = false; merge = false;
} else { } else {
res.emplace_back(string.substr(i, delimPos - i)); res.emplace_back(string.substr(i, delimPos - i));
} }
} else if(emptyPartsRole == EmptyPartsTreat::Merge) { } else if (emptyPartsRole == EmptyPartsTreat::Merge) {
if(!res.empty()) { if (!res.empty()) {
merge = true; merge = true;
} }
} }
@ -150,16 +153,15 @@ Container splitString(const typename Container::value_type &string, const typena
/*! /*!
* \brief Returns whether \a str starts with \a phrase. * \brief Returns whether \a str starts with \a phrase.
*/ */
template <typename StringType> template <typename StringType> bool startsWith(const StringType &str, const StringType &phrase)
bool startsWith(const StringType &str, const StringType &phrase)
{ {
if(str.size() < phrase.size()) { if (str.size() < phrase.size()) {
return false; return false;
} }
for(auto stri = str.cbegin(), strend = str.cend(), phrasei = phrase.cbegin(), phraseend = phrase.cend(); stri != strend; ++stri, ++phrasei) { for (auto stri = str.cbegin(), strend = str.cend(), phrasei = phrase.cbegin(), phraseend = phrase.cend(); stri != strend; ++stri, ++phrasei) {
if(phrasei == phraseend) { if (phrasei == phraseend) {
return true; return true;
} else if(*stri != *phrasei) { } else if (*stri != *phrasei) {
return false; return false;
} }
} }
@ -169,13 +171,12 @@ bool startsWith(const StringType &str, const StringType &phrase)
/*! /*!
* \brief Returns whether \a str starts with \a phrase. * \brief Returns whether \a str starts with \a phrase.
*/ */
template <typename StringType> template <typename StringType> bool startsWith(const StringType &str, const typename StringType::value_type *phrase)
bool startsWith(const StringType &str, const typename StringType::value_type *phrase)
{ {
for(auto stri = str.cbegin(), strend = str.cend(); stri != strend; ++stri, ++phrase) { for (auto stri = str.cbegin(), strend = str.cend(); stri != strend; ++stri, ++phrase) {
if(!*phrase) { if (!*phrase) {
return true; return true;
} else if(*stri != *phrase) { } else if (*stri != *phrase) {
return false; return false;
} }
} }
@ -186,12 +187,11 @@ bool startsWith(const StringType &str, const typename StringType::value_type *ph
* \brief Returns whether \a str contains the specified \a substrings. * \brief Returns whether \a str contains the specified \a substrings.
* \remarks The \a substrings must occur in the specified order. * \remarks The \a substrings must occur in the specified order.
*/ */
template <typename StringType> template <typename StringType> bool containsSubstrings(const StringType &str, std::initializer_list<StringType> substrings)
bool containsSubstrings(const StringType &str, std::initializer_list<StringType> substrings)
{ {
typename StringType::size_type currentPos = 0; typename StringType::size_type currentPos = 0;
for(const auto &substr : substrings) { for (const auto &substr : substrings) {
if((currentPos = str.find(substr, currentPos)) == StringType::npos) { if ((currentPos = str.find(substr, currentPos)) == StringType::npos) {
return false; return false;
} }
currentPos += substr.size(); currentPos += substr.size();
@ -207,8 +207,8 @@ template <typename StringType>
bool containsSubstrings(const StringType &str, std::initializer_list<const typename StringType::value_type *> substrings) bool containsSubstrings(const StringType &str, std::initializer_list<const typename StringType::value_type *> substrings)
{ {
typename StringType::size_type currentPos = 0; typename StringType::size_type currentPos = 0;
for(const auto *substr : substrings) { for (const auto *substr : substrings) {
if((currentPos = str.find(substr, currentPos)) == StringType::npos) { if ((currentPos = str.find(substr, currentPos)) == StringType::npos) {
return false; return false;
} }
currentPos += std::strlen(substr); currentPos += std::strlen(substr);
@ -219,10 +219,9 @@ bool containsSubstrings(const StringType &str, std::initializer_list<const typen
/*! /*!
* \brief Replaces all occurences of \a find with \a relpace in the specified \a str. * \brief Replaces all occurences of \a find with \a relpace in the specified \a str.
*/ */
template <typename StringType> template <typename StringType> void findAndReplace(StringType &str, const StringType &find, const StringType &replace)
void findAndReplace(StringType &str, const StringType &find, const StringType &replace)
{ {
for(typename StringType::size_type i = 0; (i = str.find(find, i)) != StringType::npos; i += replace.size()) { for (typename StringType::size_type i = 0; (i = str.find(find, i)) != StringType::npos; i += replace.size()) {
str.replace(i, find.size(), replace); str.replace(i, find.size(), replace);
} }
} }
@ -233,11 +232,10 @@ void findAndReplace(StringType &str, const StringType &find, const StringType &r
* - Uses capital letters. * - Uses capital letters.
* - Valid values for \a digit: 0 <= \a digit <= 35 * - Valid values for \a digit: 0 <= \a digit <= 35
*/ */
template <typename CharType> template <typename CharType> CharType digitToChar(CharType digit)
CharType digitToChar(CharType digit)
{ {
CharType res; CharType res;
if(digit <= 9) { if (digit <= 9) {
res = digit + '0'; res = digit + '0';
} else { } else {
res = digit + 'A' - 10; res = digit + 'A' - 10;
@ -251,17 +249,19 @@ CharType digitToChar(CharType digit)
* \tparam StringType The string type (should be an instantiation of the basic_string class template). * \tparam StringType The string type (should be an instantiation of the basic_string class template).
* \sa stringToNumber() * \sa stringToNumber()
*/ */
template <typename IntegralType, class StringType = std::string, Traits::EnableIf<std::is_integral<IntegralType>, Traits::Not<std::is_signed<IntegralType> > >...> template <typename IntegralType, class StringType = std::string,
Traits::EnableIf<std::is_integral<IntegralType>, Traits::Not<std::is_signed<IntegralType> > >...>
StringType numberToString(IntegralType number, typename StringType::value_type base = 10) StringType numberToString(IntegralType number, typename StringType::value_type base = 10)
{ {
std::size_t resSize = 0; std::size_t resSize = 0;
for(auto n = number; n; n /= base, ++resSize); for (auto n = number; n; n /= base, ++resSize)
;
StringType res; StringType res;
res.reserve(resSize); res.reserve(resSize);
do { do {
res.insert(res.begin(), digitToChar<typename StringType::value_type>(number % base)); res.insert(res.begin(), digitToChar<typename StringType::value_type>(number % base));
number /= base; number /= base;
} while(number); } while (number);
return res; return res;
} }
@ -276,19 +276,20 @@ StringType numberToString(IntegralType number, typename StringType::value_type b
{ {
const bool negative = number < 0; const bool negative = number < 0;
std::size_t resSize; std::size_t resSize;
if(negative) { if (negative) {
number = -number, resSize = 1; number = -number, resSize = 1;
} else { } else {
resSize = 0; resSize = 0;
} }
for(auto n = number; n; n /= base, ++resSize); for (auto n = number; n; n /= base, ++resSize)
;
StringType res; StringType res;
res.reserve(resSize); res.reserve(resSize);
do { do {
res.insert(res.begin(), digitToChar<typename StringType::value_type>(number % base)); res.insert(res.begin(), digitToChar<typename StringType::value_type>(number % base));
number /= base; number /= base;
} while(number); } while (number);
if(negative) { if (negative) {
res.insert(res.begin(), '-'); res.insert(res.begin(), '-');
} }
return res; return res;
@ -314,20 +315,19 @@ StringType numberToString(FloatingType number, typename StringType::value_type b
* \brief Returns number/digit of the specified \a character representation using the specified \a base. * \brief Returns number/digit of the specified \a character representation using the specified \a base.
* \throws A ConversionException will be thrown if the provided \a character does not represent a valid digit for the specified \a base. * \throws A ConversionException will be thrown if the provided \a character does not represent a valid digit for the specified \a base.
*/ */
template <typename CharType> template <typename CharType> CharType charToDigit(CharType character, CharType base)
CharType charToDigit(CharType character, CharType base)
{ {
CharType res; CharType res;
if(character >= '0' && character <= '9') { if (character >= '0' && character <= '9') {
res = character - '0'; res = character - '0';
} else if(character >= 'a' && character <= 'z') { } else if (character >= 'a' && character <= 'z') {
res = character - 'a' + 10; res = character - 'a' + 10;
} else if(character >= 'A' && character <= 'Z') { } else if (character >= 'A' && character <= 'Z') {
res = character - 'A' + 10; res = character - 'A' + 10;
} else { } else {
throw ConversionException("The string is no valid number"); throw ConversionException("The string is no valid number");
} }
if(res >= base) { if (res >= base) {
throw ConversionException("The string is no valid number"); throw ConversionException("The string is no valid number");
} }
return res; return res;
@ -344,8 +344,8 @@ template <typename IntegralType, class StringType, Traits::EnableIf<std::is_inte
IntegralType stringToNumber(const StringType &string, typename StringType::value_type base = 10) IntegralType stringToNumber(const StringType &string, typename StringType::value_type base = 10)
{ {
IntegralType result = 0; IntegralType result = 0;
for(const auto &c : string) { for (const auto &c : string) {
if(c == ' ') { if (c == ' ') {
continue; continue;
} }
result *= base; result *= base;
@ -366,16 +366,16 @@ IntegralType stringToNumber(const StringType &string, typename StringType::value
{ {
auto i = string.begin(); auto i = string.begin();
auto end = string.end(); auto end = string.end();
if(i == end) { if (i == end) {
return 0; return 0;
} }
const bool negative = (*i == '-'); const bool negative = (*i == '-');
if(negative) { if (negative) {
++i; ++i;
} }
IntegralType result = 0; IntegralType result = 0;
for(; i != end; ++i) { for (; i != end; ++i) {
if(*i == ' ') { if (*i == ' ') {
continue; continue;
} }
result *= base; result *= base;
@ -399,7 +399,7 @@ FloatingType stringToNumber(const StringType &string, typename StringType::value
std::basic_stringstream<typename StringType::value_type> ss; std::basic_stringstream<typename StringType::value_type> ss;
ss << std::setbase(base) << string; ss << std::setbase(base) << string;
FloatingType result; FloatingType result;
if((ss >> result) && ss.eof()) { if ((ss >> result) && ss.eof()) {
return result; return result;
} else { } else {
throw ConversionException("The string is no valid number."); throw ConversionException("The string is no valid number.");
@ -417,8 +417,8 @@ template <typename IntegralType, class CharType, Traits::EnableIf<std::is_integr
IntegralType stringToNumber(const CharType *string, unsigned char base = 10) IntegralType stringToNumber(const CharType *string, unsigned char base = 10)
{ {
IntegralType result = 0; IntegralType result = 0;
for(; *string; ++string) { for (; *string; ++string) {
if(*string == ' ') { if (*string == ' ') {
continue; continue;
} }
result *= base; result *= base;
@ -437,16 +437,16 @@ IntegralType stringToNumber(const CharType *string, unsigned char base = 10)
template <typename IntegralType, class CharType, Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType> >...> template <typename IntegralType, class CharType, Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType> >...>
IntegralType stringToNumber(const CharType *string, unsigned char base = 10) IntegralType stringToNumber(const CharType *string, unsigned char base = 10)
{ {
if(!*string) { if (!*string) {
return 0; return 0;
} }
const bool negative = (*string == '-'); const bool negative = (*string == '-');
if(negative) { if (negative) {
++string; ++string;
} }
IntegralType result = 0; IntegralType result = 0;
for(; *string; ++string) { for (; *string; ++string) {
if(*string == ' ') { if (*string == ' ') {
continue; continue;
} }
result *= base; result *= base;
@ -464,8 +464,7 @@ IntegralType stringToNumber(const CharType *string, unsigned char base = 10)
* *
* \tparam T The data type of the integer to be interpreted. * \tparam T The data type of the integer to be interpreted.
*/ */
template <typename T> template <typename T> std::string interpretIntegerAsString(T integer, int startOffset = 0)
std::string interpretIntegerAsString(T integer, int startOffset = 0)
{ {
char buffer[sizeof(T)]; char buffer[sizeof(T)];
ConversionUtilities::BE::getBytes(integer, buffer); ConversionUtilities::BE::getBytes(integer, buffer);
@ -476,7 +475,6 @@ CPP_UTILITIES_EXPORT std::string dataSizeToString(uint64 sizeInByte, bool includ
CPP_UTILITIES_EXPORT std::string bitrateToString(double speedInKbitsPerSecond, bool useByteInsteadOfBits = false); CPP_UTILITIES_EXPORT std::string bitrateToString(double speedInKbitsPerSecond, bool useByteInsteadOfBits = false);
CPP_UTILITIES_EXPORT std::string encodeBase64(const byte *data, uint32 dataSize); CPP_UTILITIES_EXPORT std::string encodeBase64(const byte *data, uint32 dataSize);
CPP_UTILITIES_EXPORT std::pair<std::unique_ptr<byte[]>, uint32> decodeBase64(const char *encodedStr, const uint32 strSize); CPP_UTILITIES_EXPORT std::pair<std::unique_ptr<byte[]>, uint32> decodeBase64(const char *encodedStr, const uint32 strSize);
} }
#endif // CONVERSION_UTILITIES_STRINGCONVERSION_H #endif // CONVERSION_UTILITIES_STRINGCONVERSION_H

View File

@ -59,7 +59,7 @@ typedef std::uintptr_t uintptr;
*/ */
typedef float float32; typedef float float32;
#else #else
# error "Unable to define float32!" #error "Unable to define float32!"
#endif #endif
#if __SIZEOF_DOUBLE__ == 8 #if __SIZEOF_DOUBLE__ == 8
@ -68,7 +68,7 @@ typedef float float32;
*/ */
typedef double float64; typedef double float64;
#else #else
# error "Unable to define float64!" #error "Unable to define float64!"
#endif #endif
#endif // CONVERSION_UTILITIES_TYPES_H #endif // CONVERSION_UTILITIES_TYPES_H

View File

@ -3,38 +3,37 @@
#include "../global.h" #include "../global.h"
#include <string>
#include <vector>
#include <locale>
#include <functional> #include <functional>
#include <iostream> #include <iostream>
#include <locale>
#include <string>
#include <vector>
namespace ConversionUtilities namespace ConversionUtilities {
{
/*! /*!
* \brief Converts a std::string to a wide string using the specified locale. * \brief Converts a std::string to a wide string using the specified locale.
* \deprecated Might be removed in future release because not used anymore. Use iconv based string converion functions instead. * \deprecated Might be removed in future release because not used anymore. Use iconv based string converion functions instead.
*/ */
template<class E, class T = std::char_traits<E>, class A = std::allocator<E> > template <class E, class T = std::char_traits<E>, class A = std::allocator<E> >
class CPP_UTILITIES_EXPORT Widen : public std::unary_function<const std::string &, std::basic_string<E, T, A> > class CPP_UTILITIES_EXPORT Widen : public std::unary_function<const std::string &, std::basic_string<E, T, A> > {
{
public: public:
/*! /*!
* \brief Constructs a new instance with the specified \a locale. * \brief Constructs a new instance with the specified \a locale.
*/ */
Widen(const std::locale &locale = std::locale()) : Widen(const std::locale &locale = std::locale())
m_loc(locale), : m_loc(locale)
m_pctype(&std::use_facet<std::ctype<E> >(locale)) , m_pctype(&std::use_facet<std::ctype<E> >(locale))
{} {
}
Widen(const Widen &) = delete; Widen(const Widen &) = delete;
Widen& operator= (const Widen &) = delete; Widen &operator=(const Widen &) = delete;
/*! /*!
* \brief Performs the conversation for the provided \a string. * \brief Performs the conversation for the provided \a string.
*/ */
std::basic_string<E, T, A> operator() (const std::string &string) const std::basic_string<E, T, A> operator()(const std::string &string) const
{ {
typename std::basic_string<E, T, A>::size_type srcLen = string.length(); typename std::basic_string<E, T, A>::size_type srcLen = string.length();
const char *srcBeg = string.c_str(); const char *srcBeg = string.c_str();
@ -45,9 +44,8 @@ public:
private: private:
std::locale m_loc; std::locale m_loc;
const std::ctype<E>* m_pctype; const std::ctype<E> *m_pctype;
}; };
} }
#endif // CONVERSION_UTILITIES_WIDEN_H #endif // CONVERSION_UTILITIES_WIDEN_H

View File

@ -11,26 +11,11 @@
*/ */
namespace EscapeCodes { namespace EscapeCodes {
enum class Color : char enum class Color : char { Black = '0', Red, Green, Yellow, Blue, Purple, Cyan, White };
{
Black = '0',
Red,
Green,
Yellow,
Blue,
Purple,
Cyan,
White
};
enum class ColorContext : char enum class ColorContext : char { Foreground = '3', Background = '4' };
{
Foreground = '3',
Background = '4'
};
enum class TextAttribute : char enum class TextAttribute : char {
{
Reset = '0', Reset = '0',
Bold = '1', Bold = '1',
Dim = '2', Dim = '2',
@ -41,33 +26,23 @@ enum class TextAttribute : char
Concealed = '8' Concealed = '8'
}; };
enum class Direction : char enum class Direction : char { Up = 'A', Down = 'B', Forward = 'C', Backward = 'D' };
{
Up = 'A',
Down = 'B',
Forward = 'C',
Backward = 'D'
};
inline void setStyle(std::ostream &stream, TextAttribute displayAttribute = TextAttribute::Reset) inline void setStyle(std::ostream &stream, TextAttribute displayAttribute = TextAttribute::Reset)
{ {
stream << '\e' << '[' << static_cast<char>(displayAttribute) << 'm'; stream << '\e' << '[' << static_cast<char>(displayAttribute) << 'm';
} }
inline void setStyle(std::ostream &stream, Color color, inline void setStyle(
ColorContext context = ColorContext::Foreground, std::ostream &stream, Color color, ColorContext context = ColorContext::Foreground, TextAttribute displayAttribute = TextAttribute::Reset)
TextAttribute displayAttribute = TextAttribute::Reset)
{ {
stream << '\e' << '[' << static_cast<char>(displayAttribute) << ';' stream << '\e' << '[' << static_cast<char>(displayAttribute) << ';' << static_cast<char>(context) << static_cast<char>(color) << 'm';
<< static_cast<char>(context) << static_cast<char>(color) << 'm';
} }
inline void setStyle(std::ostream &stream, Color foregroundColor, Color backgroundColor, inline void setStyle(std::ostream &stream, Color foregroundColor, Color backgroundColor, TextAttribute displayAttribute = TextAttribute::Reset)
TextAttribute displayAttribute = TextAttribute::Reset)
{ {
stream << '\e' << '[' << static_cast<char>(displayAttribute) << ';' stream << '\e' << '[' << static_cast<char>(displayAttribute) << ';' << static_cast<char>(ColorContext::Foreground)
<< static_cast<char>(ColorContext::Foreground) << static_cast<char>(foregroundColor) << ';' << static_cast<char>(foregroundColor) << ';' << static_cast<char>(ColorContext::Foreground) << static_cast<char>(backgroundColor) << 'm';
<< static_cast<char>(ColorContext::Foreground) << static_cast<char>(backgroundColor) << 'm';
} }
inline void resetStyle(std::ostream &stream) inline void resetStyle(std::ostream &stream)
@ -104,8 +79,6 @@ inline void eraseLine(std::ostream &stream)
{ {
stream << "\33[2K"; stream << "\33[2K";
} }
} }
#endif // IOUTILITIES_ANSIESCAPECODES #endif // IOUTILITIES_ANSIESCAPECODES

View File

@ -2,9 +2,9 @@
#include "../conversion/conversionexception.h" #include "../conversion/conversionexception.h"
#include <cstring>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include <cstring>
using namespace std; using namespace std;
using namespace IoUtilities; using namespace IoUtilities;
@ -25,26 +25,28 @@ using namespace ConversionUtilities;
* \brief Constructs a new BinaryReader. * \brief Constructs a new BinaryReader.
* \param stream Specifies the stream to read from. * \param stream Specifies the stream to read from.
*/ */
BinaryReader::BinaryReader(istream *stream) : BinaryReader::BinaryReader(istream *stream)
m_stream(stream), : m_stream(stream)
m_ownership(false) , m_ownership(false)
{} {
}
/*! /*!
* \brief Copies the specified BinaryReader. * \brief Copies the specified BinaryReader.
* \remarks The copy will not take ownership over the stream. * \remarks The copy will not take ownership over the stream.
*/ */
BinaryReader::BinaryReader(const BinaryReader &other) : BinaryReader::BinaryReader(const BinaryReader &other)
m_stream(other.m_stream), : m_stream(other.m_stream)
m_ownership(false) , m_ownership(false)
{} {
}
/*! /*!
* \brief Destroys the BinaryReader. * \brief Destroys the BinaryReader.
*/ */
BinaryReader::~BinaryReader() BinaryReader::~BinaryReader()
{ {
if(m_ownership) { if (m_ownership) {
delete m_stream; delete m_stream;
} }
} }
@ -62,10 +64,10 @@ BinaryReader::~BinaryReader()
*/ */
void BinaryReader::setStream(istream *stream, bool giveOwnership) void BinaryReader::setStream(istream *stream, bool giveOwnership)
{ {
if(m_ownership) { if (m_ownership) {
delete m_stream; delete m_stream;
} }
if(stream) { if (stream) {
m_stream = stream; m_stream = stream;
m_ownership = giveOwnership; m_ownership = giveOwnership;
} else { } else {
@ -102,11 +104,11 @@ string BinaryReader::readLengthPrefixedString()
int prefixLength = 1; int prefixLength = 1;
const byte beg = static_cast<byte>(m_stream->peek()); const byte beg = static_cast<byte>(m_stream->peek());
byte mask = 0x80; byte mask = 0x80;
while(prefixLength <= maxPrefixLength && (beg & mask) == 0) { while (prefixLength <= maxPrefixLength && (beg & mask) == 0) {
++prefixLength; ++prefixLength;
mask >>= 1; mask >>= 1;
} }
if(prefixLength > maxPrefixLength) { if (prefixLength > maxPrefixLength) {
throw ConversionException("Length denotation of length-prefixed string exceeds maximum."); throw ConversionException("Length denotation of length-prefixed string exceeds maximum.");
} }
memset(m_buffer, 0, maxPrefixLength); memset(m_buffer, 0, maxPrefixLength);
@ -154,10 +156,10 @@ string BinaryReader::readTerminatedString(byte termination)
*/ */
string BinaryReader::readTerminatedString(size_t maxBytesToRead, byte termination) string BinaryReader::readTerminatedString(size_t maxBytesToRead, byte termination)
{ {
unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead); unique_ptr<char[]> buff = make_unique<char[]>(maxBytesToRead);
for(char *i = buff.get(), *end = i + maxBytesToRead; i < end; ++i) { for (char *i = buff.get(), *end = i + maxBytesToRead; i < end; ++i) {
m_stream->get(*i); m_stream->get(*i);
if(*(reinterpret_cast<byte *>(i)) == termination) { if (*(reinterpret_cast<byte *>(i)) == termination) {
return string(buff.get(), i - buff.get()); return string(buff.get(), i - buff.get());
} }
} }
@ -180,7 +182,7 @@ string BinaryReader::readMultibyteTerminatedStringBE(uint16 termination)
do { do {
m_stream->get(buff[0]); m_stream->get(buff[0]);
m_stream->get(buff[1]); m_stream->get(buff[1]);
} while(!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1]))); } while (!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
return ss.str(); return ss.str();
} }
@ -200,7 +202,7 @@ string BinaryReader::readMultibyteTerminatedStringLE(uint16 termination)
do { do {
m_stream->get(buff[0]); m_stream->get(buff[0]);
m_stream->get(buff[1]); m_stream->get(buff[1]);
} while(!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1]))); } while (!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
return ss.str(); return ss.str();
} }
@ -215,13 +217,13 @@ string BinaryReader::readMultibyteTerminatedStringLE(uint16 termination)
*/ */
string BinaryReader::readMultibyteTerminatedStringBE(std::size_t maxBytesToRead, uint16 termination) string BinaryReader::readMultibyteTerminatedStringBE(std::size_t maxBytesToRead, uint16 termination)
{ {
unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead); unique_ptr<char[]> buff = make_unique<char[]>(maxBytesToRead);
char *delimChars = m_buffer; char *delimChars = m_buffer;
ConversionUtilities::BE::getBytes(termination, delimChars); ConversionUtilities::BE::getBytes(termination, delimChars);
for(char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) { for (char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
m_stream->get(*i); m_stream->get(*i);
m_stream->get(*(i + 1)); m_stream->get(*(i + 1));
if((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) { if ((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
return string(buff.get(), i - buff.get()); return string(buff.get(), i - buff.get());
} }
} }
@ -239,13 +241,13 @@ string BinaryReader::readMultibyteTerminatedStringBE(std::size_t maxBytesToRead,
*/ */
string BinaryReader::readMultibyteTerminatedStringLE(std::size_t maxBytesToRead, uint16 termination) string BinaryReader::readMultibyteTerminatedStringLE(std::size_t maxBytesToRead, uint16 termination)
{ {
unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead); unique_ptr<char[]> buff = make_unique<char[]>(maxBytesToRead);
char *delimChars = m_buffer; char *delimChars = m_buffer;
ConversionUtilities::LE::getBytes(termination, delimChars); ConversionUtilities::LE::getBytes(termination, delimChars);
for(char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) { for (char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
m_stream->get(*i); m_stream->get(*i);
m_stream->get(*(i + 1)); m_stream->get(*(i + 1));
if((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) { if ((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
return string(buff.get(), i - buff.get()); return string(buff.get(), i - buff.get());
} }
} }
@ -263,7 +265,7 @@ string BinaryReader::readMultibyteTerminatedStringLE(std::size_t maxBytesToRead,
uint32 BinaryReader::readCrc32(size_t length) uint32 BinaryReader::readCrc32(size_t length)
{ {
uint32 crc = 0x00; uint32 crc = 0x00;
for(uint32 i = 0; i < length; ++i) { for (uint32 i = 0; i < length; ++i) {
crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(m_stream->get())]; crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(m_stream->get())];
} }
return crc; return crc;
@ -280,7 +282,7 @@ uint32 BinaryReader::readCrc32(size_t length)
uint32 BinaryReader::computeCrc32(const char *buffer, size_t length) uint32 BinaryReader::computeCrc32(const char *buffer, size_t length)
{ {
uint32 crc = 0x00; uint32 crc = 0x00;
for(const char *i = buffer, *end = buffer + length; i != end; ++i) { for (const char *i = buffer, *end = buffer + length; i != end; ++i) {
crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(*i)]; crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(*i)];
} }
return crc; return crc;
@ -291,49 +293,25 @@ uint32 BinaryReader::computeCrc32(const char *buffer, size_t length)
* \remarks Internally used by readCrc32() method. * \remarks Internally used by readCrc32() method.
* \sa readCrc32() * \sa readCrc32()
*/ */
const uint32 BinaryReader::crc32Table[] = { const uint32 BinaryReader::crc32Table[] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 };
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};

View File

@ -3,19 +3,17 @@
#include "../conversion/binaryconversion.h" #include "../conversion/binaryconversion.h"
#include <vector>
#include <string>
#include <istream> #include <istream>
#include <string>
#include <vector>
namespace IoUtilities namespace IoUtilities {
{ class CPP_UTILITIES_EXPORT BinaryReader {
class CPP_UTILITIES_EXPORT BinaryReader
{
public: public:
BinaryReader(std::istream *stream); BinaryReader(std::istream *stream);
BinaryReader(const BinaryReader &other); BinaryReader(const BinaryReader &other);
BinaryReader & operator=(const BinaryReader & rhs) = delete; BinaryReader &operator=(const BinaryReader &rhs) = delete;
~BinaryReader(); ~BinaryReader();
const std::istream *stream() const; const std::istream *stream() const;
@ -127,7 +125,7 @@ inline bool BinaryReader::hasOwnership() const
*/ */
inline void BinaryReader::giveOwnership() inline void BinaryReader::giveOwnership()
{ {
if(m_stream) { if (m_stream) {
m_ownership = true; m_ownership = true;
} }
} }
@ -219,7 +217,7 @@ inline int32 BinaryReader::readInt24BE()
*m_buffer = 0; *m_buffer = 0;
m_stream->read(m_buffer + 1, 3); m_stream->read(m_buffer + 1, 3);
auto val = ConversionUtilities::BE::toInt32(m_buffer); auto val = ConversionUtilities::BE::toInt32(m_buffer);
if(val >= 0x800000) { if (val >= 0x800000) {
val = -(0x1000000 - val); val = -(0x1000000 - val);
} }
return val; return val;
@ -261,7 +259,7 @@ inline int64 BinaryReader::readInt40BE()
*m_buffer = *(m_buffer + 1) = *(m_buffer + 2) = 0; *m_buffer = *(m_buffer + 1) = *(m_buffer + 2) = 0;
m_stream->read(m_buffer + 3, 5); m_stream->read(m_buffer + 3, 5);
auto val = ConversionUtilities::BE::toInt64(m_buffer); auto val = ConversionUtilities::BE::toInt64(m_buffer);
if(val >= 0x8000000000) { if (val >= 0x8000000000) {
val = -(0x10000000000 - val); val = -(0x10000000000 - val);
} }
return val; return val;
@ -285,7 +283,7 @@ inline int64 BinaryReader::readInt56BE()
*m_buffer = 0; *m_buffer = 0;
m_stream->read(m_buffer + 1, 7); m_stream->read(m_buffer + 1, 7);
auto val = ConversionUtilities::BE::toInt64(m_buffer); auto val = ConversionUtilities::BE::toInt64(m_buffer);
if(val >= 0x80000000000000) { if (val >= 0x80000000000000) {
val = -(0x100000000000000 - val); val = -(0x100000000000000 - val);
} }
return val; return val;
@ -363,7 +361,7 @@ inline int32 BinaryReader::readInt24LE()
*(m_buffer + 3) = 0; *(m_buffer + 3) = 0;
m_stream->read(m_buffer, 3); m_stream->read(m_buffer, 3);
auto val = ConversionUtilities::LE::toInt32(m_buffer); auto val = ConversionUtilities::LE::toInt32(m_buffer);
if(val >= 0x800000) { if (val >= 0x800000) {
val = -(0x1000000 - val); val = -(0x1000000 - val);
} }
return val; return val;
@ -405,7 +403,7 @@ inline int64 BinaryReader::readInt40LE()
*(m_buffer + 5) = *(m_buffer + 6) = *(m_buffer + 7) = 0; *(m_buffer + 5) = *(m_buffer + 6) = *(m_buffer + 7) = 0;
m_stream->read(m_buffer, 5); m_stream->read(m_buffer, 5);
auto val = ConversionUtilities::LE::toInt64(m_buffer); auto val = ConversionUtilities::LE::toInt64(m_buffer);
if(val >= 0x8000000000) { if (val >= 0x8000000000) {
val = -(0x10000000000 - val); val = -(0x10000000000 - val);
} }
return val; return val;
@ -429,7 +427,7 @@ inline int64 BinaryReader::readInt56LE()
*(m_buffer + 7) = 0; *(m_buffer + 7) = 0;
m_stream->read(m_buffer, 7); m_stream->read(m_buffer, 7);
auto val = ConversionUtilities::LE::toInt64(m_buffer); auto val = ConversionUtilities::LE::toInt64(m_buffer);
if(val >= 0x80000000000000) { if (val >= 0x80000000000000) {
val = -(0x100000000000000 - val); val = -(0x100000000000000 - val);
} }
return val; return val;
@ -559,7 +557,6 @@ inline float32 BinaryReader::readFixed16LE()
{ {
return ConversionUtilities::toFloat32(readUInt32LE()); return ConversionUtilities::toFloat32(readUInt32LE());
} }
} }
#endif // IOUTILITIES_BINERYREADER_H #endif // IOUTILITIES_BINERYREADER_H

View File

@ -19,26 +19,28 @@ using namespace ConversionUtilities;
* \brief Constructs a new BinaryWriter. * \brief Constructs a new BinaryWriter.
* \param stream Specifies the stream to write to. * \param stream Specifies the stream to write to.
*/ */
BinaryWriter::BinaryWriter(ostream *stream) : BinaryWriter::BinaryWriter(ostream *stream)
m_stream(stream), : m_stream(stream)
m_ownership(false) , m_ownership(false)
{} {
}
/*! /*!
* \brief Copies the specified BinaryWriter. * \brief Copies the specified BinaryWriter.
* \remarks The copy will not take ownership over the stream. * \remarks The copy will not take ownership over the stream.
*/ */
BinaryWriter::BinaryWriter(const BinaryWriter &other) : BinaryWriter::BinaryWriter(const BinaryWriter &other)
m_stream(other.m_stream), : m_stream(other.m_stream)
m_ownership(false) , m_ownership(false)
{} {
}
/*! /*!
* \brief Destroys the BinaryWriter. * \brief Destroys the BinaryWriter.
*/ */
BinaryWriter::~BinaryWriter() BinaryWriter::~BinaryWriter()
{ {
if(m_ownership) { if (m_ownership) {
delete m_stream; delete m_stream;
} }
} }
@ -56,10 +58,10 @@ BinaryWriter::~BinaryWriter()
*/ */
void BinaryWriter::setStream(ostream *stream, bool giveOwnership) void BinaryWriter::setStream(ostream *stream, bool giveOwnership)
{ {
if(m_ownership) { if (m_ownership) {
delete m_stream; delete m_stream;
} }
if(stream) { if (stream) {
m_stream = stream; m_stream = stream;
m_ownership = giveOwnership; m_ownership = giveOwnership;
} else { } else {
@ -76,16 +78,16 @@ void BinaryWriter::setStream(ostream *stream, bool giveOwnership)
void BinaryWriter::writeLengthPrefixedString(const string &value) void BinaryWriter::writeLengthPrefixedString(const string &value)
{ {
size_t length = value.length(); size_t length = value.length();
if(length < 0x80) { if (length < 0x80) {
m_buffer[0] = 0x80 | length; m_buffer[0] = 0x80 | length;
m_stream->write(m_buffer, 1); m_stream->write(m_buffer, 1);
} else if(length < 0x4000) { } else if (length < 0x4000) {
BE::getBytes(static_cast<uint16>(0x4000 | length), m_buffer); BE::getBytes(static_cast<uint16>(0x4000 | length), m_buffer);
m_stream->write(m_buffer, 2); m_stream->write(m_buffer, 2);
} else if(length < 0x200000) { } else if (length < 0x200000) {
BE::getBytes(static_cast<uint32>(0x200000 | length), m_buffer); BE::getBytes(static_cast<uint32>(0x200000 | length), m_buffer);
m_stream->write(m_buffer + 1, 3); m_stream->write(m_buffer + 1, 3);
} else if(length < 0x10000000) { } else if (length < 0x10000000) {
BE::getBytes(static_cast<uint32>(0x10000000 | length), m_buffer); BE::getBytes(static_cast<uint32>(0x10000000 | length), m_buffer);
m_stream->write(m_buffer, 4); m_stream->write(m_buffer, 4);
} else { } else {

View File

@ -1,22 +1,20 @@
#ifndef IOUTILITIES_BINARYWRITER_H #ifndef IOUTILITIES_BINARYWRITER_H
#define IOUTILITIES_BINARYWRITER_H #define IOUTILITIES_BINARYWRITER_H
#include "../conversion/types.h"
#include "../conversion/binaryconversion.h" #include "../conversion/binaryconversion.h"
#include "../conversion/types.h"
#include <vector>
#include <string>
#include <ostream> #include <ostream>
#include <string>
#include <vector>
namespace IoUtilities namespace IoUtilities {
{
class CPP_UTILITIES_EXPORT BinaryWriter class CPP_UTILITIES_EXPORT BinaryWriter {
{
public: public:
BinaryWriter(std::ostream *stream); BinaryWriter(std::ostream *stream);
BinaryWriter(const BinaryWriter &other); BinaryWriter(const BinaryWriter &other);
BinaryWriter & operator=(const BinaryWriter & rhs) = delete; BinaryWriter &operator=(const BinaryWriter &rhs) = delete;
~BinaryWriter(); ~BinaryWriter();
const std::ostream *stream() const; const std::ostream *stream() const;
@ -117,7 +115,7 @@ inline bool BinaryWriter::hasOwnership() const
*/ */
inline void BinaryWriter::giveOwnership() inline void BinaryWriter::giveOwnership()
{ {
if(m_stream) { if (m_stream) {
m_ownership = true; m_ownership = true;
} }
} }
@ -527,7 +525,6 @@ inline void BinaryWriter::writeFixed16LE(float32 valueToConvertAndWrite)
{ {
writeUInt32LE(ConversionUtilities::toFixed16(valueToConvertAndWrite)); writeUInt32LE(ConversionUtilities::toFixed16(valueToConvertAndWrite));
} }
} }
#endif // IO_UTILITIES_BINARYWRITER_H #endif // IO_UTILITIES_BINARYWRITER_H

View File

@ -18,10 +18,10 @@ namespace IoUtilities {
*/ */
void BitReader::skipBits(std::size_t bitCount) void BitReader::skipBits(std::size_t bitCount)
{ {
if(bitCount <= m_bitsAvail) { if (bitCount <= m_bitsAvail) {
m_bitsAvail -= bitCount; m_bitsAvail -= bitCount;
} else { } else {
if((m_buffer += 1 + (bitCount -= m_bitsAvail) / 8) >= m_end) { if ((m_buffer += 1 + (bitCount -= m_bitsAvail) / 8) >= m_end) {
throwIoFailure("end of buffer exceeded"); throwIoFailure("end of buffer exceeded");
} }
m_bitsAvail = 8 - (bitCount % 8); m_bitsAvail = 8 - (bitCount % 8);
@ -29,4 +29,3 @@ void BitReader::skipBits(std::size_t bitCount)
} }
} // namespace IoUtilities } // namespace IoUtilities

View File

@ -2,8 +2,8 @@
#define IOUTILITIES_BITREADER_H #define IOUTILITIES_BITREADER_H
#include "../conversion/types.h" #include "../conversion/types.h"
#include "../io/catchiofailure.h"
#include "../global.h" #include "../global.h"
#include "../io/catchiofailure.h"
#include <ios> #include <ios>
#include <iostream> #include <iostream>
@ -11,17 +11,16 @@
namespace IoUtilities { namespace IoUtilities {
class CPP_UTILITIES_EXPORT BitReader class CPP_UTILITIES_EXPORT BitReader {
{
public: public:
BitReader(const char *buffer, std::size_t bufferSize); BitReader(const char *buffer, std::size_t bufferSize);
BitReader(const char *buffer, const char *end); BitReader(const char *buffer, const char *end);
template<typename intType> intType readBits(byte bitCount); template <typename intType> intType readBits(byte bitCount);
byte readBit(); byte readBit();
template<typename intType> intType readUnsignedExpGolombCodedBits(); template <typename intType> intType readUnsignedExpGolombCodedBits();
template<typename intType> intType readSignedExpGolombCodedBits(); template <typename intType> intType readSignedExpGolombCodedBits();
template<typename intType> intType showBits(byte bitCount); template <typename intType> intType showBits(byte bitCount);
void skipBits(std::size_t bitCount); void skipBits(std::size_t bitCount);
void align(); void align();
std::size_t bitsAvailable(); std::size_t bitsAvailable();
@ -40,9 +39,10 @@ private:
* - Does not take ownership over the specified \a buffer. * - Does not take ownership over the specified \a buffer.
* - bufferSize must be equal or greather than 1. * - bufferSize must be equal or greather than 1.
*/ */
inline BitReader::BitReader(const char *buffer, std::size_t bufferSize) : inline BitReader::BitReader(const char *buffer, std::size_t bufferSize)
BitReader(buffer, buffer + bufferSize) : BitReader(buffer, buffer + bufferSize)
{} {
}
/*! /*!
* \brief Constructs a new BitReader. * \brief Constructs a new BitReader.
@ -50,11 +50,12 @@ inline BitReader::BitReader(const char *buffer, std::size_t bufferSize) :
* - Does not take ownership over the specified \a buffer. * - Does not take ownership over the specified \a buffer.
* - \a end must be greather than \a buffer. * - \a end must be greather than \a buffer.
*/ */
inline BitReader::BitReader(const char *buffer, const char *end) : inline BitReader::BitReader(const char *buffer, const char *end)
m_buffer(reinterpret_cast<const byte *>(buffer)), : m_buffer(reinterpret_cast<const byte *>(buffer))
m_end(reinterpret_cast<const byte *>(end)), , m_end(reinterpret_cast<const byte *>(end))
m_bitsAvail(8) , m_bitsAvail(8)
{} {
}
/*! /*!
* \brief Reads the specified number of bits from the buffer advancing the current position by \a bitCount bits. * \brief Reads the specified number of bits from the buffer advancing the current position by \a bitCount bits.
@ -64,13 +65,12 @@ inline BitReader::BitReader(const char *buffer, const char *end) :
* \throws Throws ios_base::failure if the end of the buffer is exceeded. * \throws Throws ios_base::failure if the end of the buffer is exceeded.
* The reader becomes invalid in that case. * The reader becomes invalid in that case.
*/ */
template<typename intType> template <typename intType> intType BitReader::readBits(byte bitCount)
intType BitReader::readBits(byte bitCount)
{ {
intType val = 0; intType val = 0;
for(byte readAtOnce; bitCount; bitCount -= readAtOnce) { for (byte readAtOnce; bitCount; bitCount -= readAtOnce) {
if(!m_bitsAvail) { if (!m_bitsAvail) {
if(++m_buffer >= m_end) { if (++m_buffer >= m_end) {
throwIoFailure("end of buffer exceeded"); throwIoFailure("end of buffer exceeded");
} }
m_bitsAvail = 8; m_bitsAvail = 8;
@ -99,11 +99,10 @@ inline byte BitReader::readBit()
* The reader becomes invalid in that case. * The reader becomes invalid in that case.
* \sa https://en.wikipedia.org/wiki/Exponential-Golomb_coding * \sa https://en.wikipedia.org/wiki/Exponential-Golomb_coding
*/ */
template<typename intType> template <typename intType> intType BitReader::readUnsignedExpGolombCodedBits()
intType BitReader::readUnsignedExpGolombCodedBits()
{ {
byte count = 0; byte count = 0;
while(!readBit()) { while (!readBit()) {
++count; ++count;
} }
return count ? (((1 << count) | readBits<intType>(count)) - 1) : 0; return count ? (((1 << count) | readBits<intType>(count)) - 1) : 0;
@ -117,8 +116,7 @@ intType BitReader::readUnsignedExpGolombCodedBits()
* The reader becomes invalid in that case. * The reader becomes invalid in that case.
* \sa https://en.wikipedia.org/wiki/Exponential-Golomb_coding * \sa https://en.wikipedia.org/wiki/Exponential-Golomb_coding
*/ */
template<typename intType> template <typename intType> intType BitReader::readSignedExpGolombCodedBits()
intType BitReader::readSignedExpGolombCodedBits()
{ {
auto value = readUnsignedExpGolombCodedBits<typename std::make_unsigned<intType>::type>(); auto value = readUnsignedExpGolombCodedBits<typename std::make_unsigned<intType>::type>();
return (value % 2) ? static_cast<intType>((value + 1) / 2) : (-static_cast<intType>(value / 2)); return (value % 2) ? static_cast<intType>((value + 1) / 2) : (-static_cast<intType>(value / 2));
@ -127,8 +125,7 @@ intType BitReader::readSignedExpGolombCodedBits()
/*! /*!
* \brief Reads the specified number of bits from the buffer without advancing the current position. * \brief Reads the specified number of bits from the buffer without advancing the current position.
*/ */
template<typename intType> template <typename intType> intType BitReader::showBits(byte bitCount)
intType BitReader::showBits(byte bitCount)
{ {
auto tmp = *this; auto tmp = *this;
return tmp.readBits<intType>(bitCount); return tmp.readBits<intType>(bitCount);

View File

@ -19,7 +19,7 @@ const char *catchIoFailure()
{ {
try { try {
throw; throw;
} catch(const ios_base::failure &e) { } catch (const ios_base::failure &e) {
return e.what(); return e.what();
} }
} }
@ -31,6 +31,4 @@ void throwIoFailure(const char *what)
{ {
throw ios_base::failure(what); throw ios_base::failure(what);
} }
} }

View File

@ -9,7 +9,6 @@ namespace IoUtilities {
CPP_UTILITIES_EXPORT const char *catchIoFailure(); CPP_UTILITIES_EXPORT const char *catchIoFailure();
CPP_UTILITIES_EXPORT void throwIoFailure(const char *what); CPP_UTILITIES_EXPORT void throwIoFailure(const char *what);
} }
#endif // IOUTILITIES_CATCHIOFAILURE_H #endif // IOUTILITIES_CATCHIOFAILURE_H

View File

@ -3,8 +3,8 @@
#include "../global.h" #include "../global.h"
#include <iostream>
#include <functional> #include <functional>
#include <iostream>
namespace IoUtilities { namespace IoUtilities {
@ -13,14 +13,14 @@ namespace IoUtilities {
* \brief The CopyHelper class helps to copy bytes from one stream to another. * \brief The CopyHelper class helps to copy bytes from one stream to another.
* \tparam Specifies the buffer size. * \tparam Specifies the buffer size.
*/ */
template<std::size_t bufferSize> template <std::size_t bufferSize> class CPP_UTILITIES_EXPORT CopyHelper {
class CPP_UTILITIES_EXPORT CopyHelper
{
public: public:
CopyHelper(); CopyHelper();
void copy(std::istream &input, std::ostream &output, std::size_t count); void copy(std::istream &input, std::ostream &output, std::size_t count);
void callbackCopy(std::istream &input, std::ostream &output, std::size_t count, const std::function<bool (void)> &isAborted, const std::function<void (double)> &callback); void callbackCopy(std::istream &input, std::ostream &output, std::size_t count, const std::function<bool(void)> &isAborted,
const std::function<void(double)> &callback);
char *buffer(); char *buffer();
private: private:
char m_buffer[bufferSize]; char m_buffer[bufferSize];
}; };
@ -28,19 +28,18 @@ private:
/*! /*!
* \brief Constructs a new copy helper. * \brief Constructs a new copy helper.
*/ */
template<std::size_t bufferSize> template <std::size_t bufferSize> CopyHelper<bufferSize>::CopyHelper()
CopyHelper<bufferSize>::CopyHelper() {
{} }
/*! /*!
* \brief Copies \a count bytes from \a input to \a output. * \brief Copies \a count bytes from \a input to \a output.
* \remarks Set an exception mask using std::ios::exceptions() to get a std::ios_base::failure exception * \remarks Set an exception mask using std::ios::exceptions() to get a std::ios_base::failure exception
* when an IO error occurs. * when an IO error occurs.
*/ */
template<std::size_t bufferSize> template <std::size_t bufferSize> void CopyHelper<bufferSize>::copy(std::istream &input, std::ostream &output, std::size_t count)
void CopyHelper<bufferSize>::copy(std::istream &input, std::ostream &output, std::size_t count)
{ {
while(count > bufferSize) { while (count > bufferSize) {
input.read(m_buffer, bufferSize); input.read(m_buffer, bufferSize);
output.write(m_buffer, bufferSize); output.write(m_buffer, bufferSize);
count -= bufferSize; count -= bufferSize;
@ -49,7 +48,6 @@ void CopyHelper<bufferSize>::copy(std::istream &input, std::ostream &output, std
output.write(m_buffer, count); output.write(m_buffer, count);
} }
/*! /*!
* \brief Copies \a count bytes from \a input to \a output. The procedure might be aborted and * \brief Copies \a count bytes from \a input to \a output. The procedure might be aborted and
* progress updates will be reported. * progress updates will be reported.
@ -60,15 +58,16 @@ void CopyHelper<bufferSize>::copy(std::istream &input, std::ostream &output, std
* \remarks Set an exception mask using std::ios::exceptions() to get a std::ios_base::failure exception * \remarks Set an exception mask using std::ios::exceptions() to get a std::ios_base::failure exception
* when an IO error occurs. * when an IO error occurs.
*/ */
template<std::size_t bufferSize> template <std::size_t bufferSize>
void CopyHelper<bufferSize>::callbackCopy(std::istream &input, std::ostream &output, std::size_t count, const std::function<bool (void)> &isAborted, const std::function<void (double)> &callback) void CopyHelper<bufferSize>::callbackCopy(std::istream &input, std::ostream &output, std::size_t count, const std::function<bool(void)> &isAborted,
const std::function<void(double)> &callback)
{ {
const std::size_t totalBytes = count; const std::size_t totalBytes = count;
while(count > bufferSize) { while (count > bufferSize) {
input.read(m_buffer, bufferSize); input.read(m_buffer, bufferSize);
output.write(m_buffer, bufferSize); output.write(m_buffer, bufferSize);
count -= bufferSize; count -= bufferSize;
if(isAborted()) { if (isAborted()) {
return; return;
} }
callback(static_cast<double>(totalBytes - count) / totalBytes); callback(static_cast<double>(totalBytes - count) / totalBytes);
@ -81,12 +80,10 @@ void CopyHelper<bufferSize>::callbackCopy(std::istream &input, std::ostream &out
/*! /*!
* \brief Returns the internal buffer. * \brief Returns the internal buffer.
*/ */
template<std::size_t bufferSize> template <std::size_t bufferSize> char *CopyHelper<bufferSize>::buffer()
char *CopyHelper<bufferSize>::buffer()
{ {
return m_buffer; return m_buffer;
} }
} }
#endif // IOUTILITIES_COPY_H #endif // IOUTILITIES_COPY_H

View File

@ -18,7 +18,7 @@ namespace IoUtilities {
void IniFile::parse(std::istream &inputStream) void IniFile::parse(std::istream &inputStream)
{ {
// define variable for state machine // define variable for state machine
enum State {Init, Comment, ScopeName, Key, Value} state = Init; enum State { Init, Comment, ScopeName, Key, Value } state = Init;
// current character // current character
char c; char c;
// number of postponed whitespaces // number of postponed whitespaces
@ -31,10 +31,10 @@ void IniFile::parse(std::istream &inputStream)
// define actions for state machine // define actions for state machine
// called when key/value pair is complete // called when key/value pair is complete
const auto finishKeyValue = [&state, &scope, &key, &value, &whitespace, this] { const auto finishKeyValue = [&state, &scope, &key, &value, &whitespace, this] {
if(key.empty() && value.empty() && state != Value) { if (key.empty() && value.empty() && state != Value) {
return; return;
} }
if(m_data.empty() || m_data.back().first != scope) { if (m_data.empty() || m_data.back().first != scope) {
m_data.emplace_back(make_pair(scope, decltype(m_data)::value_type::second_type())); m_data.emplace_back(make_pair(scope, decltype(m_data)::value_type::second_type()));
} }
m_data.back().second.insert(make_pair(key, value)); m_data.back().second.insert(make_pair(key, value));
@ -43,12 +43,12 @@ void IniFile::parse(std::istream &inputStream)
whitespace = 0; whitespace = 0;
}; };
// called to add current character to current key or value // called to add current character to current key or value
const auto addChar = [&whitespace, &c] (string &to) { const auto addChar = [&whitespace, &c](string &to) {
if(c == ' ') { if (c == ' ') {
++whitespace; ++whitespace;
} else { } else {
if(!to.empty()) { if (!to.empty()) {
while(whitespace) { while (whitespace) {
to += ' '; to += ' ';
--whitespace; --whitespace;
} }
@ -62,10 +62,10 @@ void IniFile::parse(std::istream &inputStream)
inputStream.exceptions(ios_base::failbit | ios_base::badbit); inputStream.exceptions(ios_base::failbit | ios_base::badbit);
// parse the file char by char // parse the file char by char
try { try {
while(inputStream.get(c)) { while (inputStream.get(c)) {
switch(state) { switch (state) {
case Init: case Init:
switch(c) { switch (c) {
case '\n': case '\n':
break; break;
case '#': case '#':
@ -85,7 +85,7 @@ void IniFile::parse(std::istream &inputStream)
} }
break; break;
case Key: case Key:
switch(c) { switch (c) {
case '\n': case '\n':
finishKeyValue(); finishKeyValue();
state = Init; state = Init;
@ -103,16 +103,15 @@ void IniFile::parse(std::istream &inputStream)
} }
break; break;
case Comment: case Comment:
switch(c) { switch (c) {
case '\n': case '\n':
state = Init; state = Init;
break; break;
default: default:;
;
} }
break; break;
case ScopeName: case ScopeName:
switch(c) { switch (c) {
case ']': case ']':
state = Init; state = Init;
break; break;
@ -121,7 +120,7 @@ void IniFile::parse(std::istream &inputStream)
} }
break; break;
case Value: case Value:
switch(c) { switch (c) {
case '\n': case '\n':
finishKeyValue(); finishKeyValue();
state = Init; state = Init;
@ -136,9 +135,9 @@ void IniFile::parse(std::istream &inputStream)
break; break;
} }
} }
} catch(...) { } catch (...) {
const char *what = catchIoFailure(); const char *what = catchIoFailure();
if(inputStream.eof()) { if (inputStream.eof()) {
// we just reached the end of the file // we just reached the end of the file
// don't forget to save the last key/value pair // don't forget to save the last key/value pair
finishKeyValue(); finishKeyValue();
@ -155,9 +154,9 @@ void IniFile::make(ostream &outputStream)
{ {
// thorw an exception when an IO error occurs // thorw an exception when an IO error occurs
outputStream.exceptions(ios_base::failbit | ios_base::badbit); outputStream.exceptions(ios_base::failbit | ios_base::badbit);
for(const auto &scope : m_data) { for (const auto &scope : m_data) {
outputStream << '[' << scope.first << ']' << '\n'; outputStream << '[' << scope.first << ']' << '\n';
for(const auto &field : scope.second) { for (const auto &field : scope.second) {
outputStream << field.first << '=' << field.second << '\n'; outputStream << field.first << '=' << field.second << '\n';
} }
outputStream << '\n'; outputStream << '\n';
@ -165,4 +164,3 @@ void IniFile::make(ostream &outputStream)
} }
} // namespace IoUtilities } // namespace IoUtilities

View File

@ -3,14 +3,13 @@
#include "../global.h" #include "../global.h"
#include <vector>
#include <map> #include <map>
#include <string> #include <string>
#include <vector>
namespace IoUtilities { namespace IoUtilities {
class CPP_UTILITIES_EXPORT IniFile class CPP_UTILITIES_EXPORT IniFile {
{
public: public:
IniFile(); IniFile();
@ -27,7 +26,8 @@ private:
* \brief Constructs an empty ini file. * \brief Constructs an empty ini file.
*/ */
inline IniFile::IniFile() inline IniFile::IniFile()
{} {
}
/*! /*!
* \brief Returns the data of the file. * \brief Returns the data of the file.

View File

@ -21,7 +21,7 @@ string readFile(const string &path, std::string::size_type maxSize)
file.seekg(0, ios_base::end); file.seekg(0, ios_base::end);
string res; string res;
const auto size = static_cast<string::size_type>(file.tellg()); const auto size = static_cast<string::size_type>(file.tellg());
if(maxSize != string::npos && size > maxSize) { if (maxSize != string::npos && size > maxSize) {
throwIoFailure("File exceeds max size"); throwIoFailure("File exceeds max size");
} }
res.reserve(size); res.reserve(size);
@ -29,5 +29,4 @@ string readFile(const string &path, std::string::size_type maxSize)
res.assign((istreambuf_iterator<char>(file)), istreambuf_iterator<char>()); res.assign((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
return res; return res;
} }
} }

View File

@ -8,7 +8,6 @@
namespace IoUtilities { namespace IoUtilities {
CPP_UTILITIES_EXPORT std::string readFile(const std::string &path, std::string::size_type maxSize = std::string::npos); CPP_UTILITIES_EXPORT std::string readFile(const std::string &path, std::string::size_type maxSize = std::string::npos);
} }
#endif // IOUTILITIES_MISC_H #endif // IOUTILITIES_MISC_H

View File

@ -1,10 +1,10 @@
#include "./nativefilestream.h" #include "./nativefilestream.h"
#ifdef PLATFORM_MINGW #ifdef PLATFORM_MINGW
# include "catchiofailure.h" #include "catchiofailure.h"
# include <windows.h> #include <fcntl.h>
# include <fcntl.h> #include <sys/stat.h>
# include <sys/stat.h> #include <windows.h>
#endif #endif
using namespace std; using namespace std;
@ -17,44 +17,45 @@ namespace IoUtilities {
#else #else
NativeFileStream::NativeFileStream() : NativeFileStream::NativeFileStream()
m_filebuf(new __gnu_cxx::stdio_filebuf<char>) : m_filebuf(new __gnu_cxx::stdio_filebuf<char>)
{ {
rdbuf(m_filebuf.get()); rdbuf(m_filebuf.get());
} }
NativeFileStream::~NativeFileStream() NativeFileStream::~NativeFileStream()
{} {
}
void NativeFileStream::open(const string &path, ios_base::openmode flags) void NativeFileStream::open(const string &path, ios_base::openmode flags)
{ {
// convert path to UTF-16 // convert path to UTF-16
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, path.data(), -1, nullptr, 0); int requiredSize = MultiByteToWideChar(CP_UTF8, 0, path.data(), -1, nullptr, 0);
if(requiredSize <= 0) { if (requiredSize <= 0) {
::IoUtilities::throwIoFailure("Unable to calculate buffer size for conversion of path to UTF-16"); ::IoUtilities::throwIoFailure("Unable to calculate buffer size for conversion of path to UTF-16");
} }
auto widePath = make_unique<wchar_t[]>(static_cast<size_t>(requiredSize)); auto widePath = make_unique<wchar_t[]>(static_cast<size_t>(requiredSize));
requiredSize = MultiByteToWideChar(CP_UTF8, 0, path.data(), -1, widePath.get(), requiredSize); requiredSize = MultiByteToWideChar(CP_UTF8, 0, path.data(), -1, widePath.get(), requiredSize);
if(requiredSize <= 0) { if (requiredSize <= 0) {
::IoUtilities::throwIoFailure("Unable to convert path to UTF-16"); ::IoUtilities::throwIoFailure("Unable to convert path to UTF-16");
} }
// translate flags // translate flags
int nativeFlags = (flags & ios_base::binary ? _O_BINARY : 0); int nativeFlags = (flags & ios_base::binary ? _O_BINARY : 0);
int permissions = 0; int permissions = 0;
if((flags & ios_base::out) && (flags & ios_base::in)) { if ((flags & ios_base::out) && (flags & ios_base::in)) {
nativeFlags |= _O_RDWR; nativeFlags |= _O_RDWR;
} else if(flags & ios_base::out) { } else if (flags & ios_base::out) {
nativeFlags |= _O_WRONLY | _O_CREAT; nativeFlags |= _O_WRONLY | _O_CREAT;
permissions = _S_IREAD | _S_IWRITE; permissions = _S_IREAD | _S_IWRITE;
} else if(flags & ios_base::in) { } else if (flags & ios_base::in) {
nativeFlags |= _O_RDONLY; nativeFlags |= _O_RDONLY;
} }
if(flags & ios_base::trunc) { if (flags & ios_base::trunc) {
nativeFlags |= _O_TRUNC; nativeFlags |= _O_TRUNC;
} }
// initialize stdio_filebuf // initialize stdio_filebuf
int fd = _wopen(widePath.get(), nativeFlags, permissions); int fd = _wopen(widePath.get(), nativeFlags, permissions);
if(fd == -1) { if (fd == -1) {
::IoUtilities::throwIoFailure("_wopen failed"); ::IoUtilities::throwIoFailure("_wopen failed");
} }
m_filebuf = make_unique<__gnu_cxx::stdio_filebuf<char> >(fd, flags); m_filebuf = make_unique<__gnu_cxx::stdio_filebuf<char> >(fd, flags);
@ -63,11 +64,10 @@ void NativeFileStream::open(const string &path, ios_base::openmode flags)
void NativeFileStream::close() void NativeFileStream::close()
{ {
if(m_filebuf) { if (m_filebuf) {
m_filebuf->close(); m_filebuf->close();
} }
} }
#endif #endif
} }

View File

@ -4,12 +4,12 @@
#include "../global.h" #include "../global.h"
#ifndef PLATFORM_MINGW #ifndef PLATFORM_MINGW
# include <fstream> #include <fstream>
#else #else
# include <memory> #include <ext/stdio_filebuf.h>
# include <string> #include <iostream>
# include <iostream> #include <memory>
# include <ext/stdio_filebuf.h> #include <string>
#endif #endif
namespace IoUtilities { namespace IoUtilities {
@ -20,8 +20,7 @@ typedef std::fstream NativeFileStream;
#else #else
class CPP_UTILITIES_EXPORT NativeFileStream : public std::iostream class CPP_UTILITIES_EXPORT NativeFileStream : public std::iostream {
{
public: public:
NativeFileStream(); NativeFileStream();
~NativeFileStream(); ~NativeFileStream();
@ -41,8 +40,6 @@ inline bool NativeFileStream::is_open() const
} }
#endif #endif
} }
#endif // IOUTILITIES_NATIVE_FILE_STREAM #endif // IOUTILITIES_NATIVE_FILE_STREAM

View File

@ -1,25 +1,25 @@
#include "./path.h" #include "./path.h"
#include <string>
#include <sstream>
#include <fstream>
#include <cstdlib> #include <cstdlib>
#include <fstream>
#include <sstream>
#include <string>
#if defined(PLATFORM_UNIX) #if defined(PLATFORM_UNIX)
# include <unistd.h> #include <dirent.h>
# include <sys/types.h> #include <pwd.h>
# include <sys/stat.h> #include <sys/stat.h>
# include <pwd.h> #include <sys/types.h>
# include <dirent.h> #include <unistd.h>
#elif defined(PLATFORM_WINDOWS) #elif defined(PLATFORM_WINDOWS)
# ifdef UNICODE #ifdef UNICODE
# undef UNICODE #undef UNICODE
# endif #endif
# ifdef _UNICODE #ifdef _UNICODE
# undef _UNICODE #undef _UNICODE
# endif #endif
# include <windows.h> #include <windows.h>
#else #else
# error Platform not supported. #error Platform not supported.
#endif #endif
using namespace std; using namespace std;
@ -34,11 +34,11 @@ string fileName(const string &path)
size_t lastSlash = path.rfind('/'); size_t lastSlash = path.rfind('/');
size_t lastBackSlash = path.rfind('\\'); size_t lastBackSlash = path.rfind('\\');
size_t lastSeparator; size_t lastSeparator;
if(lastSlash == string::npos && lastBackSlash == string::npos) { if (lastSlash == string::npos && lastBackSlash == string::npos) {
return path; return path;
} else if(lastSlash == string::npos) { } else if (lastSlash == string::npos) {
lastSeparator = lastBackSlash; lastSeparator = lastBackSlash;
} else if(lastBackSlash == string::npos) { } else if (lastBackSlash == string::npos) {
lastSeparator = lastSlash; lastSeparator = lastSlash;
} else { } else {
lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash; lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;
@ -54,11 +54,11 @@ string directory(const string &path)
size_t lastSlash = path.rfind('/'); size_t lastSlash = path.rfind('/');
size_t lastBackSlash = path.rfind('\\'); size_t lastBackSlash = path.rfind('\\');
size_t lastSeparator; size_t lastSeparator;
if(lastSlash == string::npos && lastBackSlash == string::npos) { if (lastSlash == string::npos && lastBackSlash == string::npos) {
return string(); return string();
} else if(lastSlash == string::npos) { } else if (lastSlash == string::npos) {
lastSeparator = lastBackSlash; lastSeparator = lastBackSlash;
} else if(lastBackSlash == string::npos) { } else if (lastBackSlash == string::npos) {
lastSeparator = lastSlash; lastSeparator = lastSlash;
} else { } else {
lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash; lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;
@ -74,10 +74,10 @@ string directory(const string &path)
void removeInvalidChars(std::string &fileName) void removeInvalidChars(std::string &fileName)
{ {
size_t startPos = 0; size_t startPos = 0;
static const char invalidPathChars[] = {'\"', '<', '>', '?', '!', '*', '|', '/', ':', '\\', '\n'}; static const char invalidPathChars[] = { '\"', '<', '>', '?', '!', '*', '|', '/', ':', '\\', '\n' };
for(const char *i = invalidPathChars, *end = invalidPathChars + sizeof(invalidPathChars); i != end; ++i) { for (const char *i = invalidPathChars, *end = invalidPathChars + sizeof(invalidPathChars); i != end; ++i) {
startPos = fileName.find(*i); startPos = fileName.find(*i);
while(startPos != string::npos) { while (startPos != string::npos) {
fileName.replace(startPos, 1, string()); fileName.replace(startPos, 1, string());
startPos = fileName.find(*i, startPos); startPos = fileName.find(*i, startPos);
} }
@ -97,18 +97,18 @@ bool settingsDirectory(std::string &result, std::string applicationDirectoryName
result.clear(); result.clear();
// FIXME: this kind of configuration is not actually used so get rid of it, maybe just read env variable instead // FIXME: this kind of configuration is not actually used so get rid of it, maybe just read env variable instead
fstream pathConfigFile("path.config", ios_base::in); fstream pathConfigFile("path.config", ios_base::in);
if(pathConfigFile.good()) { if (pathConfigFile.good()) {
for(string line; getline(pathConfigFile, line); ) { for (string line; getline(pathConfigFile, line);) {
string::size_type p = line.find('='); string::size_type p = line.find('=');
if((p != string::npos) && (p + 1 < line.length())) { if ((p != string::npos) && (p + 1 < line.length())) {
string fieldName = line.substr(0, p); string fieldName = line.substr(0, p);
if(fieldName == "settings") { if (fieldName == "settings") {
result.assign(line.substr(p + 1)); result.assign(line.substr(p + 1));
} }
} }
} }
} }
if(!result.empty()) { if (!result.empty()) {
#if defined(PLATFORM_UNIX) #if defined(PLATFORM_UNIX)
struct stat sb; struct stat sb;
return (stat(result.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)); return (stat(result.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode));
@ -118,11 +118,11 @@ bool settingsDirectory(std::string &result, std::string applicationDirectoryName
return (ftyp != INVALID_FILE_ATTRIBUTES) && (ftyp & FILE_ATTRIBUTE_DIRECTORY); return (ftyp != INVALID_FILE_ATTRIBUTES) && (ftyp & FILE_ATTRIBUTE_DIRECTORY);
#endif #endif
} else { } else {
if(!applicationDirectoryName.empty()) { if (!applicationDirectoryName.empty()) {
removeInvalidChars(applicationDirectoryName); removeInvalidChars(applicationDirectoryName);
} }
#if defined(PLATFORM_UNIX) || defined(PLATFORM_MAC) #if defined(PLATFORM_UNIX) || defined(PLATFORM_MAC)
if(char *homeDir = getenv("HOME")) { if (char *homeDir = getenv("HOME")) {
result = homeDir; result = homeDir;
} else { } else {
struct passwd *pw = getpwuid(getuid()); struct passwd *pw = getpwuid(getuid());
@ -130,35 +130,35 @@ bool settingsDirectory(std::string &result, std::string applicationDirectoryName
} }
struct stat sb; struct stat sb;
result += "/.config"; result += "/.config";
if(createApplicationDirectory && !(stat(result.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode))) { if (createApplicationDirectory && !(stat(result.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode))) {
if(mkdir(result.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) { if (mkdir(result.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
return false; return false;
} }
} }
if(!applicationDirectoryName.empty()) { if (!applicationDirectoryName.empty()) {
result += '/'; result += '/';
result += applicationDirectoryName; result += applicationDirectoryName;
if(createApplicationDirectory && !(stat(result.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode))) { if (createApplicationDirectory && !(stat(result.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode))) {
if(mkdir(result.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) { if (mkdir(result.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
return false; return false;
} }
} }
} }
#else // PLATFORM_WINDOWS #else // PLATFORM_WINDOWS
if(char *appData = getenv("appdata")) { if (char *appData = getenv("appdata")) {
result = appData; result = appData;
if(!applicationDirectoryName.empty()) { if (!applicationDirectoryName.empty()) {
result += '\\'; result += '\\';
result += applicationDirectoryName; result += applicationDirectoryName;
if(createApplicationDirectory) { if (createApplicationDirectory) {
// FIXME: use UTF-16 API to support unicode, or rewrite using fs abstraction lib // FIXME: use UTF-16 API to support unicode, or rewrite using fs abstraction lib
DWORD ftyp = GetFileAttributesA(result.c_str()); DWORD ftyp = GetFileAttributesA(result.c_str());
if(ftyp == INVALID_FILE_ATTRIBUTES) { if (ftyp == INVALID_FILE_ATTRIBUTES) {
return false; return false;
} else if(ftyp & FILE_ATTRIBUTE_DIRECTORY) { } else if (ftyp & FILE_ATTRIBUTE_DIRECTORY) {
return true; return true;
} else { } else {
if(CreateDirectory(result.c_str(), NULL) == 0) { if (CreateDirectory(result.c_str(), NULL) == 0) {
return false; return false;
} else { } else {
return true; return true;
@ -182,10 +182,10 @@ std::list<std::string> directoryEntries(const char *path, DirectoryEntryType typ
{ {
#ifdef PLATFORM_UNIX #ifdef PLATFORM_UNIX
list<string> entries; list<string> entries;
if(auto dir = opendir(path)) { if (auto dir = opendir(path)) {
while(auto dirEntry = readdir(dir)) { while (auto dirEntry = readdir(dir)) {
bool filter = false; bool filter = false;
switch(dirEntry->d_type) { switch (dirEntry->d_type) {
case DT_REG: case DT_REG:
filter = (types & DirectoryEntryType::File) != DirectoryEntryType::None; filter = (types & DirectoryEntryType::File) != DirectoryEntryType::None;
break; break;
@ -198,7 +198,7 @@ std::list<std::string> directoryEntries(const char *path, DirectoryEntryType typ
default: default:
filter = (types & DirectoryEntryType::All) != DirectoryEntryType::None; filter = (types & DirectoryEntryType::All) != DirectoryEntryType::None;
} }
if(filter) { if (filter) {
entries.emplace_back(dirEntry->d_name); entries.emplace_back(dirEntry->d_name);
} }
} }
@ -209,5 +209,4 @@ std::list<std::string> directoryEntries(const char *path, DirectoryEntryType typ
return list<string>(); // TODO return list<string>(); // TODO
#endif #endif
} }
} }

View File

@ -3,19 +3,19 @@
#include "../global.h" #include "../global.h"
#include <string>
#include <list> #include <list>
#include <string>
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# define PATH_SEP_CHAR '\\' #define PATH_SEP_CHAR '\\'
# define SEARCH_PATH_SEP_CHAR ';' #define SEARCH_PATH_SEP_CHAR ';'
# define PATH_SEP_STR "\\" #define PATH_SEP_STR "\\"
# define SEARCH_PATH_SEP_STR ";" #define SEARCH_PATH_SEP_STR ";"
#else #else
# define PATH_SEP_CHAR '/' #define PATH_SEP_CHAR '/'
# define SEARCH_PATH_SEP_CHAR ':' #define SEARCH_PATH_SEP_CHAR ':'
# define PATH_SEP_STR "/" #define PATH_SEP_STR "/"
# define SEARCH_PATH_SEP_STR ":" #define SEARCH_PATH_SEP_STR ":"
#endif #endif
namespace IoUtilities { namespace IoUtilities {
@ -23,14 +23,7 @@ namespace IoUtilities {
/*! /*!
* \brief The DirectoryEntryType enum specifies the type of a directory entry (file, directory or symlink). * \brief The DirectoryEntryType enum specifies the type of a directory entry (file, directory or symlink).
*/ */
enum class DirectoryEntryType : unsigned char enum class DirectoryEntryType : unsigned char { None = 0, File = 1, Directory = 2, Symlink = 4, All = 0xFF };
{
None = 0,
File = 1,
Directory = 2,
Symlink = 4,
All = 0xFF
};
constexpr DirectoryEntryType operator|(DirectoryEntryType lhs, DirectoryEntryType rhs) constexpr DirectoryEntryType operator|(DirectoryEntryType lhs, DirectoryEntryType rhs)
{ {
@ -50,9 +43,9 @@ constexpr DirectoryEntryType operator&(DirectoryEntryType lhs, DirectoryEntryTyp
CPP_UTILITIES_EXPORT std::string fileName(const std::string &path); CPP_UTILITIES_EXPORT std::string fileName(const std::string &path);
CPP_UTILITIES_EXPORT std::string directory(const std::string &path); CPP_UTILITIES_EXPORT std::string directory(const std::string &path);
CPP_UTILITIES_EXPORT void removeInvalidChars(std::string &fileName); CPP_UTILITIES_EXPORT void removeInvalidChars(std::string &fileName);
CPP_UTILITIES_EXPORT bool settingsDirectory(std::string &result, std::string applicationDirectoryName = std::string(), bool createApplicationDirectory = false); CPP_UTILITIES_EXPORT bool settingsDirectory(
std::string &result, std::string applicationDirectoryName = std::string(), bool createApplicationDirectory = false);
CPP_UTILITIES_EXPORT std::list<std::string> directoryEntries(const char *path, DirectoryEntryType types = DirectoryEntryType::All); CPP_UTILITIES_EXPORT std::list<std::string> directoryEntries(const char *path, DirectoryEntryType types = DirectoryEntryType::All);
} }
#endif // IOUTILITIES_PATHHELPER_H #endif // IOUTILITIES_PATHHELPER_H

View File

@ -1,7 +1,7 @@
#include "./math.h" #include "./math.h"
#include <cstdlib>
#include <cassert> #include <cassert>
#include <cstdlib>
/*! /*!
* \namespace MathUtilities * \namespace MathUtilities
@ -24,7 +24,7 @@ int MathUtilities::random(int lowerbounds, int upperbounds)
int MathUtilities::digitsum(int number, int base) int MathUtilities::digitsum(int number, int base)
{ {
int res = 0; int res = 0;
while(number > 0) { while (number > 0) {
res += number % base; res += number % base;
number /= base; number /= base;
} }
@ -37,7 +37,7 @@ int MathUtilities::digitsum(int number, int base)
int MathUtilities::factorial(int number) int MathUtilities::factorial(int number)
{ {
int res = 1; int res = 1;
for(int i = 1; i <= number; ++i) { for (int i = 1; i <= number; ++i) {
res *= i; res *= i;
} }
return res; return res;
@ -49,11 +49,11 @@ int MathUtilities::factorial(int number)
uint64 powerModulo(const uint64 base, const uint64 exponent, const uint64 module) uint64 powerModulo(const uint64 base, const uint64 exponent, const uint64 module)
{ {
uint64 res = 1; uint64 res = 1;
for(uint64 mask = 0x8000000000000000; mask; mask >>= 1) { for (uint64 mask = 0x8000000000000000; mask; mask >>= 1) {
if(mask & exponent) { if (mask & exponent) {
res *= base; res *= base;
} }
if(mask != 1) { if (mask != 1) {
res *= res; res *= res;
} }
res %= module; res %= module;
@ -67,7 +67,7 @@ uint64 powerModulo(const uint64 base, const uint64 exponent, const uint64 module
int64 inverseModulo(int64 number, int64 module) int64 inverseModulo(int64 number, int64 module)
{ {
int64 y1 = 0, y2 = 1, tmp; int64 y1 = 0, y2 = 1, tmp;
while(number != 1) { while (number != 1) {
tmp = y1 - (module / number) * y2; tmp = y1 - (module / number) * y2;
y1 = y2; y1 = y2;
y2 = tmp; y2 = tmp;
@ -84,6 +84,7 @@ int64 inverseModulo(int64 number, int64 module)
uint64 orderModulo(const uint64 number, const uint64 module) uint64 orderModulo(const uint64 number, const uint64 module)
{ {
uint64 order = 1; uint64 order = 1;
for(; powerModulo(number, order, module) != 1; ++order); for (; powerModulo(number, order, module) != 1; ++order)
;
return order; return order;
} }

View File

@ -1,8 +1,8 @@
#ifndef MATHUTILITIES_H #ifndef MATHUTILITIES_H
#define MATHUTILITIES_H #define MATHUTILITIES_H
#include "../global.h"
#include "../conversion/types.h" #include "../conversion/types.h"
#include "../global.h"
namespace MathUtilities { namespace MathUtilities {
@ -12,7 +12,6 @@ CPP_UTILITIES_EXPORT int factorial(int number);
CPP_UTILITIES_EXPORT uint64 powerModulo(uint64 base, uint64 expontent, uint64 module); CPP_UTILITIES_EXPORT uint64 powerModulo(uint64 base, uint64 expontent, uint64 module);
CPP_UTILITIES_EXPORT int64 inverseModulo(int64 number, int64 module); CPP_UTILITIES_EXPORT int64 inverseModulo(int64 number, int64 module);
CPP_UTILITIES_EXPORT uint64 orderModulo(uint64 number, uint64 module); CPP_UTILITIES_EXPORT uint64 orderModulo(uint64 number, uint64 module);
} }
#endif // MATHUTILITIES_H #endif // MATHUTILITIES_H

View File

@ -8,38 +8,36 @@
#if __cplusplus <= 201103L #if __cplusplus <= 201103L
#define __cpp_lib_make_unique 201304 #define __cpp_lib_make_unique 201304
namespace std { namespace std {
template<typename _Tp> template <typename _Tp> struct _MakeUniq {
struct _MakeUniq typedef unique_ptr<_Tp> __single_object;
{ typedef unique_ptr<_Tp> __single_object; }; };
template<typename _Tp> template <typename _Tp> struct _MakeUniq<_Tp[]> {
struct _MakeUniq<_Tp[]> typedef unique_ptr<_Tp[]> __array;
{ typedef unique_ptr<_Tp[]> __array; }; };
template<typename _Tp, size_t _Bound> template <typename _Tp, size_t _Bound> struct _MakeUniq<_Tp[_Bound]> {
struct _MakeUniq<_Tp[_Bound]> struct __invalid_type {
{ struct __invalid_type { }; }; };
};
/// std::make_unique for single objects /// std::make_unique for single objects
template<typename _Tp, typename... _Args> template <typename _Tp, typename... _Args> inline typename _MakeUniq<_Tp>::__single_object make_unique(_Args &&... __args)
inline typename _MakeUniq<_Tp>::__single_object {
make_unique(_Args&&... __args) return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));
{ return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } }
/// std::make_unique for arrays of unknown bound /// std::make_unique for arrays of unknown bound
template<typename _Tp> template <typename _Tp> inline typename _MakeUniq<_Tp>::__array make_unique(size_t __num)
inline typename _MakeUniq<_Tp>::__array {
make_unique(size_t __num) return unique_ptr<_Tp>(new typename remove_extent<_Tp>::type[__num]());
{ return unique_ptr<_Tp>(new typename remove_extent<_Tp>::type[__num]()); } }
/// Disable std::make_unique for arrays of known bound /// Disable std::make_unique for arrays of known bound
template<typename _Tp, typename... _Args> template <typename _Tp, typename... _Args> inline typename _MakeUniq<_Tp>::__invalid_type make_unique(_Args &&...) = delete;
inline typename _MakeUniq<_Tp>::__invalid_type
make_unique(_Args&&...) = delete;
} }
#endif #endif
/// \endcond /// \endcond
#endif // MEMORY_H #endif // MEMORY_H

View File

@ -1,11 +1,11 @@
#include "./random.h" #include "./random.h"
#include <iomanip> #include <cassert>
#include <string>
#include <sstream>
#include <cmath> #include <cmath>
#include <cstdlib> #include <cstdlib>
#include <cassert> #include <iomanip>
#include <sstream>
#include <string>
using namespace std; using namespace std;
@ -28,9 +28,10 @@ const char symbols[24] = "!\"$%&/()=?'#*+~-_><.:,;";
* \brief Generates a random character sequence using the given \a randomizer. * \brief Generates a random character sequence using the given \a randomizer.
* \deprecated Might be removed in future release because API is bad and it is not used anymore anyways. * \deprecated Might be removed in future release because API is bad and it is not used anymore anyways.
*/ */
void generateRandomCharacterSequence(char *result, unsigned int length, std::function<int ()> randomizer, int highestRandomNumber, bool useSmallLetters, bool useCapitalLetters, bool useNumbers, bool useSymbols, bool useAtLeastOneOfEachCategory) void generateRandomCharacterSequence(char *result, unsigned int length, std::function<int()> randomizer, int highestRandomNumber,
bool useSmallLetters, bool useCapitalLetters, bool useNumbers, bool useSymbols, bool useAtLeastOneOfEachCategory)
{ {
if(length) { if (length) {
return; return;
} }
signed char categoryCount = 0; signed char categoryCount = 0;
@ -38,73 +39,73 @@ void generateRandomCharacterSequence(char *result, unsigned int length, std::fun
bool needCapitalLetter = false; bool needCapitalLetter = false;
bool needNumber = false; bool needNumber = false;
bool needSymbol = false; bool needSymbol = false;
if(useSmallLetters) { if (useSmallLetters) {
needSmallLetter = useAtLeastOneOfEachCategory; needSmallLetter = useAtLeastOneOfEachCategory;
++categoryCount; ++categoryCount;
} }
if(useCapitalLetters) { if (useCapitalLetters) {
needCapitalLetter = useAtLeastOneOfEachCategory; needCapitalLetter = useAtLeastOneOfEachCategory;
++categoryCount; ++categoryCount;
} }
if(useNumbers) { if (useNumbers) {
needNumber = useAtLeastOneOfEachCategory; needNumber = useAtLeastOneOfEachCategory;
++categoryCount; ++categoryCount;
} }
if(useSymbols) { if (useSymbols) {
needSymbol = useAtLeastOneOfEachCategory; needSymbol = useAtLeastOneOfEachCategory;
++categoryCount; ++categoryCount;
} }
signed char neededCharacters = useAtLeastOneOfEachCategory ? categoryCount : 0; signed char neededCharacters = useAtLeastOneOfEachCategory ? categoryCount : 0;
if(!categoryCount) { if (!categoryCount) {
*result = '\0'; *result = '\0';
return; return;
} }
for(char *i = result, *end = result + length; i < end; ++i) { for (char *i = result, *end = result + length; i < end; ++i) {
int category = -1; int category = -1;
if((neededCharacters > 0 && (randomizer() < (highestRandomNumber / 2.0))) || ((end - i) >= neededCharacters)) { if ((neededCharacters > 0 && (randomizer() < (highestRandomNumber / 2.0))) || ((end - i) >= neededCharacters)) {
if(needSmallLetter) if (needSmallLetter)
category = 0; category = 0;
if(needCapitalLetter && ((category == -1) || (randomizer() < (highestRandomNumber / 2.0)))) if (needCapitalLetter && ((category == -1) || (randomizer() < (highestRandomNumber / 2.0))))
category = 1; category = 1;
if(needNumber && ((category == -1) || (randomizer() < (highestRandomNumber / 4.0)))) if (needNumber && ((category == -1) || (randomizer() < (highestRandomNumber / 4.0))))
category = 2; category = 2;
if(needSymbol && ((category == -1) || (randomizer() < (highestRandomNumber / 8.0)))) if (needSymbol && ((category == -1) || (randomizer() < (highestRandomNumber / 8.0))))
category = 3; category = 3;
} else { } else {
if(useSmallLetters) if (useSmallLetters)
category = 0; category = 0;
if(useCapitalLetters && ((category == -1) || (randomizer() < (highestRandomNumber / 2.0)))) if (useCapitalLetters && ((category == -1) || (randomizer() < (highestRandomNumber / 2.0))))
category = 1; category = 1;
if(useNumbers && ((category == -1) || (randomizer() < (highestRandomNumber / 4.0)))) if (useNumbers && ((category == -1) || (randomizer() < (highestRandomNumber / 4.0))))
category = 2; category = 2;
if(useSymbols && ((category == -1) || (randomizer() < (highestRandomNumber / 8.0)))) if (useSymbols && ((category == -1) || (randomizer() < (highestRandomNumber / 8.0))))
category = 3; category = 3;
} }
switch(category) { switch (category) {
case 0: case 0:
*i = letters[rand() % 26]; *i = letters[rand() % 26];
if(needSmallLetter) { if (needSmallLetter) {
needSmallLetter = false; needSmallLetter = false;
--neededCharacters; --neededCharacters;
} }
break; break;
case 1: case 1:
*i = capitalLetters[rand() % 26]; *i = capitalLetters[rand() % 26];
if(needCapitalLetter) { if (needCapitalLetter) {
needCapitalLetter = false; needCapitalLetter = false;
--neededCharacters; --neededCharacters;
} }
break; break;
case 2: case 2:
*i = numbers[rand() % 9]; *i = numbers[rand() % 9];
if(needNumber) { if (needNumber) {
needNumber = false; needNumber = false;
--neededCharacters; --neededCharacters;
} }
break; break;
case 3: case 3:
*i = symbols[rand() % 22]; *i = symbols[rand() % 22];
if(needSymbol) { if (needSymbol) {
needSymbol = false; needSymbol = false;
--neededCharacters; --neededCharacters;
} }
@ -117,10 +118,10 @@ void generateRandomCharacterSequence(char *result, unsigned int length, std::fun
* \brief Generates a random character sequence using std::rand(). * \brief Generates a random character sequence using std::rand().
* \deprecated Might be removed in future release because API is bad and it is not used anymore anyways. * \deprecated Might be removed in future release because API is bad and it is not used anymore anyways.
*/ */
void generateRandomCharacterSequence(char *result, unsigned int length, bool useSmallLetters, bool useCapitalLetters, bool useNumbers, bool useSymbols, bool useAtLeastOneOfEachCategory) void generateRandomCharacterSequence(char *result, unsigned int length, bool useSmallLetters, bool useCapitalLetters, bool useNumbers,
bool useSymbols, bool useAtLeastOneOfEachCategory)
{ {
generateRandomCharacterSequence(result, length, rand, RAND_MAX, useSmallLetters, useCapitalLetters, useNumbers, useSymbols, useAtLeastOneOfEachCategory); generateRandomCharacterSequence(
result, length, rand, RAND_MAX, useSmallLetters, useCapitalLetters, useNumbers, useSymbols, useAtLeastOneOfEachCategory);
} }
} }

View File

@ -7,9 +7,11 @@
namespace RandomUtilities { namespace RandomUtilities {
CPP_UTILITIES_EXPORT void generateRandomCharacterSequence(char *result, unsigned int length, bool useSmallLetters = true, bool useCapitalLetters = true, bool useNumbers = true, bool useSymbols = true, bool useAtLeastOneOfEachCategory = true); CPP_UTILITIES_EXPORT void generateRandomCharacterSequence(char *result, unsigned int length, bool useSmallLetters = true,
CPP_UTILITIES_EXPORT void generateRandomCharacterSequence(char *result, unsigned int length, std::function<int ()> randomizer, int maximalRandomNumber, bool useSmallLetters = true, bool useCapitalLetters = true, bool useNumbers = true, bool useSymbols = true, bool useAtLeastOneOfEachCategory = true); bool useCapitalLetters = true, bool useNumbers = true, bool useSymbols = true, bool useAtLeastOneOfEachCategory = true);
CPP_UTILITIES_EXPORT void generateRandomCharacterSequence(char *result, unsigned int length, std::function<int()> randomizer, int maximalRandomNumber,
bool useSmallLetters = true, bool useCapitalLetters = true, bool useNumbers = true, bool useSymbols = true,
bool useAtLeastOneOfEachCategory = true);
} }
#endif // RANDOMUTILS_H #endif // RANDOMUTILS_H

View File

@ -8,45 +8,37 @@ namespace Traits {
/// \cond /// \cond
namespace Detail { namespace Detail {
enum class Enabler {}; enum class Enabler {};
} }
/// \endcond /// \endcond
template <typename If, typename Then, typename Else> template <typename If, typename Then, typename Else> using Conditional = typename std::conditional<If::value, Then, Else>::type;
using Conditional = typename std::conditional<If::value, Then, Else>::type;
template <bool B, typename...> template <bool B, typename...> struct Bool : std::integral_constant<bool, B> {
struct Bool : std::integral_constant<bool, B> {}; };
template <typename T> template <typename T> using Not = Bool<!T::value>;
using Not = Bool<!T::value>;
template <typename... T> template <typename... T> struct Any : Bool<false> {
struct Any : Bool<false> {}; };
template <typename Head, typename... Tail> template <typename Head, typename... Tail> struct Any<Head, Tail...> : Conditional<Head, Bool<true>, Any<Tail...> > {
struct Any<Head, Tail...> : Conditional<Head, Bool<true>, Any<Tail...> > {}; };
template <typename... T> template <typename... T> struct All : Bool<true> {
struct All : Bool<true> {}; };
template <typename Head, typename... Tail> template <typename Head, typename... Tail> struct All<Head, Tail...> : Conditional<Head, All<Tail...>, Bool<false> > {
struct All<Head, Tail...> : Conditional<Head, All<Tail...>, Bool<false> > {}; };
template <typename... Condition> template <typename... Condition> using EnableIf = typename std::enable_if<All<Condition...>::value, Detail::Enabler>::type;
using EnableIf = typename std::enable_if<All<Condition...>::value, Detail::Enabler>::type; template <typename... Condition> using DisableIf = typename std::enable_if<!All<Condition...>::value, Detail::Enabler>::type;
template <typename... Condition>
using DisableIf = typename std::enable_if<!All<Condition...>::value, Detail::Enabler>::type;
template <typename... Condition> template <typename... Condition> using EnableIfAny = typename std::enable_if<Any<Condition...>::value, Detail::Enabler>::type;
using EnableIfAny = typename std::enable_if<Any<Condition...>::value, Detail::Enabler>::type; template <typename... Condition> using DisableIfAny = typename std::enable_if<!Any<Condition...>::value, Detail::Enabler>::type;
template <typename... Condition>
using DisableIfAny = typename std::enable_if<!Any<Condition...>::value, Detail::Enabler>::type;
template <typename T, template <typename...> class Template>
struct IsSpecializationOf : Bool<false> {};
template <template <typename...> class Template, typename... Args>
struct IsSpecializationOf<Template<Args...>, Template> : Bool<true> {};
template <typename T, template <typename...> class Template> struct IsSpecializationOf : Bool<false> {
};
template <template <typename...> class Template, typename... Args> struct IsSpecializationOf<Template<Args...>, Template> : Bool<true> {
};
} }
#endif // CPP_UTILITIES_TRAITS_H #endif // CPP_UTILITIES_TRAITS_H

View File

@ -3,9 +3,9 @@
#include "./testutils.h" #include "./testutils.h"
#include <cppunit/TestPath.h>
#include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h> #include <cppunit/ui/text/TestRunner.h>
#include <cppunit/TestPath.h>
#include <iostream> #include <iostream>
@ -19,20 +19,20 @@ using namespace CPPUNIT_NS;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
TestApplication testApp(argc, argv); TestApplication testApp(argc, argv);
if(testApp) { if (testApp) {
// run tests // run tests
TextUi::TestRunner runner; TextUi::TestRunner runner;
TestFactoryRegistry &registry = TestFactoryRegistry::getRegistry(); TestFactoryRegistry &registry = TestFactoryRegistry::getRegistry();
if(!testApp.unitsSpecified() || testApp.units().empty()) { if (!testApp.unitsSpecified() || testApp.units().empty()) {
// no units specified -> test all // no units specified -> test all
runner.addTest(registry.makeTest()); runner.addTest(registry.makeTest());
} else { } else {
// pick specified units from overall test // pick specified units from overall test
Test *overallTest = registry.makeTest(); Test *overallTest = registry.makeTest();
for(const char *unit : testApp.units()) { for (const char *unit : testApp.units()) {
try { try {
runner.addTest(overallTest->findTest(unit)); runner.addTest(overallTest->findTest(unit));
} catch(const invalid_argument &) { } catch (const invalid_argument &) {
cerr << "The specified test unit \"" << unit << "\" is not available and will be ignored." << endl; cerr << "The specified test unit \"" << unit << "\" is not available and will be ignored." << endl;
} }
} }

View File

@ -6,15 +6,15 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <iostream>
#include <fstream> #include <fstream>
#include <initializer_list> #include <initializer_list>
#include <iostream>
#ifdef PLATFORM_UNIX #ifdef PLATFORM_UNIX
# include <unistd.h> #include <poll.h>
# include <poll.h> #include <sys/stat.h>
# include <sys/wait.h> #include <sys/wait.h>
# include <sys/stat.h> #include <unistd.h>
#endif #endif
using namespace std; using namespace std;
@ -39,22 +39,22 @@ TestApplication *TestApplication::m_instance = nullptr;
* \brief Constructs a TestApplication instance. * \brief Constructs a TestApplication instance.
* \throws Throws std::runtime_error if an instance has already been created. * \throws Throws std::runtime_error if an instance has already been created.
*/ */
TestApplication::TestApplication(int argc, char **argv) : TestApplication::TestApplication(int argc, char **argv)
m_helpArg(m_parser), : m_helpArg(m_parser)
m_testFilesPathArg("test-files-path", 'p', "specifies the path of the directory with test files"), , m_testFilesPathArg("test-files-path", 'p', "specifies the path of the directory with test files")
m_applicationPathArg("app-path",'a', "specifies the path of the application to be tested"), , m_applicationPathArg("app-path", 'a', "specifies the path of the application to be tested")
m_workingDirArg("working-dir", 'w', "specifies the directory to store working copies of test files"), , m_workingDirArg("working-dir", 'w', "specifies the directory to store working copies of test files")
m_unitsArg("units", 'u', "specifies the units to test; omit to test all units") , m_unitsArg("units", 'u', "specifies the units to test; omit to test all units")
{ {
// check whether there is already an instance // check whether there is already an instance
if(m_instance) { if (m_instance) {
throw runtime_error("only one TestApplication instance allowed at a time"); throw runtime_error("only one TestApplication instance allowed at a time");
} }
m_instance = this; m_instance = this;
// read TEST_FILE_PATH environment variable // read TEST_FILE_PATH environment variable
if(const char *testFilesPathEnv = getenv("TEST_FILE_PATH")) { if (const char *testFilesPathEnv = getenv("TEST_FILE_PATH")) {
if(const auto len = strlen(testFilesPathEnv)) { if (const auto len = strlen(testFilesPathEnv)) {
m_testFilesPathEnvValue.reserve(len + 1); m_testFilesPathEnvValue.reserve(len + 1);
m_testFilesPathEnvValue += testFilesPathEnv; m_testFilesPathEnvValue += testFilesPathEnv;
m_testFilesPathEnvValue += '/'; m_testFilesPathEnvValue += '/';
@ -62,52 +62,52 @@ TestApplication::TestApplication(int argc, char **argv) :
} }
// setup argument parser // setup argument parser
for(Argument *arg : initializer_list<Argument *>{&m_testFilesPathArg, &m_applicationPathArg, &m_workingDirArg}) { for (Argument *arg : initializer_list<Argument *>{ &m_testFilesPathArg, &m_applicationPathArg, &m_workingDirArg }) {
arg->setRequiredValueCount(1); arg->setRequiredValueCount(1);
arg->setValueNames({"path"}); arg->setValueNames({ "path" });
arg->setCombinable(true); arg->setCombinable(true);
} }
m_unitsArg.setRequiredValueCount(-1); m_unitsArg.setRequiredValueCount(-1);
m_unitsArg.setValueNames({"unit1", "unit2", "unit3"}); m_unitsArg.setValueNames({ "unit1", "unit2", "unit3" });
m_unitsArg.setCombinable(true); m_unitsArg.setCombinable(true);
m_parser.setMainArguments({&m_testFilesPathArg, &m_applicationPathArg, &m_workingDirArg, &m_unitsArg, &m_helpArg}); m_parser.setMainArguments({ &m_testFilesPathArg, &m_applicationPathArg, &m_workingDirArg, &m_unitsArg, &m_helpArg });
// parse arguments // parse arguments
try { try {
m_parser.parseArgs(argc, argv); m_parser.parseArgs(argc, argv);
if(m_helpArg.isPresent()) { if (m_helpArg.isPresent()) {
m_valid = false; m_valid = false;
exit(0); exit(0);
} }
cerr << "Directories used to search for testfiles:" << endl; cerr << "Directories used to search for testfiles:" << endl;
if(m_testFilesPathArg.isPresent()) { if (m_testFilesPathArg.isPresent()) {
if(*m_testFilesPathArg.values().front()) { if (*m_testFilesPathArg.values().front()) {
cerr << ((m_testFilesPathArgValue = m_testFilesPathArg.values().front()) += '/') << endl; cerr << ((m_testFilesPathArgValue = m_testFilesPathArg.values().front()) += '/') << endl;
} else { } else {
cerr << (m_testFilesPathArgValue = "./") << endl; cerr << (m_testFilesPathArgValue = "./") << endl;
} }
} }
if(!m_testFilesPathEnvValue.empty()) { if (!m_testFilesPathEnvValue.empty()) {
cerr << m_testFilesPathEnvValue << endl; cerr << m_testFilesPathEnvValue << endl;
} }
cerr << "./testfiles/" << endl << endl; cerr << "./testfiles/" << endl << endl;
cerr << "Directory used to store working copies:" << endl; cerr << "Directory used to store working copies:" << endl;
if(m_workingDirArg.isPresent()) { if (m_workingDirArg.isPresent()) {
if(*m_workingDirArg.values().front()) { if (*m_workingDirArg.values().front()) {
(m_workingDir = m_workingDirArg.values().front()) += '/'; (m_workingDir = m_workingDirArg.values().front()) += '/';
} else { } else {
m_workingDir = "./"; m_workingDir = "./";
} }
} else if(const char *workingDirEnv = getenv("WORKING_DIR")) { } else if (const char *workingDirEnv = getenv("WORKING_DIR")) {
if(const auto len = strlen(workingDirEnv)) { if (const auto len = strlen(workingDirEnv)) {
m_workingDir.reserve(len + 1); m_workingDir.reserve(len + 1);
m_workingDir += workingDirEnv; m_workingDir += workingDirEnv;
m_workingDir += '/'; m_workingDir += '/';
} }
} else { } else {
if(m_testFilesPathArg.isPresent()) { if (m_testFilesPathArg.isPresent()) {
m_workingDir = m_testFilesPathArgValue + "workingdir/"; m_workingDir = m_testFilesPathArgValue + "workingdir/";
} else if(!m_testFilesPathEnvValue.empty()) { } else if (!m_testFilesPathEnvValue.empty()) {
m_workingDir = m_testFilesPathEnvValue + "workingdir/"; m_workingDir = m_testFilesPathEnvValue + "workingdir/";
} else { } else {
m_workingDir = "./testfiles/workingdir/"; m_workingDir = "./testfiles/workingdir/";
@ -117,7 +117,7 @@ TestApplication::TestApplication(int argc, char **argv) :
m_valid = true; m_valid = true;
cerr << "Executing test cases ..." << endl; cerr << "Executing test cases ..." << endl;
} catch(const Failure &failure) { } catch (const Failure &failure) {
cerr << "Invalid arguments specified: " << failure.what() << endl; cerr << "Invalid arguments specified: " << failure.what() << endl;
m_valid = false; m_valid = false;
} }
@ -140,18 +140,18 @@ string TestApplication::testFilePath(const string &name) const
fstream file; // used to check whether the file is present fstream file; // used to check whether the file is present
// check the path specified by command line argument // check the path specified by command line argument
if(m_testFilesPathArg.isPresent()) { if (m_testFilesPathArg.isPresent()) {
file.open(path = m_testFilesPathArgValue + name, ios_base::in); file.open(path = m_testFilesPathArgValue + name, ios_base::in);
if(file.good()) { if (file.good()) {
return path; return path;
} }
} }
// check the path specified by environment variable // check the path specified by environment variable
if(!m_testFilesPathEnvValue.empty()) { if (!m_testFilesPathEnvValue.empty()) {
file.clear(); file.clear();
file.open(path = m_testFilesPathEnvValue + name, ios_base::in); file.open(path = m_testFilesPathEnvValue + name, ios_base::in);
if(file.good()) { if (file.good()) {
return path; return path;
} }
} }
@ -160,7 +160,7 @@ string TestApplication::testFilePath(const string &name) const
path = "./testfiles/" + name; path = "./testfiles/" + name;
file.clear(); file.clear();
file.open(path = m_testFilesPathEnvValue + name, ios_base::in); file.open(path = m_testFilesPathEnvValue + name, ios_base::in);
if(!file.good()) { if (!file.good()) {
cerr << "Warning: The testfile \"" << path << "\" can not be located." << endl; cerr << "Warning: The testfile \"" << path << "\" can not be located." << endl;
} }
return path; return path;
@ -180,8 +180,8 @@ string TestApplication::workingCopyPathMode(const string &name, WorkingCopyMode
// ensure working directory is present // ensure working directory is present
struct stat currentStat; struct stat currentStat;
if(stat(m_workingDir.c_str(), &currentStat) || !S_ISDIR(currentStat.st_mode)) { if (stat(m_workingDir.c_str(), &currentStat) || !S_ISDIR(currentStat.st_mode)) {
if(mkdir(m_workingDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) { if (mkdir(m_workingDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
cerr << "Unable to create working copy for \"" << name << "\": can't create working directory." << endl; cerr << "Unable to create working copy for \"" << name << "\": can't create working directory." << endl;
return string(); return string();
} }
@ -189,15 +189,15 @@ string TestApplication::workingCopyPathMode(const string &name, WorkingCopyMode
// ensure subdirectory exists // ensure subdirectory exists
const auto parts = splitString<vector<string> >(name, string("/"), EmptyPartsTreat::Omit); const auto parts = splitString<vector<string> >(name, string("/"), EmptyPartsTreat::Omit);
if(!parts.empty()) { if (!parts.empty()) {
string currentLevel = m_workingDir; string currentLevel = m_workingDir;
for(auto i = parts.cbegin(), end = parts.end() - 1; i != end; ++i) { for (auto i = parts.cbegin(), end = parts.end() - 1; i != end; ++i) {
if(currentLevel.back() != '/') { if (currentLevel.back() != '/') {
currentLevel += '/'; currentLevel += '/';
} }
currentLevel += *i; currentLevel += *i;
if(stat(currentLevel.c_str(), &currentStat) || !S_ISDIR(currentStat.st_mode)) { if (stat(currentLevel.c_str(), &currentStat) || !S_ISDIR(currentStat.st_mode)) {
if(mkdir(currentLevel.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) { if (mkdir(currentLevel.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
cerr << "Unable to create working copy for \"" << name << "\": can't create working directory." << endl; cerr << "Unable to create working copy for \"" << name << "\": can't create working directory." << endl;
return string(); return string();
} }
@ -206,14 +206,14 @@ string TestApplication::workingCopyPathMode(const string &name, WorkingCopyMode
} }
// copy file // copy file
if(mode != WorkingCopyMode::NoCopy) { if (mode != WorkingCopyMode::NoCopy) {
try { try {
origFile.open(testFilePath(name), ios_base::in | ios_base::binary); origFile.open(testFilePath(name), ios_base::in | ios_base::binary);
const string path = m_workingDir + name; const string path = m_workingDir + name;
workingCopy.open(path, ios_base::out | ios_base::binary | ios_base::trunc); workingCopy.open(path, ios_base::out | ios_base::binary | ios_base::trunc);
workingCopy << origFile.rdbuf(); workingCopy << origFile.rdbuf();
return path; return path;
} catch(...) { } catch (...) {
catchIoFailure(); catchIoFailure();
cerr << "Unable to create working copy for \"" << name << "\": an IO error occured." << endl; cerr << "Unable to create working copy for \"" << name << "\": an IO error occured." << endl;
} }
@ -240,16 +240,16 @@ string TestApplication::workingCopyPath(const string &name) const
int TestApplication::execApp(const char *const *args, string &stdout, string &stderr, bool suppressLogging, int timeout) const int TestApplication::execApp(const char *const *args, string &stdout, string &stderr, bool suppressLogging, int timeout) const
{ {
// print log message // print log message
if(!suppressLogging) { if (!suppressLogging) {
cout << '-'; cout << '-';
for(const char *const *i = args; *i; ++i) { for (const char *const *i = args; *i; ++i) {
cout << ' ' << *i; cout << ' ' << *i;
} }
cout << endl; cout << endl;
} }
// determine application path // determine application path
const char *appPath = m_applicationPathArg.firstValue(); const char *appPath = m_applicationPathArg.firstValue();
if(!appPath || !*appPath) { if (!appPath || !*appPath) {
throw runtime_error("Unable to execute application to be tested: no application path specified"); throw runtime_error("Unable to execute application to be tested: no application path specified");
} }
// create pipes // create pipes
@ -258,12 +258,12 @@ int TestApplication::execApp(const char *const *args, string &stdout, string &st
int readCoutPipe = coutPipes[0], writeCoutPipe = coutPipes[1]; int readCoutPipe = coutPipes[0], writeCoutPipe = coutPipes[1];
int readCerrPipe = cerrPipes[0], writeCerrPipe = cerrPipes[1]; int readCerrPipe = cerrPipes[0], writeCerrPipe = cerrPipes[1];
// create child process // create child process
if(int child = fork()) { if (int child = fork()) {
// parent process: read stdout and stderr from child // parent process: read stdout and stderr from child
close(writeCoutPipe), close(writeCerrPipe); close(writeCoutPipe), close(writeCerrPipe);
try { try {
if(child == -1) { if (child == -1) {
throw runtime_error("Unable to create fork"); throw runtime_error("Unable to create fork");
} }
@ -281,33 +281,33 @@ int TestApplication::execApp(const char *const *args, string &stdout, string &st
// poll as long as at least one pipe is open // poll as long as at least one pipe is open
do { do {
int retpoll = poll(fileDescriptorSet, 2, timeout); int retpoll = poll(fileDescriptorSet, 2, timeout);
if(retpoll > 0) { if (retpoll > 0) {
// poll succeeds // poll succeeds
if(fileDescriptorSet[0].revents & POLLIN) { if (fileDescriptorSet[0].revents & POLLIN) {
if((count = read(readCoutPipe, buffer, sizeof(buffer))) > 0) { if ((count = read(readCoutPipe, buffer, sizeof(buffer))) > 0) {
stdout.append(buffer, count); stdout.append(buffer, count);
} }
} else if(fileDescriptorSet[0].revents & POLLHUP) { } else if (fileDescriptorSet[0].revents & POLLHUP) {
close(readCoutPipe); close(readCoutPipe);
fileDescriptorSet[0].fd = -1; fileDescriptorSet[0].fd = -1;
} }
if(fileDescriptorSet[1].revents & POLLIN) { if (fileDescriptorSet[1].revents & POLLIN) {
if((count = read(readCerrPipe, buffer, sizeof(buffer))) > 0) { if ((count = read(readCerrPipe, buffer, sizeof(buffer))) > 0) {
stderr.append(buffer, count); stderr.append(buffer, count);
} }
} else if(fileDescriptorSet[1].revents & POLLHUP) { } else if (fileDescriptorSet[1].revents & POLLHUP) {
close(readCerrPipe); close(readCerrPipe);
fileDescriptorSet[1].fd = -1; fileDescriptorSet[1].fd = -1;
} }
} else if(retpoll == 0) { } else if (retpoll == 0) {
// timeout // timeout
throw runtime_error("Poll time-out"); throw runtime_error("Poll time-out");
} else { } else {
// fail // fail
throw runtime_error("Poll failed"); throw runtime_error("Poll failed");
} }
} while(fileDescriptorSet[0].fd >= 0 || fileDescriptorSet[1].fd >= 0); } while (fileDescriptorSet[0].fd >= 0 || fileDescriptorSet[1].fd >= 0);
} catch(...) { } catch (...) {
// ensure all pipes are close in the error case // ensure all pipes are close in the error case
close(readCoutPipe), close(readCerrPipe); close(readCoutPipe), close(readCerrPipe);
throw; throw;
@ -327,5 +327,4 @@ int TestApplication::execApp(const char *const *args, string &stdout, string &st
} }
} }
#endif #endif
} }

View File

@ -3,22 +3,20 @@
#include "../application/argumentparser.h" #include "../application/argumentparser.h"
#include <string>
#include <ostream> #include <ostream>
#include <string>
namespace TestUtilities { namespace TestUtilities {
/*! /*!
* \brief The WorkingCopyMode enum specifies additional options to influence behavior of TestApplication::workingCopyPathMode(). * \brief The WorkingCopyMode enum specifies additional options to influence behavior of TestApplication::workingCopyPathMode().
*/ */
enum class WorkingCopyMode enum class WorkingCopyMode {
{
CreateCopy, /**< a working copy of the test file is created */ CreateCopy, /**< a working copy of the test file is created */
NoCopy /**< only the directory for the working copy is created but not the test file itself */ NoCopy /**< only the directory for the working copy is created but not the test file itself */
}; };
class CPP_UTILITIES_EXPORT TestApplication class CPP_UTILITIES_EXPORT TestApplication {
{
public: public:
TestApplication(int argc, char **argv); TestApplication(int argc, char **argv);
~TestApplication(); ~TestApplication();
@ -130,11 +128,13 @@ inline CPP_UTILITIES_EXPORT int execApp(const char *const *args, std::string &ou
* \brief The AsHexNumber class allows printing values asserted with cppunit (or similar test framework) using the * \brief The AsHexNumber class allows printing values asserted with cppunit (or similar test framework) using the
* hex system in the error case. * hex system in the error case.
*/ */
template <typename T> class AsHexNumber template <typename T> class AsHexNumber {
{
public: public:
/// \brief Constructs a new instance; use asHexNumber() for convenience instead. /// \brief Constructs a new instance; use asHexNumber() for convenience instead.
AsHexNumber(const T &value) : value(value) {} AsHexNumber(const T &value)
: value(value)
{
}
const T &value; const T &value;
}; };
@ -149,7 +149,7 @@ template <typename T> bool operator==(const AsHexNumber<T> &lhs, const AsHexNumb
/*! /*!
* \brief Provides the actual formatting of the output for AsHexNumber class. * \brief Provides the actual formatting of the output for AsHexNumber class.
*/ */
template <typename T> std::ostream &operator<< (std::ostream &out, const AsHexNumber<T> &value) template <typename T> std::ostream &operator<<(std::ostream &out, const AsHexNumber<T> &value)
{ {
return out << std::hex << '0' << 'x' << unsigned(value.value) << std::dec; return out << std::hex << '0' << 'x' << unsigned(value.value) << std::dec;
} }
@ -168,10 +168,8 @@ template <typename T> AsHexNumber<T> asHexNumber(const T &value)
* \brief Asserts successful execution of application via TestApplication::execApp(). Output is stored in stdout and stderr. * \brief Asserts successful execution of application via TestApplication::execApp(). Output is stored in stdout and stderr.
* \remarks Requires cppunit. * \remarks Requires cppunit.
*/ */
# define TESTUTILS_ASSERT_EXEC(args) \ #define TESTUTILS_ASSERT_EXEC(args) CPPUNIT_ASSERT_EQUAL(0, execApp(args, stdout, stderr))
CPPUNIT_ASSERT_EQUAL(0, execApp(args, stdout, stderr))
#endif #endif
} }
#endif // TESTUTILS_H #endif // TESTUTILS_H