Reworked strlen and strnlen to look at four bytes at the time. From what I understand this should be safe.

Based on info from bit twiddling hacks: http://graphics.stanford.edu/~seander/bithacks.html
This commit is contained in:
Fredrik Holmqvist
2011-12-24 22:27:44 +01:00
parent 6ef455e4a2
commit 753a02c156
2 changed files with 43 additions and 8 deletions
+18 -3
View File
@@ -3,18 +3,33 @@
** Distributed under the terms of the NewOS License.
*/
#include <sys/types.h>
#include <string.h>
#include <SupportDefs.h>
// From Bit twiddling hacks: http://graphics.stanford.edu/~seander/bithacks.html
#define hasZeroByte(value) (value - 0x01010101) & ~value & 0x80808080
size_t
strlen(char const *s)
{
size_t i = 0;
uint32 *value;
while (s[i]) {
i += 1;
//Make sure we use aligned access
while (((uint32) s + i) & 3) {
if (!s[i]) return i;
i++;
}
//Check four bytes at once
value = (uint32 *) (s + i);
while (!(hasZeroByte(*value)))
value++;
//Find the exact length
i = ((char *) value) - s;
while (s[i])
i++;
return i;
}
+25 -5
View File
@@ -3,16 +3,36 @@
** Distributed under the terms of the NewOS License.
*/
#include <sys/types.h>
#include <string.h>
#include <SupportDefs.h>
// From Bit twiddling hacks: http://graphics.stanford.edu/~seander/bithacks.html
#define hasZeroByte(value) (value - 0x01010101) & ~value & 0x80808080
size_t
strnlen(char const *s, size_t count)
{
const char *sc;
size_t i = 0;
uint32 *value;
for (sc = s; count-- && *sc != '\0'; ++sc)
;
return sc - s;
//Make sure we use aligned access
while (((uint32) s + i) & 3) {
if (i == count || !s[i]) return i;
i++;
}
const uint32 * end = (uint32 *) s + count;
//Check four bytes at once
value = (uint32 *) (s + i);
while (value < end && !(hasZeroByte(*value)) )
value++;
//Find the exact length
i = ((char *) value) - s;
while (s[i] && i < count )
i++;
return i;
}