binbuf, strbuf and ustrbuf: add slice_get() and rw_slice_get().

This commit is contained in:
Gustavo Sverzut Barbieri 2016-08-12 18:55:37 -03:00
parent 77faebde67
commit 0d96ba9734
8 changed files with 243 additions and 4 deletions

View File

@ -150,6 +150,18 @@ EAPI void eina_binbuf_reset(Eina_Binbuf *buf) EINA_ARG_NONNULL(1);
*/ */
EAPI Eina_Bool eina_binbuf_append_length(Eina_Binbuf *buf, const unsigned char *str, size_t length) EINA_ARG_NONNULL(1, 2); EAPI Eina_Bool eina_binbuf_append_length(Eina_Binbuf *buf, const unsigned char *str, size_t length) EINA_ARG_NONNULL(1, 2);
/**
* @brief Append a slice to a buffer, reallocating as necessary.
*
* @param buf The string buffer to append to.
* @param slice The slice to append.
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
*
* This function appends @p slice to @p buf. If @p buf can't append
* it, #EINA_FALSE is returned, otherwise #EINA_TRUE is returned.
*/
EAPI Eina_Bool eina_binbuf_append_slice(Eina_Binbuf *buf, const Eina_Slice slice) EINA_ARG_NONNULL(1);
/** /**
* @brief Append an Eina_Binbuf to a buffer, reallocating as necessary. * @brief Append an Eina_Binbuf to a buffer, reallocating as necessary.
* *
@ -204,6 +216,20 @@ EAPI Eina_Bool eina_binbuf_append_char(Eina_Binbuf *buf, unsigned char c) EINA_A
*/ */
EAPI Eina_Bool eina_binbuf_insert_length(Eina_Binbuf *buf, const unsigned char *str, size_t length, size_t pos) EINA_ARG_NONNULL(1, 2); EAPI Eina_Bool eina_binbuf_insert_length(Eina_Binbuf *buf, const unsigned char *str, size_t length, size_t pos) EINA_ARG_NONNULL(1, 2);
/**
* @brief Insert a slice to a buffer, reallocating as necessary.
*
* @param buf The string buffer to insert to.
* @param slice The slice to insert.
* @param pos The position to insert the string.
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
*
* This function inserts @p slice to @p buf at position @p pos. If @p
* buf can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE
* is returned.
*/
EAPI Eina_Bool eina_binbuf_insert_slice(Eina_Binbuf *buf, const Eina_Slice slice, size_t pos) EINA_ARG_NONNULL(1);
/** /**
* @brief Insert a character to a string buffer, reallocating as * @brief Insert a character to a string buffer, reallocating as
* necessary. * necessary.
@ -286,6 +312,27 @@ EAPI void eina_binbuf_string_free(Eina_Binbuf *buf) EINA_ARG_NONNULL(1);
*/ */
EAPI size_t eina_binbuf_length_get(const Eina_Binbuf *buf) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; EAPI size_t eina_binbuf_length_get(const Eina_Binbuf *buf) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
/**
* @brief Get a read-only slice representing the current binbuf contents.
*
* @param buf the src buffer.
* @return a read-only slice for the current contents. It may become
* invalid as soon as the @a buf is changed.
*
* @since 1.19
*/
EAPI Eina_Slice eina_binbuf_slice_get(const Eina_Binbuf *buf) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @brief Get a read-write slice representing the current binbuf contents.
*
* @param buf the src buffer.
* @return a read-write slice for the current contents. It may become
* invalid as soon as the @a buf is changed with calls such as
* eina_binbuf_append(), eina_binbuf_remove()
*/
EAPI Eina_Rw_Slice eina_binbuf_rw_slice_get(const Eina_Binbuf *buf) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/** /**
* @} * @}
*/ */

View File

@ -107,6 +107,13 @@ _FUNC_EXPAND(append_length)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *s
return eina_strbuf_common_append_length(_STRBUF_CSIZE, buf, (const void *) str, length); return eina_strbuf_common_append_length(_STRBUF_CSIZE, buf, (const void *) str, length);
} }
EAPI Eina_Bool
_FUNC_EXPAND(append_slice)(_STRBUF_STRUCT_NAME *buf, const Eina_Slice slice)
{
EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE);
return eina_strbuf_common_append_length(_STRBUF_CSIZE, buf, slice.mem, slice.len);
}
EAPI Eina_Bool EAPI Eina_Bool
_FUNC_EXPAND(append_buffer)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_STRUCT_NAME *data) _FUNC_EXPAND(append_buffer)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_STRUCT_NAME *data)
{ {
@ -123,6 +130,13 @@ _FUNC_EXPAND(insert_length)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *s
return eina_strbuf_common_insert_length(_STRBUF_CSIZE, buf, (const void *) str, length, pos); return eina_strbuf_common_insert_length(_STRBUF_CSIZE, buf, (const void *) str, length, pos);
} }
EAPI Eina_Bool
_FUNC_EXPAND(insert_slice)(_STRBUF_STRUCT_NAME *buf, const Eina_Slice slice, size_t pos)
{
EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE);
return eina_strbuf_common_insert_length(_STRBUF_CSIZE, buf, slice.mem, slice.len, pos);
}
EAPI Eina_Bool EAPI Eina_Bool
_FUNC_EXPAND(append_char)(_STRBUF_STRUCT_NAME *buf, _STRBUF_DATA_TYPE c) _FUNC_EXPAND(append_char)(_STRBUF_STRUCT_NAME *buf, _STRBUF_DATA_TYPE c)
{ {
@ -171,3 +185,19 @@ _FUNC_EXPAND(length_get)(const _STRBUF_STRUCT_NAME *buf)
EINA_MAGIC_CHECK_STRBUF(buf, 0); EINA_MAGIC_CHECK_STRBUF(buf, 0);
return eina_strbuf_common_length_get(buf); return eina_strbuf_common_length_get(buf);
} }
EAPI Eina_Slice
_FUNC_EXPAND(slice_get)(const _STRBUF_STRUCT_NAME *buf)
{
Eina_Slice ret = {.len = 0, .mem = NULL};
EINA_MAGIC_CHECK_STRBUF(buf, ret);
return eina_strbuf_common_slice_get(buf);
}
EAPI Eina_Rw_Slice
_FUNC_EXPAND(rw_slice_get)(const _STRBUF_STRUCT_NAME *buf)
{
Eina_Rw_Slice ret = {.len = 0, .mem = NULL};
EINA_MAGIC_CHECK_STRBUF(buf, ret);
return eina_strbuf_common_rw_slice_get(buf);
}

View File

@ -5,6 +5,7 @@
#include <stdarg.h> #include <stdarg.h>
#include "eina_types.h" #include "eina_types.h"
#include "eina_slice.h"
/** /**
@ -225,6 +226,18 @@ EAPI Eina_Bool eina_strbuf_append_n(Eina_Strbuf *buf, const char *str, size_t ma
*/ */
EAPI Eina_Bool eina_strbuf_append_length(Eina_Strbuf *buf, const char *str, size_t length) EINA_ARG_NONNULL(1, 2); EAPI Eina_Bool eina_strbuf_append_length(Eina_Strbuf *buf, const char *str, size_t length) EINA_ARG_NONNULL(1, 2);
/**
* @brief Append a slice to a buffer, reallocating as necessary.
*
* @param buf The string buffer to append to.
* @param slice The slice to append.
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
*
* This function appends @p slice to @p buf. If @p buf can't append
* it, #EINA_FALSE is returned, otherwise #EINA_TRUE is returned.
*/
EAPI Eina_Bool eina_strbuf_append_slice(Eina_Strbuf *buf, const Eina_Slice slice) EINA_ARG_NONNULL(1);
/** /**
* @brief Append an Eina_Strbuf to a buffer, reallocating as necessary. * @brief Append an Eina_Strbuf to a buffer, reallocating as necessary.
* *
@ -357,6 +370,20 @@ EAPI Eina_Bool eina_strbuf_insert_n(Eina_Strbuf *buf, const char *str, size_t ma
*/ */
EAPI Eina_Bool eina_strbuf_insert_length(Eina_Strbuf *buf, const char *str, size_t length, size_t pos) EINA_ARG_NONNULL(1, 2); EAPI Eina_Bool eina_strbuf_insert_length(Eina_Strbuf *buf, const char *str, size_t length, size_t pos) EINA_ARG_NONNULL(1, 2);
/**
* @brief Insert a slice to a buffer, reallocating as necessary.
*
* @param buf The string buffer to insert to.
* @param slice The slice to insert.
* @param pos The position to insert the string.
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
*
* This function inserts @p slice to @p buf at position @p pos. If @p
* buf can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE
* is returned.
*/
EAPI Eina_Bool eina_strbuf_insert_slice(Eina_Strbuf *buf, const Eina_Slice slice, size_t pos) EINA_ARG_NONNULL(1);
/** /**
* @brief Insert a character to a string buffer, reallocating as * @brief Insert a character to a string buffer, reallocating as
* necessary. * necessary.
@ -670,6 +697,27 @@ EAPI void eina_strbuf_tolower(Eina_Strbuf *buf) EINA_ARG_NONNULL(1);
*/ */
EAPI Eina_Strbuf * eina_strbuf_substr_get(Eina_Strbuf *buf, size_t pos, size_t len) EINA_MALLOC EINA_WARN_UNUSED_RESULT; EAPI Eina_Strbuf * eina_strbuf_substr_get(Eina_Strbuf *buf, size_t pos, size_t len) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
/**
* @brief Get a read-only slice representing the current strbuf contents.
*
* @param buf the source string.
* @return a read-only slice for the current contents. It may become
* invalid as soon as the @a buf is changed.
*
* @since 1.19
*/
EAPI Eina_Slice eina_strbuf_slice_get(const Eina_Strbuf *buf) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @brief Get a read-write slice representing the current strbuf contents.
*
* @param buf the source string.
* @return a read-write slice for the current contents. It may become
* invalid as soon as the @a buf is changed with calls such as
* eina_strbuf_append(), eina_strbuf_remove()
*/
EAPI Eina_Rw_Slice eina_strbuf_rw_slice_get(const Eina_Strbuf *buf) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/** /**
* @} * @}
*/ */

View File

@ -787,6 +787,40 @@ eina_strbuf_common_length_get(const Eina_Strbuf *buf)
return buf->len; return buf->len;
} }
/**
* @internal
* @brief Get a read-only slice representing the current strbuf contents.
*
* @param buf The string buffer.
* @return The current memory read-only slice of the string, in bytes,
* without the trailing null byte.
*/
Eina_Slice
eina_strbuf_common_slice_get(const Eina_Strbuf *buf)
{
Eina_Slice ret;
ret.len = buf->len;
ret.mem = buf->buf;
return ret;
}
/**
* @internal
* @brief Get a read-write slice representing the current strbuf contents.
*
* @param buf The string buffer.
* @return The current memory read-write slice of the string, in
* bytes, without the trailing null byte.
*/
Eina_Rw_Slice
eina_strbuf_common_rw_slice_get(const Eina_Strbuf *buf)
{
Eina_Rw_Slice ret;
ret.len = buf->len;
ret.mem = buf->buf;
return ret;
}
/** /**
* @cond LOCAL * @cond LOCAL
*/ */

View File

@ -117,6 +117,11 @@ void
eina_strbuf_common_string_free(size_t csize, Eina_Strbuf *buf); eina_strbuf_common_string_free(size_t csize, Eina_Strbuf *buf);
size_t size_t
eina_strbuf_common_length_get(const Eina_Strbuf *buf); eina_strbuf_common_length_get(const Eina_Strbuf *buf);
Eina_Slice
eina_strbuf_common_slice_get(const Eina_Strbuf *buf);
Eina_Rw_Slice
eina_strbuf_common_rw_slice_get(const Eina_Strbuf *buf);
Eina_Bool Eina_Bool
_eina_strbuf_common_grow(size_t csize, Eina_Strbuf *buf, size_t size); _eina_strbuf_common_grow(size_t csize, Eina_Strbuf *buf, size_t size);

View File

@ -177,6 +177,18 @@ EAPI Eina_Bool eina_ustrbuf_append_n(Eina_UStrbuf *buf, const Eina_Unicode *str,
*/ */
EAPI Eina_Bool eina_ustrbuf_append_length(Eina_UStrbuf *buf, const Eina_Unicode *str, size_t length) EINA_ARG_NONNULL(1, 2); EAPI Eina_Bool eina_ustrbuf_append_length(Eina_UStrbuf *buf, const Eina_Unicode *str, size_t length) EINA_ARG_NONNULL(1, 2);
/**
* @brief Append a slice to a buffer, reallocating as necessary.
*
* @param buf The string buffer to append to.
* @param slice The slice to append.
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
*
* This function appends @p slice to @p buf. If @p buf can't append
* it, #EINA_FALSE is returned, otherwise #EINA_TRUE is returned.
*/
EAPI Eina_Bool eina_ustrbuf_append_slice(Eina_UStrbuf *buf, const Eina_Slice slice) EINA_ARG_NONNULL(1);
/** /**
* @brief Append a character to a string buffer, reallocating as * @brief Append a character to a string buffer, reallocating as
* necessary. * necessary.
@ -263,6 +275,20 @@ EAPI Eina_Bool eina_ustrbuf_insert_n(Eina_UStrbuf *buf, const Eina_Unicode *str,
*/ */
EAPI Eina_Bool eina_ustrbuf_insert_length(Eina_UStrbuf *buf, const Eina_Unicode *str, size_t length, size_t pos) EINA_ARG_NONNULL(1, 2); EAPI Eina_Bool eina_ustrbuf_insert_length(Eina_UStrbuf *buf, const Eina_Unicode *str, size_t length, size_t pos) EINA_ARG_NONNULL(1, 2);
/**
* @brief Insert a slice to a buffer, reallocating as necessary.
*
* @param buf The string buffer to insert to.
* @param slice The slice to insert.
* @param pos The position to insert the string.
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
*
* This function inserts @p slice to @p buf at position @p pos. If @p
* buf can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE
* is returned.
*/
EAPI Eina_Bool eina_ustrbuf_insert_slice(Eina_UStrbuf *buf, const Eina_Slice slice, size_t pos) EINA_ARG_NONNULL(1);
/** /**
* @brief Insert a character to a string buffer, reallocating as * @brief Insert a character to a string buffer, reallocating as
* necessary. * necessary.
@ -421,6 +447,27 @@ eina_ustrbuf_string_free(Eina_UStrbuf *buf) EINA_ARG_NONNULL(1);
EAPI size_t EAPI size_t
eina_ustrbuf_length_get(const Eina_UStrbuf *buf) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; eina_ustrbuf_length_get(const Eina_UStrbuf *buf) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
/**
* @brief Get a read-only slice representing the current ustrbuf contents.
*
* @param buf the source string.
* @return a read-only slice for the current contents. It may become
* invalid as soon as the @a buf is changed.
*
* @since 1.19
*/
EAPI Eina_Slice eina_ustrbuf_slice_get(const Eina_UStrbuf *buf) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @brief Get a read-write slice representing the current ustrbuf contents.
*
* @param buf the source string.
* @return a read-write slice for the current contents. It may become
* invalid as soon as the @a buf is changed with calls such as
* eina_ustrbuf_append(), eina_ustrbuf_remove()
*/
EAPI Eina_Rw_Slice eina_ustrbuf_rw_slice_get(const Eina_UStrbuf *buf) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/** /**
* @} * @}
*/ */

View File

@ -31,7 +31,8 @@ START_TEST(binbuf_simple)
unsigned char *txt; unsigned char *txt;
const unsigned char cbuf[] = "Null in the middle \0 and more text afterwards and \0 anotehr null just there and another one \0 here."; const unsigned char cbuf[] = "Null in the middle \0 and more text afterwards and \0 anotehr null just there and another one \0 here.";
size_t size = sizeof(cbuf) - 1; /* We don't care about the real NULL */ size_t size = sizeof(cbuf) - 1; /* We don't care about the real NULL */
Eina_Slice ro_slice;
Eina_Rw_Slice rw_slice;
eina_init(); eina_init();
@ -42,13 +43,24 @@ START_TEST(binbuf_simple)
fail_if(memcmp(eina_binbuf_string_get(buf), cbuf, size)); fail_if(memcmp(eina_binbuf_string_get(buf), cbuf, size));
fail_if(size != eina_binbuf_length_get(buf)); fail_if(size != eina_binbuf_length_get(buf));
ro_slice = eina_binbuf_slice_get(buf);
fail_if(ro_slice.len != size);
fail_if(ro_slice.mem != eina_binbuf_string_get(buf));
rw_slice = eina_binbuf_rw_slice_get(buf);
fail_if(rw_slice.len != size);
fail_if(rw_slice.mem != eina_binbuf_string_get(buf));
test_buf = eina_binbuf_new(); test_buf = eina_binbuf_new();
fail_if(!test_buf); fail_if(!test_buf);
fail_if(!eina_binbuf_append_buffer(test_buf, buf)); fail_if(!eina_binbuf_append_buffer(test_buf, buf));
fail_if(memcmp(eina_binbuf_string_get(test_buf), cbuf, size)); fail_if(memcmp(eina_binbuf_string_get(test_buf), cbuf, size));
fail_if(size != eina_binbuf_length_get(test_buf)); fail_if(size != eina_binbuf_length_get(test_buf));
eina_binbuf_append_length(buf, cbuf, size); ro_slice.mem = cbuf;
ro_slice.len = size;
eina_binbuf_append_slice(buf, ro_slice);
fail_if(memcmp(eina_binbuf_string_get(buf), cbuf, size)); fail_if(memcmp(eina_binbuf_string_get(buf), cbuf, size));
fail_if(memcmp(eina_binbuf_string_get(buf) + size, cbuf, size)); fail_if(memcmp(eina_binbuf_string_get(buf) + size, cbuf, size));
fail_if(2 * size != eina_binbuf_length_get(buf)); fail_if(2 * size != eina_binbuf_length_get(buf));

View File

@ -30,6 +30,8 @@ START_TEST(strbuf_simple)
{ {
Eina_Strbuf *buf; Eina_Strbuf *buf;
char *txt; char *txt;
Eina_Slice ro_slice;
Eina_Rw_Slice rw_slice;
#define TEST_TEXT \ #define TEST_TEXT \
"This test should be so long that it is longer than the initial size of strbuf" "This test should be so long that it is longer than the initial size of strbuf"
@ -57,6 +59,14 @@ START_TEST(strbuf_simple)
fail_if(eina_strbuf_length_get(buf) != 0); fail_if(eina_strbuf_length_get(buf) != 0);
fail_if(!strcmp(eina_strbuf_string_get(buf), TEST_TEXT)); fail_if(!strcmp(eina_strbuf_string_get(buf), TEST_TEXT));
ro_slice = eina_strbuf_slice_get(buf);
fail_if(ro_slice.len != eina_strbuf_length_get(buf));
fail_if(ro_slice.mem != eina_strbuf_string_get(buf));
rw_slice = eina_strbuf_rw_slice_get(buf);
fail_if(rw_slice.len != eina_strbuf_length_get(buf));
fail_if(rw_slice.mem != eina_strbuf_string_get(buf));
eina_strbuf_string_free(buf); eina_strbuf_string_free(buf);
fail_if(eina_strbuf_length_get(buf)); fail_if(eina_strbuf_length_get(buf));
eina_strbuf_append(buf, TEST_TEXT); eina_strbuf_append(buf, TEST_TEXT);
@ -168,6 +178,9 @@ END_TEST
START_TEST(strbuf_append) START_TEST(strbuf_append)
{ {
Eina_Strbuf *buf; Eina_Strbuf *buf;
Eina_Slice ro_slice = EINA_SLICE_STR_LITERAL("somethingELSE");
ro_slice.len -= strlen("ELSE");
eina_init(); eina_init();
@ -204,7 +217,7 @@ START_TEST(strbuf_append)
fail_if(strcmp(eina_strbuf_string_get(buf), "something")); fail_if(strcmp(eina_strbuf_string_get(buf), "something"));
eina_strbuf_reset(buf); eina_strbuf_reset(buf);
eina_strbuf_append_length(buf, "somethingELSE", strlen("something")); eina_strbuf_append_slice(buf, ro_slice);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf)); fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "something")); fail_if(strcmp(eina_strbuf_string_get(buf), "something"));
eina_strbuf_reset(buf); eina_strbuf_reset(buf);
@ -218,6 +231,9 @@ END_TEST
START_TEST(strbuf_insert) START_TEST(strbuf_insert)
{ {
Eina_Strbuf *buf; Eina_Strbuf *buf;
Eina_Slice ro_slice = EINA_SLICE_STR_LITERAL("EINA");
ro_slice.len = 2;
eina_init(); eina_init();
@ -244,7 +260,7 @@ START_TEST(strbuf_insert)
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf)); fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "1ABxyz23abcxyz")); fail_if(strcmp(eina_strbuf_string_get(buf), "1ABxyz23abcxyz"));
eina_strbuf_insert_n(buf, "EINA", 2, 3); eina_strbuf_insert_slice(buf, ro_slice, 3);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf)); fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "1ABEIxyz23abcxyz")); fail_if(strcmp(eina_strbuf_string_get(buf), "1ABEIxyz23abcxyz"));