blob: 82e5fac51c09e890af532559f6d23acd2f9b7082 [file] [log] [blame]
Viet-Trung Luu96b05c12016-01-11 11:26:36 -08001#include <string.h>
2#include <stdint.h>
3#include <limits.h>
4
George Kulakowski17e3b042016-02-18 15:59:50 -08005#define ALIGN (sizeof(size_t) - 1)
6#define ONES ((size_t)-1 / UCHAR_MAX)
7#define HIGHS (ONES * (UCHAR_MAX / 2 + 1))
8#define HASZERO(x) ((x)-ONES & ~(x)&HIGHS)
Viet-Trung Luu96b05c12016-01-11 11:26:36 -08009
George Kulakowski17e3b042016-02-18 15:59:50 -080010void* memccpy(void* restrict dest, const void* restrict src, int c, size_t n) {
11 unsigned char* d = dest;
12 const unsigned char* s = src;
13 size_t *wd, k;
14 const size_t* ws;
Viet-Trung Luu96b05c12016-01-11 11:26:36 -080015
George Kulakowski17e3b042016-02-18 15:59:50 -080016 c = (unsigned char)c;
17 if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
18 for (; ((uintptr_t)s & ALIGN) && n && (*d = *s) != c; n--, s++, d++)
19 ;
20 if ((uintptr_t)s & ALIGN)
21 goto tail;
22 k = ONES * c;
23 wd = (void*)d;
24 ws = (const void*)s;
25 for (; n >= sizeof(size_t) && !HASZERO(*ws ^ k);
26 n -= sizeof(size_t), ws++, wd++)
27 *wd = *ws;
28 d = (void*)wd;
29 s = (const void*)ws;
30 }
31 for (; n && (*d = *s) != c; n--, s++, d++)
32 ;
Viet-Trung Luu96b05c12016-01-11 11:26:36 -080033tail:
George Kulakowski17e3b042016-02-18 15:59:50 -080034 if (*s == c)
35 return d + 1;
36 return 0;
Viet-Trung Luu96b05c12016-01-11 11:26:36 -080037}