strncpy: pad the destination with NULs

And optimize for word aligned loads/stores

Signed-off-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com>
This commit is contained in:
Hamish Morrison 2012-04-22 01:31:08 +01:00 committed by Fredrik Holmqvist
parent d0b8e45eb1
commit 7e87b73402

View File

@ -5,15 +5,56 @@
#include <sys/types.h>
#include <string.h>
#include <SupportDefs.h>
char *
strncpy(char *dest, char const *src, size_t count)
/* From Bit twiddling hacks:
http://graphics.stanford.edu/~seander/bithacks.html */
#define LACKS_ZERO_BYTE(value) \
(((value - 0x01010101) & ~value & 0x80808080) == 0)
char*
strncpy(char* dest, const char* src, size_t count)
{
char *tmp = dest;
char* tmp = dest;
while (count-- && (*dest++ = *src++) != '\0')
;
// Align destination buffer for four byte writes.
while (((addr_t)dest & 3) != 0 && count != 0) {
count--;
if ((*dest++ = *src++) == '\0') {
memset(dest, '\0', count);
return tmp;
}
}
if (count == 0)
return tmp;
if (((addr_t)src & 3) == 0) {
// If the source and destination are aligned, copy a word
// word at a time
uint32* alignedSrc = (uint32*)src;
uint32* alignedDest = (uint32*)dest;
size_t alignedCount = count / 4;
count -= alignedCount * 4;
for (; alignedCount != 0 && LACKS_ZERO_BYTE(*alignedSrc);
alignedCount--)
*alignedDest++ = *alignedSrc++;
count += alignedCount * 4;
src = (char*)alignedSrc;
dest = (char*)alignedDest;
}
// Deal with the remainder.
while (count-- != 0) {
if ((*dest++ = *src++) == '\0') {
memset(dest, '\0', count);
return tmp;
}
}
return tmp;
}