contributed by < yuwen
>
透過 memchr_opt
傳入的參數分別為
const void *src_void
:memort areaint c
:the byte to search forsize_t length
:the size of its area在 64–bit Size 底下, long
代表 8 byte。
可以得知程式碼中一開始先去檢查是否小於 8 byte
/* Nonzero if either X or Y is not aligned on a "long" boundary */
#define UNALIGNED(X) ((long) X & (sizeof(long) - 1))
while (UNALIGNED(src)) {
if (!length--)
return NULL;
if (*src == d)
return (void *) src;
src++;
}
TOO_SMALL
是在檢查長度是否超出 8 byte
/* Threshhold for punting to the bytewise iterator */
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
d
是要搜尋的字元,先將d擴展為 8 byte 來做後續的搜尋
unsigned long *asrc = (unsigned long *) src;
unsigned long mask = d << 8 | d;
mask = mask << 16 | mask;
for (unsigned int i = 32; i < LBLOCKSIZE * 8; i <<= 1)
mask = (mask << i) | mask;
例如
d = 2e
第二行 mask = 2e2e
第三行 mask = 2e2e2e2e
第五行 mask = 2e2e2e2e2e2e2e2e
當要搜尋的句子長度 >= LBLOCKSIZE
時,一次 8 byte 遞迴下去找直到找到為止,若找不到則跳出 while
並回傳NULL。
while (length >= LBLOCKSIZE) {
/* XXXXX: Your implementation should appear here */
// 如果有找到
if (DETECT_CHAR(*asrc, mask)) {
// 取得該位址的字串
src = (unsigned char *) asrc;
while (length-- != 0) {
// find the target char
if (*src++ == d)
return (void *) (src - 1);
}
}
else {
// 一次減少 8 byte
length -= LBLOCKSIZE;
// 這邊宣告的是double的型態,當指標+1 等於一次前進8 byte
asrc += 1;
}
}
測試
int main()
{
const char str[] = "http://wiki.csie.ncku.edu.tw";
const char ch = 'n';
const char ch1 = '/';
const char ch2 = '.';
char *ret = memchr_opt(str, ch, strlen(str));
printf("String after |%c| is - |%s|\n", ch, ret);
char *ret1 = memchr_opt(str, ch1, strlen(str));
printf("String after |%c| is - |%s|\n", ch1, ret1);
char *ret2 = memchr_opt(str, ch2, strlen(str));
printf("String after |%c| is - |%s|\n", ch2, ret2);
return 0;
}
結果
String after |n| is - |ncku.edu.tw|
String after |/| is - |//wiki.csie.ncku.edu.tw|
String after |.| is - |.csie.ncku.edu.tw|
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up