Beispiel #1
0
ss_t *ss_cpy_substr_u(ss_t **s, const ss_t *src, const size_t char_off,
		      const size_t n)
{
	ASSERT_RETURN_IF(!s, ss_void);
	ASSERT_RETURN_IF(!src || !n, ss_clear(s)); /* BEHAVIOR: empty */
	if (*s == src) { /* aliasing */
		char *ps = get_str(*s);
		size_t actual_unicode_count = 0;
		const size_t ss = sd_get_size(*s);
		const size_t off = sc_unicode_count_to_utf8_size(ps, 0,
					ss, char_off, &actual_unicode_count);
		const size_t n_size = sc_unicode_count_to_utf8_size(ps,
			off, ss, n, &actual_unicode_count);
		ASSERT_RETURN_IF(off >= ss, ss_clear(s)); /* BEHAVIOR: empty */
		const size_t copy_size = S_MIN(ss - off, n_size);
		memmove(ps, ps + off, copy_size);
		set_size(*s, copy_size);
		if (n == actual_unicode_count) {
			set_unicode_size_cached(*s, S_TRUE);
			set_unicode_size(*s, n);
		} else { /* BEHAVIOR: cache lost */
			set_unicode_size_cached(*s, S_FALSE);
		}
	} else {
		if (*s)
			ss_clear(s);
		ss_cat_substr_u(s, src, char_off, n);
	}
	return ss_check(s);
}
Beispiel #2
0
sdm_t *sdm_alloc(const enum eSM_Type t, const size_t nsubmaps,
		 const size_t initial_reserve)
{
	ASSERT_RETURN_IF(nsubmaps < 1, NULL);
	size_t alloc_size = sizeof(sdm_t) + sizeof(sm_t *) * (nsubmaps - 1);
	sdm_t *dm = (sdm_t *)__sd_malloc(alloc_size);
	ASSERT_RETURN_IF(!dm, NULL);
	memset(dm, 0, alloc_size);
	size_t i = 0, nelems = (initial_reserve / nsubmaps) + 1;
	for (; i < nsubmaps; i++) {
		if (!(dm->maps[i] = sm_alloc(t, nelems)))
			break;	/* Allocation error */
	}
	if (i != nsubmaps) { /* Handle allocation error */
		for (i = 0; i < nsubmaps; i++) {
			if (dm->maps[i])
				free(dm->maps[i]);
			else
				break;
		}
		free(dm);
		dm = NULL;
	} else {
		/* Set routing defaults */
		sdm_set_routing(dm, NULL, NULL);
		dm->nmaps = nsubmaps;
	}
	return dm;
}
Beispiel #3
0
ss_t *ss_cpy_cn(ss_t **s, const char *src, const size_t src_size)
{
	ASSERT_RETURN_IF(!s, ss_void);
	ASSERT_RETURN_IF(!src || !src_size, ss_clear(s)); /* BEHAVIOR: empty */
	if (*s)
		ss_clear(s);
	ss_cat_cn(s, src, src_size);
	return ss_check(s);
}
Beispiel #4
0
ss_t *ss_cpy_sub(ss_t **s, const ss_t *src, const sv_t *offs, const size_t nth)
{
	ASSERT_RETURN_IF(!s, ss_void);
	ASSERT_RETURN_IF((!src || !offs), ss_clear(s)); /* BEHAVIOR: empty */
	const size_t elems = sv_size(offs) / 2;
	ASSERT_RETURN_IF(nth >= elems, ss_clear(s)); /* BEHAVIOR: empty */
	const size_t off = (size_t)sv_u_at(offs, nth * 2);
	const size_t size = (size_t)sv_u_at(offs, nth * 2 + 1);
	return ss_cpy_substr(s, src, off, size);
}
Beispiel #5
0
ss_t *ss_cpy_printf_va(ss_t **s, const size_t size, const char *fmt, va_list ap)
{
	ASSERT_RETURN_IF(!s, ss_void);
	ASSERT_RETURN_IF((!size || !fmt) && ss_clear(s), *s);
	if (*s) {
		ss_reserve(s, size);
		ss_clear(s);
	}
	return ss_cat_printf_va(s, size, fmt, ap);
}
Beispiel #6
0
ss_t *ss_cpy_printf(ss_t **s, const size_t size, const char *fmt, ...)
{
	ASSERT_RETURN_IF(!s, ss_void);
	ASSERT_RETURN_IF((!size || !fmt) && ss_clear(s), *s);
	if (*s) {
		ss_reserve(s, size);
		ss_clear(s);
	}
	va_list ap;
	va_start(ap, fmt);
	ss_cat_printf_va(s, size, fmt, ap);
	va_end(ap);
	return *s;
}
Beispiel #7
0
static ss_t *aux_rtrim(ss_t **s, const sbool_t cat, const ss_t *src)
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (!src)
		src = ss_void;
	const size_t ss = sd_get_size(src),
		     at = (cat && *s) ? sd_get_size(*s) : 0;
	if (ss > 0) {
		const sbool_t aliasing = *s == src;
		const char *ps = get_str_r(src);
		size_t i = ss - 1;
		for (; i > 0 && isspace(ps[i]); i--);
		if (isspace(ps[i]))
			i--;
		const size_t nspaces = ss - i - 1,
			     copy_size = ss - nspaces,
			     out_size = at + copy_size,
			     cat_usize = cat ? get_unicode_size(*s) : 0,
			     src_usize = *s ? get_unicode_size(*s) : 0;
		if (ss_reserve(s, out_size) >= out_size) {
			char *pt = get_str(*s);
			if (!aliasing)
				 memcpy(pt + at, ps, copy_size);
			set_size(*s, out_size);
			set_unicode_size(*s, cat_usize + src_usize - nspaces);
		}
	} else {
		if (cat)
			ss_check(s);
		else
			ss_clear(s);
	}
	return *s;
}
Beispiel #8
0
static ss_t *aux_resize(ss_t **s, const sbool_t cat, const ss_t *src,
			const size_t n, char fill_byte)
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (!src)
		src = ss_void;
	const size_t src_size = sd_get_size(src),
		     at = (cat && *s) ? sd_get_size(*s) : 0,
		     out_size = at + n;  /* BEHAVIOR: n overflow TODO */
	const sbool_t aliasing = *s == src;
	if (src_size < n) { /* fill */
		if (ss_reserve(s, out_size) >= out_size) {
			char *o = get_str(*s);
			if (!aliasing) {
				const char *p = get_str_r(src);
				memcpy(o + at, p, src_size);
			}
			memset(o + at + src_size, fill_byte,
				n - src_size);
			set_size(*s, out_size);
		}
	} else { /* else: cut (implicit) */
		if (ss_reserve(s, out_size) >= out_size) {
			if (!aliasing)
				memcpy(get_str(*s) + at, get_str_r(src), n);
			set_size(*s, out_size);
		}
	}
	return *s;
}
Beispiel #9
0
static ss_t *aux_erase(ss_t **s, const sbool_t cat, const ss_t *src,
		       const size_t off, const size_t n)
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (!src)
		src = ss_void;
	const size_t ss0 = sd_get_size(src),
			   at = (cat && *s) ? sd_get_size(*s) : 0;
	const sbool_t overflow = off + n > ss0;
	const size_t src_size = overflow ? ss0 - off : n,
		     copy_size = ss0 - off - src_size;
	if (*s == src) { /* BEHAVIOR: aliasing: copy-only */
		if (off + n >= ss0) { /* tail clean cut */
			set_size(*s, off);
		} else {
			char *ps = get_str(*s);
			memmove(ps + off, ps + off + n, copy_size);
			set_size(*s, ss0 - n);
		}
		set_unicode_size_cached(*s, S_FALSE);
	} else { /* copy or cat */
		const size_t out_size = at + off + copy_size;
		if (ss_reserve(s, out_size) >= out_size) {
			char *po = get_str(*s);
			memcpy(po + at, get_str_r(src), off);
			memcpy(po + at + off,
			       get_str_r(src) + off + n, copy_size);
			set_size(*s, out_size);
			set_unicode_size_cached(*s, S_FALSE);
		}
	}
	return ss_check(s);
}
Beispiel #10
0
static ss_t *aux_toenc(ss_t **s, const sbool_t cat, const ss_t *src, senc_f_t f)
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (!src)
		src = ss_void;
	const int aliasing = *s == src;
	const size_t in_size = sd_get_size(src),
		     at = (cat && *s) ? sd_get_size(*s) : 0,
		     out_size = at + f(NULL, in_size, NULL);
	if (ss_reserve(s, out_size) >= out_size) {
		const ss_t *src1 = aliasing ? *s : src;
		f((const unsigned char *)get_str_r(src1), in_size,
		  (unsigned char *)get_str(*s) + at);
		if (at == 0) {
			set_unicode_size_cached(*s, S_TRUE);
			set_unicode_size(*s, in_size * 2);
		} else { /* cat */
			if (is_unicode_size_cached(*s) &&
			    at == sd_get_size(*s))
				set_unicode_size(*s, get_unicode_size(*s) +
						     in_size * 2);
			else
				set_unicode_size_cached(*s, S_FALSE);
		}
		set_size(*s, out_size);
	}
	return ss_check(s);
}
Beispiel #11
0
ss_t *ss_cat_aux(ss_t **s, const size_t nargs, const ss_t *s1, ...)
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (s1 && sd_get_size(s1) > 0) {
		va_list ap;
		size_t extra_size = sd_get_size(s1);
		const ss_t *s_next, *s0 = *s;
		const size_t ss0 = *s ? sd_get_size(s0) : 0,
			     uss0 = s0 ? get_unicode_size(s0) : 0;
		va_start(ap, s1);
		size_t i = 1;
		for (; i < nargs; i++) {
			s_next = va_arg(ap, const ss_t *);
			if (s_next)
				extra_size += sd_get_size(s_next);
		}
		va_end(ap);
		if (ss_grow(s, extra_size)) {
			ss_cat_aliasing(s, s0, ss0, uss0, s1);
			if (nargs == 1)
				return *s;
			va_start(ap, s1);
			for (i = 1; i < nargs; i++) {
				s_next = va_arg(ap, const ss_t *);
				if (s_next)
					ss_cat_aliasing(s, s0, ss0, uss0,
							s_next);
			}
			va_end(ap);
		}
	}
Beispiel #12
0
sbool_t sm_s_count(const sm_t *m, const ss_t *k)
{
	ASSERT_RETURN_IF(!m, S_FALSE);
	struct SMapSX n;
	n.k = k;
	return st_locate(m, (const stn_t *)&n) ? S_TRUE : S_FALSE;
}
Beispiel #13
0
ss_t *ss_cpy_wn(ss_t **s, const wchar_t *src, const size_t src_size)
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (*s)
		ss_clear(s);
	return ss_cat_wn(s, src, src_size);
}
Beispiel #14
0
sbool_t sm_u_count(const sm_t *m, const suint32_t k)
{
	ASSERT_RETURN_IF(!m, S_FALSE);
	struct SMapuu n;
	n.k = k;
	return st_locate(m, (const stn_t *)&n) ? S_TRUE : S_FALSE;
}
Beispiel #15
0
sbool_t sm_ip_insert(sm_t **m, const sint_t k, const void *v)
{
	ASSERT_RETURN_IF(!m, S_FALSE);
	struct SMapIP n;
	n.x.k = k;
	n.v = v;
	return st_insert((st_t **)m, (const stn_t *)&n);
}
Beispiel #16
0
size_t ss_len_left(const ss_t *s)
{
	ASSERT_RETURN_IF(!s, 0);
	const size_t size = sd_get_size(s),
		     max_size = ss_get_max_size(s);
	S_ASSERT(s && max_size > size);
	return (s && max_size > size) ? max_size - size : 0;
}
Beispiel #17
0
sbool_t sm_is_insert(sm_t **m, const sint_t k, const ss_t *v)
{
	ASSERT_RETURN_IF(!m, S_FALSE);
	struct SMapIS n;
	n.x.k = k;
	n.v = ss_dup(v);
	return st_insert((st_t **)m, (const stn_t *)&n);
}
Beispiel #18
0
sint32_t sm_ii32_at(const sm_t *m, const sint32_t k)
{
	ASSERT_RETURN_IF(!m, SINT32_MIN);
	struct SMapii n;
	n.k = k;
	const struct SMapii *nr =
			(const struct SMapii *)st_locate(m, (const stn_t *)&n);
	return nr ? nr->v : (sint32_t)m->f.iaux1;
}
Beispiel #19
0
ss_t *ss_cpy_char(ss_t **s, const int c)
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (ss_reserve(s, SSU8_MAX_SIZE) >= SSU8_MAX_SIZE) {
		ss_clear(s);
		return ss_cat_char(s, c);
	}
	return *s;
}
Beispiel #20
0
S_INLINE sbool_t sm_ii_insert_aux(sm_t **m, const sint_t k,
			          const sint_t v, const st_rewrite_t rw_f)
{
	ASSERT_RETURN_IF(!m, S_FALSE);
	struct SMapII n;
	n.x.k = k;
	n.v = v;
	return st_insert_rw((st_t **)m, (const stn_t *)&n, rw_f);
}
Beispiel #21
0
const void *sm_sp_at(const sm_t *m, const ss_t *k)
{
	ASSERT_RETURN_IF(!m, NULL);
	struct SMapSP n;
	n.x.k = (ss_t *)k;	/* not going to be overwritten */
	const struct SMapSP *nr =
			(const struct SMapSP *)st_locate(m, (const stn_t *)&n);
	return nr ? nr->v : NULL;
}
Beispiel #22
0
suint32_t sm_uu32_at(const sm_t *m, const suint32_t k)
{
	ASSERT_RETURN_IF(!m, 0);
	struct SMapuu n;
	n.k = k;
	const struct SMapuu *nr =
			(const struct SMapuu *)st_locate(m, (const stn_t *)&n);
	return nr ? nr->v : (suint32_t)m->f.iaux1;
}
Beispiel #23
0
const ss_t *sm_ss_at(const sm_t *m, const ss_t *k)
{
	ASSERT_RETURN_IF(!m, ss_empty());
	struct SMapSS n;
	n.x.k = (ss_t *)k;	/* not going to be overwritten */
	const struct SMapSS *nr =
			(const struct SMapSS *)st_locate(m, (const stn_t *)&n);
	return nr ? nr->v : (ss_t *)m->f.paux1;
}
Beispiel #24
0
sint_t sm_si_at(const sm_t *m, const ss_t *k)
{
	ASSERT_RETURN_IF(!m, SINT_MIN);
	struct SMapSI n;
	n.x.k = (ss_t *)k;	/* not going to be overwritten */
	const struct SMapSI *nr =
			(const struct SMapSI *)st_locate(m, (const stn_t *)&n);
	return nr ? nr->v : m->f.iaux1;
}
Beispiel #25
0
const void *sm_ip_at(const sm_t *m, const sint_t k)
{
	ASSERT_RETURN_IF(!m, NULL);
	struct SMapIP n;
	n.x.k = k;
	const struct SMapIP *nr =
			(const struct SMapIP *)st_locate(m, (const stn_t *)&n);
	return nr ? nr->v : NULL;
}
Beispiel #26
0
const ss_t *sm_is_at(const sm_t *m, const sint_t k)
{
	ASSERT_RETURN_IF(!m, ss_empty());
	struct SMapIS n;
	n.x.k = k;
	const struct SMapIS *nr =
			(const struct SMapIS *)st_locate(m, (const stn_t *)&n);
	return nr ? nr->v : (const ss_t *)m->f.paux1;
}
Beispiel #27
0
sint_t sm_ii_at(const sm_t *m, const sint_t k)
{
	ASSERT_RETURN_IF(!m, SINT_MIN);
	struct SMapII n;
	n.x.k = k;
	const struct SMapII *nr =
			(const struct SMapII *)st_locate(m, (const stn_t *)&n);
	return nr ? nr->v : m->f.iaux1;
}
Beispiel #28
0
sbool_t sm_sp_insert(sm_t **m, const ss_t *k, const void *v)
{
	ASSERT_RETURN_IF(!m, S_FALSE);
	struct SMapSP n;
	n.x.k = NULL;
	ss_cpy(&n.x.k, k);
	n.v = v;
	return st_insert((st_t **)m, (const stn_t *)&n);
}
Beispiel #29
0
ss_t *ss_cpy(ss_t **s, const ss_t *src)
{
	ASSERT_RETURN_IF(!s, ss_void);
	RETURN_IF(*s == src && ss_check(s), *s); /* aliasing, same string */
	RETURN_IF(!src, ss_clear(s)); /* BEHAVIOR: empty */
	if (*s)
		ss_clear(s);
	return ss_cat(s, src);
}
Beispiel #30
0
S_INLINE sbool_t sm_si_insert_aux(sm_t **m, const ss_t *k,
				  const sint_t v, const st_rewrite_t rw_f)
{
	ASSERT_RETURN_IF(!m, S_FALSE);
	struct SMapSI n;
	n.x.k = NULL;
	ss_cpy(&n.x.k, k);
	n.v = v;
	return st_insert_rw((st_t **)m, (const stn_t *)&n, rw_f);
}