2023-03-06 14:42:04 +01:00
|
|
|
// SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
// author: Max Kellermann <max.kellermann@gmail.com>
|
2015-03-05 08:05:31 +01:00
|
|
|
|
|
|
|
#ifndef WSTRING_API_HXX
|
|
|
|
#define WSTRING_API_HXX
|
|
|
|
|
2020-05-01 04:25:55 +02:00
|
|
|
#include <cwchar>
|
2015-03-05 08:05:31 +01:00
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline size_t
|
2017-05-08 14:44:49 +02:00
|
|
|
StringLength(const wchar_t *p) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
|
|
|
return wcslen(p);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline const wchar_t *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFind(const wchar_t *haystack, const wchar_t *needle) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
|
|
|
return wcsstr(haystack, needle);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline const wchar_t *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFind(const wchar_t *haystack, wchar_t needle, size_t size) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
2020-05-01 04:25:55 +02:00
|
|
|
return std::wmemchr(haystack, needle, size);
|
2015-03-05 08:05:31 +01:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline wchar_t *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFind(wchar_t *haystack, wchar_t needle, size_t size) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
2020-05-01 04:25:55 +02:00
|
|
|
return std::wmemchr(haystack, needle, size);
|
2015-03-05 08:05:31 +01:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline const wchar_t *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFind(const wchar_t *haystack, wchar_t needle) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
|
|
|
return wcschr(haystack, needle);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline wchar_t *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFind(wchar_t *haystack, wchar_t needle) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
|
|
|
return wcschr(haystack, needle);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline const wchar_t *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFindLast(const wchar_t *haystack, wchar_t needle) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
|
|
|
return wcsrchr(haystack, needle);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline wchar_t *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFindLast(wchar_t *haystack, wchar_t needle) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
|
|
|
return wcsrchr(haystack, needle);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2019-09-07 23:59:59 +02:00
|
|
|
static inline const wchar_t *
|
|
|
|
StringFindLast(const wchar_t *haystack, wchar_t needle, size_t size) noexcept
|
|
|
|
{
|
|
|
|
/* there's no wmemrchr() unfortunately */
|
|
|
|
const auto *p = haystack + size;
|
|
|
|
while (p > haystack) {
|
|
|
|
--p;
|
|
|
|
if (*p == needle)
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2018-07-18 15:59:41 +02:00
|
|
|
static inline const wchar_t *
|
|
|
|
StringFindAny(const wchar_t *haystack, const wchar_t *accept) noexcept
|
|
|
|
{
|
|
|
|
return wcspbrk(haystack, accept);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline void
|
2017-05-08 14:44:49 +02:00
|
|
|
UnsafeCopyString(wchar_t *dest, const wchar_t *src) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
|
|
|
wcscpy(dest, src);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::returns_nonnull]] [[gnu::nonnull]]
|
2015-09-01 21:16:08 +02:00
|
|
|
static inline wchar_t *
|
2017-05-08 14:44:49 +02:00
|
|
|
UnsafeCopyStringP(wchar_t *dest, const wchar_t *src) noexcept
|
2015-09-01 21:16:08 +02:00
|
|
|
{
|
2018-09-06 19:33:50 +02:00
|
|
|
#if defined(_WIN32) || defined(__OpenBSD__) || defined(__NetBSD__)
|
2017-12-21 18:45:16 +01:00
|
|
|
/* emulate wcpcpy() */
|
|
|
|
UnsafeCopyString(dest, src);
|
|
|
|
return dest + StringLength(dest);
|
2017-12-21 17:55:24 +01:00
|
|
|
#elif defined(__sun) && defined (__SVR4)
|
|
|
|
return std::wcpcpy(dest, src);
|
2015-09-01 21:16:08 +02:00
|
|
|
#else
|
2017-12-21 18:45:16 +01:00
|
|
|
return wcpcpy(dest, src);
|
2015-09-01 21:16:08 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2018-07-18 17:18:34 +02:00
|
|
|
static inline int
|
|
|
|
StringCompare(const wchar_t *a, const wchar_t *b) noexcept
|
|
|
|
{
|
|
|
|
return wcscmp(a, b);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2019-08-16 14:48:54 +02:00
|
|
|
static inline int
|
|
|
|
StringCompare(const wchar_t *a, const wchar_t *b, size_t n) noexcept
|
|
|
|
{
|
|
|
|
return wcsncmp(a, b, n);
|
|
|
|
}
|
|
|
|
|
2015-03-05 08:05:31 +01:00
|
|
|
/**
|
|
|
|
* Checks whether str1 and str2 are equal.
|
|
|
|
* @param str1 String 1
|
|
|
|
* @param str2 String 2
|
|
|
|
* @return True if equal, False otherwise
|
|
|
|
*/
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline bool
|
2017-05-08 14:44:49 +02:00
|
|
|
StringIsEqual(const wchar_t *str1, const wchar_t *str2) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
2018-08-20 15:31:09 +02:00
|
|
|
return StringCompare(str1, str2) == 0;
|
2015-03-05 08:05:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks whether #a and #b are equal.
|
|
|
|
*/
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline bool
|
2017-05-08 14:44:49 +02:00
|
|
|
StringIsEqual(const wchar_t *a, const wchar_t *b, size_t length) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
|
|
|
return wcsncmp(a, b, length) == 0;
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2017-09-12 17:15:23 +02:00
|
|
|
static inline bool
|
|
|
|
StringIsEqualIgnoreCase(const wchar_t *a, const wchar_t *b) noexcept
|
|
|
|
{
|
2018-09-06 19:49:45 +02:00
|
|
|
#ifdef _WIN32
|
2017-09-12 17:15:23 +02:00
|
|
|
return _wcsicmp(a, b) == 0;
|
2018-09-06 19:49:45 +02:00
|
|
|
#else
|
|
|
|
return wcscasecmp(a, b) == 0;
|
|
|
|
#endif
|
2017-09-12 17:15:23 +02:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2017-09-12 17:15:23 +02:00
|
|
|
static inline bool
|
|
|
|
StringIsEqualIgnoreCase(const wchar_t *a, const wchar_t *b,
|
|
|
|
size_t size) noexcept
|
|
|
|
{
|
2018-09-06 19:49:45 +02:00
|
|
|
#ifdef _WIN32
|
2017-09-12 17:15:23 +02:00
|
|
|
return _wcsnicmp(a, b, size) == 0;
|
2018-09-06 19:49:45 +02:00
|
|
|
#else
|
|
|
|
return wcsncasecmp(a, b, size) == 0;
|
2017-09-12 17:15:23 +02:00
|
|
|
#endif
|
2018-09-06 19:49:45 +02:00
|
|
|
}
|
2017-09-12 17:15:23 +02:00
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2018-09-06 19:39:28 +02:00
|
|
|
static inline int
|
|
|
|
StringCollate(const wchar_t *a, const wchar_t *b) noexcept
|
|
|
|
{
|
|
|
|
return wcscoll(a, b);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::malloc]] [[gnu::returns_nonnull]] [[gnu::nonnull]]
|
2015-03-05 08:05:31 +01:00
|
|
|
static inline wchar_t *
|
2018-09-06 19:35:09 +02:00
|
|
|
DuplicateString(const wchar_t *p) noexcept
|
2015-03-05 08:05:31 +01:00
|
|
|
{
|
2017-12-21 17:55:24 +01:00
|
|
|
#if defined(__sun) && defined (__SVR4)
|
|
|
|
return std::wcsdup(p);
|
|
|
|
#else
|
2015-03-05 08:05:31 +01:00
|
|
|
return wcsdup(p);
|
2017-12-21 17:55:24 +01:00
|
|
|
#endif
|
2015-03-05 08:05:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|