static inline Eina_Bool
_eina_strbuf_resize(Eina_Strbuf *buf, size_t size)
{
+ size_t new_size, new_step, delta;
char *buffer;
- size_t new_size;
- size_t new_step;
size += 1; // Add extra space for '\0'
- new_size = buf->size;
- new_step = buf->step;
-
- /*
- * first we have to determine the new buffer size
- */
if (size == buf->size)
/* nothing to do */
return EINA_TRUE;
else if (size > buf->size)
- {
- /* enlarge the buffer */
- while (size > new_size)
- {
- new_size += new_step;
- if (new_step < EINA_STRBUF_MAX_STEP)
- new_step *= 2;
- if (new_step > EINA_STRBUF_MAX_STEP)
- new_step = EINA_STRBUF_MAX_STEP;
- }
- }
+ delta = size - buf->size;
+ else
+ delta = buf->size - size;
+
+ /* check if should keep the same step (just used while growing) */
+ if ((delta <= buf->step) && (size > buf->size))
+ new_step = buf->step;
else
{
- /* shrink the buffer */
- if (new_step > EINA_STRBUF_INIT_STEP)
- new_step /= 2;
- while (new_size - new_step > size)
- {
- new_size -= new_step;
- if (new_step > EINA_STRBUF_INIT_STEP)
- new_step /= 2;
- if (new_step < EINA_STRBUF_INIT_STEP)
- new_step = EINA_STRBUF_INIT_STEP;
- }
+ new_step = (((delta / EINA_STRBUF_INIT_STEP) + 1)
+ * EINA_STRBUF_INIT_STEP);
+
+ if (new_step > EINA_STRBUF_MAX_STEP)
+ new_step = EINA_STRBUF_MAX_STEP;
}
+ new_size = (((size / new_step) + 1) * new_step);
+
/* reallocate the buffer to the new size */
- eina_error_set(0);
buffer = realloc(buf->buf, new_size);
if (EINA_UNLIKELY(!buffer))
{
buf->buf = buffer;
buf->size = new_size;
buf->step = new_step;
+ eina_error_set(0);
return EINA_TRUE;
}
}
END_TEST
+START_TEST(strbuf_realloc)
+{
+ Eina_Strbuf *buf;
+ char pattern[1024 * 16];
+ unsigned int i;
+ size_t sz;
+
+ for (i = 0; i < sizeof(pattern) - 1; i++)
+ pattern[i] = 'a' + (i % 26);
+ pattern[i] = '\0';
+
+ eina_init();
+
+ buf = eina_strbuf_new();
+ fail_if(!buf);
+
+ sz = 0;
+
+ eina_strbuf_append_length(buf, pattern, 1);
+ fail_if(eina_strbuf_length_get(buf) != sz + 1);
+ fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 1));
+ sz += 1;
+
+ eina_strbuf_append_length(buf, pattern, 32);
+ fail_if(eina_strbuf_length_get(buf) != sz + 32);
+ fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 32));
+ sz += 32;
+
+ eina_strbuf_append_length(buf, pattern, 64);
+ fail_if(eina_strbuf_length_get(buf) != sz + 64);
+ fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 64));
+ sz += 64;
+
+ eina_strbuf_append_length(buf, pattern, 128);
+ fail_if(eina_strbuf_length_get(buf) != sz + 128);
+ fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 128));
+ sz += 128;
+
+ eina_strbuf_append_length(buf, pattern, 4096);
+ fail_if(eina_strbuf_length_get(buf) != sz + 4096);
+ fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 4096));
+ sz += 4096;
+
+ eina_strbuf_append_length(buf, pattern, sizeof(pattern) - 1);
+ fail_if(eina_strbuf_length_get(buf) != sz + sizeof(pattern) - 1);
+ fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, sizeof(pattern) - 1));
+ sz += sizeof(pattern) - 1;
+
+
+ eina_strbuf_remove(buf, 1024, 1024 + 1234);
+ fail_if(eina_strbuf_length_get(buf) != sz - 1234);
+ sz -= 1234;
+
+ eina_strbuf_remove(buf, 0, 0 + 8192);
+ fail_if(eina_strbuf_length_get(buf) != sz - 8192);
+ sz -= 8192;
+
+ eina_strbuf_remove(buf, 0, 0 + 32);
+ fail_if(eina_strbuf_length_get(buf) != sz - 32);
+ sz -= 32;
+
+
+ eina_strbuf_free(buf);
+
+ eina_shutdown();
+}
+END_TEST
+
START_TEST(strbuf_append_realloc)
{
Eina_Strbuf *buf;
tcase_add_test(tc, strbuf_append);
tcase_add_test(tc, strbuf_insert);
tcase_add_test(tc, strbuf_replace);
+ tcase_add_test(tc, strbuf_realloc);
tcase_add_test(tc, strbuf_append_realloc);
tcase_add_test(tc, strbuf_prepend_realloc);
}