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:
@@ -3,18 +3,33 @@
|
|||||||
** Distributed under the terms of the NewOS License.
|
** Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <string.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
|
size_t
|
||||||
strlen(char const *s)
|
strlen(char const *s)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
uint32 *value;
|
||||||
|
|
||||||
while (s[i]) {
|
//Make sure we use aligned access
|
||||||
i += 1;
|
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;
|
return i;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,36 @@
|
|||||||
** Distributed under the terms of the NewOS License.
|
** Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <string.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
|
size_t
|
||||||
strnlen(char const *s, size_t count)
|
strnlen(char const *s, size_t count)
|
||||||
{
|
{
|
||||||
const char *sc;
|
size_t i = 0;
|
||||||
|
uint32 *value;
|
||||||
|
|
||||||
for (sc = s; count-- && *sc != '\0'; ++sc)
|
//Make sure we use aligned access
|
||||||
;
|
while (((uint32) s + i) & 3) {
|
||||||
return sc - s;
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user