xref: /haiku/src/system/libroot/posix/string/strnlen.cpp (revision 002f37b0cca92e4cf72857c72ac95db5a8b09615)
1 /*
2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 
6 #include <string.h>
7 #include <SupportDefs.h>
8 
9 
10 /* From Bit twiddling hacks:
11 	http://graphics.stanford.edu/~seander/bithacks.html */
12 #define LACKS_ZERO_BYTE(value) \
13 	(((value - 0x01010101) & ~value & 0x80808080) == 0)
14 
15 
16 size_t
17 strnlen(const char* string, size_t count)
18 {
19 	size_t length = 0;
20 	/* Align access for four byte reads */
21 	for (; (((addr_t)string + length) & 3) != 0; length++) {
22 		if (length == count || string[length] == '\0')
23 			return length;
24 	}
25 
26 	/* Check four bytes for zero char */
27 	const uint32* kMaxScanPosition = (uint32*)(string + count - 4);
28 	uint32* valuePointer = (uint32*)(string + length);
29 	for (; valuePointer <= kMaxScanPosition && LACKS_ZERO_BYTE(*valuePointer);
30 		valuePointer++)
31 		;
32 
33 	/* Find the exact length */
34 	for (length = ((char*)valuePointer) - string; length < count
35 		&& string[length] != '\0'; length++)
36 		;
37 
38 	return length;
39 }
40