aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/Logging/AppenderConsole.cpp45
-rw-r--r--src/common/Logging/AppenderConsole.h14
-rw-r--r--src/common/Logging/AppenderFile.cpp27
-rw-r--r--src/common/Logging/AppenderFile.h6
-rw-r--r--src/common/Logging/Log.cpp63
-rw-r--r--src/common/Logging/Log.h11
-rw-r--r--src/common/Logging/LogCommon.h15
-rw-r--r--src/common/Logging/enuminfo_AppenderConsole.cpp103
-rw-r--r--src/common/Logging/enuminfo_LogCommon.cpp124
-rw-r--r--src/common/Metric/Metric.cpp2
-rw-r--r--src/common/Utilities/Util.cpp93
-rw-r--r--src/common/Utilities/Util.h34
12 files changed, 380 insertions, 157 deletions
diff --git a/src/common/Logging/AppenderConsole.cpp b/src/common/Logging/AppenderConsole.cpp
index 86e7634f1b9..af2117c6d0c 100644
--- a/src/common/Logging/AppenderConsole.cpp
+++ b/src/common/Logging/AppenderConsole.cpp
@@ -17,6 +17,9 @@
#include "AppenderConsole.h"
#include "LogMessage.h"
+#include "SmartEnum.h"
+#include "StringFormat.h"
+#include "StringConvert.h"
#include "Util.h"
#include <sstream>
@@ -24,17 +27,17 @@
#include <Windows.h>
#endif
-AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*> extraArgs)
+AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args)
: Appender(id, name, level, flags), _colored(false)
{
for (uint8 i = 0; i < NUM_ENABLED_LOG_LEVELS; ++i)
- _colors[i] = ColorTypes(MaxColors);
+ _colors[i] = ColorTypes(NUM_COLOR_TYPES);
- if (!extraArgs.empty())
- InitColors(extraArgs[0]);
+ if (3 < args.size())
+ InitColors(name, args[3]);
}
-void AppenderConsole::InitColors(std::string const& str)
+void AppenderConsole::InitColors(std::string const& name, std::string_view str)
{
if (str.empty())
{
@@ -42,23 +45,23 @@ void AppenderConsole::InitColors(std::string const& str)
return;
}
- int color[NUM_ENABLED_LOG_LEVELS];
-
- std::istringstream ss(str);
-
- for (uint8 i = 0; i < NUM_ENABLED_LOG_LEVELS; ++i)
+ std::vector<std::string_view> colorStrs = Trinity::Tokenize(str, ' ', false);
+ if (colorStrs.size() != NUM_ENABLED_LOG_LEVELS)
{
- ss >> color[i];
-
- if (!ss)
- return;
-
- if (color[i] < 0 || color[i] >= MaxColors)
- return;
+ throw InvalidAppenderArgsException(Trinity::StringFormat("Log::CreateAppenderFromConfig: Invalid color data '%s' for console appender %s (expected %u entries, got %zu)",
+ std::string(str).c_str(), name.c_str(), NUM_ENABLED_LOG_LEVELS, colorStrs.size()));
}
for (uint8 i = 0; i < NUM_ENABLED_LOG_LEVELS; ++i)
- _colors[i] = ColorTypes(color[i]);
+ {
+ if (Optional<uint8> color = Trinity::StringTo<uint8>(colorStrs[i]); color && EnumUtils::IsValid<ColorTypes>(*color))
+ _colors[i] = static_cast<ColorTypes>(*color);
+ else
+ {
+ throw InvalidAppenderArgsException(Trinity::StringFormat("Log::CreateAppenderFromConfig: Invalid color '%s' for log level %s on console appender %s",
+ std::string(colorStrs[i]).c_str(), EnumUtils::ToTitle(static_cast<LogLevel>(i)), name.c_str()));
+ }
+ }
_colored = true;
}
@@ -66,7 +69,7 @@ void AppenderConsole::InitColors(std::string const& str)
void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color)
{
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
- static WORD WinColorFG[MaxColors] =
+ static WORD WinColorFG[NUM_COLOR_TYPES] =
{
0, // BLACK
FOREGROUND_RED, // RED
@@ -127,7 +130,7 @@ void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color)
BG_WHITE
};
- static uint8 UnixColorFG[MaxColors] =
+ static uint8 UnixColorFG[NUM_COLOR_TYPES] =
{
FG_BLACK, // BLACK
FG_RED, // RED
@@ -146,7 +149,7 @@ void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color)
FG_WHITE // LWHITE
};
- fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm", UnixColorFG[color], (color >= YELLOW && color < MaxColors ? ";1" : ""));
+ fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm", UnixColorFG[color], (color >= YELLOW && color < NUM_COLOR_TYPES ? ";1" : ""));
#endif
}
diff --git a/src/common/Logging/AppenderConsole.h b/src/common/Logging/AppenderConsole.h
index 72c2bf98e10..6c6be4b6c59 100644
--- a/src/common/Logging/AppenderConsole.h
+++ b/src/common/Logging/AppenderConsole.h
@@ -20,6 +20,7 @@
#include "Appender.h"
+// EnumUtils: DESCRIBE THIS
enum ColorTypes
{
BLACK,
@@ -36,19 +37,18 @@ enum ColorTypes
LBLUE,
LMAGENTA,
LCYAN,
- WHITE
+ WHITE,
+ NUM_COLOR_TYPES // SKIP
};
-const uint8 MaxColors = uint8(WHITE) + 1;
-
class TC_COMMON_API AppenderConsole : public Appender
{
public:
- typedef std::integral_constant<AppenderType, APPENDER_CONSOLE>::type TypeIndex;
+ static constexpr AppenderType type = APPENDER_CONSOLE;
- AppenderConsole(uint8 _id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*> extraArgs);
- void InitColors(const std::string& init_str);
- AppenderType getType() const override { return TypeIndex::value; }
+ AppenderConsole(uint8 _id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args);
+ void InitColors(std::string const& name, std::string_view init_str);
+ AppenderType getType() const override { return type; }
private:
void SetColor(bool stdout_stream, ColorTypes color);
diff --git a/src/common/Logging/AppenderFile.cpp b/src/common/Logging/AppenderFile.cpp
index 3cfd6b950a6..bb38cade4e4 100644
--- a/src/common/Logging/AppenderFile.cpp
+++ b/src/common/Logging/AppenderFile.cpp
@@ -18,23 +18,25 @@
#include "AppenderFile.h"
#include "Log.h"
#include "LogMessage.h"
+#include "StringConvert.h"
+#include "Util.h"
#include <algorithm>
-AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*> extraArgs) :
+AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args) :
Appender(id, name, level, flags),
logfile(nullptr),
_logDir(sLog->GetLogsDir()),
_maxFileSize(0),
_fileSize(0)
{
- if (extraArgs.empty())
- throw InvalidAppenderArgsException(Trinity::StringFormat("Log::CreateAppenderFromConfig: Missing file name for appender %s\n", name.c_str()));
+ if (args.size() < 4)
+ throw InvalidAppenderArgsException(Trinity::StringFormat("Log::CreateAppenderFromConfig: Missing file name for appender %s", name.c_str()));
- _fileName = extraArgs[0];
+ _fileName.assign(args[3]);
- char const* mode = "a";
- if (extraArgs.size() > 1)
- mode = extraArgs[1];
+ std::string mode = "a";
+ if (4 < args.size())
+ mode.assign(args[4]);
if (flags & APPENDER_FLAGS_USE_TIMESTAMP)
{
@@ -45,14 +47,19 @@ AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, Ap
_fileName += sLog->GetLogsTimestamp();
}
- if (extraArgs.size() > 2)
- _maxFileSize = atoi(extraArgs[2]);
+ if (5 < args.size())
+ {
+ if (Optional<uint32> size = Trinity::StringTo<uint32>(args[5]))
+ _maxFileSize = *size;
+ else
+ throw InvalidAppenderArgsException(Trinity::StringFormat("Log::CreateAppenderFromConfig: Invalid size '%s' for appender %s", std::string(args[5]).c_str(), name.c_str()));
+ }
_dynamicName = std::string::npos != _fileName.find("%s");
_backup = (flags & APPENDER_FLAGS_MAKE_FILE_BACKUP) != 0;
if (!_dynamicName)
- logfile = OpenFile(_fileName, mode, !strcmp(mode, "w") && _backup);
+ logfile = OpenFile(_fileName, mode, (mode == "w") && _backup);
}
AppenderFile::~AppenderFile()
diff --git a/src/common/Logging/AppenderFile.h b/src/common/Logging/AppenderFile.h
index a320e90eb2b..c360e81a2ae 100644
--- a/src/common/Logging/AppenderFile.h
+++ b/src/common/Logging/AppenderFile.h
@@ -24,12 +24,12 @@
class TC_COMMON_API AppenderFile : public Appender
{
public:
- typedef std::integral_constant<AppenderType, APPENDER_FILE>::type TypeIndex;
+ static constexpr AppenderType type = APPENDER_FILE;
- AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*> extraArgs);
+ AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args);
~AppenderFile();
FILE* OpenFile(std::string const& name, std::string const& mode, bool backup);
- AppenderType getType() const override { return TypeIndex::value; }
+ AppenderType getType() const override { return type; }
private:
void CloseFile();
diff --git a/src/common/Logging/Log.cpp b/src/common/Logging/Log.cpp
index 6c364105a7b..fba5ac84aaf 100644
--- a/src/common/Logging/Log.cpp
+++ b/src/common/Logging/Log.cpp
@@ -25,6 +25,7 @@
#include "LogMessage.h"
#include "LogOperation.h"
#include "Strand.h"
+#include "StringConvert.h"
#include "Util.h"
#include <chrono>
#include <sstream>
@@ -47,7 +48,7 @@ uint8 Log::NextAppenderId()
return AppenderId++;
}
-Appender* Log::GetAppenderByName(std::string const& name)
+Appender* Log::GetAppenderByName(std::string_view name)
{
auto it = appenders.begin();
while (it != appenders.end() && it->second && it->second->getName() != name)
@@ -65,10 +66,9 @@ void Log::CreateAppenderFromConfigLine(std::string const& appenderName, std::str
// if type = File. optional1 = file and option2 = mode
// if type = Console. optional1 = Color
- Tokenizer tokens(options, ',');
- auto iter = tokens.begin();
+ std::vector<std::string_view> tokens = Trinity::Tokenize(options, ',', true);
- size_t size = tokens.size();
+ size_t const size = tokens.size();
std::string name = appenderName.substr(9);
if (size < 2)
@@ -78,33 +78,41 @@ void Log::CreateAppenderFromConfigLine(std::string const& appenderName, std::str
}
AppenderFlags flags = APPENDER_FLAGS_NONE;
- AppenderType type = AppenderType(atoi(*iter++));
- LogLevel level = LogLevel(atoi(*iter++));
+ AppenderType type = AppenderType(Trinity::StringTo<uint8>(tokens[0]).value_or(APPENDER_INVALID));
+ LogLevel level = LogLevel(Trinity::StringTo<uint8>(tokens[1]).value_or(LOG_LEVEL_INVALID));
- if (level > LOG_LEVEL_FATAL)
+ auto factoryFunction = appenderFactory.find(type);
+ if (factoryFunction == appenderFactory.end())
{
- fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %d for appender %s\n", level, name.c_str());
+ fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type '%s' for appender %s\n", std::string(tokens[0]).c_str(), name.c_str());
return;
}
- if (size > 2)
- flags = AppenderFlags(atoi(*iter++));
-
- auto factoryFunction = appenderFactory.find(type);
- if (factoryFunction == appenderFactory.end())
+ if (level > NUM_ENABLED_LOG_LEVELS)
{
- fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %d for appender %s\n", type, name.c_str());
+ fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level '%s' for appender %s\n", std::string(tokens[1]).c_str(), name.c_str());
return;
}
+ if (size > 2)
+ {
+ if (Optional<uint8> flagsVal = Trinity::StringTo<uint8>(tokens[2]))
+ flags = AppenderFlags(*flagsVal);
+ else
+ {
+ fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown flags '%s' for appender %s\n", std::string(tokens[2]).c_str(), name.c_str());
+ return;
+ }
+ }
+
try
{
- Appender* appender = factoryFunction->second(NextAppenderId(), name, level, flags, std::vector<char const*>(iter, tokens.end()));
+ Appender* appender = factoryFunction->second(NextAppenderId(), name, level, flags, tokens);
appenders[appender->getId()].reset(appender);
}
catch (InvalidAppenderArgsException const& iaae)
{
- fprintf(stderr, "%s", iaae.what());
+ fprintf(stderr, "%s\n", iaae.what());
}
}
@@ -119,7 +127,6 @@ void Log::CreateLoggerFromConfigLine(std::string const& loggerName, std::string
return;
LogLevel level = LOG_LEVEL_DISABLED;
- uint8 type = uint8(-1);
std::string name = loggerName.substr(7);
@@ -129,8 +136,7 @@ void Log::CreateLoggerFromConfigLine(std::string const& loggerName, std::string
return;
}
- Tokenizer tokens(options, ',');
- Tokenizer::const_iterator iter = tokens.begin();
+ std::vector<std::string_view> tokens = Trinity::Tokenize(options, ',', true);
if (tokens.size() != 2)
{
@@ -145,10 +151,10 @@ void Log::CreateLoggerFromConfigLine(std::string const& loggerName, std::string
return;
}
- level = LogLevel(atoi(*iter++));
- if (level > LOG_LEVEL_FATAL)
+ level = LogLevel(Trinity::StringTo<uint8>(tokens[0]).value_or(LOG_LEVEL_INVALID));
+ if (level > NUM_ENABLED_LOG_LEVELS)
{
- fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level %u for logger %s\n", type, name.c_str());
+ fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level '%s' for logger %s\n", std::string(tokens[0]).c_str(), name.c_str());
return;
}
@@ -158,20 +164,15 @@ void Log::CreateLoggerFromConfigLine(std::string const& loggerName, std::string
logger = std::make_unique<Logger>(name, level);
//fprintf(stdout, "Log::CreateLoggerFromConfig: Created Logger %s, Level %u\n", name.c_str(), level);
- std::istringstream ss(*iter);
- std::string str;
-
- ss >> str;
- while (ss)
+ for (std::string_view appenderName : Trinity::Tokenize(tokens[1], ' ', false))
{
- if (Appender* appender = GetAppenderByName(str))
+ if (Appender* appender = GetAppenderByName(appenderName))
{
logger->addAppender(appender->getId(), appender);
//fprintf(stdout, "Log::CreateLoggerFromConfig: Added Appender %s to Logger %s\n", appender->getName().c_str(), name.c_str());
}
else
- fprintf(stderr, "Error while configuring Appender %s in Logger %s. Appender does not exist", str.c_str(), name.c_str());
- ss >> str;
+ fprintf(stderr, "Error while configuring Appender %s in Logger %s. Appender does not exist\n", std::string(appenderName).c_str(), name.c_str());
}
}
@@ -201,7 +202,7 @@ void Log::ReadLoggersFromConfig()
Close(); // Clean any Logger or Appender created
- AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE, std::vector<char const*>());
+ AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE, {});
appenders[appender->getId()].reset(appender);
Logger* rootLogger = new Logger(LOGGER_ROOT, LOG_LEVEL_ERROR);
diff --git a/src/common/Logging/Log.h b/src/common/Logging/Log.h
index a496687ab57..5ec20040187 100644
--- a/src/common/Logging/Log.h
+++ b/src/common/Logging/Log.h
@@ -40,12 +40,12 @@ namespace Trinity
#define LOGGER_ROOT "root"
-typedef Appender*(*AppenderCreatorFn)(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*>&& extraArgs);
+typedef Appender*(*AppenderCreatorFn)(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs);
template <class AppenderImpl>
-Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*>&& extraArgs)
+Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs)
{
- return new AppenderImpl(id, name, level, flags, std::forward<std::vector<char const*>>(extraArgs));
+ return new AppenderImpl(id, name, level, flags, extraArgs);
}
class TC_COMMON_API Log
@@ -90,8 +90,7 @@ class TC_COMMON_API Log
template<class AppenderImpl>
void RegisterAppender()
{
- using Index = typename AppenderImpl::TypeIndex;
- RegisterAppender(Index::value, &CreateAppender<AppenderImpl>);
+ RegisterAppender(AppenderImpl::type, &CreateAppender<AppenderImpl>);
}
std::string const& GetLogsDir() const { return m_logsDir; }
@@ -105,7 +104,7 @@ class TC_COMMON_API Log
void write(std::unique_ptr<LogMessage>&& msg) const;
Logger const* GetLoggerByType(std::string const& type) const;
- Appender* GetAppenderByName(std::string const& name);
+ Appender* GetAppenderByName(std::string_view name);
uint8 NextAppenderId();
void CreateAppenderFromConfig(std::string const& name);
void CreateLoggerFromConfig(std::string const& name);
diff --git a/src/common/Logging/LogCommon.h b/src/common/Logging/LogCommon.h
index 04df9fb31d5..35844e0e0f7 100644
--- a/src/common/Logging/LogCommon.h
+++ b/src/common/Logging/LogCommon.h
@@ -18,7 +18,10 @@
#ifndef LogCommon_h__
#define LogCommon_h__
-enum LogLevel
+#include "Define.h"
+
+// EnumUtils: DESCRIBE THIS
+enum LogLevel : uint8
{
LOG_LEVEL_DISABLED = 0,
LOG_LEVEL_TRACE = 1,
@@ -28,18 +31,22 @@ enum LogLevel
LOG_LEVEL_ERROR = 5,
LOG_LEVEL_FATAL = 6,
- NUM_ENABLED_LOG_LEVELS = 6
+ NUM_ENABLED_LOG_LEVELS = LOG_LEVEL_FATAL, // SKIP
+ LOG_LEVEL_INVALID = 0xFF // SKIP
};
+// EnumUtils: DESCRIBE THIS
enum AppenderType : uint8
{
APPENDER_NONE,
APPENDER_CONSOLE,
APPENDER_FILE,
- APPENDER_DB
+ APPENDER_DB,
+
+ APPENDER_INVALID = 0xFF // SKIP
};
-enum AppenderFlags
+enum AppenderFlags : uint8
{
APPENDER_FLAGS_NONE = 0x00,
APPENDER_FLAGS_PREFIX_TIMESTAMP = 0x01,
diff --git a/src/common/Logging/enuminfo_AppenderConsole.cpp b/src/common/Logging/enuminfo_AppenderConsole.cpp
new file mode 100644
index 00000000000..1b5562b1f84
--- /dev/null
+++ b/src/common/Logging/enuminfo_AppenderConsole.cpp
@@ -0,0 +1,103 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "AppenderConsole.h"
+#include "Define.h"
+#include "SmartEnum.h"
+#include <stdexcept>
+
+namespace Trinity::Impl::EnumUtilsImpl
+{
+
+/********************************************************************\
+|* data for enum 'ColorTypes' in 'AppenderConsole.h' auto-generated *|
+\********************************************************************/
+template <>
+TC_API_EXPORT EnumText EnumUtils<ColorTypes>::ToString(ColorTypes value)
+{
+ switch (value)
+ {
+ case BLACK: return { "BLACK", "BLACK", "" };
+ case RED: return { "RED", "RED", "" };
+ case GREEN: return { "GREEN", "GREEN", "" };
+ case BROWN: return { "BROWN", "BROWN", "" };
+ case BLUE: return { "BLUE", "BLUE", "" };
+ case MAGENTA: return { "MAGENTA", "MAGENTA", "" };
+ case CYAN: return { "CYAN", "CYAN", "" };
+ case GREY: return { "GREY", "GREY", "" };
+ case YELLOW: return { "YELLOW", "YELLOW", "" };
+ case LRED: return { "LRED", "LRED", "" };
+ case LGREEN: return { "LGREEN", "LGREEN", "" };
+ case LBLUE: return { "LBLUE", "LBLUE", "" };
+ case LMAGENTA: return { "LMAGENTA", "LMAGENTA", "" };
+ case LCYAN: return { "LCYAN", "LCYAN", "" };
+ case WHITE: return { "WHITE", "WHITE", "" };
+ default: throw std::out_of_range("value");
+ }
+}
+
+template <>
+TC_API_EXPORT size_t EnumUtils<ColorTypes>::Count() { return 15; }
+
+template <>
+TC_API_EXPORT ColorTypes EnumUtils<ColorTypes>::FromIndex(size_t index)
+{
+ switch (index)
+ {
+ case 0: return BLACK;
+ case 1: return RED;
+ case 2: return GREEN;
+ case 3: return BROWN;
+ case 4: return BLUE;
+ case 5: return MAGENTA;
+ case 6: return CYAN;
+ case 7: return GREY;
+ case 8: return YELLOW;
+ case 9: return LRED;
+ case 10: return LGREEN;
+ case 11: return LBLUE;
+ case 12: return LMAGENTA;
+ case 13: return LCYAN;
+ case 14: return WHITE;
+ default: throw std::out_of_range("index");
+ }
+}
+
+template <>
+TC_API_EXPORT size_t EnumUtils<ColorTypes>::ToIndex(ColorTypes value)
+{
+ switch (value)
+ {
+ case BLACK: return 0;
+ case RED: return 1;
+ case GREEN: return 2;
+ case BROWN: return 3;
+ case BLUE: return 4;
+ case MAGENTA: return 5;
+ case CYAN: return 6;
+ case GREY: return 7;
+ case YELLOW: return 8;
+ case LRED: return 9;
+ case LGREEN: return 10;
+ case LBLUE: return 11;
+ case LMAGENTA: return 12;
+ case LCYAN: return 13;
+ case WHITE: return 14;
+ default: throw std::out_of_range("value");
+ }
+}
+}
diff --git a/src/common/Logging/enuminfo_LogCommon.cpp b/src/common/Logging/enuminfo_LogCommon.cpp
new file mode 100644
index 00000000000..de7d35e118e
--- /dev/null
+++ b/src/common/Logging/enuminfo_LogCommon.cpp
@@ -0,0 +1,124 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "LogCommon.h"
+#include "Define.h"
+#include "SmartEnum.h"
+#include <stdexcept>
+
+namespace Trinity::Impl::EnumUtilsImpl
+{
+
+/************************************************************\
+|* data for enum 'LogLevel' in 'LogCommon.h' auto-generated *|
+\************************************************************/
+template <>
+TC_API_EXPORT EnumText EnumUtils<LogLevel>::ToString(LogLevel value)
+{
+ switch (value)
+ {
+ case LOG_LEVEL_DISABLED: return { "LOG_LEVEL_DISABLED", "LOG_LEVEL_DISABLED", "" };
+ case LOG_LEVEL_TRACE: return { "LOG_LEVEL_TRACE", "LOG_LEVEL_TRACE", "" };
+ case LOG_LEVEL_DEBUG: return { "LOG_LEVEL_DEBUG", "LOG_LEVEL_DEBUG", "" };
+ case LOG_LEVEL_INFO: return { "LOG_LEVEL_INFO", "LOG_LEVEL_INFO", "" };
+ case LOG_LEVEL_WARN: return { "LOG_LEVEL_WARN", "LOG_LEVEL_WARN", "" };
+ case LOG_LEVEL_ERROR: return { "LOG_LEVEL_ERROR", "LOG_LEVEL_ERROR", "" };
+ case LOG_LEVEL_FATAL: return { "LOG_LEVEL_FATAL", "LOG_LEVEL_FATAL", "" };
+ default: throw std::out_of_range("value");
+ }
+}
+
+template <>
+TC_API_EXPORT size_t EnumUtils<LogLevel>::Count() { return 7; }
+
+template <>
+TC_API_EXPORT LogLevel EnumUtils<LogLevel>::FromIndex(size_t index)
+{
+ switch (index)
+ {
+ case 0: return LOG_LEVEL_DISABLED;
+ case 1: return LOG_LEVEL_TRACE;
+ case 2: return LOG_LEVEL_DEBUG;
+ case 3: return LOG_LEVEL_INFO;
+ case 4: return LOG_LEVEL_WARN;
+ case 5: return LOG_LEVEL_ERROR;
+ case 6: return LOG_LEVEL_FATAL;
+ default: throw std::out_of_range("index");
+ }
+}
+
+template <>
+TC_API_EXPORT size_t EnumUtils<LogLevel>::ToIndex(LogLevel value)
+{
+ switch (value)
+ {
+ case LOG_LEVEL_DISABLED: return 0;
+ case LOG_LEVEL_TRACE: return 1;
+ case LOG_LEVEL_DEBUG: return 2;
+ case LOG_LEVEL_INFO: return 3;
+ case LOG_LEVEL_WARN: return 4;
+ case LOG_LEVEL_ERROR: return 5;
+ case LOG_LEVEL_FATAL: return 6;
+ default: throw std::out_of_range("value");
+ }
+}
+
+/****************************************************************\
+|* data for enum 'AppenderType' in 'LogCommon.h' auto-generated *|
+\****************************************************************/
+template <>
+TC_API_EXPORT EnumText EnumUtils<AppenderType>::ToString(AppenderType value)
+{
+ switch (value)
+ {
+ case APPENDER_NONE: return { "APPENDER_NONE", "APPENDER_NONE", "" };
+ case APPENDER_CONSOLE: return { "APPENDER_CONSOLE", "APPENDER_CONSOLE", "" };
+ case APPENDER_FILE: return { "APPENDER_FILE", "APPENDER_FILE", "" };
+ case APPENDER_DB: return { "APPENDER_DB", "APPENDER_DB", "" };
+ default: throw std::out_of_range("value");
+ }
+}
+
+template <>
+TC_API_EXPORT size_t EnumUtils<AppenderType>::Count() { return 4; }
+
+template <>
+TC_API_EXPORT AppenderType EnumUtils<AppenderType>::FromIndex(size_t index)
+{
+ switch (index)
+ {
+ case 0: return APPENDER_NONE;
+ case 1: return APPENDER_CONSOLE;
+ case 2: return APPENDER_FILE;
+ case 3: return APPENDER_DB;
+ default: throw std::out_of_range("index");
+ }
+}
+
+template <>
+TC_API_EXPORT size_t EnumUtils<AppenderType>::ToIndex(AppenderType value)
+{
+ switch (value)
+ {
+ case APPENDER_NONE: return 0;
+ case APPENDER_CONSOLE: return 1;
+ case APPENDER_FILE: return 2;
+ case APPENDER_DB: return 3;
+ default: throw std::out_of_range("value");
+ }
+}
+}
diff --git a/src/common/Metric/Metric.cpp b/src/common/Metric/Metric.cpp
index b5762dbd8e2..97d68568a3f 100644
--- a/src/common/Metric/Metric.cpp
+++ b/src/common/Metric/Metric.cpp
@@ -89,7 +89,7 @@ void Metric::LoadFromConfigs()
return;
}
- Tokenizer tokens(connectionInfo, ';');
+ std::vector<std::string_view> tokens = Trinity::Tokenize(connectionInfo, ';', true);
if (tokens.size() != 3)
{
TC_LOG_ERROR("metric", "'Metric.ConnectionInfo' specified with wrong format in configuration file.");
diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp
index f3f76569d11..317f8c754f8 100644
--- a/src/common/Utilities/Util.cpp
+++ b/src/common/Utilities/Util.cpp
@@ -19,6 +19,7 @@
#include "Common.h"
#include "Containers.h"
#include "IpAddress.h"
+#include "StringConvert.h"
#include "StringFormat.h"
#include <utf8.h>
#include <algorithm>
@@ -35,39 +36,22 @@
#include <arpa/inet.h>
#endif
-Tokenizer::Tokenizer(std::string_view src, const char sep, uint32 vectorReserve /*= 0*/, bool keepEmptyStrings /*= true*/)
+std::vector<std::string_view> Trinity::Tokenize(std::string_view str, char sep, bool keepEmpty)
{
- m_str = new char[src.length() + 1];
- memcpy(m_str, src.data(), src.length() + 1);
+ std::vector<std::string_view> tokens;
- if (vectorReserve)
- m_storage.reserve(vectorReserve);
-
- char* posold = m_str;
- char* posnew = m_str;
-
- for (;;)
+ size_t start = 0;
+ for (size_t end = str.find(sep); end != std::string_view::npos; end = str.find(sep, start))
{
- if (*posnew == sep)
- {
- if (keepEmptyStrings || posold != posnew)
- m_storage.push_back(posold);
-
- posold = posnew + 1;
- *posnew = '\0';
- }
- else if (*posnew == '\0')
- {
- // Hack like, but the old code accepted these kind of broken strings,
- // so changing it would break other things
- if (posold != posnew)
- m_storage.push_back(posold);
+ if (keepEmpty || (start < end))
+ tokens.push_back(str.substr(start, end - start));
+ start = end+1;
+ }
- break;
- }
+ if (keepEmpty || (start < str.length()))
+ tokens.push_back(str.substr(start));
- ++posnew;
- }
+ return tokens;
}
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
@@ -210,32 +194,43 @@ std::string secsToTimeString(uint64 timeInSecs, TimeFormat timeFormat, bool hour
return ss.str();
}
-int64 MoneyStringToMoney(std::string const& moneyString)
+Optional<int64> MoneyStringToMoney(std::string const& moneyString)
{
int64 money = 0;
- if (!(std::count(moneyString.begin(), moneyString.end(), 'g') == 1 ||
- std::count(moneyString.begin(), moneyString.end(), 's') == 1 ||
- std::count(moneyString.begin(), moneyString.end(), 'c') == 1))
- return 0; // Bad format
+ bool hadG = false;
+ bool hadS = false;
+ bool hadC = false;
- Tokenizer tokens(moneyString, ' ');
- for (char const* token : tokens)
+ for (std::string_view token : Trinity::Tokenize(moneyString, ' ', false))
{
- std::string tokenString(token);
- size_t gCount = std::count(tokenString.begin(), tokenString.end(), 'g');
- size_t sCount = std::count(tokenString.begin(), tokenString.end(), 's');
- size_t cCount = std::count(tokenString.begin(), tokenString.end(), 'c');
- if (gCount + sCount + cCount != 1)
- return 0;
-
- uint64 amount = strtoull(token, nullptr, 10);
- if (gCount == 1)
- money += amount * 100 * 100;
- else if (sCount == 1)
- money += amount * 100;
- else if (cCount == 1)
- money += amount;
+ uint32 unit;
+ switch (token[token.length() - 1])
+ {
+ case 'g':
+ if (hadG) return std::nullopt;
+ hadG = true;
+ unit = 100 * 100;
+ break;
+ case 's':
+ if (hadS) return std::nullopt;
+ hadS = true;
+ unit = 100;
+ break;
+ case 'c':
+ if (hadC) return std::nullopt;
+ hadC = true;
+ unit = 1;
+ break;
+ default:
+ return std::nullopt;
+ }
+
+ Optional<uint64> amount = Trinity::StringTo<uint32>(token.substr(0, token.length() - 1));
+ if (amount)
+ money += (unit * *amount);
+ else
+ return std::nullopt;
}
return money;
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index 28d0285d74d..8708405882e 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -37,35 +37,19 @@ enum class TimeFormat : uint8
Numeric // 1:2:3:4
};
-class TC_COMMON_API Tokenizer
+namespace Trinity
{
-public:
- typedef std::vector<char const*> StorageType;
-
- typedef StorageType::size_type size_type;
-
- typedef StorageType::const_iterator const_iterator;
- typedef StorageType::reference reference;
- typedef StorageType::const_reference const_reference;
-
-public:
- Tokenizer(std::string_view src, char const sep, uint32 vectorReserve = 0, bool keepEmptyStrings = true);
- ~Tokenizer() { delete[] m_str; }
+ TC_COMMON_API std::vector<std::string_view> Tokenize(std::string_view str, char sep, bool keepEmpty);
- const_iterator begin() const { return m_storage.begin(); }
- const_iterator end() const { return m_storage.end(); }
+ /* this would return string_view into temporary otherwise */
+ std::vector<std::string_view> Tokenize(std::string&&, char, bool) = delete;
+ std::vector<std::string_view> Tokenize(std::string const&&, char, bool) = delete;
- size_type size() const { return m_storage.size(); }
-
- reference operator [] (size_type i) { return m_storage[i]; }
- const_reference operator [] (size_type i) const { return m_storage[i]; }
-
-private:
- char* m_str;
- StorageType m_storage;
-};
+ /* the delete overload means we need to make this explicit */
+ inline std::vector<std::string_view> Tokenize(char const* str, char sep, bool keepEmpty) { return Tokenize(std::string_view(str ? str : ""), sep, keepEmpty); }
+}
-TC_COMMON_API int64 MoneyStringToMoney(std::string const& moneyString);
+TC_COMMON_API Optional<int64> MoneyStringToMoney(std::string const& moneyString);
TC_COMMON_API struct tm* localtime_r(time_t const* time, struct tm *result);
TC_COMMON_API time_t LocalTimeToUTCTime(time_t time);