xref: /haiku/src/system/libroot/posix/string/strncpy.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
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 
17 char*
18 strncpy(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