diff options
author | Karl Williamson <khw@cpan.org> | 2020-01-12 10:11:54 -0700 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2020-01-13 20:54:05 -0700 |
commit | 1ab100a8598da3fcda1b313c7a6415231a170eea (patch) | |
tree | 959c120e5f7b9c16d9612819836d054fb74cdae9 /inline.h | |
parent | 7bea1fb03caa036528182ef907f72095b5d91dea (diff) | |
download | perl-1ab100a8598da3fcda1b313c7a6415231a170eea.tar.gz |
Rewrite and inline my_strnlen()
This commit changes this function to use memchr() instead of looping
byte-by-byte through the string. And it inlines it into 3 lines of
code. This should give comparable performance to a native libc
strnlen().
Diffstat (limited to 'inline.h')
-rw-r--r-- | inline.h | 30 |
1 files changed, 30 insertions, 0 deletions
@@ -2495,6 +2495,36 @@ Perl_foldEQ_locale(const char *s1, const char *s2, I32 len) return 1; } +/* +=for apidoc my_strnlen + +The C library C<strnlen> if available, or a Perl implementation of it. + +C<my_strnlen()> computes the length of the string, up to C<maxlen> +characters. It will will never attempt to address more than C<maxlen> +characters, making it suitable for use with strings that are not +guaranteed to be NUL-terminated. + +=cut + +Description stolen from http://man.openbsd.org/strnlen.3, +implementation stolen from PostgreSQL. +*/ +#ifndef HAS_STRNLEN + +PERL_STATIC_INLINE Size_t +Perl_my_strnlen(const char *str, Size_t maxlen) +{ + const char *end = (char *) memchr(str, '\0', maxlen); + + PERL_ARGS_ASSERT_MY_STRNLEN; + + if (end == NULL) return maxlen; + return end - str; +} + +#endif + #if ! defined (HAS_MEMRCHR) && (defined(PERL_CORE) || defined(PERL_EXT)) PERL_STATIC_INLINE void * |