1/*
2** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3** Distributed under the terms of the NewOS License.
4*/
5
6#include <sys/types.h>
7#include <string.h>
8#include <SupportDefs.h>
9
10
11/* From Bit twiddling hacks:
12	http://graphics.stanford.edu/~seander/bithacks.html */
13#define LACKS_ZERO_BYTE(value) \
14	(((value - 0x01010101) & ~value & 0x80808080) == 0)
15
16
17char*
18strncpy(char* dest, const char* src, size_t count)
19{
20	char* tmp = dest;
21
22	// Align destination buffer for four byte writes.
23	while (((addr_t)dest & 3) != 0 && count != 0) {
24		count--;
25		if ((*dest++ = *src++) == '\0') {
26			memset(dest, '\0', count);
27			return tmp;
28		}
29	}
30
31	if (count == 0)
32		return tmp;
33
34	if (((addr_t)src & 3) == 0) {
35		// If the source and destination are aligned, copy a word
36		// word at a time
37		uint32* alignedSrc = (uint32*)src;
38		uint32* alignedDest = (uint32*)dest;
39		size_t alignedCount = count / 4;
40		count -= alignedCount * 4;
41
42		for (; alignedCount != 0 && LACKS_ZERO_BYTE(*alignedSrc);
43				alignedCount--)
44			*alignedDest++ = *alignedSrc++;
45
46		count += alignedCount * 4;
47		src = (char*)alignedSrc;
48		dest = (char*)alignedDest;
49	}
50
51	// Deal with the remainder.
52	while (count-- != 0) {
53		if ((*dest++ = *src++) == '\0') {
54			memset(dest, '\0', count);
55			return tmp;
56		}
57	}
58
59	return tmp;
60}
61
62