コード例 #1
0
ファイル: flonum.c プロジェクト: kstephens/ss
ss_INLINE
ss ss_box_flonum(ss_flonum_t v)
{
  ss_s_flonum *self = ss_alloc(ss_t_flonum, sizeof(*self));
  self->value = v;
  return self;
}
コード例 #2
0
ファイル: memory.c プロジェクト: kstephens/ss
ss_INLINE
ss ss_alloc_copy(ss type, size_t size, void *ptr)
{
  void *self = ss_alloc(type, size);
  memcpy(self, ptr, size);
  return self;
}
コード例 #3
0
ファイル: sstring.c プロジェクト: nobody1986/libsrt
static ss_t *aux_replace(ss_t **s, const sbool_t cat, const ss_t *src,
			 const size_t off, const ss_t *s1, const ss_t *s2)
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (!s1)
		s1 = ss_void;
	if (!s2)
		s2 = ss_void;
	if (!src)
		src = ss_void;
	const size_t at = (cat && *s) ? sd_get_size(*s) : 0;
	const char *p0 = get_str_r(src),
		   *p2 = get_str_r(s2);
	const size_t l1 = sd_get_size(s1), l2 = sd_get_size(s2);
	size_t i = off, l = sd_get_size(src);
	ss_t *out = NULL;
	ssize_t size_delta = l2 > l1 ? (ssize_t)(l2 - l1) :
				       -(ssize_t)(l1 - l2);
	sbool_t aliasing = S_FALSE;
	size_t out_size = at + l;
	char *o, *o0;
	if (l2 >= l1) { /* resize required */
		size_t nfound = 0;
		/* scan required size */
		for (;; i+= l1, nfound++)
			if ((i = ss_find(src, i, s1)) == S_NPOS)
				break;
		if (nfound == 0)	/* 0 occurrences: return */
			return ss_check(s);
		if (size_delta >= 0)
			out_size += (size_t)size_delta * nfound;
		else
			out_size -= (size_t)(-size_delta) * nfound;
		/* allocate output string */
		out = ss_alloc(out_size);
		if (!out) {
			S_ERROR("not enough memory");
			sd_set_alloc_errors(*s);
			return ss_check(s);
		}
		o0 = o = get_str(out);
		/* copy prefix data (cat) */
		if (at > 0)
			memcpy(o, get_str_r(*s), at);
	} else {
		if (s && *s && *s == src) {
			aliasing = S_TRUE;
		} else {
			if (ss_reserve(s, out_size) < out_size) /* BEHAVIOR */
				return ss_check(s);
		}
		o0 = o = get_str(*s);
	}
	typedef void (*memcpy_t)(void *, const void *, size_t);
	memcpy_t f_cpy;
	if (aliasing) {
		f_cpy = (memcpy_t)memmove;
	} else {
		f_cpy = (memcpy_t)memcpy;
		o += at;
		if (off > 0)	/* copy not affected data */
			memcpy(o, p0, off);
	}
	o += off;
	size_t i_next = s1 == s2? S_NPOS : /* no replace */
			ss_find(src, i + off, s1);
	for (i = off;;) {
		/* before match copy: */
		if (i_next == S_NPOS) {
			f_cpy(o, p0 + i, l - i);
			o += (l - i);
			break;
		}
		f_cpy(o, p0 + i, i_next - i);
		o += (i_next - i);
		/* replace: */
		f_cpy(o, p2, l2);
		o += l2;
		i = i_next + l1;
		/* prepare next search: */
		i_next = ss_find(src, i, s1);
	}
	if (out) {
		ss_t *s_bck = *s;
		*s = out;
		ss_free(&s_bck);
	}
	set_size(*s, (size_t)(o - o0));
	return *s;
}
コード例 #4
0
ファイル: sstring.c プロジェクト: nobody1986/libsrt
static ss_t *aux_toXcase(ss_t **s, const sbool_t cat, const ss_t *src,
			 sint32_t (*towX)(sint32_t))
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (!src)
		src = ss_void;
	const size_t ss = sd_get_size(src),
		     sso_max = *s ? ss_get_max_size(*s) : 0;
	const char *ps = get_str_r(src);
	ss_t *out = NULL;
	const sbool_t aliasing = *s == src;
	unsigned char is_cached_usize = 0;
	ssize_t extra = sc_utf8_calc_case_extra_size(ps, 0, ss, towX);
	size_t cached_usize = 0,
	       at;
	/* If possible, keep Unicode size cached: */
	if (*s) {
		if (is_unicode_size_cached(*s) && is_unicode_size_cached(src)) {
			is_cached_usize = 1;
			cached_usize = get_unicode_size(src) +
				       get_unicode_size(*s);
		}
		at = cat ? sd_get_size(*s) : 0;
	} else { /* copy */
		if (is_unicode_size_cached(src)) {
			is_cached_usize = 1;
			cached_usize = get_unicode_size(src);
		}
		at = 0;
	}
	/* Check if it is necessary to allocate more memory: */
	size_t sso_req = extra < 0 ? (at + ss - (size_t)(-extra)) :
				     (at + ss + (size_t)extra);
	char *po0;
	if (!*s || sso_req > sso_max || (aliasing && extra > 0)) {
		if (*s && (*s)->ext_buffer) { /* BEHAVIOR */
			S_ERROR("not enough memory: strings stored in the "
				"stored in fixed-length buffer can not be "
				"resized.");
			sd_set_alloc_errors(*s);
			return ss_check(s);
		}
		out = ss_alloc(sso_req);
		if (!out) {	/* BEHAVIOR */
			S_ERROR("not enough memory: can not "
				"change character case");
			if (*s)
				sd_set_alloc_errors(*s);
			return ss_check(s);
		}
		char *pout = get_str(out);
		if (at > 0) /* cat */
			memcpy(pout, get_str(*s), at);
		po0 = pout + at;
	} else {
		po0 = get_str(*s) + at;
	}
	/* Case conversion loop: */
	size_t i = 0;
	int c = 0;
	char *po = po0,
	      u8[SSU8_MAX_SIZE];
	for (; i < ss;) {
#ifdef S_ENABLE_UTF8_7BIT_PARALLEL_CASE_OPTIMIZATIONS
		unsigned *pou = (unsigned *)po;
		const size_t i2 = sc_parallel_toX(ps, i, ss, pou, towX);
		if (i != i2) {
			po += (i2 - i);
			i = i2;
			if (i >= ss)
				break;
		}
#endif
		const size_t csize = ss_utf8_to_wc(ps, i, ss, &c, *s);
		const int c2 = towX(c);
		size_t csize2;
		if (c2 == c) {
			csize2 = csize;
			if (!aliasing)
				memcpy(po, ps + i, csize2);
		} else {
			csize2 = sc_wc_to_utf8(c2, u8, 0, SSU8_MAX_SIZE);
			memcpy(po, u8, csize2);
		}
		i += csize;
		po += csize2;
	}
	if (out) {	/* Case of using a secondary string was required */
		ss_t *s_bck = *s;
		*s = out;
		ss_free(&s_bck);
	}
	if (*s) {
		set_size(*s, sso_req);
		set_unicode_size_cached(*s, is_cached_usize);
		set_unicode_size(*s, cached_usize);
	}
	return ss_check(s);
}