123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- #include "il2cpp-config.h"
- #include "../char-conversions.h"
- #include "il2cpp-object-internals.h"
- #include "utils/Functional.h"
- #include "utils/Memory.h"
- #include "utils/StringUtils.h"
- #include "utils/utf8-cpp/source/utf8/unchecked.h"
- #include <stdarg.h>
- namespace il2cpp
- {
- namespace utils
- {
- std::string StringUtils::Printf(const char* format, ...)
- {
- va_list argsToCheckSize;
- int n;
- std::string ret;
- va_start(argsToCheckSize, format);
- #if IL2CPP_COMPILER_MSVC
- // MS vsnprintf always returns -1 if string doesn't fit, rather than
- // the needed size. Used their 'special' function instead to get required size
- n = _vscprintf_p(format, argsToCheckSize);
- #else
- // use a temporary buffer as some docs indicate we cannot pass NULL to vsnprintf
- char buf[1];
- n = vsnprintf(buf, 0, format, argsToCheckSize);
- #endif
- if (n == -1)
- return NULL;
- ret.resize(n + 1, 0);
- va_end(argsToCheckSize);
- va_list argsToFormat;
- va_start(argsToFormat, format);
- n = vsnprintf(&ret[0], ret.size(), format, argsToFormat);
- va_end(argsToFormat);
- IL2CPP_ASSERT(n < (int)ret.size());
- if (n == -1)
- return NULL;
- // The v*printf methods might put a trailing NUL character, which should not not be in a
- // std::string, so strip it out.
- if (!ret.empty() && ret[ret.size() - 1] == '\0')
- ret = ret.substr(0, ret.size() - 1);
- return ret;
- }
- std::string StringUtils::NPrintf(const char* format, size_t max_n, ...)
- {
- va_list argsToCheckSize;
- size_t n;
- std::string ret;
- va_start(argsToCheckSize, max_n);
- #if IL2CPP_COMPILER_MSVC
- // MS vsnprintf always returns -1 if string doesn't fit, rather than
- // the needed size. Used their 'special' function instead to get required size
- n = _vscprintf_p(format, argsToCheckSize);
- #else
- // use a temporary buffer as some docs indicate we cannot pass NULL to vsnprintf
- char buf[1];
- n = vsnprintf(buf, 0, format, argsToCheckSize);
- #endif
- if (n == -1)
- return NULL;
- n = (max_n < ++n) ? max_n : n;
- ret.resize(n, 0);
- va_end(argsToCheckSize);
- va_list argsToFormat;
- va_start(argsToFormat, max_n);
- n = vsnprintf(&ret[0], n, format, argsToFormat);
- va_end(argsToFormat);
- IL2CPP_ASSERT(n < ret.size());
- if (n == -1)
- return NULL;
- // The v*printf methods might put a trailing NUL character, which should not not be in a
- // std::string, so strip it out.
- if (!ret.empty() && ret[ret.size() - 1] == '\0')
- ret = ret.substr(0, ret.size() - 1);
- return ret;
- }
- std::string StringUtils::Utf16ToUtf8(const Il2CppChar* utf16String)
- {
- return Utf16ToUtf8(utf16String, -1);
- }
- std::string StringUtils::Utf16ToUtf8(const Il2CppChar* utf16String, int maximumSize)
- {
- const Il2CppChar* ptr = utf16String;
- size_t length = 0;
- while (*ptr)
- {
- ptr++;
- length++;
- if (maximumSize != -1 && length == maximumSize)
- break;
- }
- std::string utf8String;
- utf8String.reserve(length);
- utf8::unchecked::utf16to8(utf16String, ptr, std::back_inserter(utf8String));
- return utf8String;
- }
- std::string StringUtils::Utf16ToUtf8(const UTF16String& utf16String)
- {
- return Utf16ToUtf8(utf16String.c_str(), static_cast<int>(utf16String.length()));
- }
- UTF16String StringUtils::Utf8ToUtf16(const char* utf8String)
- {
- return Utf8ToUtf16(utf8String, strlen(utf8String));
- }
- UTF16String StringUtils::Utf8ToUtf16(const char* utf8String, size_t length)
- {
- UTF16String utf16String;
- if (utf8::is_valid(utf8String, utf8String + length))
- {
- utf16String.reserve(length);
- utf8::unchecked::utf8to16(utf8String, utf8String + length, std::back_inserter(utf16String));
- }
- return utf16String;
- }
- UTF16String StringUtils::Utf8ToUtf16(const std::string& utf8String)
- {
- return Utf8ToUtf16(utf8String.c_str(), utf8String.length());
- }
- char* StringUtils::StringDuplicate(const char *strSource)
- {
- char* result = NULL;
- if (!strSource)
- return NULL;
- size_t length = strlen(strSource) + 1;
- if ((result = (char*)IL2CPP_MALLOC(length)))
- #if IL2CPP_COMPILER_MSVC
- strcpy_s(result, length, strSource);
- #elif IL2CPP_TARGET_LINUX
- strncpy(result, strSource, length);
- #else
- strlcpy(result, strSource, length);
- #endif
- return result;
- }
- Il2CppChar* StringUtils::StringDuplicate(const Il2CppChar* strSource, size_t length)
- {
- size_t byteLengthWithNullTerminator = sizeof(Il2CppChar) * (length + 1);
- Il2CppChar* utf16name = (Il2CppChar*)IL2CPP_MALLOC(byteLengthWithNullTerminator);
- memcpy(utf16name, strSource, byteLengthWithNullTerminator);
- return utf16name;
- }
- void StringUtils::StringDelete(const char* str)
- {
- IL2CPP_FREE((void*)str);
- }
- bool StringUtils::EndsWith(const std::string& string, const std::string& suffix)
- {
- const size_t stringLength = string.length();
- const size_t suffixLength = suffix.length();
- if (suffixLength > stringLength)
- return false;
- return string.rfind(suffix.c_str(), stringLength - suffixLength, suffixLength) != std::string::npos;
- }
- Il2CppChar* StringUtils::GetChars(Il2CppString* str)
- {
- return str->chars;
- }
- int32_t StringUtils::GetLength(Il2CppString* str)
- {
- return str->length;
- }
- } /* utils */
- } /* il2cpp */
|