Fix decoration for static builds

- Also add improvemnts a few other things in the build system
This commit is contained in:
Martchus 2016-08-29 15:35:48 +02:00
parent cf521a3255
commit d6b08b8ed9
38 changed files with 2622 additions and 2569 deletions

View File

@ -1,7 +1,7 @@
#ifndef APPLICATION_UTILITIES_ARGUMENTPARSER_H
#define APPLICATION_UTILITIES_ARGUMENTPARSER_H
#include "./global.h"
#include "../global.h"
#include <vector>
#include <initializer_list>
@ -14,10 +14,10 @@ class ArgumentParserTests;
namespace ApplicationUtilities {
LIB_EXPORT extern const char *applicationName;
LIB_EXPORT extern const char *applicationAuthor;
LIB_EXPORT extern const char *applicationVersion;
LIB_EXPORT extern const char *applicationUrl;
CPP_UTILITIES_EXPORT extern const char *applicationName;
CPP_UTILITIES_EXPORT extern const char *applicationAuthor;
CPP_UTILITIES_EXPORT extern const char *applicationVersion;
CPP_UTILITIES_EXPORT extern const char *applicationUrl;
#define SET_APPLICATION_INFO \
::ApplicationUtilities::applicationName = APP_NAME; \
@ -68,12 +68,12 @@ constexpr bool operator&(ValueCompletionBehavior lhs, ValueCompletionBehavior rh
}
/// \endcond
Argument LIB_EXPORT *firstPresentUncombinableArg(const ArgumentVector &args, const Argument *except);
Argument CPP_UTILITIES_EXPORT *firstPresentUncombinableArg(const ArgumentVector &args, const Argument *except);
/*!
* \brief The ArgumentOccurrence struct holds argument values for an occurrence of an argument.
*/
struct LIB_EXPORT ArgumentOccurrence
struct CPP_UTILITIES_EXPORT ArgumentOccurrence
{
ArgumentOccurrence(std::size_t index);
ArgumentOccurrence(std::size_t index, const std::vector<Argument *> parentPath, Argument *parent);
@ -119,7 +119,7 @@ inline ArgumentOccurrence::ArgumentOccurrence(std::size_t index, const std::vect
}
}
class LIB_EXPORT Argument
class CPP_UTILITIES_EXPORT Argument
{
friend class ArgumentParser;
@ -200,7 +200,7 @@ private:
const char *m_preDefinedCompletionValues;
};
class LIB_EXPORT ArgumentParser
class CPP_UTILITIES_EXPORT ArgumentParser
{
friend ArgumentParserTests;
public:
@ -767,7 +767,7 @@ inline void ArgumentParser::setDefaultArgument(Argument *argument)
m_defaultArg = argument;
}
class LIB_EXPORT HelpArgument : public Argument
class CPP_UTILITIES_EXPORT HelpArgument : public Argument
{
public:
HelpArgument(ArgumentParser &parser);

View File

@ -1,7 +1,7 @@
#ifndef APPLICATIONUTILITIES_COMMANDLINEUTILS_H
#define APPLICATIONUTILITIES_COMMANDLINEUTILS_H
#include "./global.h"
#include "../global.h"
namespace ApplicationUtilities {
@ -15,10 +15,10 @@ enum class Response
No
};
bool LIB_EXPORT confirmPrompt(const char *message, Response defaultResponse = Response::None);
bool CPP_UTILITIES_EXPORT confirmPrompt(const char *message, Response defaultResponse = Response::None);
#ifdef PLATFORM_WINDOWS
void LIB_EXPORT startConsole();
void CPP_UTILITIES_EXPORT startConsole();
# define CMD_UTILS_START_CONSOLE ::ApplicationUtilities::startConsole();
#else
# define CMD_UTILS_START_CONSOLE

View File

@ -1,14 +1,14 @@
#ifndef APPLICATION_UTILITIES_FAILURE_H
#define APPLICATION_UTILITIES_FAILURE_H
#include "./global.h"
#include "../global.h"
#include <exception>
#include <string>
namespace ApplicationUtilities {
class LIB_EXPORT Failure : public std::exception
class CPP_UTILITIES_EXPORT Failure : public std::exception
{
public:
Failure();

View File

@ -5,7 +5,7 @@
namespace ApplicationUtilities {
class LIB_EXPORT FakeQtConfigArguments
class CPP_UTILITIES_EXPORT FakeQtConfigArguments
{
public:
FakeQtConfigArguments();

View File

@ -1,113 +1,113 @@
#ifndef APPLICATION_UTILITIES_GLOBAL_H
#define APPLICATION_UTILITIES_GLOBAL_H
#ifdef _WIN32
# ifndef PLATFORM_WINDOWS
/// \brief Defined when compiling for Windows.
# define PLATFORM_WINDOWS
# endif
# if defined(__MINGW32__) || defined(__MINGW64__)
# ifndef PLATFORM_MINGW
/// \brief Defined when compiling with mingw(-w64).
# define PLATFORM_MINGW
# endif
# endif
#elif __unix__
# ifndef PLATFORM_UNIX
/// \brief Defined when compiling for any UNIX (like) system.
# define PLATFORM_UNIX
# endif
#endif
#ifdef __linux__
# ifndef PLATFORM_LINUX
/// \brief Defined when compiling for Linux.
# define PLATFORM_LINUX
# endif
#endif
/*!
* \def LIB_EXPORT
* \brief Marks a symbol for shared library export.
*/
/*!
* \def LIB_IMPORT
* \brief Declares a symbol to be an import from a shared library.
*/
/*!
* \def LIB_HIDDEN
* \brief Hidden visibility indicates that the symbol will not be placed into
* the dynamic symbol table, so no other module (executable or shared library)
* can reference it directly.
*/
#ifdef PLATFORM_WINDOWS
# define LIB_EXPORT __declspec(dllexport)
# define LIB_IMPORT __declspec(dllimport)
# define LIB_HIDDEN
#else
# define LIB_EXPORT __attribute__((visibility("default")))
# define LIB_IMPORT __attribute__((visibility("default")))
# define LIB_HIDDEN __attribute__((visibility("hidden")))
#endif
/*!
* \def USE_NOTHROW
* \brief Marks a function as never throwing, under no circumstances.
* \remarks If the function does nevertheless throw, the behaviour is undefined.
*/
#ifndef USE_NOTHROW
# if __cplusplus >= 201103L
# define USE_NOTHROW noexcept
# else
# define USE_NOTHROW throw()
# endif
#endif
/*!
* \def DECLARE_ENUM
* \brief Declares an enum without preventing lupdate to parse the file correctly.
*/
#define DECLARE_ENUM(name, base) enum name : base
/*!
* \def DECLARE_ENUM_CLASS
* \brief Declares an enum without preventing lupdate to parse the file correctly.
*/
#define DECLARE_ENUM_CLASS(name, base) enum class name : base
/*!
* \def VAR_UNUSED
* \brief Prevents warnings about unused variables.
*/
#define VAR_UNUSED(x) (void)x;
/*!
* \def IF_DEBUG_BUILD
* \brief Wraps debug-only lines conveniently.
*/
#ifdef DEBUG_BUILD
# define IF_DEBUG_BUILD(x) x
#else
# define IF_DEBUG_BUILD(x)
#endif
/*!
* \def FALLTHROUGH
* \brief Prevents clang from warning about missing break in switch-case.
* \remarks Does nothing if another compiler is used.
*/
#ifdef __clang__
# define FALLTHROUGH [[clang::fallthrough]]
# else
# define FALLTHROUGH
#endif
#endif // APPLICATION_UTILITIES_GLOBAL_H
#ifndef APPLICATION_UTILITIES_GLOBAL_H
#define APPLICATION_UTILITIES_GLOBAL_H
#ifdef _WIN32
# ifndef PLATFORM_WINDOWS
/// \brief Defined when compiling for Windows.
# define PLATFORM_WINDOWS
# endif
# if defined(__MINGW32__) || defined(__MINGW64__)
# ifndef PLATFORM_MINGW
/// \brief Defined when compiling with mingw(-w64).
# define PLATFORM_MINGW
# endif
# endif
#elif __unix__
# ifndef PLATFORM_UNIX
/// \brief Defined when compiling for any UNIX (like) system.
# define PLATFORM_UNIX
# endif
#endif
#ifdef __linux__
# ifndef PLATFORM_LINUX
/// \brief Defined when compiling for Linux.
# define PLATFORM_LINUX
# endif
#endif
/*!
* \def LIB_EXPORT
* \brief Marks a symbol for shared library export.
*/
/*!
* \def LIB_IMPORT
* \brief Declares a symbol to be an import from a shared library.
*/
/*!
* \def LIB_HIDDEN
* \brief Hidden visibility indicates that the symbol will not be placed into
* the dynamic symbol table, so no other module (executable or shared library)
* can reference it directly.
*/
#ifdef PLATFORM_WINDOWS
# define LIB_EXPORT __declspec(dllexport)
# define LIB_IMPORT __declspec(dllimport)
# define LIB_HIDDEN
#else
# define LIB_EXPORT __attribute__((visibility("default")))
# define LIB_IMPORT __attribute__((visibility("default")))
# define LIB_HIDDEN __attribute__((visibility("hidden")))
#endif
/*!
* \def USE_NOTHROW
* \brief Marks a function as never throwing, under no circumstances.
* \remarks If the function does nevertheless throw, the behaviour is undefined.
*/
#ifndef USE_NOTHROW
# if __cplusplus >= 201103L
# define USE_NOTHROW noexcept
# else
# define USE_NOTHROW throw()
# endif
#endif
/*!
* \def DECLARE_ENUM
* \brief Declares an enum without preventing lupdate to parse the file correctly.
*/
#define DECLARE_ENUM(name, base) enum name : base
/*!
* \def DECLARE_ENUM_CLASS
* \brief Declares an enum without preventing lupdate to parse the file correctly.
*/
#define DECLARE_ENUM_CLASS(name, base) enum class name : base
/*!
* \def VAR_UNUSED
* \brief Prevents warnings about unused variables.
*/
#define VAR_UNUSED(x) (void)x;
/*!
* \def IF_DEBUG_BUILD
* \brief Wraps debug-only lines conveniently.
*/
#ifdef DEBUG_BUILD
# define IF_DEBUG_BUILD(x) x
#else
# define IF_DEBUG_BUILD(x)
#endif
/*!
* \def FALLTHROUGH
* \brief Prevents clang from warning about missing break in switch-case.
* \remarks Does nothing if another compiler is used.
*/
#ifdef __clang__
# define FALLTHROUGH [[clang::fallthrough]]
# else
# define FALLTHROUGH
#endif
#endif // APPLICATION_UTILITIES_GLOBAL_H

View File

@ -52,7 +52,7 @@ enum class DatePart
Day /**< day */
};
class LIB_EXPORT DateTime
class CPP_UTILITIES_EXPORT DateTime
{
public:
explicit constexpr DateTime();

View File

@ -3,11 +3,9 @@
#include "./datetime.h"
#include "../application/global.h"
namespace ChronoUtilities {
class LIB_EXPORT Period
class CPP_UTILITIES_EXPORT Period
{
public:
Period(const DateTime &beg, const DateTime &end);

View File

@ -1,7 +1,7 @@
#ifndef CHRONO_UTILITIES_TIMESPAN_H
#define CHRONO_UTILITIES_TIMESPAN_H
#include "../application/global.h"
#include "../global.h"
#include "../conversion/types.h"
#include <string>
@ -25,7 +25,7 @@ enum class TimeSpanOutputFormat
WithMeasures /**< measures are used, eg.: 34 d 5 h 10 min 7 s 31 ms */
};
class LIB_EXPORT TimeSpan
class CPP_UTILITIES_EXPORT TimeSpan
{
friend class DateTime;
public:

View File

@ -18,6 +18,7 @@ else()
set(ACTUAL_ADDITIONAL_LINK_FLAGS ${ADDITIONAL_LINK_FLAGS})
set(ACTUAL_ADDITIONAL_COMPILE_DEFINITIONS ${ADDITIONAL_COMPILE_DEFINITIONS})
endif()
# add target for building the application
add_executable(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${GUI_TYPE} ${HEADER_FILES} ${SRC_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${QM_FILES} ${WINDOWS_ICON_PATH})
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${ACTUAL_ADDITIONAL_LINK_FLAGS} ${LIBRARIES})
@ -33,7 +34,6 @@ install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
RUNTIME DESTINATION bin
COMPONENT binary
)
if(NOT TARGET install-binary)
add_custom_target(install-binary
DEPENDS ${META_PROJECT_NAME}
@ -64,7 +64,6 @@ foreach(ICON_FILE ${ICON_FILES})
COMPONENT desktop
)
endforeach()
if(NOT TARGET install-desktop)
add_custom_target(install-desktop
DEPENDS ${META_PROJECT_NAME}

View File

@ -39,7 +39,7 @@ set(TARGET_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bin/${TARGET_PREFIX}${META_PROJEC
option(FORCE_OLD_ABI "specifies whether usage of old ABI should be forced" OFF)
if(FORCE_OLD_ABI)
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
set(META_REQUIRED_CFLAGS "${META_REQUIRED_CFLAGS} -D-D_GLIBCXX_USE_CXX11_ABI=0")
set(META_REQUIRED_BUILD_FLAGS "${META_REQUIRED_BUILD_CFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
message(STATUS "Forcing usage of old CXX11 ABI.")
else()
message(STATUS "Using default CXX11 ABI (not forcing old CX11 ABI).")
@ -59,9 +59,14 @@ if(LOGGING_ENABLED)
endif()
# options for deciding whether to build static and/or shared libraries
if((NOT ${META_PROJECT_TYPE} STREQUAL "library") AND (NOT ${META_PROJECT_TYPE} STREQUAL ""))
if(("${META_PROJECT_TYPE}" STREQUAL "library") OR ("${META_PROJECT_TYPE}" STREQUAL ""))
option(BUILD_STATIC_LIBS "whether to build static libraries (disabled by default)" OFF)
option(BUILD_SHARED_LIBS "whether to build dynamic libraries (enabled by default)" ON)
option(DISABLE_SHARED_LIBS "whether building dynamic libraries is disabled (prevents BUILD_SHARED_LIBS being re-enabled when using Qt Creator)" OFF)
if(DISABLE_SHARED_LIBS)
set(BUILD_SHARED_LIBS OFF)
else()
option(BUILD_SHARED_LIBS "whether to build dynamic libraries (enabled by default)" ON)
endif()
endif()
# options for forcing static linkage when building applications or dynamic libraries

View File

@ -30,6 +30,7 @@ set(LIB_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${SELECTED_LIB_SUFFIX}")
set(CMAKE_MODULE_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/share/${META_PROJECT_NAME}/cmake/modules")
set(CMAKE_CONFIG_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/share/${META_PROJECT_NAME}/cmake")
# remove library prefix when building with mingw-w64 (just for consistency with qmake)
if(MINGW)
set(CMAKE_SHARED_LIBRARY_PREFIX "")
@ -40,6 +41,29 @@ if(MINGW)
set(WINDOWS_EXT "dll")
endif(MINGW)
# create global header and define build flags
if(NOT META_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_SHARED_LIB_COMPILE_DEFINITIONS ${META_COMPILE_DEFINITIONS})
endif()
if(NOT META_STATIC_LIB_COMPILE_DEFINITIONS)
set(META_STATIC_LIB_COMPILE_DEFINITIONS ${META_COMPILE_DEFINITIONS} ${META_PROJECT_VARNAME_UPPER}_STATIC)
endif()
# add global library-specific header
include(TemplateFinder)
find_template_file("global.h" CPP_UTILITIES GLOBAL_H_TEMPLATE_FILE)
if("${META_PROJECT_NAME}" STREQUAL "c++utilities")
set(GENERAL_GLOBAL_H_INCLUDE_PATH "\"./application/global.h\"")
else()
set(GENERAL_GLOBAL_H_INCLUDE_PATH "<c++utilities/application/global.h>")
endif()
configure_file(
"${GLOBAL_H_TEMPLATE_FILE}"
"${CMAKE_CURRENT_SOURCE_DIR}/global.h" # simply add this to source to ease inclusion
NEWLINE_STYLE UNIX # since this goes to sources ensure consistency
)
list(APPEND HEADER_FILES global.h)
# add target for building the library
if(BUILD_SHARED_LIBS)
# use correct linker flags and compile definitions (depend on linkage)
@ -65,6 +89,8 @@ endif()
# add target for building a static version of the library
if(BUILD_STATIC_LIBS)
set(ACTUAL_ADDITIONAL_COMPILE_DEFINITIONS ${ADDITIONAL_STATIC_COMPILE_DEFINITIONS})
list(APPEND ACTUAL_ADDITIONAL_COMPILE_DEFINITIONS ${META_STATIC_LIB_COMPILE_DEFINITIONS})
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static STATIC ${HEADER_FILES} ${SRC_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${QM_FILES} ${WINDOWS_ICON_PATH})
# add target link libraries for the static lib also because otherwise Qt header files can not be located
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static ${STATIC_LIBRARIES})
@ -73,7 +99,7 @@ if(BUILD_STATIC_LIBS)
SOVERSION ${META_VERSION_MAJOR}
OUTPUT_NAME ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
CXX_STANDARD 11
COMPILE_DEFINITIONS "${ADDITIONAL_STATIC_COMPILE_DEFINITIONS}"
COMPILE_DEFINITIONS "${ACTUAL_ADDITIONAL_COMPILE_DEFINITIONS}"
)
set(META_STATIC_LIB_DEPENDS ${${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static_LIB_DEPENDS}) # used in config file
endif()
@ -101,7 +127,6 @@ write_basic_package_version_file(
# create pkg-config file from template
# will (currently) not contain Libs.private if static libs haven't been built anyways
include(TemplateFinder)
find_template_file("template.pc" CPP_UTILITIES PKGCONFIG_TEMPLATE_FILE)
configure_file(
"${PKGCONFIG_TEMPLATE_FILE}"
@ -119,7 +144,6 @@ install(
COMPONENT
cmake-config
)
if(NOT TARGET install-cmake-config)
add_custom_target(install-cmake-config
DEPENDS ${META_PROJECT_NAME}
@ -152,7 +176,6 @@ if(BUILD_SHARED_LIBS)
COMPONENT binary
)
endif()
if(NOT TARGET install-binary)
add_custom_target(install-binary
DEPENDS ${META_PROJECT_NAME}
@ -190,7 +213,6 @@ foreach(HEADER_FILE ${HEADER_FILES} ${ADDITIONAL_HEADER_FILES})
COMPONENT header
)
endforeach()
if(NOT TARGET install-header)
add_custom_target(install-header
DEPENDS ${META_PROJECT_NAME}
@ -207,7 +229,6 @@ foreach(CMAKE_MODULE_FILE ${CMAKE_MODULE_FILES})
COMPONENT cmake-modules
)
endforeach()
if(NOT TARGET install-cmake-modules)
add_custom_target(install-cmake-modules
DEPENDS ${META_PROJECT_NAME}
@ -224,7 +245,6 @@ foreach(CMAKE_TEMPLATE_FILE ${CMAKE_TEMPLATE_FILES})
COMPONENT cmake-templates
)
endforeach()
if(NOT TARGET install-cmake-templates)
add_custom_target(install-cmake-templates
DEPENDS ${META_PROJECT_NAME}
@ -245,21 +265,18 @@ if(NOT TARGET install-mingw-w64)
DEPENDS install-binary install-header install-cmake-stuff ${LOCALIZATION_TARGET}
)
endif()
if(NOT TARGET install-mingw-w64-importlib-strip)
add_custom_target(install-mingw-w64-importlib-strip
DEPENDS install-binary-strip
COMMAND "${CMAKE_FIND_ROOT_PATH}/bin/strip" --strip-unneeded "\$\{DESTDIR\}\$\{DESTDIR:+/\}${CMAKE_INSTALL_PREFIX}/lib/lib${META_PROJECT_NAME}.dll.a"
)
endif()
if(NOT TARGET install-mingw-w64-staticlib-strip)
add_custom_target(install-mingw-w64-staticlib-strip
DEPENDS install-binary-strip
COMMAND "${CMAKE_FIND_ROOT_PATH}/bin/strip" -g "\$\{DESTDIR\}\$\{DESTDIR:+/\}${CMAKE_INSTALL_PREFIX}/lib/lib${META_PROJECT_NAME}.a"
)
endif()
if(NOT TARGET install-mingw-w64-strip)
add_custom_target(install-mingw-w64-strip
DEPENDS install-binary-strip install-mingw-w64-importlib-strip install-mingw-w64-staticlib-strip install-header install-cmake-stuff ${LOCALIZATION_TARGET}

View File

@ -1,41 +1,44 @@
@PACKAGE_INIT@
set(@META_PROJECT_VARNAME@_HAS_SHARED_LIB "@BUILD_SHARED_LIBS@")
set(@META_PROJECT_VARNAME@_SHARED_LIB "@META_PROJECT_NAME@")
set(@META_PROJECT_VARNAME@_HAS_STATIC_LIB "@BUILD_STATIC_LIBS@")
set(@META_PROJECT_VARNAME@_STATIC_LIB "@META_PROJECT_NAME@.a")
set(@META_PROJECT_VARNAME@_STATIC_LIB_DEPENDS @META_STATIC_LIB_DEPENDS@)
set(@META_PROJECT_VARNAME@_INCLUDE_DIRS "@PACKAGE_HEADER_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME@_BIN_DIR "@PACKAGE_BIN_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME@_LIB_DIR "@PACKAGE_LIB_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME@_MODULE_DIRS "@PACKAGE_CMAKE_MODULE_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME@_CONFIG_DIRS "@PACKAGE_CMAKE_CONFIG_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME@_REQUIRED_CFLAGS "@META_REQUIRED_CFLAGS@")
set(@META_PROJECT_VARNAME_UPPER@_HAS_SHARED_LIB "@BUILD_SHARED_LIBS@")
set(@META_PROJECT_VARNAME_UPPER@_SHARED_LIB "@META_PROJECT_NAME@")
set(@META_PROJECT_VARNAME_UPPER@_SHARED_LIB_COMPILE_DEFINITIONS @META_SHARED_LIB_COMPILE_DEFINITIONS@)
set(@META_PROJECT_VARNAME_UPPER@_HAS_STATIC_LIB "@BUILD_STATIC_LIBS@")
set(@META_PROJECT_VARNAME_UPPER@_STATIC_LIB "@META_PROJECT_NAME@.a")
set(@META_PROJECT_VARNAME_UPPER@_STATIC_LIB_DEPENDS @META_STATIC_LIB_DEPENDS@)
set(@META_PROJECT_VARNAME_UPPER@_STATIC_LIB_COMPILE_DEFINITIONS @META_STATIC_LIB_COMPILE_DEFINITIONS@)
set(@META_PROJECT_VARNAME_UPPER@_INCLUDE_DIRS "@PACKAGE_HEADER_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME_UPPER@_BIN_DIR "@PACKAGE_BIN_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME_UPPER@_LIB_DIR "@PACKAGE_LIB_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME_UPPER@_MODULE_DIRS "@PACKAGE_CMAKE_MODULE_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME_UPPER@_CONFIG_DIRS "@PACKAGE_CMAKE_CONFIG_INSTALL_DESTINATION@")
if(@META_PROJECT_VARNAME@_HAS_SHARED_LIB)
set(@META_PROJECT_VARNAME@_LIB "${@META_PROJECT_VARNAME@_SHARED_LIB}")
if(@META_PROJECT_VARNAME_UPPER@_HAS_SHARED_LIB)
set(@META_PROJECT_VARNAME_UPPER@_LIB "${@META_PROJECT_VARNAME_UPPER@_SHARED_LIB}")
else()
set(@META_PROJECT_VARNAME@_LIB "${@META_PROJECT_VARNAME@_STATIC_LIB}")
set(@META_PROJECT_VARNAME_UPPER@_LIB "${@META_PROJECT_VARNAME_UPPER@_STATIC_LIB}")
endif()
macro(use_@META_PROJECT_VARNAME@)
include_directories(BEFORE SYSTEM ${@META_PROJECT_VARNAME@_INCLUDE_DIRS})
link_directories(${@META_PROJECT_VARNAME@_LIB_DIR})
macro(use_@META_PROJECT_VARNAME_UPPER@)
include_directories(BEFORE SYSTEM ${@META_PROJECT_VARNAME_UPPER@_INCLUDE_DIRS})
link_directories(${@META_PROJECT_VARNAME_UPPER@_LIB_DIR})
# add library to list of libraries to link against when building dynamic libraries or applications
if(@META_PROJECT_VARNAME@_HAS_STATIC_LIB AND ((NOT ARGV0 AND ((STATIC_LINKAGE AND "${META_PROJECT_TYPE}" STREQUAL "application") OR (STATIC_LIBRARY_LINKAGE AND ("${META_PROJECT_TYPE}" STREQUAL "" OR "${META_PROJECT_TYPE}" STREQUAL "library")))) OR ("${ARGV0}" STREQUAL "STATIC") OR (NOT ARGV0 AND NOT @META_PROJECT_VARNAME@_HAS_SHARED_LIB)))
list(APPEND LIBRARIES ${@META_PROJECT_VARNAME@_STATIC_LIB} ${@META_PROJECT_VARNAME@_STATIC_LIB_DEPENDS})
message(STATUS "Linking ${META_PROJECT_NAME} statically against @META_PROJECT_NAME@ (${@META_PROJECT_VARNAME@_STATIC_LIB} ${@META_PROJECT_VARNAME@_STATIC_LIB_DEPENDS}).")
elseif(@META_PROJECT_VARNAME@_HAS_SHARED_LIB AND (NOT ARGV0 OR ("${ARGV0}" STREQUAL "SHARED")))
list(APPEND LIBRARIES ${@META_PROJECT_VARNAME@_SHARED_LIB})
message(STATUS "Linking ${META_PROJECT_NAME} dynamically against @META_PROJECT_NAME@ (${@META_PROJECT_VARNAME@_SHARED_LIB}).")
if(@META_PROJECT_VARNAME_UPPER@_HAS_STATIC_LIB AND ((NOT ARGV0 AND ((STATIC_LINKAGE AND "${META_PROJECT_TYPE}" STREQUAL "application") OR (STATIC_LIBRARY_LINKAGE AND ("${META_PROJECT_TYPE}" STREQUAL "" OR "${META_PROJECT_TYPE}" STREQUAL "library")))) OR ("${ARGV0}" STREQUAL "STATIC") OR (NOT ARGV0 AND NOT @META_PROJECT_VARNAME_UPPER@_HAS_SHARED_LIB)))
list(APPEND LIBRARIES ${@META_PROJECT_VARNAME_UPPER@_STATIC_LIB} ${@META_PROJECT_VARNAME_UPPER@_STATIC_LIB_DEPENDS})
message(STATUS "Linking ${META_PROJECT_NAME} statically against @META_PROJECT_NAME@ (${@META_PROJECT_VARNAME_UPPER@_STATIC_LIB} ${@META_PROJECT_VARNAME_UPPER@_STATIC_LIB_DEPENDS}).")
list(APPEND ADDITIONAL_STATIC_COMPILE_DEFINITIONS ${@META_PROJECT_VARNAME_UPPER@_STATIC_LIB_COMPILE_DEFINITIONS})
elseif(@META_PROJECT_VARNAME_UPPER@_HAS_SHARED_LIB AND (NOT ARGV0 OR ("${ARGV0}" STREQUAL "SHARED")))
list(APPEND LIBRARIES ${@META_PROJECT_VARNAME_UPPER@_SHARED_LIB})
message(STATUS "Linking ${META_PROJECT_NAME} dynamically against @META_PROJECT_NAME@ (${@META_PROJECT_VARNAME_UPPER@_SHARED_LIB}).")
list(APPEND ADDITIONAL_SHARED_COMPILE_DEFINITIONS ${@META_PROJECT_VARNAME_UPPER@_SHARED_LIB_COMPILE_DEFINITIONS})
elseif(ARGV0)
message(FATAL_ERROR "Can not link ${META_PROJECT_NAME} against @META_PROJECT_NAME@ with the specified linkage ${ARGV0}.")
else()
message(FATAL_ERROR "Can not link ${META_PROJECT_NAME} against @META_PROJECT_NAME@.")
endif()
# add library (including dependencies) to list of libraries to be provided as transitive dependencies when building static libraries
list(APPEND STATIC_LIBRARIES ${@META_PROJECT_VARNAME@_STATIC_LIB} ${@META_PROJECT_VARNAME@_STATIC_LIB_DEPENDS})
message(STATUS "Adding ${@META_PROJECT_VARNAME@_STATIC_LIB} ${@META_PROJECT_VARNAME@_STATIC_LIB_DEPENDS} to static library dependencies of ${META_PROJECT_NAME}.")
list(APPEND STATIC_LIBRARIES ${@META_PROJECT_VARNAME_UPPER@_STATIC_LIB} ${@META_PROJECT_VARNAME_UPPER@_STATIC_LIB_DEPENDS})
message(STATUS "Adding ${@META_PROJECT_VARNAME_UPPER@_STATIC_LIB} ${@META_PROJECT_VARNAME_UPPER@_STATIC_LIB_DEPENDS} to static library dependencies of ${META_PROJECT_NAME}.")
# make CMake modules of the project available
list(APPEND CMAKE_MODULE_PATH ${@META_PROJECT_VARNAME@_MODULE_DIRS})
list(APPEND CMAKE_MODULE_PATH ${@META_PROJECT_VARNAME_UPPER@_MODULE_DIRS})
endmacro()

View File

@ -1,5 +1,8 @@
#ifndef APP_METADATA_AVAIL
#define APP_METADATA_AVAIL
// Created via CMake from template config.h.in
// WARNING! Any changes to this file will be overwritten by the next CMake run!
#ifndef APPLICATION_CONFIG
#define APPLICATION_CONFIG
#define PROJECT_NAME @META_PROJECT_NAME_STR@
#define APP_NAME @META_APP_NAME_STR@
@ -12,4 +15,4 @@
#cmakedefine SVG_SUPPORT
#cmakedefine SVG_ICON_SUPPORT
#endif // APP_METADATA_AVAIL
#endif // APPLICATION_CONFIG

View File

@ -0,0 +1,17 @@
// Created via CMake from template global.h.in
// WARNING! Any changes to this file will be overwritten by the next CMake run!
#ifndef @META_PROJECT_VARNAME_UPPER@_GLOBAL
#define @META_PROJECT_VARNAME_UPPER@_GLOBAL
#include @GENERAL_GLOBAL_H_INCLUDE_PATH@
#ifdef @META_PROJECT_VARNAME_UPPER@_STATIC
# define @META_PROJECT_VARNAME_UPPER@_EXPORT
# define @META_PROJECT_VARNAME_UPPER@_IMPORT
#else
# define @META_PROJECT_VARNAME_UPPER@_EXPORT LIB_EXPORT
# define @META_PROJECT_VARNAME_UPPER@_IMPORT LIB_IMPORT
#endif
#endif // @META_PROJECT_VARNAME_UPPER@_GLOBAL

View File

@ -10,4 +10,4 @@ URL: @META_APP_URL@
Libs: -L${libdir} -l@TARGET_PREFIX@@META_PROJECT_NAME@@TARGET_SUFFIX@
Libs.private: @META_STATIC_LIB_DEPENDS@
Cflags: -I${includedir} @META_REQUIRED_CFLAGS@
Cflags: -I${includedir}

View File

@ -1,200 +1,200 @@
#ifndef CONVERSION_UTILITIES_BINARY_CONVERSION_H
#define CONVERSION_UTILITIES_BINARY_CONVERSION_H
#include "./types.h"
#include "../application/global.h"
#ifdef __BYTE_ORDER__
# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN true
# define CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN
# elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
# define CONVERSION_UTILITIES_BYTE_ORDER_MIDDLE_ENDIAN
# elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN true
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
# define CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN
# endif
#endif
#ifdef __FLOAT_WORD_ORDER__
# if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_BIG_ENDIAN
# elif __FLOAT_WORD_ORDER__ == __ORDER_PDP_ENDIAN__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_MIDDLE_ENDIAN
# elif __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_LITTLE_ENDIAN
# endif
#endif
#if defined(__BYTE_ORDER__) && defined(__FLOAT_WORD_ORDER__)
#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)
# ifndef __BYTE_ORDER__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN true
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
# define CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN
# endif
# ifndef __FLOAT_WORD_ORDER__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_LITTLE_ENDIAN
# endif
# elif defined(__MIPSEB__) || defined(__s390__) || defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN)
# ifndef __BYTE_ORDER__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN true
# define CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN
# endif
# ifndef __FLOAT_WORD_ORDER__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_BIG_ENDIAN
# endif
# else
# error "Unable to determine byte order!"
# endif
#endif
#if defined(CONVERSION_UTILITIES_BYTE_ORDER_MIDDLE_ENDIAN)
# error "Middle endian byte order is not supported!"
#endif
#if defined(CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_MIDDLE_ENDIAN)
# error "Middle endian byte order is not supported!"
#endif
/*!
* \namespace ConversionUtilities
* \brief Contains several functions providing conversions between different data types.
*
* 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.
*/
namespace ConversionUtilities
{
/*!
* \brief Encapsulates binary conversion functions using the big endian byte order.
* \sa <a href="http://en.wikipedia.org/wiki/Endianness">Endianness - Wikipedia</a>
*/
namespace BE {
#if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 0
#elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 1
#endif
#include "./binaryconversionprivate.h"
#undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
}
/*!
* \brief Encapsulates binary conversion functions using the little endian byte order.
* \sa <a href="http://en.wikipedia.org/wiki/Endianness">Endianness - Wikipedia</a>
*/
namespace LE {
#if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 1
#elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 0
#endif
#include "./binaryconversionprivate.h"
#undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
}
/*!
* \brief Returns the 8.8 fixed point representation converted from the specified 32-bit floating point number.
*/
LIB_EXPORT constexpr uint16 toFixed8(float32 float32value)
{
return static_cast<uint16>(float32value * 256.0f);
}
/*!
* \brief Returns a 32-bit floating point number converted from the specified 8.8 fixed point representation.
*/
LIB_EXPORT constexpr float32 toFloat32(uint16 fixed8value)
{
return static_cast<float32>(fixed8value) / 256.0f;
}
/*!
* \brief Returns the 16.16 fixed point representation converted from the specified 32-bit floating point number.
*/
LIB_EXPORT constexpr uint32 toFixed16(float32 float32value)
{
return static_cast<uint32>(float32value * 65536.0f);
}
/*!
* \brief Returns a 32-bit floating point number converted from the specified 16.16 fixed point representation.
*/
LIB_EXPORT constexpr float32 toFloat32(uint32 fixed16value)
{
return static_cast<float32>(fixed16value) / 65536.0f;
}
/*!
* \brief Returns a 32-bit synchsafe integer converted from a normal 32-bit integer.
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
*/
LIB_EXPORT constexpr uint32 toSynchsafeInt(uint32 normalInt)
{
return ((normalInt & 0x0000007fu) )
| ((normalInt & 0x00003f80u) << 1)
| ((normalInt & 0x001fc000u) << 2)
| ((normalInt & 0x0fe00000u) << 3);
}
/*!
* \brief Returns a normal 32-bit integer converted from a 32-bit synchsafe integer.
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
*/
LIB_EXPORT constexpr uint32 toNormalInt(uint32 synchsafeInt)
{
return ((synchsafeInt & 0x0000007fu) )
| ((synchsafeInt & 0x00007f00u) >> 1)
| ((synchsafeInt & 0x007f0000u) >> 2)
| ((synchsafeInt & 0x7f000000u) >> 3);
}
/*!
* \brief Swaps the byte order of the specified 16-bit unsigned integer.
*/
LIB_EXPORT constexpr uint16 swapOrder(uint16 value)
{
return (value >> 8) | (value << 8);
}
/*!
* \brief Swaps the byte order of the specified 32-bit unsigned integer.
*/
LIB_EXPORT constexpr uint32 swapOrder(uint32 value)
{
return (value >> 24)
| ((value & 0x00FF0000) >> 8)
| ((value & 0x0000FF00) << 8)
| (value << 24);
}
/*!
* \brief Swaps the byte order of the specified 64-bit unsigned integer.
*/
LIB_EXPORT constexpr uint64 swapOrder(uint64 value)
{
return(value >> (7 * 8))
| ((value & 0x00FF000000000000) >> (5 * 8))
| ((value & 0x0000FF0000000000) >> (3 * 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
#ifndef CONVERSION_UTILITIES_BINARY_CONVERSION_H
#define CONVERSION_UTILITIES_BINARY_CONVERSION_H
#include "./types.h"
#include "../global.h"
#ifdef __BYTE_ORDER__
# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN true
# define CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN
# elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
# define CONVERSION_UTILITIES_BYTE_ORDER_MIDDLE_ENDIAN
# elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN true
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
# define CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN
# endif
#endif
#ifdef __FLOAT_WORD_ORDER__
# if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_BIG_ENDIAN
# elif __FLOAT_WORD_ORDER__ == __ORDER_PDP_ENDIAN__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_MIDDLE_ENDIAN
# elif __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_LITTLE_ENDIAN
# endif
#endif
#if defined(__BYTE_ORDER__) && defined(__FLOAT_WORD_ORDER__)
#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)
# ifndef __BYTE_ORDER__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN true
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
# define CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN
# endif
# ifndef __FLOAT_WORD_ORDER__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_LITTLE_ENDIAN
# endif
# elif defined(__MIPSEB__) || defined(__s390__) || defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN)
# ifndef __BYTE_ORDER__
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
# define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN true
# define CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN
# endif
# ifndef __FLOAT_WORD_ORDER__
# define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_BIG_ENDIAN
# endif
# else
# error "Unable to determine byte order!"
# endif
#endif
#if defined(CONVERSION_UTILITIES_BYTE_ORDER_MIDDLE_ENDIAN)
# error "Middle endian byte order is not supported!"
#endif
#if defined(CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_MIDDLE_ENDIAN)
# error "Middle endian byte order is not supported!"
#endif
/*!
* \namespace ConversionUtilities
* \brief Contains several functions providing conversions between different data types.
*
* 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.
*/
namespace ConversionUtilities
{
/*!
* \brief Encapsulates binary conversion functions using the big endian byte order.
* \sa <a href="http://en.wikipedia.org/wiki/Endianness">Endianness - Wikipedia</a>
*/
namespace BE {
#if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 0
#elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 1
#endif
#include "./binaryconversionprivate.h"
#undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
}
/*!
* \brief Encapsulates binary conversion functions using the little endian byte order.
* \sa <a href="http://en.wikipedia.org/wiki/Endianness">Endianness - Wikipedia</a>
*/
namespace LE {
#if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 1
#elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN)
# define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 0
#endif
#include "./binaryconversionprivate.h"
#undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
}
/*!
* \brief Returns the 8.8 fixed point representation converted from the specified 32-bit floating point number.
*/
CPP_UTILITIES_EXPORT constexpr uint16 toFixed8(float32 float32value)
{
return static_cast<uint16>(float32value * 256.0f);
}
/*!
* \brief Returns a 32-bit floating point number converted from the specified 8.8 fixed point representation.
*/
CPP_UTILITIES_EXPORT constexpr float32 toFloat32(uint16 fixed8value)
{
return static_cast<float32>(fixed8value) / 256.0f;
}
/*!
* \brief Returns the 16.16 fixed point representation converted from the specified 32-bit floating point number.
*/
CPP_UTILITIES_EXPORT constexpr uint32 toFixed16(float32 float32value)
{
return static_cast<uint32>(float32value * 65536.0f);
}
/*!
* \brief Returns a 32-bit floating point number converted from the specified 16.16 fixed point representation.
*/
CPP_UTILITIES_EXPORT constexpr float32 toFloat32(uint32 fixed16value)
{
return static_cast<float32>(fixed16value) / 65536.0f;
}
/*!
* \brief Returns a 32-bit synchsafe integer converted from a normal 32-bit integer.
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
*/
CPP_UTILITIES_EXPORT constexpr uint32 toSynchsafeInt(uint32 normalInt)
{
return ((normalInt & 0x0000007fu) )
| ((normalInt & 0x00003f80u) << 1)
| ((normalInt & 0x001fc000u) << 2)
| ((normalInt & 0x0fe00000u) << 3);
}
/*!
* \brief Returns a normal 32-bit integer converted from a 32-bit synchsafe integer.
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
*/
CPP_UTILITIES_EXPORT constexpr uint32 toNormalInt(uint32 synchsafeInt)
{
return ((synchsafeInt & 0x0000007fu) )
| ((synchsafeInt & 0x00007f00u) >> 1)
| ((synchsafeInt & 0x007f0000u) >> 2)
| ((synchsafeInt & 0x7f000000u) >> 3);
}
/*!
* \brief Swaps the byte order of the specified 16-bit unsigned integer.
*/
CPP_UTILITIES_EXPORT constexpr uint16 swapOrder(uint16 value)
{
return (value >> 8) | (value << 8);
}
/*!
* \brief Swaps the byte order of the specified 32-bit unsigned integer.
*/
CPP_UTILITIES_EXPORT constexpr uint32 swapOrder(uint32 value)
{
return (value >> 24)
| ((value & 0x00FF0000) >> 8)
| ((value & 0x0000FF00) << 8)
| (value << 24);
}
/*!
* \brief Swaps the byte order of the specified 64-bit unsigned integer.
*/
CPP_UTILITIES_EXPORT constexpr uint64 swapOrder(uint64 value)
{
return(value >> (7 * 8))
| ((value & 0x00FF000000000000) >> (5 * 8))
| ((value & 0x0000FF0000000000) >> (3 * 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

View File

@ -6,12 +6,12 @@
#include "./types.h"
#include "../application/global.h"
#include "../global.h"
/*!
* \brief Returns a 16-bit signed integer converted from two bytes at a specified position in a char array.
*/
LIB_EXPORT inline int16 toInt16(const char *value)
CPP_UTILITIES_EXPORT inline int16 toInt16(const char *value)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<int16>(value[0]) << 8 & 0xFF00)
@ -25,7 +25,7 @@ LIB_EXPORT inline int16 toInt16(const char *value)
/*!
* \brief Returns a 16-bit unsigned integer converted from two bytes at a specified position in a char array.
*/
LIB_EXPORT inline uint16 toUInt16(const char *value)
CPP_UTILITIES_EXPORT inline uint16 toUInt16(const char *value)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<uint16>(value[0]) << 8 & 0xFF00)
@ -39,7 +39,7 @@ LIB_EXPORT inline uint16 toUInt16(const char *value)
/*!
* \brief Returns a 32-bit signed integer converted from four bytes at a specified position in a char array.
*/
LIB_EXPORT inline int32 toInt32(const char *value)
CPP_UTILITIES_EXPORT inline int32 toInt32(const char *value)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<int32>(value[0]) << 24 & 0xFF000000)
@ -57,7 +57,7 @@ LIB_EXPORT inline int32 toInt32(const char *value)
/*!
* \brief Returns a 32-bit unsigned integer converted from three bytes at a specified position in a char array.
*/
LIB_EXPORT inline uint32 toUInt24(const char *value)
CPP_UTILITIES_EXPORT inline uint32 toUInt24(const char *value)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<uint32>(value[0]) << 16 & 0x00FF0000)
@ -73,7 +73,7 @@ LIB_EXPORT inline uint32 toUInt24(const char *value)
/*!
* \brief Returns a 32-bit unsigned integer converted from four bytes at a specified position in a char array.
*/
LIB_EXPORT inline uint32 toUInt32(const char *value)
CPP_UTILITIES_EXPORT inline uint32 toUInt32(const char *value)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<uint32>(value[0]) << 24 & 0xFF000000)
@ -91,7 +91,7 @@ LIB_EXPORT inline uint32 toUInt32(const char *value)
/*!
* \brief Returns a 64-bit signed integer converted from eight bytes at a specified position in a char array.
*/
LIB_EXPORT inline int64 toInt64(const char *value)
CPP_UTILITIES_EXPORT inline int64 toInt64(const char *value)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<int64>(value[0]) << 56 & 0xFF00000000000000)
@ -117,7 +117,7 @@ LIB_EXPORT inline int64 toInt64(const char *value)
/*!
* \brief Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a char array.
*/
LIB_EXPORT inline uint64 toUInt64(const char *value)
CPP_UTILITIES_EXPORT inline uint64 toUInt64(const char *value)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
return (static_cast<uint64>(value[0]) << 56 & 0xFF00000000000000)
@ -143,7 +143,7 @@ LIB_EXPORT inline uint64 toUInt64(const char *value)
/*!
* \brief Returns a 32-bit floating point number converted from four bytes at a specified position in a char array.
*/
LIB_EXPORT inline float32 toFloat32(const char *value)
CPP_UTILITIES_EXPORT inline float32 toFloat32(const char *value)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
int32 val = toInt32(value);
@ -159,7 +159,7 @@ LIB_EXPORT inline float32 toFloat32(const char *value)
/*!
* \brief Returns a 64-bit floating point number converted from eight bytes at a specified position in a char array.
*/
LIB_EXPORT inline float64 toFloat64(const char *value)
CPP_UTILITIES_EXPORT inline float64 toFloat64(const char *value)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
int64 val = toInt64(value);
@ -175,7 +175,7 @@ LIB_EXPORT inline float64 toFloat64(const char *value)
/*!
* \brief Stores the specified 16-bit signed integer value at a specified position in a char array.
*/
LIB_EXPORT inline void getBytes(int16 value, char *outputbuffer)
CPP_UTILITIES_EXPORT inline void getBytes(int16 value, char *outputbuffer)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 8) & 0xFF);
@ -189,7 +189,7 @@ LIB_EXPORT inline void getBytes(int16 value, char *outputbuffer)
/*!
* \brief Stores the specified 16-bit unsigned integer value at a specified position in a char array.
*/
LIB_EXPORT inline void getBytes(uint16 value, char *outputbuffer)
CPP_UTILITIES_EXPORT inline void getBytes(uint16 value, char *outputbuffer)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 8) & 0xFF);
@ -204,7 +204,7 @@ LIB_EXPORT inline void getBytes(uint16 value, char *outputbuffer)
* \brief Stores the specified 24-bit unsigned integer value at a specified position in a char array.
* \remarks Ignores the most significant byte.
*/
LIB_EXPORT inline void getBytes24(uint32 value, char *outputbuffer)
CPP_UTILITIES_EXPORT inline void getBytes24(uint32 value, char *outputbuffer)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 16) & 0xFF);
@ -220,7 +220,7 @@ LIB_EXPORT inline void getBytes24(uint32 value, char *outputbuffer)
/*!
* \brief Stores the specified 32-bit signed integer value at a specified position in a char array.
*/
LIB_EXPORT inline void getBytes(int32 value, char *outputbuffer)
CPP_UTILITIES_EXPORT inline void getBytes(int32 value, char *outputbuffer)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 24) & 0xFF);
@ -238,7 +238,7 @@ LIB_EXPORT inline void getBytes(int32 value, char *outputbuffer)
/*!
* \brief Stores the specified 32-bit signed integer value at a specified position in a char array.
*/
LIB_EXPORT inline void getBytes(uint32 value, char *outputbuffer)
CPP_UTILITIES_EXPORT inline void getBytes(uint32 value, char *outputbuffer)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 24) & 0xFF);
@ -256,7 +256,7 @@ LIB_EXPORT inline void getBytes(uint32 value, char *outputbuffer)
/*!
* \brief Stores the specified 64-bit signed integer value at a specified position in a char array.
*/
LIB_EXPORT inline void getBytes(int64 value, char *outputbuffer)
CPP_UTILITIES_EXPORT inline void getBytes(int64 value, char *outputbuffer)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 56) & 0xFF);
@ -282,7 +282,7 @@ LIB_EXPORT inline void getBytes(int64 value, char *outputbuffer)
/*!
* \brief Stores the specified 64-bit unsigned integer value at a specified position in a char array.
*/
LIB_EXPORT inline void getBytes(uint64 value, char *outputbuffer)
CPP_UTILITIES_EXPORT inline void getBytes(uint64 value, char *outputbuffer)
{
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
outputbuffer[0] = static_cast<char>((value >> 56) & 0xFF);
@ -308,7 +308,7 @@ LIB_EXPORT inline void getBytes(uint64 value, char *outputbuffer)
/*!
* \brief Stores the specified 32-bit floating point value at a specified position in a char array.
*/
LIB_EXPORT inline void getBytes(float32 value, char *outputbuffer)
CPP_UTILITIES_EXPORT inline void getBytes(float32 value, char *outputbuffer)
{
char *c = reinterpret_cast<char *>(&value);
int32 i = *reinterpret_cast<int32 *>(c);
@ -318,7 +318,7 @@ LIB_EXPORT inline void getBytes(float32 value, char *outputbuffer)
/*!
* \brief Stores the specified 64-bit floating point value at a specified position in a char array.
*/
LIB_EXPORT inline void getBytes(float64 value, char *outputbuffer)
CPP_UTILITIES_EXPORT inline void getBytes(float64 value, char *outputbuffer)
{
char *c = reinterpret_cast<char *>(&value);
int64 i = *reinterpret_cast<int64 *>(c);

View File

@ -1,14 +1,14 @@
#ifndef CONVERSION_UTILITIES_CONVERSIONEXCEPTION_H
#define CONVERSION_UTILITIES_CONVERSIONEXCEPTION_H
#include "../application/global.h"
#include "../global.h"
#include <stdexcept>
#include <string>
namespace ConversionUtilities {
class LIB_EXPORT ConversionException : public std::runtime_error
class CPP_UTILITIES_EXPORT ConversionException : public std::runtime_error
{
public:
ConversionException() USE_NOTHROW;

View File

@ -19,7 +19,7 @@ namespace ConversionUtilities
/*!
* \brief The StringDataDeleter struct deletes the data of a StringData instance.
*/
struct LIB_EXPORT StringDataDeleter {
struct CPP_UTILITIES_EXPORT StringDataDeleter {
/*!
* \brief Deletes the specified \a stringData with std::free(), because the memory has been
* allocated using std::malloc()/std::realloc().
@ -36,15 +36,15 @@ struct LIB_EXPORT StringDataDeleter {
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
LIB_EXPORT StringData convertString(const char *fromCharset, const char *toCharset, const char *inputBuffer, std::size_t inputBufferSize, float outputBufferSizeFactor = 1.0f);
LIB_EXPORT StringData convertUtf8ToUtf16LE(const char *inputBuffer, std::size_t inputBufferSize);
LIB_EXPORT StringData convertUtf16LEToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
LIB_EXPORT StringData convertUtf8ToUtf16BE(const char *inputBuffer, std::size_t inputBufferSize);
LIB_EXPORT StringData convertUtf16BEToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
LIB_EXPORT StringData convertLatin1ToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
LIB_EXPORT StringData convertUtf8ToLatin1(const char *inputBuffer, std::size_t inputBufferSize);
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 convertUtf16LEToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16BE(const char *inputBuffer, std::size_t inputBufferSize);
CPP_UTILITIES_EXPORT StringData convertUtf16BEToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
CPP_UTILITIES_EXPORT StringData convertLatin1ToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
CPP_UTILITIES_EXPORT StringData convertUtf8ToLatin1(const char *inputBuffer, std::size_t inputBufferSize);
LIB_EXPORT void truncateString(std::string &str, char terminationChar = '\0');
CPP_UTILITIES_EXPORT void truncateString(std::string &str, char terminationChar = '\0');
/*!
* \brief Joins the given \a strings using the specified \a delimiter.
@ -59,7 +59,7 @@ LIB_EXPORT void truncateString(std::string &str, char terminationChar = '\0');
* \tparam Container The STL-container used to provide the \a strings.
* \returns Returns the joined string.
*/
template <class Container = std::initializer_list<std::string> > LIB_EXPORT
template <class Container = std::initializer_list<std::string> > CPP_UTILITIES_EXPORT
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;
@ -108,7 +108,7 @@ enum class EmptyPartsTreat
* \tparam Container The STL-container used to return the parts.
* \returns Returns the parts.
*/
template <class Container = std::list<std::string> > LIB_EXPORT
template <class Container = std::list<std::string> > CPP_UTILITIES_EXPORT
Container splitString(const typename Container::value_type &string, const typename Container::value_type &delimiter, EmptyPartsTreat emptyPartsRole = EmptyPartsTreat::Keep, int maxParts = -1)
{
--maxParts;
@ -148,7 +148,7 @@ Container splitString(const typename Container::value_type &string, const typena
/*!
* \brief Returns whether \a str starts with \a phrase.
*/
template <typename StringType> LIB_EXPORT bool startsWith(const StringType &str, const StringType &phrase)
template <typename StringType> CPP_UTILITIES_EXPORT bool startsWith(const StringType &str, const StringType &phrase)
{
if(str.size() < phrase.size()) {
return false;
@ -166,7 +166,7 @@ template <typename StringType> LIB_EXPORT bool startsWith(const StringType &str,
/*!
* \brief Returns whether \a str starts with \a phrase.
*/
template <typename StringType> LIB_EXPORT bool startsWith(const StringType &str, const typename StringType::value_type *phrase)
template <typename StringType> CPP_UTILITIES_EXPORT bool startsWith(const StringType &str, const typename StringType::value_type *phrase)
{
for(auto stri = str.cbegin(), strend = str.cend(); stri != strend; ++stri, ++phrase) {
if(!*phrase) {
@ -182,7 +182,7 @@ template <typename StringType> LIB_EXPORT bool startsWith(const StringType &str,
* \brief Returns whether \a str contains the specified \a substrings.
* \remarks The \a substrings must occur in the specified order.
*/
template <typename StringType> LIB_EXPORT bool containsSubstrings(const StringType &str, std::initializer_list<StringType> substrings)
template <typename StringType> CPP_UTILITIES_EXPORT bool containsSubstrings(const StringType &str, std::initializer_list<StringType> substrings)
{
typename StringType::size_type currentPos = 0;
for(const auto &substr : substrings) {
@ -198,7 +198,7 @@ template <typename StringType> LIB_EXPORT bool containsSubstrings(const StringTy
* \brief Returns whether \a str contains the specified \a substrings.
* \remarks The \a substrings must occur in the specified order.
*/
template <typename StringType> LIB_EXPORT bool containsSubstrings(const StringType &str, std::initializer_list<const typename StringType::value_type *> substrings)
template <typename StringType> CPP_UTILITIES_EXPORT bool containsSubstrings(const StringType &str, std::initializer_list<const typename StringType::value_type *> substrings)
{
typename StringType::size_type currentPos = 0;
for(const auto *substr : substrings) {
@ -213,7 +213,7 @@ template <typename StringType> LIB_EXPORT bool containsSubstrings(const StringTy
/*!
* \brief Replaces all occurences of \a find with \a relpace in the specified \a str.
*/
template <typename StringType> LIB_EXPORT void findAndReplace(StringType &str, const StringType &find, const StringType &replace)
template <typename StringType> CPP_UTILITIES_EXPORT 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()) {
str.replace(i, find.size(), replace);
@ -226,7 +226,7 @@ template <typename StringType> LIB_EXPORT void findAndReplace(StringType &str, c
* \tparam StringType The string type (should be an instantiation of the basic_string class template).
* \sa stringToNumber()
*/
template <typename NumberType, typename StringType = std::string> LIB_EXPORT StringType numberToString(NumberType number, int base = 10)
template <typename NumberType, typename StringType = std::string> CPP_UTILITIES_EXPORT StringType numberToString(NumberType number, int base = 10)
{
std::basic_stringstream<typename StringType::value_type> ss;
ss << std::setbase(base) << number;
@ -240,7 +240,7 @@ template <typename NumberType, typename StringType = std::string> LIB_EXPORT Str
* \throws A ConversionException will be thrown if the provided string is not a valid number.
* \sa numberToString()
*/
template <typename NumberType, typename StringType> LIB_EXPORT NumberType stringToNumber(const StringType &string, int base = 10)
template <typename NumberType, typename StringType> CPP_UTILITIES_EXPORT NumberType stringToNumber(const StringType &string, int base = 10)
{
std::basic_stringstream<typename StringType::value_type> ss;
ss << std::setbase(base) << string;
@ -259,7 +259,7 @@ template <typename NumberType, typename StringType> LIB_EXPORT NumberType string
* \throws A ConversionException will be thrown if the provided string is not a valid number.
* \sa numberToString()
*/
template <typename NumberType, typename CharType> LIB_EXPORT NumberType stringToNumber(const CharType *string, int base = 10)
template <typename NumberType, typename CharType> CPP_UTILITIES_EXPORT NumberType stringToNumber(const CharType *string, int base = 10)
{
std::basic_stringstream<CharType> ss;
ss << std::setbase(base) << string;
@ -280,17 +280,17 @@ template <typename NumberType, typename CharType> LIB_EXPORT NumberType stringTo
*
* \tparam T The data type of the integer to be interpreted.
*/
template <typename T> LIB_EXPORT std::string interpretIntegerAsString(T integer, int startOffset = 0)
template <typename T> CPP_UTILITIES_EXPORT std::string interpretIntegerAsString(T integer, int startOffset = 0)
{
char buffer[sizeof(T)];
ConversionUtilities::BE::getBytes(integer, buffer);
return std::string(buffer + startOffset, sizeof(T) - startOffset);
}
LIB_EXPORT std::string dataSizeToString(uint64 sizeInByte, bool includeByte = false);
LIB_EXPORT std::string bitrateToString(double speedInKbitsPerSecond, bool useByteInsteadOfBits = false);
LIB_EXPORT std::string encodeBase64(const byte *data, uint32 dataSize);
LIB_EXPORT std::pair<std::unique_ptr<byte[]>, uint32> decodeBase64(const char *encodedStr, const uint32 strSize);
CPP_UTILITIES_EXPORT std::string dataSizeToString(uint64 sizeInByte, bool includeByte = 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::pair<std::unique_ptr<byte[]>, uint32> decodeBase64(const char *encodedStr, const uint32 strSize);
}

View File

@ -1,74 +1,74 @@
#ifndef CONVERSION_UTILITIES_TYPES_H
#define CONVERSION_UTILITIES_TYPES_H
#include <cstdint>
/*!
* \brief signed byte
*/
typedef std::int8_t sbyte;
/*!
* \brief unsigned byte
*/
typedef std::uint8_t byte;
/*!
* \brief signed 16-bit integer
*/
typedef std::int16_t int16;
/*!
* \brief signed 32-bit integer
*/
typedef std::int32_t int32;
/*!
* \brief signed 64-bit integer
*/
typedef std::int64_t int64;
/*!
* \brief signed pointer
*/
typedef std::intptr_t intptr;
/*!
* \brief unsigned 16-bit integer
*/
typedef std::uint16_t uint16;
/*!
* \brief unsigned 32-bit integer
*/
typedef std::uint32_t uint32;
/*!
* \brief unsigned 64-bit integer
*/
typedef std::uint64_t uint64;
/*!
* \brief unsigned pointer
*/
typedef std::uintptr_t uintptr;
#if __SIZEOF_FLOAT__ == 4
/*!
* \brief 32-bit floating point
*/
typedef float float32;
#else
#error "Unable to define float32!"
#endif
#if __SIZEOF_DOUBLE__ == 8
/*!
* \brief 64-bit floating point
*/
typedef double float64;
#else
#error "Unable to define float64!"
#endif
#endif // CONVERSION_UTILITIES_TYPES_H
#ifndef CONVERSION_UTILITIES_TYPES_H
#define CONVERSION_UTILITIES_TYPES_H
#include <cstdint>
/*!
* \brief signed byte
*/
typedef std::int8_t sbyte;
/*!
* \brief unsigned byte
*/
typedef std::uint8_t byte;
/*!
* \brief signed 16-bit integer
*/
typedef std::int16_t int16;
/*!
* \brief signed 32-bit integer
*/
typedef std::int32_t int32;
/*!
* \brief signed 64-bit integer
*/
typedef std::int64_t int64;
/*!
* \brief signed pointer
*/
typedef std::intptr_t intptr;
/*!
* \brief unsigned 16-bit integer
*/
typedef std::uint16_t uint16;
/*!
* \brief unsigned 32-bit integer
*/
typedef std::uint32_t uint32;
/*!
* \brief unsigned 64-bit integer
*/
typedef std::uint64_t uint64;
/*!
* \brief unsigned pointer
*/
typedef std::uintptr_t uintptr;
#if __SIZEOF_FLOAT__ == 4
/*!
* \brief 32-bit floating point
*/
typedef float float32;
#else
# error "Unable to define float32!"
#endif
#if __SIZEOF_DOUBLE__ == 8
/*!
* \brief 64-bit floating point
*/
typedef double float64;
#else
# error "Unable to define float64!"
#endif
#endif // CONVERSION_UTILITIES_TYPES_H

View File

@ -1,52 +1,52 @@
#ifndef CONVERSION_UTILITIES_WIDEN_H
#define CONVERSION_UTILITIES_WIDEN_H
#include "../application/global.h"
#include <string>
#include <vector>
#include <locale>
#include <functional>
#include <iostream>
namespace ConversionUtilities
{
/*!
* \brief Converts a std::string to a wide string using the specified locale.
*/
template<class E, class T = std::char_traits<E>, class A = std::allocator<E> >
class LIB_EXPORT Widen : public std::unary_function<const std::string &, std::basic_string<E, T, A> >
{
public:
/*!
* \brief Constructs a new instance with the specified \a locale.
*/
Widen(const std::locale &locale = std::locale()) :
m_loc(locale),
m_pctype(&std::use_facet<std::ctype<E> >(locale))
{}
Widen(const Widen &) = delete;
Widen& operator= (const Widen &) = delete;
/*!
* \brief Performs the conversation for the provided \a string.
*/
std::basic_string<E, T, A> operator() (const std::string &string) const
{
typename std::basic_string<E, T, A>::size_type srcLen = string.length();
const char *srcBeg = string.c_str();
std::vector<E> tmp(srcLen);
m_pctype->widen(srcBeg, srcBeg + srcLen, &tmp[0]);
return std::basic_string<E, T, A>(&tmp[0], srcLen);
}
private:
std::locale m_loc;
const std::ctype<E>* m_pctype;
};
}
#endif // CONVERSION_UTILITIES_WIDEN_H
#ifndef CONVERSION_UTILITIES_WIDEN_H
#define CONVERSION_UTILITIES_WIDEN_H
#include "../global.h"
#include <string>
#include <vector>
#include <locale>
#include <functional>
#include <iostream>
namespace ConversionUtilities
{
/*!
* \brief Converts a std::string to a wide string using the specified locale.
*/
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> >
{
public:
/*!
* \brief Constructs a new instance with the specified \a locale.
*/
Widen(const std::locale &locale = std::locale()) :
m_loc(locale),
m_pctype(&std::use_facet<std::ctype<E> >(locale))
{}
Widen(const Widen &) = delete;
Widen& operator= (const Widen &) = delete;
/*!
* \brief Performs the conversation for the provided \a string.
*/
std::basic_string<E, T, A> operator() (const std::string &string) const
{
typename std::basic_string<E, T, A>::size_type srcLen = string.length();
const char *srcBeg = string.c_str();
std::vector<E> tmp(srcLen);
m_pctype->widen(srcBeg, srcBeg + srcLen, &tmp[0]);
return std::basic_string<E, T, A>(&tmp[0], srcLen);
}
private:
std::locale m_loc;
const std::ctype<E>* m_pctype;
};
}
#endif // CONVERSION_UTILITIES_WIDEN_H

17
global.h Normal file
View File

@ -0,0 +1,17 @@
// Created via CMake from template global.h.in
// WARNING! Any changes to this file will be overwritten by the next CMake run!
#ifndef CPP_UTILITIES_GLOBAL
#define CPP_UTILITIES_GLOBAL
#include "./application/global.h"
#ifdef CPP_UTILITIES_STATIC
# define CPP_UTILITIES_EXPORT
# define CPP_UTILITIES_IMPORT
#else
# define CPP_UTILITIES_EXPORT LIB_EXPORT
# define CPP_UTILITIES_IMPORT LIB_IMPORT
#endif
#endif // CPP_UTILITIES_GLOBAL

View File

@ -1,7 +1,7 @@
#ifndef IOUTILITIES_ANSIESCAPECODES
#define IOUTILITIES_ANSIESCAPECODES
#include "../application/global.h"
#include "../global.h"
#include <ostream>

View File

@ -1,339 +1,339 @@
#include "./binaryreader.h"
#include "../misc/memory.h"
#include "../conversion/conversionexception.h"
#include <sstream>
#include <cstring>
using namespace std;
using namespace IoUtilities;
using namespace ConversionUtilities;
/*!
* \namespace IoUtilities
* \brief Contains utility classes helping to read and write streams.
*/
/*!
* \class IoUtilities::BinaryReader
* \brief Reads primitive data types from a std::istream.
* \remarks Supports both, little endian and big endian.
*/
/*!
* \brief Constructs a new BinaryReader.
* \param stream Specifies the stream to read from.
*/
BinaryReader::BinaryReader(istream *stream) :
m_stream(stream),
m_ownership(false)
{}
/*!
* \brief Copies the specified BinaryReader.
* \remarks The copy will not take ownership over the stream.
*/
BinaryReader::BinaryReader(const BinaryReader &other) :
m_stream(other.m_stream),
m_ownership(false)
{}
/*!
* \brief Destroys the BinaryReader.
*/
BinaryReader::~BinaryReader()
{
if(m_ownership) {
delete m_stream;
}
}
/*!
* \brief Assigns the stream the reader will read from when calling one of the read-methods.
*
* You can assign a null pointer when ensuring that none of the read-methods is called
* until a stream is assigned.
*
* \param stream Specifies the stream to be assigned.
* \param giveOwnership Indicated whether the reader should take ownership (default is false).
*
* \sa setStream()
*/
void BinaryReader::setStream(istream *stream, bool giveOwnership)
{
if(m_ownership) {
delete m_stream;
}
if(stream) {
m_stream = stream;
m_ownership = giveOwnership;
} else {
m_stream = nullptr;
m_ownership = false;
}
}
/*!
* \brief Returns the size of the assigned stream.
*
* The size is determined by seeking to the end of the stream and returning this offset.
*
* \remarks The method will seek back to the previous offset before returning.
*/
istream::pos_type BinaryReader::readStreamsize()
{
istream::pos_type cp = m_stream->tellg();
m_stream->seekg(0, ios_base::end);
const auto streamsize = m_stream->tellg();
m_stream->seekg(cp);
return streamsize;
}
/*!
* \brief Reads a length prefixed string from the current stream.
*
* \remarks Reads the length prefix from the stream and then a string of the denoted length.
* Advances the current position of the stream by the denoted length of the string plus the prefix length.
*/
string BinaryReader::readLengthPrefixedString()
{
static const int maxPrefixLength = 4;
int prefixLength = 1;
byte beg = m_stream->peek();
byte mask = 0x80;
while(prefixLength <= maxPrefixLength && (beg & mask) == 0) {
++prefixLength;
mask >>= 1;
}
if(prefixLength > maxPrefixLength) {
throw ConversionException("Length denotation of length-prefixed string exceeds maximum.");
}
memset(m_buffer, 0, maxPrefixLength);
m_stream->read(m_buffer + (maxPrefixLength - prefixLength), prefixLength);
*(m_buffer + (maxPrefixLength - prefixLength)) ^= mask;
uint32 prefix = BE::toUInt32(m_buffer);
return readString(prefix);
}
/*!
* \brief Reads a string from the current stream of the given \a length from the stream and advances the current position of the stream by \a length byte.
*/
string BinaryReader::readString(size_t length)
{
string res;
res.resize(length);
m_stream->read(&res[0], length);
return res;
}
/*!
* \brief Reads a terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus one byte.
*
* \param termination The byte to be recognized as termination value.
*/
string BinaryReader::readTerminatedString(byte termination)
{
stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
ss.exceptions(ios_base::badbit | ios_base::failbit);
m_stream->get(*ss.rdbuf(), termination); // delim byte is not extracted from the stream
m_stream->seekg(1, ios_base::cur); // "extract" delim byte manually
return ss.str();
}
/*!
* \brief Reads a terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus one byte
* but maximal by \a maxBytesToRead.
*
* \param maxBytesToRead The maximal number of bytes to read.
* \param termination The value to be recognized as termination.
*/
string BinaryReader::readTerminatedString(size_t maxBytesToRead, byte termination)
{
unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead);
for(char *i = buff.get(), *end = i + maxBytesToRead; i < end; ++i) {
m_stream->get(*i);
if(*(reinterpret_cast<byte *>(i)) == termination) {
return string(buff.get(), i - buff.get());
}
}
return string(buff.get(), maxBytesToRead);
}
/*!
* \brief Reads a multibyte-terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus two bytes.
*
* \param termination Specifies the two byte sized big endian value to be recognized as termination.
*/
string BinaryReader::readMultibyteTerminatedStringBE(uint16 termination)
{
stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
ss.exceptions(ios_base::badbit | ios_base::failbit);
char *delimChars = m_buffer, *buff = m_buffer + 2;
ConversionUtilities::BE::getBytes(termination, delimChars);
do {
m_stream->get(buff[0]);
m_stream->get(buff[1]);
} while(!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
return ss.str();
}
/*!
* \brief Reads a multibyte-terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus two bytes.
*
* \param termination Specifies the two byte sized little endian value to be recognized as termination.
*/
string BinaryReader::readMultibyteTerminatedStringLE(uint16 termination)
{
stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
ss.exceptions(ios_base::badbit | ios_base::failbit);
char *delimChars = m_buffer, *buff = m_buffer + 2;
ConversionUtilities::LE::getBytes(termination, delimChars);
do {
m_stream->get(buff[0]);
m_stream->get(buff[1]);
} while(!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
return ss.str();
}
/*!
* \brief Reads a terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus two bytes
* but maximal by \a maxBytesToRead.
*
* \param maxBytesToRead The maximal number of bytes to read.
* \param termination The two byte sized big endian value to be recognized as termination.
*/
string BinaryReader::readMultibyteTerminatedStringBE(std::size_t maxBytesToRead, uint16 termination)
{
unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead);
char *delimChars = m_buffer;
ConversionUtilities::BE::getBytes(termination, delimChars);
for(char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
m_stream->get(*i);
m_stream->get(*(i + 1));
if((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
return string(buff.get(), i - buff.get());
}
}
return string(buff.get(), maxBytesToRead);
}
/*!
* \brief Reads a terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus two bytes
* but maximal by \a maxBytesToRead.
*
* \param maxBytesToRead The maximal number of bytes to read.
* \param termination The two byte sized little endian value to be recognized as termination.
*/
string BinaryReader::readMultibyteTerminatedStringLE(std::size_t maxBytesToRead, uint16 termination)
{
unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead);
char *delimChars = m_buffer;
ConversionUtilities::LE::getBytes(termination, delimChars);
for(char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
m_stream->get(*i);
m_stream->get(*(i + 1));
if((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
return string(buff.get(), i - buff.get());
}
}
return string(buff.get(), maxBytesToRead);
}
/*!
* \brief Reads \a length bytes from the stream and computes the CRC-32 for that block of data.
*
* \remarks Cyclic redundancy check (CRC) is an error-detecting code commonly used in
* digital networks and storage devices to detect accidental changes to raw data.
* \remarks Ogg compatible version
* \sa <a href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check">Cyclic redundancy check - Wikipedia</a>
*/
uint32 BinaryReader::readCrc32(size_t length)
{
uint32 crc = 0x00;
for(uint32 i = 0; i < length; ++i) {
crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(m_stream->get())];
}
return crc;
}
/*!
* \brief Reads \a length bytes from the buffer and computes the CRC-32 for that block of data.
*
* \remarks Cyclic redundancy check (CRC) is an error-detecting code commonly used in
* digital networks and storage devices to detect accidental changes to raw data.
* \remarks Ogg compatible version
* \sa <a href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check">Cyclic redundancy check - Wikipedia</a>
*/
uint32 BinaryReader::computeCrc32(const char *buffer, size_t length)
{
uint32 crc = 0x00;
for(const char *i = buffer, *end = buffer + length; i != end; ++i) {
crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(*i)];
}
return crc;
}
/*!
* \brief CRC-32 table.
* \remarks Internally used by readCrc32() method.
* \sa readCrc32()
*/
const uint32 BinaryReader::crc32Table[] = {
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
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
};
#include "./binaryreader.h"
#include "../misc/memory.h"
#include "../conversion/conversionexception.h"
#include <sstream>
#include <cstring>
using namespace std;
using namespace IoUtilities;
using namespace ConversionUtilities;
/*!
* \namespace IoUtilities
* \brief Contains utility classes helping to read and write streams.
*/
/*!
* \class IoUtilities::BinaryReader
* \brief Reads primitive data types from a std::istream.
* \remarks Supports both, little endian and big endian.
*/
/*!
* \brief Constructs a new BinaryReader.
* \param stream Specifies the stream to read from.
*/
BinaryReader::BinaryReader(istream *stream) :
m_stream(stream),
m_ownership(false)
{}
/*!
* \brief Copies the specified BinaryReader.
* \remarks The copy will not take ownership over the stream.
*/
BinaryReader::BinaryReader(const BinaryReader &other) :
m_stream(other.m_stream),
m_ownership(false)
{}
/*!
* \brief Destroys the BinaryReader.
*/
BinaryReader::~BinaryReader()
{
if(m_ownership) {
delete m_stream;
}
}
/*!
* \brief Assigns the stream the reader will read from when calling one of the read-methods.
*
* You can assign a null pointer when ensuring that none of the read-methods is called
* until a stream is assigned.
*
* \param stream Specifies the stream to be assigned.
* \param giveOwnership Indicated whether the reader should take ownership (default is false).
*
* \sa setStream()
*/
void BinaryReader::setStream(istream *stream, bool giveOwnership)
{
if(m_ownership) {
delete m_stream;
}
if(stream) {
m_stream = stream;
m_ownership = giveOwnership;
} else {
m_stream = nullptr;
m_ownership = false;
}
}
/*!
* \brief Returns the size of the assigned stream.
*
* The size is determined by seeking to the end of the stream and returning this offset.
*
* \remarks The method will seek back to the previous offset before returning.
*/
istream::pos_type BinaryReader::readStreamsize()
{
istream::pos_type cp = m_stream->tellg();
m_stream->seekg(0, ios_base::end);
const auto streamsize = m_stream->tellg();
m_stream->seekg(cp);
return streamsize;
}
/*!
* \brief Reads a length prefixed string from the current stream.
*
* \remarks Reads the length prefix from the stream and then a string of the denoted length.
* Advances the current position of the stream by the denoted length of the string plus the prefix length.
*/
string BinaryReader::readLengthPrefixedString()
{
static const int maxPrefixLength = 4;
int prefixLength = 1;
byte beg = m_stream->peek();
byte mask = 0x80;
while(prefixLength <= maxPrefixLength && (beg & mask) == 0) {
++prefixLength;
mask >>= 1;
}
if(prefixLength > maxPrefixLength) {
throw ConversionException("Length denotation of length-prefixed string exceeds maximum.");
}
memset(m_buffer, 0, maxPrefixLength);
m_stream->read(m_buffer + (maxPrefixLength - prefixLength), prefixLength);
*(m_buffer + (maxPrefixLength - prefixLength)) ^= mask;
uint32 prefix = BE::toUInt32(m_buffer);
return readString(prefix);
}
/*!
* \brief Reads a string from the current stream of the given \a length from the stream and advances the current position of the stream by \a length byte.
*/
string BinaryReader::readString(size_t length)
{
string res;
res.resize(length);
m_stream->read(&res[0], length);
return res;
}
/*!
* \brief Reads a terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus one byte.
*
* \param termination The byte to be recognized as termination value.
*/
string BinaryReader::readTerminatedString(byte termination)
{
stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
ss.exceptions(ios_base::badbit | ios_base::failbit);
m_stream->get(*ss.rdbuf(), termination); // delim byte is not extracted from the stream
m_stream->seekg(1, ios_base::cur); // "extract" delim byte manually
return ss.str();
}
/*!
* \brief Reads a terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus one byte
* but maximal by \a maxBytesToRead.
*
* \param maxBytesToRead The maximal number of bytes to read.
* \param termination The value to be recognized as termination.
*/
string BinaryReader::readTerminatedString(size_t maxBytesToRead, byte termination)
{
unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead);
for(char *i = buff.get(), *end = i + maxBytesToRead; i < end; ++i) {
m_stream->get(*i);
if(*(reinterpret_cast<byte *>(i)) == termination) {
return string(buff.get(), i - buff.get());
}
}
return string(buff.get(), maxBytesToRead);
}
/*!
* \brief Reads a multibyte-terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus two bytes.
*
* \param termination Specifies the two byte sized big endian value to be recognized as termination.
*/
string BinaryReader::readMultibyteTerminatedStringBE(uint16 termination)
{
stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
ss.exceptions(ios_base::badbit | ios_base::failbit);
char *delimChars = m_buffer, *buff = m_buffer + 2;
ConversionUtilities::BE::getBytes(termination, delimChars);
do {
m_stream->get(buff[0]);
m_stream->get(buff[1]);
} while(!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
return ss.str();
}
/*!
* \brief Reads a multibyte-terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus two bytes.
*
* \param termination Specifies the two byte sized little endian value to be recognized as termination.
*/
string BinaryReader::readMultibyteTerminatedStringLE(uint16 termination)
{
stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
ss.exceptions(ios_base::badbit | ios_base::failbit);
char *delimChars = m_buffer, *buff = m_buffer + 2;
ConversionUtilities::LE::getBytes(termination, delimChars);
do {
m_stream->get(buff[0]);
m_stream->get(buff[1]);
} while(!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
return ss.str();
}
/*!
* \brief Reads a terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus two bytes
* but maximal by \a maxBytesToRead.
*
* \param maxBytesToRead The maximal number of bytes to read.
* \param termination The two byte sized big endian value to be recognized as termination.
*/
string BinaryReader::readMultibyteTerminatedStringBE(std::size_t maxBytesToRead, uint16 termination)
{
unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead);
char *delimChars = m_buffer;
ConversionUtilities::BE::getBytes(termination, delimChars);
for(char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
m_stream->get(*i);
m_stream->get(*(i + 1));
if((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
return string(buff.get(), i - buff.get());
}
}
return string(buff.get(), maxBytesToRead);
}
/*!
* \brief Reads a terminated string from the current stream.
*
* Advances the current position of the stream by the string length plus two bytes
* but maximal by \a maxBytesToRead.
*
* \param maxBytesToRead The maximal number of bytes to read.
* \param termination The two byte sized little endian value to be recognized as termination.
*/
string BinaryReader::readMultibyteTerminatedStringLE(std::size_t maxBytesToRead, uint16 termination)
{
unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead);
char *delimChars = m_buffer;
ConversionUtilities::LE::getBytes(termination, delimChars);
for(char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
m_stream->get(*i);
m_stream->get(*(i + 1));
if((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
return string(buff.get(), i - buff.get());
}
}
return string(buff.get(), maxBytesToRead);
}
/*!
* \brief Reads \a length bytes from the stream and computes the CRC-32 for that block of data.
*
* \remarks Cyclic redundancy check (CRC) is an error-detecting code commonly used in
* digital networks and storage devices to detect accidental changes to raw data.
* \remarks Ogg compatible version
* \sa <a href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check">Cyclic redundancy check - Wikipedia</a>
*/
uint32 BinaryReader::readCrc32(size_t length)
{
uint32 crc = 0x00;
for(uint32 i = 0; i < length; ++i) {
crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(m_stream->get())];
}
return crc;
}
/*!
* \brief Reads \a length bytes from the buffer and computes the CRC-32 for that block of data.
*
* \remarks Cyclic redundancy check (CRC) is an error-detecting code commonly used in
* digital networks and storage devices to detect accidental changes to raw data.
* \remarks Ogg compatible version
* \sa <a href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check">Cyclic redundancy check - Wikipedia</a>
*/
uint32 BinaryReader::computeCrc32(const char *buffer, size_t length)
{
uint32 crc = 0x00;
for(const char *i = buffer, *end = buffer + length; i != end; ++i) {
crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(*i)];
}
return crc;
}
/*!
* \brief CRC-32 table.
* \remarks Internally used by readCrc32() method.
* \sa readCrc32()
*/
const uint32 BinaryReader::crc32Table[] = {
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
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
};

File diff suppressed because it is too large Load Diff

View File

@ -1,95 +1,95 @@
#include "./binarywriter.h"
#include "../conversion/conversionexception.h"
#include <cstring>
#include <memory>
using namespace std;
using namespace IoUtilities;
using namespace ConversionUtilities;
/*!
* \class IoUtilities::BinaryWriter
* \brief Writes primitive data types to a std::ostream.
* \remarks Supports both, little endian and big endian.
*/
/*!
* \brief Constructs a new BinaryWriter.
* \param stream Specifies the stream to write to.
*/
BinaryWriter::BinaryWriter(ostream *stream) :
m_stream(stream),
m_ownership(false)
{}
/*!
* \brief Copies the specified BinaryWriter.
* \remarks The copy will not take ownership over the stream.
*/
BinaryWriter::BinaryWriter(const BinaryWriter &other) :
m_stream(other.m_stream),
m_ownership(false)
{}
/*!
* \brief Destroys the BinaryWriter.
*/
BinaryWriter::~BinaryWriter()
{
if(m_ownership) {
delete m_stream;
}
}
/*!
* \brief Assigns the stream the writer will write to when calling one of the write-methods.
*
* You can assign a null pointer when ensuring that none of the write-methods is called
* until a stream is assigned.
*
* \param stream Specifies the stream to be assigned.
* \param giveOwnership Indicated whether the reader should take ownership (default is false).
*
* \sa setStream()
*/
void BinaryWriter::setStream(ostream *stream, bool giveOwnership)
{
if(m_ownership) {
delete m_stream;
}
if(stream) {
m_stream = stream;
m_ownership = giveOwnership;
} else {
m_stream = nullptr;
m_ownership = false;
}
}
/*!
* \brief Writes the length of a string and the string itself to the current stream.
*
* Advances the current position of the stream by the length of the string plus the size of the length prefix.
*/
void BinaryWriter::writeLengthPrefixedString(const string &value)
{
size_t length = value.length();
if(length < 0x80) {
m_buffer[0] = 0x80 | length;
m_stream->write(m_buffer, 1);
} else if(length < 0x4000) {
BE::getBytes(static_cast<uint16>(0x4000 | length), m_buffer);
m_stream->write(m_buffer, 2);
} else if(length < 0x200000) {
BE::getBytes(static_cast<uint32>(0x200000 | length), m_buffer);
m_stream->write(m_buffer + 1, 3);
} else if(length < 0x10000000) {
BE::getBytes(static_cast<uint32>(0x10000000 | length), m_buffer);
m_stream->write(m_buffer, 4);
} else {
throw ConversionException("The size of the string exceeds the maximum.");
}
m_stream->write(value.c_str(), length);
}
#include "./binarywriter.h"
#include "../conversion/conversionexception.h"
#include <cstring>
#include <memory>
using namespace std;
using namespace IoUtilities;
using namespace ConversionUtilities;
/*!
* \class IoUtilities::BinaryWriter
* \brief Writes primitive data types to a std::ostream.
* \remarks Supports both, little endian and big endian.
*/
/*!
* \brief Constructs a new BinaryWriter.
* \param stream Specifies the stream to write to.
*/
BinaryWriter::BinaryWriter(ostream *stream) :
m_stream(stream),
m_ownership(false)
{}
/*!
* \brief Copies the specified BinaryWriter.
* \remarks The copy will not take ownership over the stream.
*/
BinaryWriter::BinaryWriter(const BinaryWriter &other) :
m_stream(other.m_stream),
m_ownership(false)
{}
/*!
* \brief Destroys the BinaryWriter.
*/
BinaryWriter::~BinaryWriter()
{
if(m_ownership) {
delete m_stream;
}
}
/*!
* \brief Assigns the stream the writer will write to when calling one of the write-methods.
*
* You can assign a null pointer when ensuring that none of the write-methods is called
* until a stream is assigned.
*
* \param stream Specifies the stream to be assigned.
* \param giveOwnership Indicated whether the reader should take ownership (default is false).
*
* \sa setStream()
*/
void BinaryWriter::setStream(ostream *stream, bool giveOwnership)
{
if(m_ownership) {
delete m_stream;
}
if(stream) {
m_stream = stream;
m_ownership = giveOwnership;
} else {
m_stream = nullptr;
m_ownership = false;
}
}
/*!
* \brief Writes the length of a string and the string itself to the current stream.
*
* Advances the current position of the stream by the length of the string plus the size of the length prefix.
*/
void BinaryWriter::writeLengthPrefixedString(const string &value)
{
size_t length = value.length();
if(length < 0x80) {
m_buffer[0] = 0x80 | length;
m_stream->write(m_buffer, 1);
} else if(length < 0x4000) {
BE::getBytes(static_cast<uint16>(0x4000 | length), m_buffer);
m_stream->write(m_buffer, 2);
} else if(length < 0x200000) {
BE::getBytes(static_cast<uint32>(0x200000 | length), m_buffer);
m_stream->write(m_buffer + 1, 3);
} else if(length < 0x10000000) {
BE::getBytes(static_cast<uint32>(0x10000000 | length), m_buffer);
m_stream->write(m_buffer, 4);
} else {
throw ConversionException("The size of the string exceeds the maximum.");
}
m_stream->write(value.c_str(), length);
}

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,8 @@
#define IOUTILITIES_BITREADER_H
#include "../conversion/types.h"
#include "../application/global.h"
#include "../io/catchiofailure.h"
#include "../global.h"
#include <ios>
#include <iostream>
@ -11,7 +11,7 @@
namespace IoUtilities {
class LIB_EXPORT BitReader
class CPP_UTILITIES_EXPORT BitReader
{
public:
BitReader(const char *buffer, std::size_t bufferSize);

View File

@ -1,36 +1,36 @@
// ensure the old ABI is used
// TODO: add condition for GCC version if GCC Bug 66145 is fixed
#define _GLIBCXX_USE_CXX11_ABI 0
#include "./catchiofailure.h"
#include <ios>
using namespace std;
namespace IoUtilities {
/*!
* \brief Provides a workaround for GCC Bug 66145.
* \returns Returns the error message.
* \throws Throws the current exception if it is not std::ios_base::failure.
*/
const char *catchIoFailure()
{
try {
throw;
} catch(const ios_base::failure &e) {
return e.what();
}
}
/*!
* \brief Throws a std::ios_base::failure with the specified message.
*/
void throwIoFailure(const char *what)
{
throw ios_base::failure(what);
}
}
// ensure the old ABI is used
// TODO: add condition for GCC version if GCC Bug 66145 is fixed
#define _GLIBCXX_USE_CXX11_ABI 0
#include "./catchiofailure.h"
#include <ios>
using namespace std;
namespace IoUtilities {
/*!
* \brief Provides a workaround for GCC Bug 66145.
* \returns Returns the error message.
* \throws Throws the current exception if it is not std::ios_base::failure.
*/
const char *catchIoFailure()
{
try {
throw;
} catch(const ios_base::failure &e) {
return e.what();
}
}
/*!
* \brief Throws a std::ios_base::failure with the specified message.
*/
void throwIoFailure(const char *what)
{
throw ios_base::failure(what);
}
}

View File

@ -1,15 +1,15 @@
#ifndef IOUTILITIES_CATCHIOFAILURE_H
#define IOUTILITIES_CATCHIOFAILURE_H
#include "../application/global.h"
#include <string>
namespace IoUtilities {
LIB_EXPORT const char *catchIoFailure();
LIB_EXPORT void throwIoFailure(const char *what);
}
#endif // IOUTILITIES_CATCHIOFAILURE_H
#ifndef IOUTILITIES_CATCHIOFAILURE_H
#define IOUTILITIES_CATCHIOFAILURE_H
#include "../global.h"
#include <string>
namespace IoUtilities {
CPP_UTILITIES_EXPORT const char *catchIoFailure();
CPP_UTILITIES_EXPORT void throwIoFailure(const char *what);
}
#endif // IOUTILITIES_CATCHIOFAILURE_H

View File

@ -1,7 +1,7 @@
#ifndef IOUTILITIES_COPY_H
#define IOUTILITIES_COPY_H
#include "../application/global.h"
#include "../global.h"
#include <iostream>
#include <functional>
@ -14,7 +14,7 @@ namespace IoUtilities {
* \tparam Specifies the buffer size.
*/
template<std::size_t bufferSize>
class LIB_EXPORT CopyHelper
class CPP_UTILITIES_EXPORT CopyHelper
{
public:
CopyHelper();

View File

@ -1,7 +1,7 @@
#ifndef IOUTILITIES_INIFILE_H
#define IOUTILITIES_INIFILE_H
#include "../application/global.h"
#include "../global.h"
#include <vector>
#include <map>
@ -9,7 +9,7 @@
namespace IoUtilities {
class LIB_EXPORT IniFile
class CPP_UTILITIES_EXPORT IniFile
{
public:
IniFile();

View File

@ -1,218 +1,217 @@
#include "./path.h"
#include "../application/global.h"
#include "../conversion/widen.h"
#include <string>
#include <sstream>
#include <fstream>
#include <cstdlib>
#ifdef PLATFORM_UNIX
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <pwd.h>
# include <dirent.h>
#else
# ifdef PLATFORM_WINDOWS
# ifdef UNICODE
# undef UNICODE
# endif
# ifdef _UNICODE
# undef _UNICODE
# endif
# include <windows.h>
# endif
#endif
using namespace std;
using namespace ConversionUtilities;
namespace IoUtilities {
/*!
* \brief Returns the file name and extension of the specified \a path string.
*/
string fileName(const string &path)
{
size_t lastSlash = path.rfind('/');
size_t lastBackSlash = path.rfind('\\');
size_t lastSeparator;
if(lastSlash == string::npos && lastBackSlash == string::npos) {
return path;
} else if(lastSlash == string::npos) {
lastSeparator = lastBackSlash;
} else if(lastBackSlash == string::npos) {
lastSeparator = lastSlash;
} else {
lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;
}
return path.substr(lastSeparator + 1);
}
/*!
* \brief Returns the directory of the specified \a path string (including trailing slash).
*/
string directory(const string &path)
{
size_t lastSlash = path.rfind('/');
size_t lastBackSlash = path.rfind('\\');
size_t lastSeparator;
if(lastSlash == string::npos && lastBackSlash == string::npos) {
return string();
} else if(lastSlash == string::npos) {
lastSeparator = lastBackSlash;
} else if(lastBackSlash == string::npos) {
lastSeparator = lastSlash;
} else {
lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;
}
return path.substr(0, lastSeparator + 1);
}
/*!
* \brief Removes invalid characters from the specified \a fileName.
*
* The characters <, >, ?, !, *, |, /, :, \ and new lines are considered as invalid.
*/
void removeInvalidChars(std::string &fileName)
{
size_t startPos = 0;
static const char invalidPathChars[] = {'\"', '<', '>', '?', '!', '*', '|', '/', ':', '\\', '\n'};
for(const char *i = invalidPathChars, *end = invalidPathChars + sizeof(invalidPathChars); i != end; ++i) {
startPos = fileName.find(*i);
while(startPos != string::npos) {
fileName.replace(startPos, 1, string());
startPos = fileName.find(*i, startPos);
}
}
}
/*!
* \brief Locates a directory meant to store application settings.
* \param result Specifies a string to store the path in.
* \param applicationDirectoryName Specifies the name for the application subdirectory.
* \param createApplicationDirectory Indicates wheter the application subdirectory should be created if not present.
* \returns Returns if a settings directory could be located.
*/
bool settingsDirectory(std::string &result, std::string applicationDirectoryName, bool createApplicationDirectory)
{
result.clear();
fstream pathConfigFile("path.config", ios_base::in);
if(pathConfigFile.good()) {
for(string line; getline(pathConfigFile, line); ) {
string::size_type p = line.find('=');
if((p != string::npos) && (p + 1 < line.length())) {
string fieldName = line.substr(0, p);
if(fieldName == "settings") {
result.assign(line.substr(p + 1));
}
}
}
}
if(!result.empty()) {
#ifdef PLATFORM_UNIX
struct stat sb;
return (stat(result.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode));
#else
# ifdef PLATFORM_WINDOWS
DWORD ftyp = GetFileAttributesA(result.c_str());
return (ftyp != INVALID_FILE_ATTRIBUTES) && (ftyp & FILE_ATTRIBUTE_DIRECTORY);
# else
# error Platform not supported.
# endif
#endif
} else {
if(!applicationDirectoryName.empty()) {
removeInvalidChars(applicationDirectoryName);
}
#ifdef PLATFORM_UNIX
if(char *homeDir = getenv("HOME")) {
result = string(homeDir);
} else {
struct passwd *pw = getpwuid(getuid());
result = string(pw->pw_dir);
}
struct stat sb;
result += "/.config";
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) {
return false;
}
}
if(!applicationDirectoryName.empty()) {
result += "/" + applicationDirectoryName;
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) {
return false;
}
}
}
#else
# ifdef PLATFORM_WINDOWS
if(char *appData = getenv("appdata")) {
result = appData;
if(!applicationDirectoryName.empty()) {
result += "\\" + applicationDirectoryName;
if(createApplicationDirectory) {
DWORD ftyp = GetFileAttributesA(result.c_str());
if(ftyp == INVALID_FILE_ATTRIBUTES) {
return false;
} else if(ftyp & FILE_ATTRIBUTE_DIRECTORY) {
return true;
} else {
if(CreateDirectory(result.c_str(), NULL) == 0) {
return false;
} else {
return true;
}
}
}
}
} else {
return false;
}
# else
# error Platform not supported.
# endif
#endif
}
return true;
}
/*!
* \brief Returns the names of the directory entries in the specified \a path with the specified \a types.
*/
std::list<std::string> directoryEntries(const char *path, DirectoryEntryType types)
{
#ifdef PLATFORM_UNIX
list<string> entries;
if(auto dir = opendir(path)) {
while(auto dirEntry = readdir(dir)) {
bool filter = false;
switch(dirEntry->d_type) {
case DT_REG:
filter = (types & DirectoryEntryType::File) != DirectoryEntryType::None;
break;
case DT_DIR:
filter = (types & DirectoryEntryType::Directory) != DirectoryEntryType::None;
break;
case DT_LNK:
filter = (types & DirectoryEntryType::Symlink) != DirectoryEntryType::None;
break;
default:
filter = (types & DirectoryEntryType::All) != DirectoryEntryType::None;
}
if(filter) {
entries.emplace_back(dirEntry->d_name);
}
}
closedir(dir);
}
return entries;
#else
return list<string>(); // TODO
#endif
}
}
#include "./path.h"
#include "../conversion/widen.h"
#include <string>
#include <sstream>
#include <fstream>
#include <cstdlib>
#ifdef PLATFORM_UNIX
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <pwd.h>
# include <dirent.h>
#else
# ifdef PLATFORM_WINDOWS
# ifdef UNICODE
# undef UNICODE
# endif
# ifdef _UNICODE
# undef _UNICODE
# endif
# include <windows.h>
# endif
#endif
using namespace std;
using namespace ConversionUtilities;
namespace IoUtilities {
/*!
* \brief Returns the file name and extension of the specified \a path string.
*/
string fileName(const string &path)
{
size_t lastSlash = path.rfind('/');
size_t lastBackSlash = path.rfind('\\');
size_t lastSeparator;
if(lastSlash == string::npos && lastBackSlash == string::npos) {
return path;
} else if(lastSlash == string::npos) {
lastSeparator = lastBackSlash;
} else if(lastBackSlash == string::npos) {
lastSeparator = lastSlash;
} else {
lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;
}
return path.substr(lastSeparator + 1);
}
/*!
* \brief Returns the directory of the specified \a path string (including trailing slash).
*/
string directory(const string &path)
{
size_t lastSlash = path.rfind('/');
size_t lastBackSlash = path.rfind('\\');
size_t lastSeparator;
if(lastSlash == string::npos && lastBackSlash == string::npos) {
return string();
} else if(lastSlash == string::npos) {
lastSeparator = lastBackSlash;
} else if(lastBackSlash == string::npos) {
lastSeparator = lastSlash;
} else {
lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;
}
return path.substr(0, lastSeparator + 1);
}
/*!
* \brief Removes invalid characters from the specified \a fileName.
*
* The characters <, >, ?, !, *, |, /, :, \ and new lines are considered as invalid.
*/
void removeInvalidChars(std::string &fileName)
{
size_t startPos = 0;
static const char invalidPathChars[] = {'\"', '<', '>', '?', '!', '*', '|', '/', ':', '\\', '\n'};
for(const char *i = invalidPathChars, *end = invalidPathChars + sizeof(invalidPathChars); i != end; ++i) {
startPos = fileName.find(*i);
while(startPos != string::npos) {
fileName.replace(startPos, 1, string());
startPos = fileName.find(*i, startPos);
}
}
}
/*!
* \brief Locates a directory meant to store application settings.
* \param result Specifies a string to store the path in.
* \param applicationDirectoryName Specifies the name for the application subdirectory.
* \param createApplicationDirectory Indicates wheter the application subdirectory should be created if not present.
* \returns Returns if a settings directory could be located.
*/
bool settingsDirectory(std::string &result, std::string applicationDirectoryName, bool createApplicationDirectory)
{
result.clear();
fstream pathConfigFile("path.config", ios_base::in);
if(pathConfigFile.good()) {
for(string line; getline(pathConfigFile, line); ) {
string::size_type p = line.find('=');
if((p != string::npos) && (p + 1 < line.length())) {
string fieldName = line.substr(0, p);
if(fieldName == "settings") {
result.assign(line.substr(p + 1));
}
}
}
}
if(!result.empty()) {
#ifdef PLATFORM_UNIX
struct stat sb;
return (stat(result.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode));
#else
# ifdef PLATFORM_WINDOWS
DWORD ftyp = GetFileAttributesA(result.c_str());
return (ftyp != INVALID_FILE_ATTRIBUTES) && (ftyp & FILE_ATTRIBUTE_DIRECTORY);
# else
# error Platform not supported.
# endif
#endif
} else {
if(!applicationDirectoryName.empty()) {
removeInvalidChars(applicationDirectoryName);
}
#ifdef PLATFORM_UNIX
if(char *homeDir = getenv("HOME")) {
result = string(homeDir);
} else {
struct passwd *pw = getpwuid(getuid());
result = string(pw->pw_dir);
}
struct stat sb;
result += "/.config";
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) {
return false;
}
}
if(!applicationDirectoryName.empty()) {
result += "/" + applicationDirectoryName;
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) {
return false;
}
}
}
#else
# ifdef PLATFORM_WINDOWS
if(char *appData = getenv("appdata")) {
result = appData;
if(!applicationDirectoryName.empty()) {
result += "\\" + applicationDirectoryName;
if(createApplicationDirectory) {
DWORD ftyp = GetFileAttributesA(result.c_str());
if(ftyp == INVALID_FILE_ATTRIBUTES) {
return false;
} else if(ftyp & FILE_ATTRIBUTE_DIRECTORY) {
return true;
} else {
if(CreateDirectory(result.c_str(), NULL) == 0) {
return false;
} else {
return true;
}
}
}
}
} else {
return false;
}
# else
# error Platform not supported.
# endif
#endif
}
return true;
}
/*!
* \brief Returns the names of the directory entries in the specified \a path with the specified \a types.
*/
std::list<std::string> directoryEntries(const char *path, DirectoryEntryType types)
{
#ifdef PLATFORM_UNIX
list<string> entries;
if(auto dir = opendir(path)) {
while(auto dirEntry = readdir(dir)) {
bool filter = false;
switch(dirEntry->d_type) {
case DT_REG:
filter = (types & DirectoryEntryType::File) != DirectoryEntryType::None;
break;
case DT_DIR:
filter = (types & DirectoryEntryType::Directory) != DirectoryEntryType::None;
break;
case DT_LNK:
filter = (types & DirectoryEntryType::Symlink) != DirectoryEntryType::None;
break;
default:
filter = (types & DirectoryEntryType::All) != DirectoryEntryType::None;
}
if(filter) {
entries.emplace_back(dirEntry->d_name);
}
}
closedir(dir);
}
return entries;
#else
return list<string>(); // TODO
#endif
}
}

110
io/path.h
View File

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

View File

@ -1,17 +1,17 @@
#ifndef MATHUTILITIES_H
#define MATHUTILITIES_H
#include "../application/global.h"
#include "../global.h"
#include "../conversion/types.h"
namespace MathUtilities {
LIB_EXPORT int random(int lowerbounds, int upperbounds);
LIB_EXPORT int digitsum(int number, int base = 10);
LIB_EXPORT int factorial(int number);
LIB_EXPORT uint64 powerModulo(uint64 base, uint64 expontent, uint64 module);
LIB_EXPORT int64 inverseModulo(int64 number, int64 module);
LIB_EXPORT uint64 orderModulo(uint64 number, uint64 module);
CPP_UTILITIES_EXPORT int random(int lowerbounds, int upperbounds);
CPP_UTILITIES_EXPORT int digitsum(int number, int base = 10);
CPP_UTILITIES_EXPORT int factorial(int number);
CPP_UTILITIES_EXPORT uint64 powerModulo(uint64 base, uint64 expontent, uint64 module);
CPP_UTILITIES_EXPORT int64 inverseModulo(int64 number, int64 module);
CPP_UTILITIES_EXPORT uint64 orderModulo(uint64 number, uint64 module);
}

View File

@ -1,125 +1,125 @@
#include "./random.h"
#include <iomanip>
#include <string>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <cassert>
using namespace std;
/*!
* \namespace RandomUtilities
* \brief Contains utility functions for generating random character sequences.
*/
namespace RandomUtilities {
//! @cond
const char letters[28] = "qwertzuiopasdfghjklyxcvbnm";
const char capitalLetters[28] = "QWERTZUIOPASDFGHJKLYXCVBNM";
const char numbers[11] = "1234567890";
const char symbols[24] = "!\"$%&/()=?'#*+~-_><.:,;";
//! @endcond
/*!
* \brief Generates a random character sequence using the given \a randomizer.
* \remarks Might be removed because not used anymore.
*/
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) {
return;
}
signed char categoryCount = 0;
bool needSmallLetter = false;
bool needCapitalLetter = false;
bool needNumber = false;
bool needSymbol = false;
if(useSmallLetters) {
needSmallLetter = useAtLeastOneOfEachCategory;
++categoryCount;
}
if(useCapitalLetters) {
needCapitalLetter = useAtLeastOneOfEachCategory;
++categoryCount;
}
if(useNumbers) {
needNumber = useAtLeastOneOfEachCategory;
++categoryCount;
}
if(useSymbols) {
needSymbol = useAtLeastOneOfEachCategory;
++categoryCount;
}
signed char neededCharacters = useAtLeastOneOfEachCategory ? categoryCount : 0;
if(!categoryCount) {
*result = '\0';
return;
}
for(char *i = result, *end = result + length; i < end; ++i) {
int category = -1;
if((neededCharacters > 0 && (randomizer() < (highestRandomNumber / 2.0))) || ((end - i) >= neededCharacters)) {
if(needSmallLetter)
category = 0;
if(needCapitalLetter && ((category == -1) || (randomizer() < (highestRandomNumber / 2.0))))
category = 1;
if(needNumber && ((category == -1) || (randomizer() < (highestRandomNumber / 4.0))))
category = 2;
if(needSymbol && ((category == -1) || (randomizer() < (highestRandomNumber / 8.0))))
category = 3;
} else {
if(useSmallLetters)
category = 0;
if(useCapitalLetters && ((category == -1) || (randomizer() < (highestRandomNumber / 2.0))))
category = 1;
if(useNumbers && ((category == -1) || (randomizer() < (highestRandomNumber / 4.0))))
category = 2;
if(useSymbols && ((category == -1) || (randomizer() < (highestRandomNumber / 8.0))))
category = 3;
}
switch(category) {
case 0:
*i = letters[rand() % 26];
if(needSmallLetter) {
needSmallLetter = false;
--neededCharacters;
}
break;
case 1:
*i = capitalLetters[rand() % 26];
if(needCapitalLetter) {
needCapitalLetter = false;
--neededCharacters;
}
break;
case 2:
*i = numbers[rand() % 9];
if(needNumber) {
needNumber = false;
--neededCharacters;
}
break;
case 3:
*i = symbols[rand() % 22];
if(needSymbol) {
needSymbol = false;
--neededCharacters;
}
break;
}
}
}
/*!
* \brief Generates a random character sequence using std::rand().
* \remarks Might be removed because not used anymore.
*/
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);
}
}
#include "./random.h"
#include <iomanip>
#include <string>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <cassert>
using namespace std;
/*!
* \namespace RandomUtilities
* \brief Contains utility functions for generating random character sequences.
*/
namespace RandomUtilities {
//! @cond
const char letters[28] = "qwertzuiopasdfghjklyxcvbnm";
const char capitalLetters[28] = "QWERTZUIOPASDFGHJKLYXCVBNM";
const char numbers[11] = "1234567890";
const char symbols[24] = "!\"$%&/()=?'#*+~-_><.:,;";
//! @endcond
/*!
* \brief Generates a random character sequence using the given \a randomizer.
* \remarks Might be removed because not used anymore.
*/
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) {
return;
}
signed char categoryCount = 0;
bool needSmallLetter = false;
bool needCapitalLetter = false;
bool needNumber = false;
bool needSymbol = false;
if(useSmallLetters) {
needSmallLetter = useAtLeastOneOfEachCategory;
++categoryCount;
}
if(useCapitalLetters) {
needCapitalLetter = useAtLeastOneOfEachCategory;
++categoryCount;
}
if(useNumbers) {
needNumber = useAtLeastOneOfEachCategory;
++categoryCount;
}
if(useSymbols) {
needSymbol = useAtLeastOneOfEachCategory;
++categoryCount;
}
signed char neededCharacters = useAtLeastOneOfEachCategory ? categoryCount : 0;
if(!categoryCount) {
*result = '\0';
return;
}
for(char *i = result, *end = result + length; i < end; ++i) {
int category = -1;
if((neededCharacters > 0 && (randomizer() < (highestRandomNumber / 2.0))) || ((end - i) >= neededCharacters)) {
if(needSmallLetter)
category = 0;
if(needCapitalLetter && ((category == -1) || (randomizer() < (highestRandomNumber / 2.0))))
category = 1;
if(needNumber && ((category == -1) || (randomizer() < (highestRandomNumber / 4.0))))
category = 2;
if(needSymbol && ((category == -1) || (randomizer() < (highestRandomNumber / 8.0))))
category = 3;
} else {
if(useSmallLetters)
category = 0;
if(useCapitalLetters && ((category == -1) || (randomizer() < (highestRandomNumber / 2.0))))
category = 1;
if(useNumbers && ((category == -1) || (randomizer() < (highestRandomNumber / 4.0))))
category = 2;
if(useSymbols && ((category == -1) || (randomizer() < (highestRandomNumber / 8.0))))
category = 3;
}
switch(category) {
case 0:
*i = letters[rand() % 26];
if(needSmallLetter) {
needSmallLetter = false;
--neededCharacters;
}
break;
case 1:
*i = capitalLetters[rand() % 26];
if(needCapitalLetter) {
needCapitalLetter = false;
--neededCharacters;
}
break;
case 2:
*i = numbers[rand() % 9];
if(needNumber) {
needNumber = false;
--neededCharacters;
}
break;
case 3:
*i = symbols[rand() % 22];
if(needSymbol) {
needSymbol = false;
--neededCharacters;
}
break;
}
}
}
/*!
* \brief Generates a random character sequence using std::rand().
* \remarks Might be removed because not used anymore.
*/
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);
}
}

View File

@ -1,15 +1,15 @@
#ifndef RANDOMUTILS_H
#define RANDOMUTILS_H
#include "../application/global.h"
#include <functional>
namespace RandomUtilities {
LIB_EXPORT void generateRandomCharacterSequence(char *result, unsigned int length, bool useSmallLetters = true, bool useCapitalLetters = true, bool useNumbers = true, bool useSymbols = true, bool useAtLeastOneOfEachCategory = true);
LIB_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
#ifndef RANDOMUTILS_H
#define RANDOMUTILS_H
#include "../global.h"
#include <functional>
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, std::function<int ()> randomizer, int maximalRandomNumber, bool useSmallLetters = true, bool useCapitalLetters = true, bool useNumbers = true, bool useSymbols = true, bool useAtLeastOneOfEachCategory = true);
}
#endif // RANDOMUTILS_H

View File

@ -8,7 +8,7 @@
namespace TestUtilities {
class LIB_EXPORT TestApplication
class CPP_UTILITIES_EXPORT TestApplication
{
public:
TestApplication(int argc, char **argv);
@ -79,7 +79,7 @@ inline const std::vector<const char *> &TestApplication::units() const
* \remarks A TestApplication must be present.
* \sa TestApplication::testFilePath()
*/
inline LIB_EXPORT std::string testFilePath(const std::string &name)
inline CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &name)
{
return TestApplication::instance()->testFilePath(name);
}
@ -90,7 +90,7 @@ inline LIB_EXPORT std::string testFilePath(const std::string &name)
* \remarks A TestApplication must be present.
* \sa TestApplication::workingCopyPath()
*/
inline LIB_EXPORT std::string workingCopyPath(const std::string &name)
inline CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &name)
{
return TestApplication::instance()->workingCopyPath(name);
}
@ -100,7 +100,7 @@ inline LIB_EXPORT std::string workingCopyPath(const std::string &name)
* \remarks A TestApplication must be present.
* \sa TestApplication::execApp()
*/
inline LIB_EXPORT int execApp(const char *const *args, std::string &output, std::string &errors)
inline CPP_UTILITIES_EXPORT int execApp(const char *const *args, std::string &output, std::string &errors)
{
return TestApplication::instance()->execApp(args, output, errors);
}