ustr-replace-code.h
#ifndef USTR_REPLACE_H
#error " Include ustr-replace.h before this file."
#endif
USTR_CONF_i_PROTO
size_t ustrp__replace_inline_buf(struct Ustr_pool *p, struct Ustr **ps1,
const void *optr, size_t olen,
const void *nptr, size_t nlen, size_t lim)
{
size_t num = 0;
size_t pos = 0;
USTR_ASSERT(ustr_owner(*ps1));
USTR_ASSERT((nlen == olen) || !ustr_alloc(*ps1));
while ((pos = ustr_srch_buf_fwd(*ps1, pos, optr, olen)))
{
USTR_ASSERT((nlen == olen) ||
(ustr_fixed(*ps1) &&
(ustr_size(*ps1) >= (ustr_len(*ps1) + (nlen - olen)))));
ustrp__sc_sub_buf(p, ps1, pos, olen, nptr, nlen);
pos += nlen - 1;
++num;
if (lim && (num == lim))
break;
}
if (!num)
errno = 0;
return (num);
}
USTR_CONF_i_PROTO
size_t ustrp__replace_buf(struct Ustr_pool *p, struct Ustr **ps1,
const void *optr, size_t olen,
const void *nptr, size_t nlen, size_t lim)
{
size_t num = 0;
size_t tlen = 0;
size_t pos = 0;
struct Ustr *ret = USTR_NULL;
const char *rptr;
size_t lpos = 0;
size_t roff = 0;
USTR_ASSERT(ps1 && ustrp__assert_valid(!!p, *ps1));
if ((nlen == olen) && ustr_owner(*ps1))
return (ustrp__replace_inline_buf(p, ps1, optr, olen, nptr, nlen, lim));
tlen = ustr_len(*ps1);
while ((pos = ustr_srch_buf_fwd(*ps1, pos, optr, olen)))
{
pos += olen - 1;
if (nlen < olen)
tlen -= (olen - nlen);
else
{
if (tlen > (tlen + (nlen - olen)))
{
errno = USTR__ENOMEM;
return (0);
}
tlen += (nlen - olen);
}
++num;
if (lim && (num == lim))
break;
}
if (!num)
{
errno = 0;
return (0);
}
if (!tlen)
return (ustrp__del(p, ps1, ustr_len(*ps1)) ? num : 0);
if (ustr_fixed(*ps1) && ((num <= 2) || ustr_limited(*ps1)))
{
if (tlen <= ustr_size(*ps1))
return (ustrp__replace_inline_buf(p, ps1, optr, olen, nptr, nlen, lim));
if (ustr_limited(*ps1))
goto fail_alloc;
}
if (!(ret = ustrp__dupx_undef(p, USTR__DUPX_FROM(*ps1), tlen)))
goto fail_alloc;
rptr = ustr_cstr(*ps1);
lpos = 1;
roff = 0;
pos = 0;
num = 0;
while ((pos = ustr_srch_buf_fwd(*ps1, pos, optr, olen)))
{
const char *tptr = rptr + roff;
size_t blen = pos - (roff + 1);
pos += olen - 1;
USTR_ASSERT(pos == (roff + blen + olen));
ustrp__sub_buf(p, &ret, lpos, tptr, blen); lpos += blen;
ustrp__sub_buf(p, &ret, lpos, nptr, nlen); lpos += nlen;
roff = pos;
++num;
if (lim && (num == lim))
break;
}
ustrp__sub_buf(p, &ret, lpos, rptr + roff, ustr_len(*ps1) - roff);
if (!ustr_fixed(*ps1) || (tlen > ustr_size(*ps1)))
ustrp__sc_free2(p, ps1, ret);
else
{
ustrp__set(p, ps1, ret);
ustrp__free(p, ret);
}
return (num);
fail_alloc:
ustr_setf_enomem_err(*ps1);
return (0);
}
USTR_CONF_I_PROTO
size_t ustr_replace_buf(struct Ustr **ps1, const void *optr, size_t olen,
const void *nptr, size_t nlen, size_t lim)
{ return (ustrp__replace_buf(0, ps1, optr, olen, nptr, nlen, lim)); }
USTR_CONF_I_PROTO
size_t ustrp_replace_buf(struct Ustr_pool *p, struct Ustrp **ps1,
const void *optr, size_t olen,
const void *nptr, size_t nlen, size_t lim)
{
struct Ustr *tmp = &(*ps1)->s;
int ret = ustrp__replace_buf(p, &tmp, optr, olen, nptr, nlen, lim);
*ps1 = USTRP(tmp);
return (ret);
}
USTR_CONF_i_PROTO
size_t ustrp__replace(struct Ustr_pool *p, struct Ustr **ps1,
const struct Ustr *srch,
const struct Ustr *repl, size_t lim)
{
struct Ustr *t1 = USTR_NULL;
struct Ustr *t2 = USTR_NULL;
size_t ret = 0;
USTR_ASSERT(ustrp__assert_valid(!!p, srch));
USTR_ASSERT(ustrp__assert_valid(!!p, repl));
if (srch == *ps1) srch = t1 = ustrp__dup(p, *ps1);
if (repl == *ps1) repl = t2 = ustrp__dup(p, *ps1);
if (srch && repl)
ret = ustrp__replace_buf(p, ps1,
ustr_cstr(srch), ustr_len(srch),
ustr_cstr(repl), ustr_len(repl), lim);
ustrp__free(p, t1);
ustrp__free(p, t2);
return (ret);
}
USTR_CONF_I_PROTO
size_t ustr_replace(struct Ustr **ps1, const struct Ustr *srch,
const struct Ustr *repl, size_t lim)
{ return (ustrp__replace(0, ps1, srch, repl, lim)); }
USTR_CONF_I_PROTO
size_t ustrp_replace(struct Ustr_pool *p, struct Ustrp **ps1,
const struct Ustrp *srch,
const struct Ustrp *repl, size_t lim)
{
struct Ustr *tmp = &(*ps1)->s;
int ret = ustrp__replace(p, &tmp, &srch->s, &repl->s, lim);
*ps1 = USTRP(tmp);
return (ret);
}
USTR_CONF_i_PROTO
size_t ustrp__replace_inline_rep_chr(struct Ustr_pool *p, struct Ustr **ps1,
char odata, size_t olen,
char ndata, size_t nlen, size_t lim)
{
size_t num = 0;
size_t pos = 0;
USTR_ASSERT(ustr_owner(*ps1));
USTR_ASSERT((nlen == olen) || !ustr_alloc(*ps1));
while ((pos = ustr_srch_rep_chr_fwd(*ps1, pos, odata, olen)))
{
USTR_ASSERT((nlen == olen) ||
(ustr_fixed(*ps1) &&
(ustr_size(*ps1) >= (ustr_len(*ps1) + (nlen - olen)))));
ustrp__sc_sub_rep_chr(p, ps1, pos, olen, ndata, nlen);
pos += nlen - 1;
++num;
if (lim && (num == lim))
break;
}
if (!num)
errno = 0;
return (num);
}
USTR_CONF_i_PROTO
size_t ustrp__replace_rep_chr(struct Ustr_pool *p, struct Ustr **ps1,
char odata, size_t olen,
char ndata, size_t nlen, size_t lim)
{
size_t num = 0;
size_t tlen = 0;
size_t pos = 0;
struct Ustr *ret = USTR_NULL;
const char *rptr;
size_t lpos = 0;
size_t roff = 0;
USTR_ASSERT(ps1 && ustrp__assert_valid(!!p, *ps1));
if ((nlen == olen) && ustr_owner(*ps1))
return (ustrp__replace_inline_rep_chr(p, ps1, odata,olen, ndata,nlen, lim));
tlen = ustr_len(*ps1);
while ((pos = ustr_srch_rep_chr_fwd(*ps1, pos, odata, olen)))
{
pos += olen - 1;
if (nlen < olen)
tlen -= (olen - nlen);
else
{
if (tlen > (tlen + (nlen - olen)))
{
errno = USTR__ENOMEM;
return (0);
}
tlen += (nlen - olen);
}
++num;
if (lim && (num == lim))
break;
}
if (!num)
{
errno = 0;
return (0);
}
if (!tlen)
return (ustrp__del(p, ps1, ustr_len(*ps1)) ? num : 0);
if (ustr_fixed(*ps1) && ((num <= 2) || ustr_limited(*ps1)))
{
if (tlen <= ustr_size(*ps1))
return (ustrp__replace_inline_rep_chr(p, ps1, odata,olen,ndata,nlen,lim));
if (ustr_limited(*ps1))
goto fail_alloc;
}
if (!(ret = ustrp__dupx_undef(p, USTR__DUPX_FROM(*ps1), tlen)))
goto fail_alloc;
rptr = ustr_cstr(*ps1);
lpos = 1;
roff = 0;
pos = 0;
num = 0;
while ((pos = ustr_srch_rep_chr_fwd(*ps1, pos, odata, olen)))
{
const char *tptr = rptr + roff;
size_t blen = pos - (roff + 1);
pos += olen - 1;
USTR_ASSERT(pos == (roff + blen + olen));
ustrp__sub_buf(p, &ret, lpos, tptr, blen); lpos += blen;
ustrp__sub_rep_chr(p, &ret, lpos, ndata, nlen); lpos += nlen;
roff = pos;
++num;
if (lim && (num == lim))
break;
}
ustrp__sub_buf(p, &ret, lpos, rptr + roff, ustr_len(*ps1) - roff);
if (!ustr_fixed(*ps1) || (tlen > ustr_size(*ps1)))
ustrp__sc_free2(p, ps1, ret);
else
{
ustrp__set(p, ps1, ret);
ustrp__free(p, ret);
}
return (num);
fail_alloc:
ustr_setf_enomem_err(*ps1);
return (0);
}
USTR_CONF_I_PROTO
size_t ustr_replace_rep_chr(struct Ustr **ps1, char odata, size_t olen,
char ndata, size_t nlen, size_t lim)
{ return (ustrp__replace_rep_chr(0, ps1, odata, olen, ndata, nlen, lim)); }
USTR_CONF_I_PROTO
size_t ustrp_replace_rep_chr(struct Ustr_pool *p, struct Ustrp **ps1,
char odata, size_t olen,
char ndata, size_t nlen, size_t lim)
{
struct Ustr *tmp = &(*ps1)->s;
int ret = ustrp__replace_rep_chr(p, &tmp, odata, olen, ndata, nlen, lim);
*ps1 = USTRP(tmp);
return (ret);
}