Skip to content

Commit

Permalink
Fix issue #315: Provide platform support for strnlen
Browse files Browse the repository at this point in the history
  • Loading branch information
Neil MacIntosh authored Aug 19, 2016
2 parents 93b3258 + aadcce2 commit 5112ba0
Showing 1 changed file with 29 additions and 4 deletions.
33 changes: 29 additions & 4 deletions gsl/string_span
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
#endif // _MSC_VER <= 1800
#endif // _MSC_VER

#ifndef __CYGWIN__
#define GSL_PLATFORM_HAS_STRNLEN
#endif

// In order to test the library, we need it to throw exceptions that we can catch
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION

Expand Down Expand Up @@ -95,6 +99,27 @@ using zstring = basic_zstring<char, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent>
using wzstring = basic_zstring<wchar_t, Extent>;

namespace details
{
inline std::size_t string_length(const char *str, std::size_t n)
{
#ifdef GSL_PLATFORM_HAS_STRNLEN
return strnlen(str, n);
#else
if (str == nullptr || n == 0)
return 0;

std::size_t len = 0;
span<const char> str_span{str, n};

while (len < n && str_span[len])
len++;

return len;
#endif
}
}

//
// ensure_sentinel()
//
Expand Down Expand Up @@ -127,14 +152,14 @@ inline span<T, dynamic_extent> ensure_z(T* const& sz, std::ptrdiff_t max = PTRDI
// overloads to share an implementation
inline span<char, dynamic_extent> ensure_z(char* const& sz, std::ptrdiff_t max)
{
auto len = strnlen(sz, narrow_cast<size_t>(max));
auto len = details::string_length(sz, narrow_cast<size_t>(max));
Ensures(sz[len] == 0);
return {sz, static_cast<std::ptrdiff_t>(len)};
}

inline span<const char, dynamic_extent> ensure_z(const char* const& sz, std::ptrdiff_t max)
{
auto len = strnlen(sz, narrow_cast<size_t>(max));
auto len = details::string_length(sz, narrow_cast<size_t>(max));
Ensures(sz[len] == 0);
return {sz, static_cast<std::ptrdiff_t>(len)};
}
Expand Down Expand Up @@ -196,7 +221,7 @@ namespace details
{
std::ptrdiff_t operator()(char* const ptr, std::ptrdiff_t length) noexcept
{
return narrow_cast<std::ptrdiff_t>(strnlen(ptr, narrow_cast<size_t>(length)));
return narrow_cast<std::ptrdiff_t>(details::string_length(ptr, narrow_cast<size_t>(length)));
}
};

Expand All @@ -214,7 +239,7 @@ namespace details
{
std::ptrdiff_t operator()(const char* const ptr, std::ptrdiff_t length) noexcept
{
return narrow_cast<std::ptrdiff_t>(strnlen(ptr, narrow_cast<size_t>(length)));
return narrow_cast<std::ptrdiff_t>(details::string_length(ptr, narrow_cast<size_t>(length)));
}
};

Expand Down

0 comments on commit 5112ba0

Please sign in to comment.