ustr-srch-code.h
#ifndef USTR_SRCH_H
#error " Include ustr-srch.h before this file."
#endif
#ifndef USTR_CONF_HAVE_MEMRCHR
#ifdef __GLIBC__
#define USTR_CONF_HAVE_MEMRCHR 1
#else
#define USTR_CONF_HAVE_MEMRCHR 0
#endif
#endif
USTR_CONF_I_PROTO
size_t ustr_srch_chr_fwd(const struct Ustr *s1, size_t off, char val)
{
const char *beg = ustr_cstr(s1);
const char *ptr;
size_t len = ustr_len(s1);
const char *tmp;
USTR_ASSERT(ustr_assert_valid(s1));
USTR_ASSERT_RET(off <= len, 0);
ptr = beg + off;
len -= off;
if (!(tmp = memchr(ptr, val, len))) return (0);
len = tmp - beg;
return (len + 1);
}
#if USTR_CONF_HAVE_MEMRCHR
USTR_CONF_I_PROTO size_t ustr_srch_chr_rev(const struct Ustr *s1, size_t off,
char val)
{
const char *ptr = ustr_cstr(s1);
size_t len = ustr_len(s1);
const char *tmp;
USTR_ASSERT(ustr_assert_valid(s1));
USTR_ASSERT_RET(off <= len, 0);
len -= off;
if (!(tmp = memrchr(ptr, val, len))) return (0);
len = tmp - ptr;
return (len + 1);
}
#else
USTR_CONF_I_PROTO size_t ustr_srch_chr_rev(const struct Ustr *s1, size_t off,
char val)
{
const char *ptr = ustr_cstr(s1);
size_t len = ustr_len(s1);
const char *tmp = ptr;
const char *prev = 0;
USTR_ASSERT(ustr_assert_valid(s1));
USTR_ASSERT_RET(off <= len, 0);
len -= off;
while ((tmp = memchr(tmp, val, len - (tmp - ptr))))
{
prev = tmp;
++tmp;
}
if (!prev)
return (0);
len = prev - ptr;
return (len + 1);
}
#endif
#if ! USTR_CONF_HAVE_MEMMEM
USTR_CONF_i_PROTO void *ustr__sys_memmem(const void *hs, size_t hslen,
const void *nd, size_t ndlen)
{
const char *ptr = hs;
if (ndlen == 0)
return ((void *)hs);
while (hslen >= ndlen)
{
if (!memcmp(ptr, nd, ndlen))
return ((void *)ptr);
--hslen;
++ptr;
}
return (0);
}
#endif
USTR_CONF_I_PROTO size_t ustr_srch_buf_fwd(const struct Ustr *s1, size_t off,
const void *val, size_t vlen)
{
const char *beg = ustr_cstr(s1);
const char *ptr;
size_t len = ustr_len(s1);
char *tmp = 0;
USTR_ASSERT(ustr_assert_valid(s1));
if (vlen == 1)
return (ustr_srch_chr_fwd(s1, off, ((const char *)val)[0]));
USTR_ASSERT_RET(off <= len, 0);
if (vlen == 0)
return (len ? (off + 1) : 0);
ptr = beg + off;
len -= off;
if (!(tmp = USTR__SYS_MEMMEM(ptr, len, val, vlen)))
return (0);
len = tmp - beg;
return (len + 1);
}
USTR_CONF_I_PROTO size_t ustr_srch_buf_rev(const struct Ustr *s1, size_t off,
const void *val, size_t vlen)
{
const char *ptr = ustr_cstr(s1);
size_t len = ustr_len(s1);
const char *prev = 0;
const char *tmp = 0;
USTR_ASSERT(ustr_assert_valid(s1));
if (vlen == 1)
return (ustr_srch_chr_rev(s1, off, ((const char *)val)[0]));
USTR_ASSERT_RET(off <= len, 0);
len -= off;
if (vlen == 0)
return (len);
tmp = ptr;
while (((len - (tmp - ptr)) >= vlen) &&
(tmp = USTR__SYS_MEMMEM(tmp, len - (tmp - ptr), val, vlen)))
{
prev = tmp;
++tmp;
}
if (!prev)
return (0);
len = prev - ptr;
return (len + 1);
}
USTR_CONF_I_PROTO
size_t ustr_srch_subustr_fwd(const struct Ustr *s1, size_t off,
const struct Ustr *s2, size_t pos, size_t len)
{
USTR_ASSERT(ustr_assert_valid(s1) && ustr_assert_valid(s2));
if (!ustr_assert_valid_subustr(s2, pos, len))
return (ustr_srch_buf_fwd(s1, off, "", 0));
return (ustr_srch_buf_fwd(s1, off, ustr_cstr(s2) + --pos, len));
}
USTR_CONF_I_PROTO
size_t ustr_srch_subustr_rev(const struct Ustr *s1, size_t off,
const struct Ustr *s2, size_t pos, size_t len)
{
USTR_ASSERT(ustr_assert_valid(s1) && ustr_assert_valid(s2));
if (!ustr_assert_valid_subustr(s2, pos, len))
return (ustr_srch_buf_rev(s1, off, "", 0));
return (ustr_srch_buf_rev(s1, off, ustr_cstr(s2) + --pos, len));
}
USTR_CONF_i_PROTO
void *ustr__memrepchr(const void *hs, size_t hslen, char nd, size_t ndlen)
{
const char *ptr = hs;
USTR_ASSERT(ndlen);
while (hslen >= ndlen)
{
const char *tmp = memchr(ptr, nd, hslen);
size_t len = ndlen;
if (!tmp)
break;
if (ndlen > (hslen - (tmp - ptr)))
break;
tmp += len;
while (len > 0)
{
--tmp;
if (*tmp != nd)
break;
--len;
}
if (!len)
return ((void *)tmp);
hslen -= (tmp - ptr);
ptr = tmp;
}
return (0);
}
USTR_CONF_I_PROTO size_t ustr_srch_rep_chr_fwd(const struct Ustr *s1,size_t off,
char val, size_t vlen)
{
const char *beg = ustr_cstr(s1);
const char *ptr;
size_t len = ustr_len(s1);
char *tmp = 0;
USTR_ASSERT(ustr_assert_valid(s1));
if (vlen == 1)
return (ustr_srch_chr_fwd(s1, off, val));
USTR_ASSERT_RET(off <= len, 0);
if (vlen == 0)
return (len ? (off + 1) : 0);
ptr = beg + off;
len -= off;
if (!(tmp = ustr__memrepchr(ptr, len, val, vlen)))
return (0);
len = tmp - beg;
return (len + 1);
}
USTR_CONF_I_PROTO size_t ustr_srch_rep_chr_rev(const struct Ustr *s1,size_t off,
char val, size_t vlen)
{
const char *ptr = ustr_cstr(s1);
size_t len = ustr_len(s1);
const char *prev = 0;
const char *tmp = 0;
USTR_ASSERT(ustr_assert_valid(s1));
if (vlen == 1)
return (ustr_srch_chr_rev(s1, off, val));
USTR_ASSERT_RET(off <= len, 0);
len -= off;
if (vlen == 0)
return (len);
tmp = ptr;
while (((len - (tmp - ptr)) >= vlen) &&
(tmp = ustr__memrepchr(tmp, len - (tmp - ptr), val, vlen)))
{
prev = tmp;
++tmp;
}
if (!prev)
return (0);
len = prev - ptr;
return (len + 1);
}
USTR_CONF_i_PROTO
void *ustr__memcasechr(const void *hs, const char nd, size_t len)
{
const unsigned char *s1 = hs;
unsigned char c2 = nd;
if ((c2 >= 0x61) && (c2 <= 0x7a))
c2 ^= 0x20;
while (len)
{
unsigned char c1 = *s1;
if ((c1 >= 0x61) && (c1 <= 0x7a))
c1 ^= 0x20;
if (c1 == c2)
return ((void *)s1);
--len;
++s1;
}
return (0);
}
USTR_CONF_i_PROTO
void *ustr__memcasemem(const void *hs,size_t hslen, const void *nd,size_t ndlen)
{
const char *ptr = hs;
USTR_ASSERT(ndlen);
while (hslen >= ndlen)
{
if (!ustr__memcasecmp(ptr, nd, ndlen))
return ((void *)ptr);
--hslen;
++ptr;
}
return (0);
}
USTR_CONF_i_PROTO
void *ustr__memcaserepchr(const void *hs, size_t hslen, char nd, size_t ndlen)
{
const unsigned char *s1 = hs;
unsigned char c2 = nd;
USTR_ASSERT(ndlen);
if ((c2 >= 0x61) && (c2 <= 0x7a))
c2 ^= 0x20;
while (hslen >= ndlen)
{
const unsigned char *tmp = ustr__memcasechr(s1, nd, hslen);
size_t len = ndlen;
if (!tmp)
break;
if (ndlen > (hslen - (tmp - s1)))
break;
tmp += len;
while (len > 0)
{
unsigned char c1 = *--tmp;
if ((c1 >= 0x61) && (c1 <= 0x7a))
c1 ^= 0x20;
if (c1 != c2)
break;
--len;
}
if (!len)
return ((void *)tmp);
hslen -= (tmp - s1);
s1 = tmp;
}
return (0);
}
USTR_CONF_I_PROTO
size_t ustr_srch_case_chr_fwd(const struct Ustr *s1, size_t off, char val)
{
const char *beg = ustr_cstr(s1);
const char *ptr;
size_t len = ustr_len(s1);
const char *tmp;
USTR_ASSERT(ustr_assert_valid(s1));
USTR_ASSERT_RET(off <= len, 0);
ptr = beg + off;
len -= off;
if (!(tmp = ustr__memcasechr(ptr, val, len))) return (0);
len = tmp - beg;
return (len + 1);
}
USTR_CONF_I_PROTO
size_t ustr_srch_case_chr_rev(const struct Ustr *s1, size_t off, char val)
{
const char *ptr = ustr_cstr(s1);
size_t len = ustr_len(s1);
const char *tmp = ptr;
const char *prev = 0;
USTR_ASSERT(ustr_assert_valid(s1));
USTR_ASSERT_RET(off <= len, 0);
len -= off;
while ((tmp = ustr__memcasechr(tmp, val, len - (tmp - ptr))))
{
prev = tmp;
++tmp;
}
if (!prev)
return (0);
len = prev - ptr;
return (len + 1);
}
USTR_CONF_I_PROTO
size_t ustr_srch_case_buf_fwd(const struct Ustr *s1, size_t off,
const void *val, size_t vlen)
{
const char *beg = ustr_cstr(s1);
const char *ptr;
size_t len = ustr_len(s1);
char *tmp = 0;
USTR_ASSERT(ustr_assert_valid(s1));
if (vlen == 1)
return (ustr_srch_case_chr_fwd(s1, off, ((const char *)val)[0]));
USTR_ASSERT_RET(off <= len, 0);
if (vlen == 0)
return (len ? (off + 1) : 0);
ptr = beg + off;
len -= off;
if (!(tmp = ustr__memcasemem(ptr, len, val, vlen)))
return (0);
len = tmp - beg;
return (len + 1);
}
USTR_CONF_I_PROTO
size_t ustr_srch_case_buf_rev(const struct Ustr *s1, size_t off,
const void *val, size_t vlen)
{
const char *ptr = ustr_cstr(s1);
size_t len = ustr_len(s1);
const char *prev = 0;
const char *tmp = 0;
USTR_ASSERT(ustr_assert_valid(s1));
if (vlen == 1)
return (ustr_srch_case_chr_rev(s1, off, ((const char *)val)[0]));
USTR_ASSERT_RET(off <= len, 0);
len -= off;
if (vlen == 0)
return (len);
tmp = ptr;
while (((len - (tmp - ptr)) >= vlen) &&
(tmp = ustr__memcasemem(tmp, len - (tmp - ptr), val, vlen)))
{
prev = tmp;
++tmp;
}
if (!prev)
return (0);
len = prev - ptr;
return (len + 1);
}
USTR_CONF_I_PROTO
size_t ustr_srch_case_subustr_fwd(const struct Ustr *s1, size_t off,
const struct Ustr *s2, size_t pos, size_t len)
{
USTR_ASSERT(ustr_assert_valid(s1) && ustr_assert_valid(s2));
if (!ustr_assert_valid_subustr(s2, pos, len))
return (ustr_srch_case_buf_fwd(s1, off, "", 0));
return (ustr_srch_case_buf_fwd(s1, off, ustr_cstr(s2) + --pos, len));
}
USTR_CONF_I_PROTO
size_t ustr_srch_case_subustr_rev(const struct Ustr *s1, size_t off,
const struct Ustr *s2, size_t pos, size_t len)
{
USTR_ASSERT(ustr_assert_valid(s1) && ustr_assert_valid(s2));
if (!ustr_assert_valid_subustr(s2, pos, len))
return (ustr_srch_case_buf_rev(s1, off, "", 0));
return (ustr_srch_case_buf_rev(s1, off, ustr_cstr(s2) + --pos, len));
}
USTR_CONF_I_PROTO
size_t ustr_srch_case_rep_chr_fwd(const struct Ustr *s1, size_t off,
char val, size_t vlen)
{
const char *beg = ustr_cstr(s1);
const char *ptr;
size_t len = ustr_len(s1);
char *tmp = 0;
USTR_ASSERT(ustr_assert_valid(s1));
if (vlen == 1)
return (ustr_srch_case_chr_fwd(s1, off, val));
USTR_ASSERT_RET(off <= len, 0);
if (vlen == 0)
return (len ? (off + 1) : 0);
ptr = beg + off;
len -= off;
if (!(tmp = ustr__memcaserepchr(ptr, len, val, vlen)))
return (0);
len = tmp - beg;
return (len + 1);
}
USTR_CONF_I_PROTO
size_t ustr_srch_case_rep_chr_rev(const struct Ustr *s1, size_t off,
char val, size_t vlen)
{
const char *ptr = ustr_cstr(s1);
size_t len = ustr_len(s1);
const char *prev = 0;
const char *tmp = 0;
USTR_ASSERT(ustr_assert_valid(s1));
if (vlen == 1)
return (ustr_srch_case_chr_rev(s1, off, val));
USTR_ASSERT_RET(off <= len, 0);
len -= off;
if (vlen == 0)
return (len);
tmp = ptr;
while (((len - (tmp - ptr)) >= vlen) &&
(tmp = ustr__memcaserepchr(tmp, len - (tmp - ptr), val, vlen)))
{
prev = tmp;
++tmp;
}
if (!prev)
return (0);
len = prev - ptr;
return (len + 1);
}