aboutsummaryrefslogtreecommitdiff
path: root/src/userspace/mlibc/string/strlen.c
blob: f6524954f8b0a844ae8cc220c87cc49051ebdb17 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <mlibc/stdlib.h>

size_t strlen(const char *str)
{
	const char *char_ptr;
	const unsigned long int *longword_ptr;
	unsigned long int longword, himagic, lomagic;

	for (char_ptr = str; ((unsigned long int)char_ptr & (sizeof(longword) - 1)) != 0;
	     ++char_ptr)
		if (*char_ptr == '\0')
			return char_ptr - str;

	longword_ptr = (unsigned long int *)char_ptr;

	himagic = 0x80808080L;
	lomagic = 0x01010101L;

	for (;;) {
		longword = *longword_ptr++;

		if (((longword - lomagic) & himagic) != 0) {
			const char *cp = (const char *)(longword_ptr - 1);

			if (cp[0] == 0)
				return cp - str;
			if (cp[1] == 0)
				return cp - str + 1;
			if (cp[2] == 0)
				return cp - str + 2;
			if (cp[3] == 0)
				return cp - str + 3;
		}
	}
}