summaryrefslogtreecommitdiff
path: root/inline.h
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2020-01-12 10:11:54 -0700
committerKarl Williamson <khw@cpan.org>2020-01-13 20:54:05 -0700
commit1ab100a8598da3fcda1b313c7a6415231a170eea (patch)
tree959c120e5f7b9c16d9612819836d054fb74cdae9 /inline.h
parent7bea1fb03caa036528182ef907f72095b5d91dea (diff)
downloadperl-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.h30
1 files changed, 30 insertions, 0 deletions
diff --git a/inline.h b/inline.h
index 38b523b15d..7196849cf6 100644
--- a/inline.h
+++ b/inline.h
@@ -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 *