diff options
| -rw-r--r-- | src/common/Utilities/Util.cpp | 52 | ||||
| -rw-r--r-- | src/common/Utilities/Util.h | 76 | ||||
| -rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandArgs.h | 76 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_go.cpp | 8 | 
4 files changed, 101 insertions, 111 deletions
diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp index 5e29d7d60dd..da086c6b6cc 100644 --- a/src/common/Utilities/Util.cpp +++ b/src/common/Utilities/Util.cpp @@ -35,10 +35,10 @@    #include <arpa/inet.h>  #endif -Tokenizer::Tokenizer(const std::string &src, const char sep, uint32 vectorReserve /*= 0*/, bool keepEmptyStrings /*= true*/) +Tokenizer::Tokenizer(std::string_view src, const char sep, uint32 vectorReserve /*= 0*/, bool keepEmptyStrings /*= true*/)  {      m_str = new char[src.length() + 1]; -    memcpy(m_str, src.c_str(), src.length() + 1); +    memcpy(m_str, src.data(), src.length() + 1);      if (vectorReserve)          m_storage.reserve(vectorReserve); @@ -400,12 +400,12 @@ bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize)      return true;  } -bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr) +bool Utf8toWStr(std::string_view utf8str, std::wstring& wstr)  {      wstr.clear();      try      { -        utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), std::back_inserter(wstr)); +        utf8::utf8to16(utf8str.begin(), utf8str.end(), std::back_inserter(wstr));      }      catch(std::exception const&)      { @@ -439,7 +439,7 @@ bool WStrToUtf8(wchar_t const* wstr, size_t size, std::string& utf8str)      return true;  } -bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str) +bool WStrToUtf8(std::wstring_view wstr, std::string& utf8str)  {      try      { @@ -448,7 +448,7 @@ bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str)          if (wstr.size())          { -            char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str()+wstr.size(), &utf8str2[0]); +            char* oend = utf8::utf16to8(wstr.begin(), wstr.end(), &utf8str2[0]);              utf8str2.resize(oend-(&utf8str2[0]));                // remove unused tail          }          utf8str = utf8str2; @@ -462,22 +462,10 @@ bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str)      return true;  } -typedef wchar_t const* const* wstrlist; - -void wstrToUpper(std::wstring& str) -{ -    std::transform(str.begin(), str.end(), str.begin(), wcharToUpper); -} - -void strToLower(std::string& str) -{ -    std::transform(str.begin(), str.end(), str.begin(), [](char c) { return std::tolower(c); }); -} - -void wstrToLower(std::wstring& str) -{ -    std::transform(str.begin(), str.end(), str.begin(), wcharToLower); -} +void wstrToUpper(std::wstring& str) { std::transform(std::begin(str), std::end(str), std::begin(str), wcharToUpper); } +void wstrToLower(std::wstring& str) { std::transform(std::begin(str), std::end(str), std::begin(str), wcharToLower); } +void strToUpper(std::string& str) { std::transform(std::begin(str), std::end(str), std::begin(str), charToUpper); } +void strToLower(std::string& str) { std::transform(std::begin(str), std::end(str), std::begin(str), charToLower); }  std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension)  { @@ -528,7 +516,7 @@ std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension)      return wname;  } -bool utf8ToConsole(const std::string& utf8str, std::string& conStr) +bool utf8ToConsole(std::string_view utf8str, std::string& conStr)  {  #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS      std::wstring wstr; @@ -545,7 +533,7 @@ bool utf8ToConsole(const std::string& utf8str, std::string& conStr)      return true;  } -bool consoleToUtf8(const std::string& conStr, std::string& utf8str) +bool consoleToUtf8(std::string_view conStr, std::string& utf8str)  {  #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS      std::wstring wstr; @@ -560,7 +548,7 @@ bool consoleToUtf8(const std::string& conStr, std::string& utf8str)  #endif  } -bool Utf8FitTo(const std::string& str, std::wstring const& search) +bool Utf8FitTo(std::string_view str, std::wstring_view search)  {      std::wstring temp; @@ -640,7 +628,7 @@ std::string Trinity::Impl::ByteArrayToHexStr(uint8 const* bytes, size_t arrayLen      return ss.str();  } -void Trinity::Impl::HexStrToByteArray(std::string const& str, uint8* out, size_t outlen, bool reverse /*= false*/) +void Trinity::Impl::HexStrToByteArray(std::string_view str, uint8* out, size_t outlen, bool reverse /*= false*/)  {      ASSERT(str.size() == (2 * outlen)); @@ -663,14 +651,12 @@ void Trinity::Impl::HexStrToByteArray(std::string const& str, uint8* out, size_t      }  } -bool StringToBool(std::string const& str) +bool StringToBool(std::string_view str)  { -    std::string lowerStr = str; -    std::transform(str.begin(), str.end(), lowerStr.begin(), ::tolower); -    return lowerStr == "1" || lowerStr == "true" || lowerStr == "yes"; +    return ((str == "1") || StringEqualI(str, "true") || StringEqualI(str, "yes"));  } -bool StringEqualI(std::string const& str1, std::string const& str2) +bool StringEqualI(std::string_view str1, std::string_view str2)  {      return std::equal(str1.begin(), str1.end(), str2.begin(), str2.end(),                        [](char a, char b) @@ -679,12 +665,12 @@ bool StringEqualI(std::string const& str1, std::string const& str2)                        });  } -bool StringStartsWith(std::string const& haystack, std::string const& needle) +bool StringStartsWith(std::string_view haystack, std::string_view needle)  {      return (haystack.rfind(needle, 0) == 0);  } -bool StringContainsStringI(std::string const& haystack, std::string const& needle) +bool StringContainsStringI(std::string_view haystack, std::string_view needle)  {      return haystack.end() !=          std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), [](char c1, char c2) { return std::toupper(c1) == std::toupper(c2); }); diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h index 9d4717dded4..cd8765b309f 100644 --- a/src/common/Utilities/Util.h +++ b/src/common/Utilities/Util.h @@ -23,6 +23,7 @@  #include <array>  #include <string> +#include <string_view>  #include <sstream>  #include <utility>  #include <vector> @@ -46,7 +47,7 @@ public:      typedef StorageType::const_reference const_reference;  public: -    Tokenizer(const std::string &src, char const sep, uint32 vectorReserve = 0, bool keepEmptyStrings = true); +    Tokenizer(std::string_view src, char const sep, uint32 vectorReserve = 0, bool keepEmptyStrings = true);      ~Tokenizer() { delete[] m_str; }      const_iterator begin() const { return m_storage.begin(); } @@ -103,17 +104,17 @@ template <class T>  inline T square(T x) { return x*x; }  // UTF8 handling -TC_COMMON_API bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr); +TC_COMMON_API bool Utf8toWStr(std::string_view utf8str, std::wstring& wstr);  // in wsize==max size of buffer, out wsize==real string size  TC_COMMON_API bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize); -inline bool Utf8toWStr(const std::string& utf8str, wchar_t* wstr, size_t& wsize) +inline bool Utf8toWStr(std::string_view utf8str, wchar_t* wstr, size_t& wsize)  { -    return Utf8toWStr(utf8str.c_str(), utf8str.size(), wstr, wsize); +    return Utf8toWStr(utf8str.data(), utf8str.size(), wstr, wsize);  } -TC_COMMON_API bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str); +TC_COMMON_API bool WStrToUtf8(std::wstring_view wstr, std::string& utf8str);  // size==real string size  TC_COMMON_API bool WStrToUtf8(wchar_t const* wstr, size_t size, std::string& utf8str); @@ -205,34 +206,34 @@ inline bool isNumericOrSpace(wchar_t wchar)      return isNumeric(wchar) || wchar == L' ';  } -inline bool isBasicLatinString(const std::wstring &wstr, bool numericOrSpace) +inline bool isBasicLatinString(std::wstring_view wstr, bool numericOrSpace)  { -    for (size_t i = 0; i < wstr.size(); ++i) -        if (!isBasicLatinCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) +    for (wchar_t c : wstr) +        if (!isBasicLatinCharacter(c) && (!numericOrSpace || !isNumericOrSpace(c)))              return false;      return true;  } -inline bool isExtendedLatinString(const std::wstring &wstr, bool numericOrSpace) +inline bool isExtendedLatinString(std::wstring_view wstr, bool numericOrSpace)  { -    for (size_t i = 0; i < wstr.size(); ++i) -        if (!isExtendedLatinCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) +    for (wchar_t c : wstr) +        if (!isExtendedLatinCharacter(c) && (!numericOrSpace || !isNumericOrSpace(c)))              return false;      return true;  } -inline bool isCyrillicString(const std::wstring &wstr, bool numericOrSpace) +inline bool isCyrillicString(std::wstring_view wstr, bool numericOrSpace)  { -    for (size_t i = 0; i < wstr.size(); ++i) -        if (!isCyrillicCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) +    for (wchar_t c : wstr) +        if (!isCyrillicCharacter(c) && (!numericOrSpace || !isNumericOrSpace(c)))              return false;      return true;  } -inline bool isEastAsianString(const std::wstring &wstr, bool numericOrSpace) +inline bool isEastAsianString(std::wstring_view wstr, bool numericOrSpace)  { -    for (size_t i = 0; i < wstr.size(); ++i) -        if (!isEastAsianCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) +    for (wchar_t c : wstr) +        if (!isEastAsianCharacter(c) && (!numericOrSpace || !isNumericOrSpace(c)))              return false;      return true;  } @@ -288,15 +289,19 @@ inline wchar_t wcharToLower(wchar_t wchar)      return wchar;  } +inline char charToUpper(char c) { return std::toupper(c); } +inline char charToLower(char c) { return std::tolower(c); } +  TC_COMMON_API void wstrToUpper(std::wstring& str); -TC_COMMON_API void strToLower(std::string& str);  TC_COMMON_API void wstrToLower(std::wstring& str); +TC_COMMON_API void strToUpper(std::string& str); +TC_COMMON_API void strToLower(std::string& str);  TC_COMMON_API std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension); -TC_COMMON_API bool utf8ToConsole(const std::string& utf8str, std::string& conStr); -TC_COMMON_API bool consoleToUtf8(const std::string& conStr, std::string& utf8str); -TC_COMMON_API bool Utf8FitTo(const std::string& str, std::wstring const& search); +TC_COMMON_API bool utf8ToConsole(std::string_view utf8str, std::string& conStr); +TC_COMMON_API bool consoleToUtf8(std::string_view conStr, std::string& utf8str); +TC_COMMON_API bool Utf8FitTo(std::string_view str, std::wstring_view search);  TC_COMMON_API void utf8printf(FILE* out, const char *str, ...);  TC_COMMON_API void vutf8printf(FILE* out, const char *str, va_list* ap);  TC_COMMON_API bool Utf8ToUpperOnlyLatin(std::string& utf8String); @@ -309,7 +314,7 @@ TC_COMMON_API uint32 GetPID();  namespace Trinity::Impl  {      TC_COMMON_API std::string ByteArrayToHexStr(uint8 const* bytes, size_t length, bool reverse = false); -    TC_COMMON_API void HexStrToByteArray(std::string const& str, uint8* out, size_t outlen, bool reverse = false); +    TC_COMMON_API void HexStrToByteArray(std::string_view str, uint8* out, size_t outlen, bool reverse = false);  }  template <typename Container> @@ -319,19 +324,19 @@ std::string ByteArrayToHexStr(Container const& c, bool reverse = false)  }  template <size_t Size> -void HexStrToByteArray(std::string const& str, std::array<uint8, Size>& buf, bool reverse = false) +void HexStrToByteArray(std::string_view str, std::array<uint8, Size>& buf, bool reverse = false)  {      Trinity::Impl::HexStrToByteArray(str, buf.data(), Size, reverse);  }  template <size_t Size> -std::array<uint8, Size> HexStrToByteArray(std::string const& str, bool reverse = false) +std::array<uint8, Size> HexStrToByteArray(std::string_view str, bool reverse = false)  {      std::array<uint8, Size> arr;      HexStrToByteArray(str, arr, reverse);      return arr;  } -inline std::vector<uint8> HexStrToByteVector(std::string const& str, bool reverse = false) +inline std::vector<uint8> HexStrToByteVector(std::string_view str, bool reverse = false)  {      std::vector<uint8> buf;      size_t const sz = (str.size() / 2); @@ -340,13 +345,13 @@ inline std::vector<uint8> HexStrToByteVector(std::string const& str, bool revers      return buf;  } -TC_COMMON_API bool StringToBool(std::string const& str); +TC_COMMON_API bool StringToBool(std::string_view str); -TC_COMMON_API bool StringEqualI(std::string const& str1, std::string const& str2); -TC_COMMON_API bool StringStartsWith(std::string const& haystack, std::string const& needle); -TC_COMMON_API bool StringContainsStringI(std::string const& haystack, std::string const& needle); +TC_COMMON_API bool StringEqualI(std::string_view str1, std::string_view str2); +TC_COMMON_API bool StringStartsWith(std::string_view haystack, std::string_view needle); +TC_COMMON_API bool StringContainsStringI(std::string_view haystack, std::string_view needle);  template <typename T> -inline bool ValueContainsStringI(std::pair<T, std::string> const& haystack, std::string const& needle) +inline bool ValueContainsStringI(std::pair<T, std::string_view> const& haystack, std::string_view needle)  {      return StringContainsStringI(haystack.second, needle);  } @@ -546,16 +551,13 @@ constexpr typename std::underlying_type<E>::type AsUnderlyingType(E enumValue)      return static_cast<typename std::underlying_type<E>::type>(enumValue);  } -template<typename Ret, typename Only> -Ret* Coalesce(Only* arg) -{ -    return arg; -} -  template<typename Ret, typename T1, typename... T>  Ret* Coalesce(T1* first, T*... rest)  { -    return static_cast<Ret*>(first ? static_cast<Ret*>(first) : Coalesce<Ret>(rest...)); +    if constexpr (sizeof...(T) > 0) +        return (first ? static_cast<Ret*>(first) : Coalesce<Ret>(rest...)); +    else +        return static_cast<Ret*>(first);  }  #endif diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h index 504f4d0dca3..bcfc336f7b3 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h @@ -22,7 +22,10 @@  #include "ChatCommandTags.h"  #include "SmartEnum.h"  #include "Util.h" +#include <charconv>  #include <map> +#include <string> +#include <string_view>  struct GameTele; @@ -43,42 +46,26 @@ namespace ChatCommands  template <typename T, typename = void>  struct ArgInfo { static_assert(!std::is_same_v<T,T>, "Invalid command parameter type - see ChatCommandArgs.h for possible types"); }; -// catch-all for signed integral types +// catch-all for integral types  template <typename T> -struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>>> +struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T>>>  {      static char const* TryConsume(T& val, char const* args)      {          char const* next = args; -        std::string token(args, Trinity::Impl::ChatCommands::tokenize(next)); -        try -        { -            size_t processedChars = 0; -            val = std::stoll(token, &processedChars, 0); -            if (processedChars != token.length()) -                return nullptr; -        } -        catch (...) { return nullptr; } -        return next; -    } -}; +        std::string_view token(args, Trinity::Impl::ChatCommands::tokenize(next)); + +        std::from_chars_result result; +        if (StringStartsWith(token, "0x")) +            result = std::from_chars(token.data() + 2, token.data() + token.length(), val, 16); +        else if (StringStartsWith(token, "0b")) +            result = std::from_chars(token.data() + 2, token.data() + token.length(), val, 2); +        else +            result = std::from_chars(token.data(), token.data() + token.length(), val, 10); + +        if ((token.data() + token.length()) != result.ptr) +            return nullptr; -// catch-all for unsigned integral types -template <typename T> -struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>>> -{ -    static char const* TryConsume(T& val, char const* args) -    { -        char const* next = args; -        std::string token(args, Trinity::Impl::ChatCommands::tokenize(next)); -        try -        { -            size_t processedChars = 0; -            val = std::stoull(token, &processedChars, 0); -            if (processedChars != token.length()) -                return nullptr; -        } -        catch (...) { return nullptr; }          return next;      }  }; @@ -93,6 +80,7 @@ struct ArgInfo<T, std::enable_if_t<std::is_floating_point_v<T>>>          std::string token(args, Trinity::Impl::ChatCommands::tokenize(next));          try          { +            // @todo replace this once libc++ supports double args to from_chars for required minimum              size_t processedChars = 0;              val = std::stold(token, &processedChars);              if (processedChars != token.length()) @@ -103,16 +91,16 @@ struct ArgInfo<T, std::enable_if_t<std::is_floating_point_v<T>>>      }  }; -// string +// string_view  template <> -struct ArgInfo<std::string, void> +struct ArgInfo<std::string_view, void>  { -    static char const* TryConsume(std::string& val, char const* args) +    static char const* TryConsume(std::string_view& val, char const* args)      {          char const* next = args;          if (size_t len = Trinity::Impl::ChatCommands::tokenize(next))          { -            val.assign(args, len); +            val = std::string_view(args, len);              return next;          }          else @@ -120,19 +108,33 @@ struct ArgInfo<std::string, void>      }  }; +// string +template <> +struct ArgInfo<std::string, void> +{ +    static char const* TryConsume(std::string& val, char const* args) +    { +        std::string_view view; +        args = ArgInfo<std::string_view>::TryConsume(view, args); +        if (args) +            val.assign(view); +        return args; +    } +}; +  // wstring  template <>  struct ArgInfo<std::wstring, void>  {      static char const* TryConsume(std::wstring& val, char const* args)      { -        std::string utf8Str; -        char const* ret = ArgInfo<std::string>::TryConsume(utf8Str, args); +        std::string_view utf8view; +        char const* ret = ArgInfo<std::string_view>::TryConsume(utf8view, args);          if (!ret)              return nullptr; -        if (!Utf8toWStr(utf8Str, val)) +        if (!Utf8toWStr(utf8view, val))              return nullptr;          return ret; diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 4ea253742f4..f782a972180 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -372,7 +372,7 @@ public:          return DoTeleport(handler, loc);      } -    static bool HandleGoInstanceCommand(ChatHandler* handler, std::vector<std::string> const& labels) +    static bool HandleGoInstanceCommand(ChatHandler* handler, std::vector<std::string_view> labels)      {          if (labels.empty())              return false; @@ -384,7 +384,7 @@ public:              uint32 count = 0;              std::string const& scriptName = sObjectMgr->GetScriptName(pair.second.ScriptId);              char const* mapName = ASSERT_NOTNULL(sMapStore.LookupEntry(pair.first))->MapName[handler->GetSessionDbcLocale()]; -            for (auto const& label : labels) +            for (std::string_view label : labels)                  if (StringContainsStringI(scriptName, label))                      ++count; @@ -457,7 +457,7 @@ public:          return false;      } -    static bool HandleGoBossCommand(ChatHandler* handler, std::vector<std::string> const& needles) +    static bool HandleGoBossCommand(ChatHandler* handler, std::vector<std::string_view> needles)      {          if (needles.empty())              return false; @@ -474,7 +474,7 @@ public:              uint32 count = 0;              std::string const& scriptName = sObjectMgr->GetScriptName(data.ScriptID); -            for (auto const& label : needles) +            for (std::string_view label : needles)                  if (StringContainsStringI(scriptName, label) || StringContainsStringI(data.Name, label))                      ++count;  | 
