diff --git a/legacy/eina/src/include/Eina.h b/legacy/eina/src/include/Eina.h index 2cc7f5da37..f44d1840fc 100644 --- a/legacy/eina/src/include/Eina.h +++ b/legacy/eina/src/include/Eina.h @@ -152,6 +152,7 @@ extern "C" { #include "eina_matrixsparse.h" #include "eina_str.h" #include "eina_strbuf.h" +#include "eina_ustrbuf.h" #include "eina_unicode.h" #include "eina_quadtree.h" diff --git a/legacy/eina/src/include/Makefile.am b/legacy/eina/src/include/Makefile.am index 52eed111f4..ee8ce46d6e 100644 --- a/legacy/eina/src/include/Makefile.am +++ b/legacy/eina/src/include/Makefile.am @@ -49,6 +49,7 @@ eina_inline_tiler.x \ eina_str.h \ eina_inline_str.x \ eina_strbuf.h \ +eina_ustrbuf.h \ eina_unicode.h \ eina_quadtree.h diff --git a/legacy/eina/src/include/eina_strbuf.h b/legacy/eina/src/include/eina_strbuf.h index 07c2741c43..d425fd5048 100644 --- a/legacy/eina/src/include/eina_strbuf.h +++ b/legacy/eina/src/include/eina_strbuf.h @@ -2,6 +2,7 @@ #define EINA_STRBUF_H #include +#include #include "eina_types.h" @@ -10,37 +11,258 @@ * * @{ */ - /** - * @defgroup Eina_String_Buffer_Group String Buffer + * @addtogroup Eina_String_Buffer_Group String Buffer + * + * @brief These functions provide string buffers management. + * + * The String Buffer data type is designed to be a mutable string, + * allowing to append, prepend or insert a string to a buffer. * * @{ */ - /** * @typedef Eina_Strbuf * Type for a string buffer. */ typedef struct _Eina_Strbuf Eina_Strbuf; +/** + * @brief Create a new string buffer. + * + * @return Newly allocated string buffer instance. + * + * This function creates a new string buffer. On error, @c NULL is + * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To + * free the resources, use eina_strbuf_free(). + * + * @see eina_strbuf_free() + * @see eina_strbuf_append() + * @see eina_strbuf_string_get() + */ EAPI Eina_Strbuf *eina_strbuf_new(void) EINA_MALLOC EINA_WARN_UNUSED_RESULT; +/** + * @brief Free a string buffer. + * + * @param buf The string buffer to free. + * + * This function frees the memory of @p buf. @p buf must have been + * created by eina_strbuf_new(). + */ EAPI void eina_strbuf_free(Eina_Strbuf *buf) EINA_ARG_NONNULL(1); +/** + * @brief Reset a string buffer. + * + * @param buf The string buffer to reset. + * + * This function reset @p buf: the buffer len is set to 0, and the + * string is set to '\\0'. No memory is free'd. + */ EAPI void eina_strbuf_reset(Eina_Strbuf *buf) EINA_ARG_NONNULL(1); +/** + * @brief Append a string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends @p str to @p buf. It computes the length of + * @p str, so is slightly slower than eina_strbuf_append_length(). If + * the length is known beforehand, consider using that variant. If + * @p buf can't append it, #EINA_FALSE is returned, otherwise + * #EINA_TRUE is returned. + * + * @see eina_strbuf_append() + * @see eina_strbuf_append_length() + */ EAPI Eina_Bool eina_strbuf_append(Eina_Strbuf *buf, const char *str) EINA_ARG_NONNULL(1, 2); +/** + * @brief Append an escaped string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends the escaped string @p str to @p buf. If @p + * str can not be appended, #EINA_FALSE is returned, otherwise, + * #EINA_TRUE is returned. + */ EAPI Eina_Bool eina_strbuf_append_escaped(Eina_Strbuf *buf, const char *str) EINA_ARG_NONNULL(1, 2); +/** + * @brief Append a string to a buffer, reallocating as necessary, + * limited by the given length. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @param maxlen The maximum number of characters to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends at most @p maxlen characters of @p str to + * @p buf. It can't appends more than the length of @p str. It + * computes the length of @p str, so is slightly slower than + * eina_strbuf_append_length(). If the length is known beforehand, + * consider using that variant (@p maxlen should then be checked so + * that it is greater than the size of @p str). If @p str can not be + * appended, #EINA_FALSE is returned, otherwise, #EINA_TRUE is + * returned. + * + * @see eina_strbuf_append() + * @see eina_strbuf_append_length() + */ EAPI Eina_Bool eina_strbuf_append_n(Eina_Strbuf *buf, const char *str, size_t maxlen) EINA_ARG_NONNULL(1, 2); +/** + * @brief Append a string of exact length to a buffer, reallocating as necessary. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @param length The exact length to use. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends @p str to @p buf. @p str must be of size at + * most @p length. It is slightly faster than eina_strbuf_append() as + * it does not compute the size of @p str. It is useful when dealing + * with strings of known size, such as eina_strngshare. If @p buf + * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + * + * @see eina_stringshare_length() + * @see eina_strbuf_append() + * @see eina_strbuf_append_n() + */ EAPI Eina_Bool eina_strbuf_append_length(Eina_Strbuf *buf, const char *str, size_t length) EINA_ARG_NONNULL(1, 2); +/** + * @brief Append a character to a string buffer, reallocating as + * necessary. + * + * @param buf The string buffer to append to. + * @param c The char to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p c to @p buf. If it can not insert it, + * #EINA_FALSE is returned, otherwise #EINA_TRUE is returned. + */ EAPI Eina_Bool eina_strbuf_append_char(Eina_Strbuf *buf, char c) EINA_ARG_NONNULL(1); +/** + * @brief Append a string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to append to. + * @param fmt The string to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * @see eina_strbuf_append() + */ EAPI Eina_Bool eina_strbuf_append_printf(Eina_Strbuf *buf, const char *fmt, ...) EINA_ARG_NONNULL(1, 2) EINA_PRINTF(2, 3); +/** + * @brief Append a string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to append to. + * @param fmt The string to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * @see eina_strbuf_append() + */ EAPI Eina_Bool eina_strbuf_append_vprintf(Eina_Strbuf *buf, const char *fmt, va_list args) EINA_ARG_NONNULL(1, 2); - +/** + * @brief Insert a string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to insert. + * @param str The string to insert. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p str to @p buf at position @p pos. It + * computes the length of @p str, so is slightly slower than + * eina_strbuf_insert_length(). If the length is known beforehand, + * consider using that variant. If @p buf can't insert it, #EINA_FALSE + * is returned, otherwise #EINA_TRUE is returned. + */ EAPI Eina_Bool eina_strbuf_insert(Eina_Strbuf *buf, const char *str, size_t pos) EINA_ARG_NONNULL(1, 2); +/** + * @brief Insert an escaped string to a buffer, reallocating as + * necessary. + * + * @param buf The string buffer to insert to. + * @param str The string to insert. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts the escaped string @p str to @p buf at + * position @p pos. If @p buf can't insert @p str, #EINA_FALSE is + * returned, otherwise #EINA_TRUE is returned. + */ EAPI Eina_Bool eina_strbuf_insert_escaped(Eina_Strbuf *buf, const char *str, size_t pos) EINA_ARG_NONNULL(1, 2); +/** + * @brief Insert a string to a buffer, reallocating as necessary. Limited by maxlen. + * + * @param buf The string buffer to insert to. + * @param str The string to insert. + * @param maxlen The maximum number of chars to insert. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p str ot @p buf at position @p pos, with at + * most @p maxlen bytes. The number of inserted characters can not be + * greater than the length of @p str. It computes the length of + * @p str, so is slightly slower than eina_strbuf_insert_length(). If the + * length is known beforehand, consider using that variant (@p maxlen + * should then be checked so that it is greater than the size of + * @p str). If @p str can not be inserted, #EINA_FALSE is returned, + * otherwise, #EINA_TRUE is returned. + */ EAPI Eina_Bool eina_strbuf_insert_n(Eina_Strbuf *buf, const char *str, size_t maxlen, size_t pos) EINA_ARG_NONNULL(1, 2); +/** + * @brief Insert a string of exact length to a buffer, reallocating as necessary. + * + * @param buf The string buffer to insert to. + * @param str The string to insert. + * @param length The exact length to use. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p str to @p buf. @p str must be of size at + * most @p length. It is slightly faster than eina_strbuf_insert() as + * it does not compute the size of @p str. It is useful when dealing + * with strings of known size, such as eina_strngshare. If @p buf + * can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + * + * @see eina_stringshare_length() + * @see eina_strbuf_insert() + * @see eina_strbuf_insert_n() + */ 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 character to a string buffer, reallocating as + * necessary. + * + * @param buf The string buffer to insert to. + * @param c The char to insert. + * @param pos The position to insert the char. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p c to @p buf at position @p pos. If @p buf + * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + */ EAPI Eina_Bool eina_strbuf_insert_char(Eina_Strbuf *buf, char c, size_t pos) EINA_ARG_NONNULL(1); +/** + * @brief Insert a string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to insert. + * @param fmt The string to insert. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + */ EAPI Eina_Bool eina_strbuf_insert_printf(Eina_Strbuf *buf, const char *fmt, size_t pos, ...) EINA_ARG_NONNULL(1, 2) EINA_PRINTF(2, 4); +/** + * @brief Insert a string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to insert. + * @param fmt The string to insert. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + */ EAPI Eina_Bool eina_strbuf_insert_vprintf(Eina_Strbuf *buf, const char *fmt, size_t pos, va_list args) EINA_ARG_NONNULL(1, 2); /** @@ -143,11 +365,67 @@ EAPI Eina_Bool eina_strbuf_insert_vprintf(Eina_Strbuf *buf, const char *fmt, siz */ #define eina_strbuf_prepend_vprintf(buf, fmt, args) eina_strbuf_insert_vprintf(buf, fmt, 0, args) +/** + * @brief Remove a slice of the given string buffer. + * + * @param buf The string buffer to remove a slice. + * @param start The initial (inclusive) slice position to start + * removing, in bytes. + * @param end The final (non-inclusive) slice position to finish + * removing, in bytes. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function removes a slice of @p buf, starting at @p start + * (inclusive) and ending at @p end (non-inclusive). Both values are + * in bytes. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. + */ EAPI Eina_Bool eina_strbuf_remove(Eina_Strbuf *buf, size_t start, size_t end) EINA_ARG_NONNULL(1); +/** + * @brief Retrieve a pointer to the contents of a string buffer + * + * @param buf The string buffer. + * @return The current string in the string buffer. + * + * This function returns the string contained in @p buf. The returned + * value must not be modified and will no longer be valid if @p buf is + * modified. In other words, any eina_strbuf_append() or similar will + * make that pointer invalid. + * + * @see eina_strbuf_string_steal() + */ EAPI const char *eina_strbuf_string_get(const Eina_Strbuf *buf) EINA_ARG_NONNULL(1); +/** + * @brief Steal the contents of a string buffer. + * + * @param buf The string buffer to steal. + * @return The current string in the string buffer. + * + * This function returns the string contained in @p buf. @p buf is + * then initialized and does not own the returned string anymore. The + * caller must release the memory of the returned string by calling + * free(). + * + * @see eina_strbuf_string_get() + */ EAPI char *eina_strbuf_string_steal(Eina_Strbuf *buf) EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); +/** + * @brief Free the contents of a string buffer but not the buffer. + * + * @param buf The string buffer to free the string of. + * + * This function frees the string contained in @p buf without freeing + * @p buf. + */ EAPI void eina_strbuf_string_free(Eina_Strbuf *buf) EINA_ARG_NONNULL(1); +/** + * @brief Retrieve the length of the string buffer content. + * + * @param buf The string buffer. + * @return The current length of the string, in bytes. + * + * This function returns the length of @p buf. + */ EAPI size_t eina_strbuf_length_get(const Eina_Strbuf *buf) EINA_ARG_NONNULL(1); EAPI Eina_Bool eina_strbuf_replace(Eina_Strbuf *buf, const char *str, const char *with, unsigned int n) EINA_ARG_NONNULL(1, 2, 3); @@ -171,9 +449,7 @@ EAPI int eina_strbuf_replace_all(Eina_Strbuf *buf, const char *str, const char * /** * @} */ - /** * @} */ - #endif /* EINA_STRBUF_H */ diff --git a/legacy/eina/src/include/eina_ustrbuf.h b/legacy/eina/src/include/eina_ustrbuf.h new file mode 100644 index 0000000000..c5f16bdd39 --- /dev/null +++ b/legacy/eina/src/include/eina_ustrbuf.h @@ -0,0 +1,401 @@ +#ifndef EINA_USTRBUF_H +#define EINA_USTRBUF_H + +#include + +#include "eina_types.h" +#include "eina_unicode.h" + +/** + * @addtogroup Eina_Data_Types_Group Data Types + * + * @{ + */ +/** + * @addtogroup Eina_Unicode_String_Buffer_Group Unicode String Buffer + * + * @brief These functions provide unicode string buffers management. + * + * The Unicode String Buffer data type is designed to be a mutable string, + * allowing to append, prepend or insert a string to a buffer. + * + * @{ + */ + +/** + * @typedef Eina_UStrbuf + * Type for a string buffer. + */ +typedef struct _Eina_Strbuf Eina_UStrbuf; + +/** + * @brief Create a new string buffer. + * + * @return Newly allocated string buffer instance. + * + * This function creates a new string buffer. On error, @c NULL is + * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To + * free the resources, use eina_ustrbuf_free(). + * + * @see eina_ustrbuf_free() + * @see eina_ustrbuf_append() + * @see eina_ustrbuf_string_get() + */ +EAPI Eina_UStrbuf *eina_ustrbuf_new(void) EINA_MALLOC EINA_WARN_UNUSED_RESULT; + +/** + * @brief Free a string buffer. + * + * @param buf The string buffer to free. + * + * This function frees the memory of @p buf. @p buf must have been + * created by eina_ustrbuf_new(). + */ +EAPI void eina_ustrbuf_free(Eina_UStrbuf *buf) EINA_ARG_NONNULL(1); +/** + * @brief Reset a string buffer. + * + * @param buf The string buffer to reset. + * + * This function reset @p buf: the buffer len is set to 0, and the + * string is set to '\\0'. No memory is free'd. + */ +EAPI void eina_ustrbuf_reset(Eina_UStrbuf *buf) EINA_ARG_NONNULL(1); + +/** + * @brief Append a string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends @p str to @p buf. It computes the length of + * @p str, so is slightly slower than eina_ustrbuf_append_length(). If + * the length is known beforehand, consider using that variant. If + * @p buf can't append it, #EINA_FALSE is returned, otherwise + * #EINA_TRUE is returned. + * + * @see eina_ustrbuf_append() + * @see eina_ustrbuf_append_length() + */ +EAPI Eina_Bool eina_ustrbuf_append(Eina_UStrbuf *buf, const Eina_Unicode *str) EINA_ARG_NONNULL(1, 2); +/** + * @brief Append an escaped string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends the escaped string @p str to @p buf. If @p + * str can not be appended, #EINA_FALSE is returned, otherwise, + * #EINA_TRUE is returned. + */ +EAPI Eina_Bool eina_ustrbuf_append_escaped(Eina_UStrbuf *buf, const Eina_Unicode *str) EINA_ARG_NONNULL(1, 2); +/** + * @brief Append a string to a buffer, reallocating as necessary, + * limited by the given length. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @param maxlen The maximum number of characters to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends at most @p maxlen characters of @p str to + * @p buf. It can't appends more than the length of @p str. It + * computes the length of @p str, so is slightly slower than + * eina_ustrbuf_append_length(). If the length is known beforehand, + * consider using that variant (@p maxlen should then be checked so + * that it is greater than the size of @p str). If @p str can not be + * appended, #EINA_FALSE is returned, otherwise, #EINA_TRUE is + * returned. + * + * @see eina_ustrbuf_append() + * @see eina_ustrbuf_append_length() + */ +EAPI Eina_Bool eina_ustrbuf_append_n(Eina_UStrbuf *buf, const Eina_Unicode *str, size_t maxlen) EINA_ARG_NONNULL(1, 2); +/** + * @brief Append a string of exact length to a buffer, reallocating as necessary. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @param length The exact length to use. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends @p str to @p buf. @p str must be of size at + * most @p length. It is slightly faster than eina_ustrbuf_append() as + * it does not compute the size of @p str. It is useful when dealing + * with strings of known size, such as eina_strngshare. If @p buf + * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + * + * @see eina_stringshare_length() + * @see eina_ustrbuf_append() + * @see eina_ustrbuf_append_n() + */ +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 character to a string buffer, reallocating as + * necessary. + * + * @param buf The string buffer to append to. + * @param c The char to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p c to @p buf. If it can not insert it, + * #EINA_FALSE is returned, otherwise #EINA_TRUE is returned. + */ +EAPI Eina_Bool eina_ustrbuf_append_char(Eina_UStrbuf *buf, Eina_Unicode c) EINA_ARG_NONNULL(1); + +/** + * @brief Insert a string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to insert. + * @param str The string to insert. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p str to @p buf at position @p pos. It + * computes the length of @p str, so is slightly slower than + * eina_ustrbuf_insert_length(). If the length is known beforehand, + * consider using that variant. If @p buf can't insert it, #EINA_FALSE + * is returned, otherwise #EINA_TRUE is returned. + */ +EAPI Eina_Bool eina_ustrbuf_insert(Eina_UStrbuf *buf, const Eina_Unicode *str, size_t pos) EINA_ARG_NONNULL(1, 2); +/** + * @brief Insert an escaped string to a buffer, reallocating as + * necessary. + * + * @param buf The string buffer to insert to. + * @param str The string to insert. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts the escaped string @p str to @p buf at + * position @p pos. If @p buf can't insert @p str, #EINA_FALSE is + * returned, otherwise #EINA_TRUE is returned. + */ +EAPI Eina_Bool eina_ustrbuf_insert_escaped(Eina_UStrbuf *buf, const Eina_Unicode *str, size_t pos) EINA_ARG_NONNULL(1, 2); +/** + * @brief Insert a string to a buffer, reallocating as necessary. Limited by maxlen. + * + * @param buf The string buffer to insert to. + * @param str The string to insert. + * @param maxlen The maximum number of chars to insert. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p str ot @p buf at position @p pos, with at + * most @p maxlen bytes. The number of inserted characters can not be + * greater than the length of @p str. It computes the length of + * @p str, so is slightly slower than eina_ustrbuf_insert_length(). If the + * length is known beforehand, consider using that variant (@p maxlen + * should then be checked so that it is greater than the size of + * @p str). If @p str can not be inserted, #EINA_FALSE is returned, + * otherwise, #EINA_TRUE is returned. + */ +EAPI Eina_Bool eina_ustrbuf_insert_n(Eina_UStrbuf *buf, const Eina_Unicode *str, size_t maxlen, size_t pos) EINA_ARG_NONNULL(1, 2); +/** + * @brief Insert a string of exact length to a buffer, reallocating as necessary. + * + * @param buf The string buffer to insert to. + * @param str The string to insert. + * @param length The exact length to use. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p str to @p buf. @p str must be of size at + * most @p length. It is slightly faster than eina_ustrbuf_insert() as + * it does not compute the size of @p str. It is useful when dealing + * with strings of known size, such as eina_strngshare. If @p buf + * can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + * + * @see eina_stringshare_length() + * @see eina_ustrbuf_insert() + * @see eina_ustrbuf_insert_n() + */ +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 character to a string buffer, reallocating as + * necessary. + * + * @param buf The string buffer to insert to. + * @param c The char to insert. + * @param pos The position to insert the char. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p c to @p buf at position @p pos. If @p buf + * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + */ +EAPI Eina_Bool eina_ustrbuf_insert_char(Eina_UStrbuf *buf, Eina_Unicode c, size_t pos) EINA_ARG_NONNULL(1); + +/** + * @def eina_ustrbuf_prepend(buf, str) + * @brief Prepend the given string to the given buffer + * + * @param buf The string buffer to prepend to. + * @param str The string to prepend. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This macro is calling eina_ustrbuf_insert() at position 0.If @p buf + * can't prepend it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + */ +#define eina_ustrbuf_prepend(buf, str) eina_ustrbuf_insert(buf, str, 0) + +/** + * @def eina_ustrbuf_prepend_escaped(buf, str) + * @brief Prepend the given escaped string to the given buffer + * + * @param buf The string buffer to prepend to. + * @param str The string to prepend. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This macro is calling eina_ustrbuf_insert_escaped() at position 0. If + * @p buf can't prepend it, #EINA_FALSE is returned, otherwise + * #EINA_TRUE is returned. + */ +#define eina_ustrbuf_prepend_escaped(buf, str) eina_ustrbuf_insert_escaped(buf, str, 0) + +/** + * @def eina_ustrbuf_prepend_n(buf, str) + * @brief Prepend the given escaped string to the given buffer + * + * @param buf The string buffer to prepend to. + * @param str The string to prepend. + * @param maxlen The maximum number of Eina_Unicode *s to prepend. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This macro is calling eina_ustrbuf_insert_n() at position 0. If + * @p buf can't prepend it, #EINA_FALSE is returned, otherwise + * #EINA_TRUE is returned. + */ +#define eina_ustrbuf_prepend_n(buf, str, maxlen) eina_ustrbuf_insert_n(buf, str, maxlen, 0) + +/** + * @def eina_ustrbuf_prepend_length(buf, str) + * @brief Prepend the given escaped string to the given buffer + * + * @param buf The string buffer to prepend to. + * @param str The string to prepend. + * @param length The exact length to use. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This macro is calling eina_ustrbuf_insert_length() at position 0. If + * @p buf can't prepend it, #EINA_FALSE is returned, otherwise + * #EINA_TRUE is returned. + */ +#define eina_ustrbuf_prepend_length(buf, str, length) eina_ustrbuf_insert_length(buf, str, length, 0) + +/** + * @def eina_ustrbuf_prepend_Eina_Unicode *(buf, str) + * @brief Prepend the given Eina_Unicode *acter to the given buffer + * + * @param buf The string buffer to prepend to. + * @param c The Eina_Unicode *acter to prepend. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This macro is calling eina_ustrbuf_insert_Eina_Unicode *() at position 0. If + * @p buf can't prepend it, #EINA_FALSE is returned, otherwise + * #EINA_TRUE is returned. + */ +#define eina_ustrbuf_prepend_Eina_Unicode *(buf, c) eina_ustrbuf_insert_Eina_Unicode *(buf, c, 0) + +/** + * @def eina_ustrbuf_prepend_printf(buf, fmt, ...) + * @brief Prepend the given string to the given buffer + * + * @param buf The string buffer to prepend to. + * @param str The string to prepend. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This macro is calling eina_ustrbuf_insert_printf() at position 0.If @p buf + * can't prepend it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + */ +#define eina_ustrbuf_prepend_printf(buf, fmt, ...) eina_ustrbuf_insert_printf(buf, fmt, 0, ##__VA_ARGS__) + +/** + * @def eina_ustrbuf_prepend_vprintf(buf, fmt, args) + * @brief Prepend the given string to the given buffer + * + * @param buf The string buffer to prepend to. + * @param fmt The string to prepend. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This macro is calling eina_ustrbuf_insert_vprintf() at position 0.If @p buf + * can't prepend it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + */ +#define eina_ustrbuf_prepend_vprintf(buf, fmt, args) eina_ustrbuf_insert_vprintf(buf, fmt, 0, args) + +/** + * @brief Remove a slice of the given string buffer. + * + * @param buf The string buffer to remove a slice. + * @param start The initial (inclusive) slice position to start + * removing, in bytes. + * @param end The final (non-inclusive) slice position to finish + * removing, in bytes. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function removes a slice of @p buf, starting at @p start + * (inclusive) and ending at @p end (non-inclusive). Both values are + * in bytes. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. + */ +EAPI Eina_Bool eina_ustrbuf_remove(Eina_UStrbuf *buf, size_t start, size_t end) EINA_ARG_NONNULL(1); +/** + * @brief Retrieve a pointer to the contents of a string buffer + * + * @param buf The string buffer. + * @return The current string in the string buffer. + * + * This function returns the string contained in @p buf. The returned + * value must not be modified and will no longer be valid if @p buf is + * modified. In other words, any eina_ustrbuf_append() or similar will + * make that pointer invalid. + * + * @see eina_ustrbuf_string_steal() + */ +EAPI const Eina_Unicode *eina_ustrbuf_string_get(const Eina_UStrbuf *buf) EINA_ARG_NONNULL(1); +/** + * @brief Steal the contents of a string buffer. + * + * @param buf The string buffer to steal. + * @return The current string in the string buffer. + * + * This function returns the string contained in @p buf. @p buf is + * then initialized and does not own the returned string anymore. The + * caller must release the memory of the returned string by calling + * free(). + * + * @see eina_ustrbuf_string_get() + */ +EAPI Eina_Unicode *eina_ustrbuf_string_steal(Eina_UStrbuf *buf) EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); +/** + * @brief Free the contents of a string buffer but not the buffer. + * + * @param buf The string buffer to free the string of. + * + * This function frees the string contained in @p buf without freeing + * @p buf. + */ +EAPI void eina_ustrbuf_string_free(Eina_UStrbuf *buf) EINA_ARG_NONNULL(1); +/** + * @brief Retrieve the length of the string buffer content. + * + * @param buf The string buffer. + * @return The current length of the string, in bytes. + * + * This function returns the length of @p buf. + */ +EAPI size_t eina_ustrbuf_length_get(const Eina_UStrbuf *buf) EINA_ARG_NONNULL(1); +/** + * @} + */ +/** + * @} + */ +#endif /* EINA_STRBUF_H */ diff --git a/legacy/eina/src/lib/Makefile.am b/legacy/eina/src/lib/Makefile.am index 740a3d471a..35519c6da5 100644 --- a/legacy/eina/src/lib/Makefile.am +++ b/legacy/eina/src/lib/Makefile.am @@ -42,6 +42,8 @@ eina_hamster.c \ eina_safety_checks.c \ eina_str.c \ eina_strbuf.c \ +eina_strbuf_common.c \ +eina_ustrbuf.c \ eina_unicode.c \ eina_quadtree.c diff --git a/legacy/eina/src/lib/eina_main.c b/legacy/eina/src/lib/eina_main.c index d1c62dce36..88949aeb38 100644 --- a/legacy/eina/src/lib/eina_main.c +++ b/legacy/eina/src/lib/eina_main.c @@ -118,6 +118,7 @@ S(counter); S(benchmark); S(rectangle); S(strbuf); +S(ustrbuf); S(quadtree); #undef S @@ -148,6 +149,7 @@ static const struct eina_desc_setup _eina_desc_setup[] = { S(benchmark), S(rectangle), S(strbuf), + S(ustrbuf), S(quadtree) #undef S }; diff --git a/legacy/eina/src/lib/eina_strbuf.c b/legacy/eina/src/lib/eina_strbuf.c index 8a900964c0..feafea4ca4 100644 --- a/legacy/eina/src/lib/eina_strbuf.c +++ b/legacy/eina/src/lib/eina_strbuf.c @@ -1,477 +1,26 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ +#define _STRBUF_DATA_TYPE char +#define _STRBUF_CSIZE sizeof(_STRBUF_DATA_TYPE) +#define _STRBUF_STRUCT_NAME Eina_Strbuf +#define _STRBUF_STRLEN_FUNC(x) strlen(x) +#define _STRBUF_STRESCAPE_FUNC(x) eina_str_escape(x) +#define _STRBUF_MAGIC EINA_MAGIC_STRBUF +static const char _STRBUF_MAGIC_STR[] = "Eina Strbuf"; + +#define _FUNC_EXPAND(y) eina_strbuf_##y #define _GNU_SOURCE - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include -#include -#include -#ifdef _WIN32 -# include -#endif -#include "eina_private.h" -#include "eina_str.h" -#include "eina_magic.h" -#include "eina_error.h" -#include "eina_safety_checks.h" #include "eina_strbuf.h" +#include "eina_strbuf_common.h" +#include "eina_unicode.h" +#include "eina_private.h" -/*============================================================================* - * Local * - *============================================================================*/ +#include "eina_strbuf_template_c.i" -/** - * @cond LOCAL - */ -static const char EINA_MAGIC_STRBUF_STR[] = "Eina Strbuf"; -#define EINA_MAGIC_CHECK_STRBUF(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK((d), EINA_MAGIC_STRBUF)) \ - { \ - EINA_MAGIC_FAIL((d), EINA_MAGIC_STRBUF); \ - return __VA_ARGS__; \ - } \ - } while (0) - -#define EINA_STRBUF_INIT_SIZE 32 -#define EINA_STRBUF_INIT_STEP 32 -#define EINA_STRBUF_MAX_STEP 4096 - -struct _Eina_Strbuf -{ - char *buf; - size_t len; - size_t size; - size_t step; - - EINA_MAGIC -}; - -/** - * @internal - * - * init the buffer - * @param buf the buffer to init - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ -static Eina_Bool -_eina_strbuf_init(Eina_Strbuf *buf) -{ - buf->len = 0; - buf->size = EINA_STRBUF_INIT_SIZE; - buf->step = EINA_STRBUF_INIT_STEP; - - eina_error_set(0); - buf->buf = malloc(buf->size); - if (EINA_UNLIKELY(!buf->buf)) - { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return EINA_FALSE; - } - buf->buf[0] = '\0'; - return EINA_TRUE; -} - -/** - * @internal - * - * resize the buffer - * @param buf the buffer to resize - * @param size the minimum size of the buffer - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ -static inline Eina_Bool -_eina_strbuf_resize(Eina_Strbuf *buf, size_t size) -{ - size_t new_size, new_step, delta; - char *buffer; - - size += 1; // Add extra space for '\0' - - if (size == buf->size) - /* nothing to do */ - return EINA_TRUE; - else if (size > buf->size) - 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 - { - 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 */ - buffer = realloc(buf->buf, new_size); - if (EINA_UNLIKELY(!buffer)) - { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return EINA_FALSE; - } - - buf->buf = buffer; - buf->size = new_size; - buf->step = new_step; - eina_error_set(0); - return EINA_TRUE; -} - -/** - * @internal - * - * If required, enlarge the buffer to fit the new size. - * - * @param buf the buffer to resize - * @param size the minimum size of the buffer - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ -static inline Eina_Bool -_eina_strbuf_grow(Eina_Strbuf *buf, size_t size) -{ - if ((size + 1) < buf->size) - return EINA_TRUE; - return _eina_strbuf_resize(buf, size); -} - -/** - * @internal - * - * insert string of known length at random within existing strbuf limits. - * - * @param buf the buffer to resize, must be valid. - * @param str the string to copy, must be valid (!NULL and smaller than @a len) - * @param len the amount of bytes in @a str to copy, must be valid. - * @param pos the position inside buffer to insert, must be valid (smaller - * than eina_strbuf_length_get()) - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ -static inline Eina_Bool -_eina_strbuf_insert_length(Eina_Strbuf *buf, const char *str, size_t len, size_t pos) -{ - if (EINA_UNLIKELY(!_eina_strbuf_grow(buf, buf->len + len))) - return EINA_FALSE; - - /* move the existing text */ - memmove(buf->buf + len + pos, buf->buf + pos, buf->len - pos); - - /* and now insert the given string */ - memcpy(buf->buf + pos, str, len); - - buf->len += len; - buf->buf[buf->len] = '\0'; - return EINA_TRUE; -} - -/** - * @endcond - */ - -/*============================================================================* - * Global * - *============================================================================*/ - -/** - * @cond LOCAL - */ - -/** - * @internal - * @brief Initialize the strbuf module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the strbuf module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -Eina_Bool -eina_strbuf_init(void) -{ - eina_magic_string_static_set(EINA_MAGIC_STRBUF, EINA_MAGIC_STRBUF_STR); - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the strbuf module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the strbuf module set up by - * eina_strbuf_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool -eina_strbuf_shutdown(void) -{ - return EINA_TRUE; -} - -/** - * @endcond - */ - -/*============================================================================* - * API * - *============================================================================*/ - -/** - * @addtogroup Eina_String_Buffer_Group String Buffer - * - * @brief These functions provide string buffers management. - * - * The String Buffer data type is designed to be a mutable string, - * allowing to append, prepend or insert a string to a buffer. - * - * @{ - */ - -/** - * @brief Create a new string buffer. - * - * @return Newly allocated string buffer instance. - * - * This function creates a new string buffer. On error, @c NULL is - * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To - * free the resources, use eina_strbuf_free(). - * - * @see eina_strbuf_free() - * @see eina_strbuf_append() - * @see eina_strbuf_string_get() - */ -EAPI Eina_Strbuf * -eina_strbuf_new(void) -{ - Eina_Strbuf *buf; - - eina_error_set(0); - buf = malloc(sizeof(Eina_Strbuf)); - if (EINA_UNLIKELY(!buf)) - { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - EINA_MAGIC_SET(buf, EINA_MAGIC_STRBUF); - - if (EINA_UNLIKELY(!_eina_strbuf_init(buf))) - { - eina_strbuf_free(buf); - return NULL; - } - - return buf; -} - -/** - * @brief Free a string buffer. - * - * @param buf The string buffer to free. - * - * This function frees the memory of @p buf. @p buf must have been - * created by eina_strbuf_new(). - */ -EAPI void -eina_strbuf_free(Eina_Strbuf *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf); - EINA_MAGIC_SET(buf, EINA_MAGIC_NONE); - - free(buf->buf); - free(buf); -} - -/** - * @brief Reset a string buffer. - * - * @param buf The string buffer to reset. - * - * This function reset @p buf: the buffer len is set to 0, and the - * string is set to '\\0'. No memory is free'd. - */ -EAPI void -eina_strbuf_reset(Eina_Strbuf *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf); - buf->len = 0; - buf->step = EINA_STRBUF_INIT_STEP; - - buf->buf[0] = '\0'; -} - -/** - * @brief Append a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends @p str to @p buf. It computes the length of - * @p str, so is slightly slower than eina_strbuf_append_length(). If - * the length is known beforehand, consider using that variant. If - * @p buf can't append it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - * - * @see eina_strbuf_append() - * @see eina_strbuf_append_length() - */ -EAPI Eina_Bool -eina_strbuf_append(Eina_Strbuf *buf, const char *str) -{ - size_t len; - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - len = strlen(str); - if (EINA_UNLIKELY(!_eina_strbuf_grow(buf, buf->len + len))) - return EINA_FALSE; - memcpy(buf->buf + buf->len, str, len + 1); - buf->len += len; - return EINA_TRUE; -} - -/** - * @brief Append an escaped string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends the escaped string @p str to @p buf. If @p - * str can not be appended, #EINA_FALSE is returned, otherwise, - * #EINA_TRUE is returned. - */ -EAPI Eina_Bool -eina_strbuf_append_escaped(Eina_Strbuf *buf, const char *str) -{ - size_t len; - char *esc; - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - esc = eina_str_escape(str); - if (EINA_UNLIKELY(!esc)) - return EINA_FALSE; - len = strlen(esc); - if (EINA_UNLIKELY(!_eina_strbuf_grow(buf, buf->len + len))) - { - free(esc); - return EINA_FALSE; - } - memcpy(buf->buf + buf->len, esc, len + 1); - buf->len += len; - free(esc); - return EINA_TRUE; -} - -/** - * @brief Append a string to a buffer, reallocating as necessary, - * limited by the given length. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @param maxlen The maximum number of characters to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends at most @p maxlen characters of @p str to - * @p buf. It can't appends more than the length of @p str. It - * computes the length of @p str, so is slightly slower than - * eina_strbuf_append_length(). If the length is known beforehand, - * consider using that variant (@p maxlen should then be checked so - * that it is greater than the size of @p str). If @p str can not be - * appended, #EINA_FALSE is returned, otherwise, #EINA_TRUE is - * returned. - * - * @see eina_strbuf_append() - * @see eina_strbuf_append_length() - */ -EAPI Eina_Bool -eina_strbuf_append_n(Eina_Strbuf *buf, const char *str, size_t maxlen) -{ - size_t len; - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - len = strlen(str); - if (len > maxlen) len = maxlen; - if (EINA_UNLIKELY(!_eina_strbuf_grow(buf, buf->len + len))) - return EINA_FALSE; - - memcpy(buf->buf + buf->len, str, len); - buf->len += len; - buf->buf[buf->len] = '\0'; - return EINA_TRUE; -} - -/** - * @brief Append a string of exact length to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @param length The exact length to use. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends @p str to @p buf. @p str must be of size at - * most @p length. It is slightly faster than eina_strbuf_append() as - * it does not compute the size of @p str. It is useful when dealing - * with strings of known size, such as eina_strngshare. If @p buf - * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - * - * @see eina_stringshare_length() - * @see eina_strbuf_append() - * @see eina_strbuf_append_n() - */ -EAPI Eina_Bool -eina_strbuf_append_length(Eina_Strbuf *buf, const char *str, size_t length) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - if (EINA_UNLIKELY(!_eina_strbuf_grow(buf, buf->len + length))) - return EINA_FALSE; - - memcpy(buf->buf + buf->len, str, length); - buf->len += length; - buf->buf[buf->len] = '\0'; - return EINA_TRUE; -} - -/** - * @brief Append a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param fmt The string to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * @see eina_strbuf_append() - */ EAPI Eina_Bool eina_strbuf_append_printf(Eina_Strbuf *buf, const char *fmt, ...) { @@ -480,9 +29,6 @@ eina_strbuf_append_printf(Eina_Strbuf *buf, const char *fmt, ...) size_t len; Eina_Bool ret; - EINA_SAFETY_ON_NULL_RETURN_VAL(fmt, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - va_start(args, fmt); len = vasprintf(&str, fmt, args); va_end(args); @@ -495,15 +41,6 @@ eina_strbuf_append_printf(Eina_Strbuf *buf, const char *fmt, ...) return ret; } -/** - * @brief Append a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param fmt The string to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * @see eina_strbuf_append() - */ EAPI Eina_Bool eina_strbuf_append_vprintf(Eina_Strbuf *buf, const char *fmt, va_list args) { @@ -511,9 +48,6 @@ eina_strbuf_append_vprintf(Eina_Strbuf *buf, const char *fmt, va_list args) size_t len; Eina_Bool ret; - EINA_SAFETY_ON_NULL_RETURN_VAL(fmt, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - len = vasprintf(&str, fmt, args); if (len <= 0 || !str) @@ -524,188 +58,6 @@ eina_strbuf_append_vprintf(Eina_Strbuf *buf, const char *fmt, va_list args) return ret; } -/** - * @brief Insert a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert. - * @param str The string to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str to @p buf at position @p pos. It - * computes the length of @p str, so is slightly slower than - * eina_strbuf_insert_length(). If the length is known beforehand, - * consider using that variant. If @p buf can't insert it, #EINA_FALSE - * is returned, otherwise #EINA_TRUE is returned. - */ -EAPI Eina_Bool -eina_strbuf_insert(Eina_Strbuf *buf, const char *str, size_t pos) -{ - size_t len; - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - if (pos >= buf->len) - return eina_strbuf_append(buf, str); - - len = strlen(str); - return _eina_strbuf_insert_length(buf, str, len, pos); -} - -/** - * @brief Insert an escaped string to a buffer, reallocating as - * necessary. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts the escaped string @p str to @p buf at - * position @p pos. If @p buf can't insert @p str, #EINA_FALSE is - * returned, otherwise #EINA_TRUE is returned. - */ -EAPI Eina_Bool -eina_strbuf_insert_escaped(Eina_Strbuf *buf, const char *str, size_t pos) -{ - Eina_Bool ret; - size_t len; - char *esc; - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - esc = eina_str_escape(str); - if (EINA_UNLIKELY(!esc)) - return EINA_FALSE; - len = strlen(esc); - ret = _eina_strbuf_insert_length(buf, esc, len, pos); - free(esc); - return ret; -} - -/** - * @brief Insert a string to a buffer, reallocating as necessary. Limited by maxlen. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param maxlen The maximum number of chars to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str ot @p buf at position @p pos, with at - * most @p maxlen bytes. The number of inserted characters can not be - * greater than the length of @p str. It computes the length of - * @p str, so is slightly slower than eina_strbuf_insert_length(). If the - * length is known beforehand, consider using that variant (@p maxlen - * should then be checked so that it is greater than the size of - * @p str). If @p str can not be inserted, #EINA_FALSE is returned, - * otherwise, #EINA_TRUE is returned. - */ -EAPI Eina_Bool -eina_strbuf_insert_n(Eina_Strbuf *buf, const char *str, size_t maxlen, size_t pos) -{ - size_t len; - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - if (pos >= buf->len) - return eina_strbuf_append_n(buf, str, maxlen); - - len = strlen(str); - if (len > maxlen) len = maxlen; - return _eina_strbuf_insert_length(buf, str, len, pos); -} - -/** - * @brief Insert a string of exact length to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param length The exact length to use. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str to @p buf. @p str must be of size at - * most @p length. It is slightly faster than eina_strbuf_insert() as - * it does not compute the size of @p str. It is useful when dealing - * with strings of known size, such as eina_strngshare. If @p buf - * can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - * - * @see eina_stringshare_length() - * @see eina_strbuf_insert() - * @see eina_strbuf_insert_n() - */ -EAPI Eina_Bool -eina_strbuf_insert_length(Eina_Strbuf *buf, const char *str, size_t length, size_t pos) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - if (pos >= buf->len) - return eina_strbuf_append_length(buf, str, length); - - return _eina_strbuf_insert_length(buf, str, length, pos); -} - -/** - * @brief Append a character to a string buffer, reallocating as - * necessary. - * - * @param buf The string buffer to append to. - * @param c The char to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p c to @p buf. If it can not insert it, - * #EINA_FALSE is returned, otherwise #EINA_TRUE is returned. - */ -EAPI Eina_Bool -eina_strbuf_append_char(Eina_Strbuf *buf, char c) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - if (EINA_UNLIKELY(!_eina_strbuf_grow(buf, buf->len + 1))) - return EINA_FALSE; - buf->buf[(buf->len)++] = c; - buf->buf[buf->len] = '\0'; - return EINA_TRUE; -} - -/** - * @brief Insert a character to a string buffer, reallocating as - * necessary. - * - * @param buf The string buffer to insert to. - * @param c The char to insert. - * @param pos The position to insert the char. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p c to @p buf at position @p pos. If @p buf - * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -EAPI Eina_Bool -eina_strbuf_insert_char(Eina_Strbuf *buf, char c, size_t pos) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - if (pos >= buf->len) - return eina_strbuf_append_char(buf, c); - - return _eina_strbuf_insert_length(buf, &c, 1, pos); -} - -/** - * @brief Insert a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert. - * @param fmt The string to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ EAPI Eina_Bool eina_strbuf_insert_printf(Eina_Strbuf *buf, const char *fmt, size_t pos, ...) { @@ -714,9 +66,6 @@ eina_strbuf_insert_printf(Eina_Strbuf *buf, const char *fmt, size_t pos, ...) size_t len; Eina_Bool ret; - EINA_SAFETY_ON_NULL_RETURN_VAL(fmt, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - va_start(args, pos); len = vasprintf(&str, fmt, args); va_end(args); @@ -729,14 +78,6 @@ eina_strbuf_insert_printf(Eina_Strbuf *buf, const char *fmt, size_t pos, ...) return ret; } -/** - * @brief Insert a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert. - * @param fmt The string to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ EAPI Eina_Bool eina_strbuf_insert_vprintf(Eina_Strbuf *buf, const char *fmt, size_t pos, va_list args) { @@ -744,9 +85,6 @@ eina_strbuf_insert_vprintf(Eina_Strbuf *buf, const char *fmt, size_t pos, va_lis size_t len; Eina_Bool ret; - EINA_SAFETY_ON_NULL_RETURN_VAL(fmt, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - len = vasprintf(&str, fmt, args); if (len <= 0 || !str) @@ -755,278 +93,4 @@ eina_strbuf_insert_vprintf(Eina_Strbuf *buf, const char *fmt, size_t pos, va_lis ret = eina_strbuf_insert(buf, str, pos); free(str); return ret; -} - -/** - * @brief Remove a slice of the given string buffer. - * - * @param buf The string buffer to remove a slice. - * @param start The initial (inclusive) slice position to start - * removing, in bytes. - * @param end The final (non-inclusive) slice position to finish - * removing, in bytes. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function removes a slice of @p buf, starting at @p start - * (inclusive) and ending at @p end (non-inclusive). Both values are - * in bytes. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. - */ -EAPI Eina_Bool -eina_strbuf_remove(Eina_Strbuf *buf, size_t start, size_t end) -{ - size_t remove_len, tail_len; - - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - if (end >= buf->len) - end = buf->len; - - if (end <= start) - return EINA_TRUE; - - remove_len = end - start; - if (remove_len == buf->len) - { - free(buf->buf); - return _eina_strbuf_init(buf); - } - - tail_len = buf->len - end + 1; /* includes '\0' */ - memmove(buf->buf + start, buf->buf + end, tail_len); - buf->len -= remove_len; - return _eina_strbuf_resize(buf, buf->len); -} - -/** - * @brief Retrieve a pointer to the contents of a string buffer - * - * @param buf The string buffer. - * @return The current string in the string buffer. - * - * This function returns the string contained in @p buf. The returned - * value must not be modified and will no longer be valid if @p buf is - * modified. In other words, any eina_strbuf_append() or similar will - * make that pointer invalid. - * - * @see eina_strbuf_string_steal() - */ -EAPI const char * -eina_strbuf_string_get(const Eina_Strbuf *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf, NULL); - - return buf->buf; -} - -/** - * @brief Steal the contents of a string buffer. - * - * @param buf The string buffer to steal. - * @return The current string in the string buffer. - * - * This function returns the string contained in @p buf. @p buf is - * then initialized and does not own the returned string anymore. The - * caller must release the memory of the returned string by calling - * free(). - * - * @see eina_strbuf_string_get() - */ -EAPI char * -eina_strbuf_string_steal(Eina_Strbuf *buf) -{ - char *ret; - - EINA_MAGIC_CHECK_STRBUF(buf, NULL); - - ret = buf->buf; - // TODO: Check return value and do something clever - _eina_strbuf_init(buf); - return ret; -} - -/** - * @brief Free the contents of a string buffer but not the buffer. - * - * @param buf The string buffer to free the string of. - * - * This function frees the string contained in @p buf without freeing - * @p buf. - */ -EAPI void -eina_strbuf_string_free(Eina_Strbuf *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf); - - free(buf->buf); - _eina_strbuf_init(buf); -} - -/** - * @brief Retrieve the length of the string buffer content. - * - * @param buf The string buffer. - * @return The current length of the string, in bytes. - * - * This function returns the length of @p buf. - */ -EAPI size_t -eina_strbuf_length_get(const Eina_Strbuf *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf, 0); - - return buf->len; -} - -/** - * @ brief Replace the n-th string with an other string. - * - * @param buf The string buffer to work with. - * @param str The string to replace. - * @param with The replaceing string. - * @param n The number of the fitting string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function replaces the n-th occurence of @p str in @p buf with - * @p with. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. - */ -EAPI Eina_Bool -eina_strbuf_replace(Eina_Strbuf *buf, const char *str, const char *with, unsigned int n) -{ - size_t len1, len2; - char *spos; - size_t pos; - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(with, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, 0); - - if (n == 0) - return EINA_FALSE; - - spos = buf->buf; - while (n--) - { - spos = strstr(spos, str); - if (!spos || *spos == '\0') - return EINA_FALSE; - if (n) spos++; - } - - pos = spos - buf->buf; - len1 = strlen(str); - len2 = strlen(with); - if (len1 != len2) - { - /* resize the buffer if necessary */ - if (EINA_UNLIKELY(!_eina_strbuf_grow(buf, buf->len - len1 + len2))) - return EINA_FALSE; - /* move the existing text */ - memmove(buf->buf + pos + len2, buf->buf + pos + len1, - buf->len - pos - len1); - } - /* and now insert the given string */ - memcpy(buf->buf + pos, with, len2); - buf->len += len2 - len1; - buf->buf[buf->len] = 0; - - return EINA_TRUE; -} - -/** - * @brief Replace all strings with an other string. - - * @param buf the string buffer to work with. - * @param str The string to replace. - * @param with The replaceing string. - * @return How often the string was replaced. - * - * This function replaces all the occurences of @p str in @ buf with - * the string @p with. This function returns the number of times @p str - * has been replaced. On failure, it returns 0. - */ -EAPI int -eina_strbuf_replace_all(Eina_Strbuf *buf, const char *str, const char *with) -{ - size_t len1, len2, len; - char *tmp_buf = NULL; - char *spos; - size_t pos, start; - size_t pos_tmp, start_tmp; - int n = 0; - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, 0); - EINA_SAFETY_ON_NULL_RETURN_VAL(with, 0); - EINA_MAGIC_CHECK_STRBUF(buf, 0); - - spos = strstr(buf->buf, str); - if (!spos || *spos == '\0') - return 0; - - len1 = strlen(str); - len2 = strlen(with); - - /* if the size of the two string is equal, it is fairly easy to replace them - * we don't need to resize the buffer or doing other calculations */ - if (len1 == len2) - { - while (spos) - { - memcpy(spos, with, len2); - spos = strstr(spos + len2, str); - n++; - } - return n; - } - - pos = pos_tmp = spos - buf->buf; - tmp_buf = buf->buf; - buf->buf = malloc(buf->size); - if (EINA_UNLIKELY(!buf->buf)) - { - buf->buf = tmp_buf; - return 0; - } - start = start_tmp = 0; - len = buf->len; - - while (spos) - { - n++; - len = (len + len2) - len1; - /* resize the buffer if necessary */ - if (EINA_UNLIKELY(!_eina_strbuf_grow(buf, len))) - { - /* we have to stop replacing here, because we haven't enough - * memory to go on */ - len = (len + len1) - len2; - break; - } - - /* copy the untouched text */ - memcpy(buf->buf + start, tmp_buf + start_tmp, pos - start); - /* copy the new string */ - memcpy(buf->buf + pos, with, len2); - - /* calculate the next positions */ - start_tmp = pos_tmp + len1; - start = pos + len2; - spos = strstr(tmp_buf + start_tmp, str); - /* this calculations don't make sense if spos == NULL, but the - * calculated values won't be used, because the loop will stop - * then */ - pos_tmp = spos - tmp_buf; - pos = start + pos_tmp - start_tmp; - } - /* and now copy the rest of the text */ - memcpy(buf->buf + start, tmp_buf + start_tmp, len - start); - buf->len = len; - buf->buf[buf->len] = 0; - - free(tmp_buf); - - return n; -} - -/** - * @} - */ +} \ No newline at end of file diff --git a/legacy/eina/src/lib/eina_strbuf_common.c b/legacy/eina/src/lib/eina_strbuf_common.c new file mode 100644 index 0000000000..4ce33488d0 --- /dev/null +++ b/legacy/eina/src/lib/eina_strbuf_common.c @@ -0,0 +1,800 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#define _GNU_SOURCE + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#ifdef _WIN32 +# include +#endif + +#include "eina_private.h" +#include "eina_str.h" +#include "eina_magic.h" +#include "eina_error.h" +#include "eina_safety_checks.h" +#include "eina_strbuf.h" +#include "eina_strbuf_common.h" + +/*============================================================================* + * Local * + *============================================================================*/ + +/** + * @cond LOCAL + */ + +#define EINA_STRBUF_INIT_SIZE 32 +#define EINA_STRBUF_INIT_STEP 32 +#define EINA_STRBUF_MAX_STEP 4096 + +/** + * @internal + * + * init the buffer + * @param buf the buffer to init + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + */ +static Eina_Bool +_eina_strbuf_common_init(size_t csize, Eina_Strbuf *buf) +{ + buf->len = 0; + buf->size = EINA_STRBUF_INIT_SIZE; + buf->step = EINA_STRBUF_INIT_STEP; + + eina_error_set(0); + buf->buf = calloc(csize, buf->size); + if (EINA_UNLIKELY(!buf->buf)) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + return EINA_TRUE; +} + +/** + * @internal + * + * resize the buffer + * @param buf the buffer to resize + * @param size the minimum size of the buffer + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + */ +static inline Eina_Bool +_eina_strbuf_common_resize(size_t csize, Eina_Strbuf *buf, size_t size) +{ + size_t new_size, new_step, delta; + void *buffer; + + size += 1; // Add extra space for '\0' + + if (size == buf->size) + /* nothing to do */ + return EINA_TRUE; + else if (size > buf->size) + 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 + { + 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 */ + buffer = realloc(buf->buf, new_size * csize); + if (EINA_UNLIKELY(!buffer)) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + + buf->buf = buffer; + buf->size = new_size; + buf->step = new_step; + eina_error_set(0); + return EINA_TRUE; +} + +/** + * @internal + * + * If required, enlarge the buffer to fit the new size. + * + * @param buf the buffer to resize + * @param size the minimum size of the buffer + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + */ +Eina_Bool +_eina_strbuf_common_grow(size_t csize, Eina_Strbuf *buf, size_t size) +{ + if ((size + 1) < buf->size) + return EINA_TRUE; + return _eina_strbuf_common_resize(csize, buf, size); +} + +/** + * @internal + * + * insert string of known length at random within existing strbuf limits. + * + * @param buf the buffer to resize, must be valid. + * @param str the string to copy, must be valid (!NULL and smaller than @a len) + * @param len the amount of bytes in @a str to copy, must be valid. + * @param pos the position inside buffer to insert, must be valid (smaller + * than eina_strbuf_common_length_get()) + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + */ +static inline Eina_Bool +_eina_strbuf_common_insert_length(size_t csize, Eina_Strbuf *buf, const void *str, size_t len, size_t pos) +{ + if (EINA_UNLIKELY(!_eina_strbuf_common_grow(csize, buf, buf->len + len))) + return EINA_FALSE; + + /* move the existing text */ + memmove(buf->buf + ((len + pos) * csize), buf->buf + (pos * csize), (buf->len - pos) * csize); + + /* and now insert the given string */ + memcpy(buf->buf + (pos * csize), str, len * csize); + + buf->len += len; + memset(buf->buf + (buf->len * csize), 0, csize); + return EINA_TRUE; +} + +/** + * @endcond + */ + +/*============================================================================* + * Global * + *============================================================================*/ + +/** + * @cond LOCAL + */ + +/** + * @internal + * @brief Initialize the strbuf module. + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function sets up the strbuf module of Eina. It is called by + * eina_init(). + * + * @see eina_init() + */ +Eina_Bool +eina_strbuf_common_init(void) +{ + return EINA_TRUE; +} + +/** + * @internal + * @brief Shut down the strbuf module. + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function shuts down the strbuf module set up by + * eina_strbuf_common_init(). It is called by eina_shutdown(). + * + * @see eina_shutdown() + */ +Eina_Bool +eina_strbuf_common_shutdown(void) +{ + return EINA_TRUE; +} + +/*============================================================================* + * API * + *============================================================================*/ + +/** + * @brief Create a new string buffer. + * + * @return Newly allocated string buffer instance. + * + * This function creates a new string buffer. On error, @c NULL is + * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To + * free the resources, use eina_strbuf_common_free(). + * + * @see eina_strbuf_common_free() + * @see eina_strbuf_common_append() + * @see eina_strbuf_common_string_get() + */ +Eina_Strbuf * +eina_strbuf_common_new(size_t csize) +{ + Eina_Strbuf *buf; + + eina_error_set(0); + buf = malloc(sizeof(Eina_Strbuf)); + if (EINA_UNLIKELY(!buf)) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return NULL; + } + + if (EINA_UNLIKELY(!_eina_strbuf_common_init(csize, buf))) + { + eina_strbuf_common_free(buf); + return NULL; + } + + return buf; +} + +/** + * @brief Free a string buffer. + * + * @param buf The string buffer to free. + * + * This function frees the memory of @p buf. @p buf must have been + * created by eina_strbuf_common_new(). + */ +void +eina_strbuf_common_free(Eina_Strbuf *buf) +{ + free(buf->buf); + free(buf); +} + +/** + * @brief Reset a string buffer. + * + * @param buf The string buffer to reset. + * + * This function reset @p buf: the buffer len is set to 0, and the + * string is set to '\\0'. No memory is free'd. + */ +void +eina_strbuf_common_reset(size_t csize, Eina_Strbuf *buf) +{ + buf->len = 0; + buf->step = EINA_STRBUF_INIT_STEP; + + memset(buf->buf, 0, csize); +} + +/** + * @brief Append a string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends @p str to @p buf. It computes the length of + * @p str, so is slightly slower than eina_strbuf_common_append_length(). If + * the length is known beforehand, consider using that variant. If + * @p buf can't append it, #EINA_FALSE is returned, otherwise + * #EINA_TRUE is returned. + * + * @see eina_strbuf_common_append() + * @see eina_strbuf_common_append_length() + */ +Eina_Bool +eina_strbuf_common_append(size_t csize, Eina_Strbuf *buf, const void *str, size_t len) +{ + + EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); + + if (EINA_UNLIKELY(!_eina_strbuf_common_grow(csize, buf, buf->len + len))) + return EINA_FALSE; + memcpy(buf->buf + (buf->len * csize), str, (len + 1) * csize); + buf->len += len; + return EINA_TRUE; +} + +/** + * @brief Append a string to a buffer, reallocating as necessary, + * limited by the given length. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @param maxlen The maximum number of characters to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends at most @p maxlen characters of @p str to + * @p buf. It can't appends more than the length of @p str. It + * computes the length of @p str, so is slightly slower than + * eina_strbuf_common_append_length(). If the length is known beforehand, + * consider using that variant (@p maxlen should then be checked so + * that it is greater than the size of @p str). If @p str can not be + * appended, #EINA_FALSE is returned, otherwise, #EINA_TRUE is + * returned. + * + * @see eina_strbuf_common_append() + * @see eina_strbuf_common_append_length() + */ +Eina_Bool +eina_strbuf_common_append_n(size_t csize, Eina_Strbuf *buf, const void *str, size_t len, size_t maxlen) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); + + if (len > maxlen) len = maxlen; + if (EINA_UNLIKELY(!_eina_strbuf_common_grow(csize, buf, buf->len + len))) + return EINA_FALSE; + + memcpy(buf->buf + (buf->len * csize), str, len * csize); + buf->len += len; + memset(buf->buf + (buf->len * csize), 0, csize); + return EINA_TRUE; +} + +/** + * @brief Append a string of exact length to a buffer, reallocating as necessary. + * + * @param buf The string buffer to append to. + * @param str The string to append. + * @param length The exact length to use. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function appends @p str to @p buf. @p str must be of size at + * most @p length. It is slightly faster than eina_strbuf_common_append() as + * it does not compute the size of @p str. It is useful when dealing + * with strings of known size, such as eina_strngshare. If @p buf + * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + * + * @see eina_stringshare_length() + * @see eina_strbuf_common_append() + * @see eina_strbuf_common_append_n() + */ +Eina_Bool +eina_strbuf_common_append_length(size_t csize, Eina_Strbuf *buf, const void *str, size_t length) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); + + if (EINA_UNLIKELY(!_eina_strbuf_common_grow(csize, buf, buf->len + length))) + return EINA_FALSE; + + memcpy(buf->buf + (buf->len * csize), str, length * csize); + buf->len += length; + memset(buf->buf + (buf->len * csize), 0, csize); + return EINA_TRUE; +} + +/** + * @brief Insert a string to a buffer, reallocating as necessary. + * + * @param buf The string buffer to insert. + * @param str The string to insert. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p str to @p buf at position @p pos. It + * computes the length of @p str, so is slightly slower than + * eina_strbuf_common_insert_length(). If the length is known beforehand, + * consider using that variant. If @p buf can't insert it, #EINA_FALSE + * is returned, otherwise #EINA_TRUE is returned. + */ +Eina_Bool +eina_strbuf_common_insert(size_t csize, Eina_Strbuf *buf, const void *str, size_t len, size_t pos) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); + + if (pos >= buf->len) + return eina_strbuf_common_append(csize, buf, str, len); + + return _eina_strbuf_common_insert_length(csize, buf, str, len, pos); +} + +/** + * @brief Insert a string to a buffer, reallocating as necessary. Limited by maxlen. + * + * @param buf The string buffer to insert to. + * @param str The string to insert. + * @param maxlen The maximum number of chars to insert. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p str ot @p buf at position @p pos, with at + * most @p maxlen bytes. The number of inserted characters can not be + * greater than the length of @p str. It computes the length of + * @p str, so is slightly slower than eina_strbuf_common_insert_length(). If the + * length is known beforehand, consider using that variant (@p maxlen + * should then be checked so that it is greater than the size of + * @p str). If @p str can not be inserted, #EINA_FALSE is returned, + * otherwise, #EINA_TRUE is returned. + */ +Eina_Bool +eina_strbuf_common_insert_n(size_t csize, Eina_Strbuf *buf, const void *str, size_t len, size_t maxlen, size_t pos) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); + + if (pos >= buf->len) + return eina_strbuf_common_append_n(csize, buf, str, len, maxlen); + + if (len > maxlen) len = maxlen; + return _eina_strbuf_common_insert_length(csize, buf, str, len, pos); +} + +/** + * @brief Insert a string of exact length to a buffer, reallocating as necessary. + * + * @param buf The string buffer to insert to. + * @param str The string to insert. + * @param length The exact length to use. + * @param pos The position to insert the string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p str to @p buf. @p str must be of size at + * most @p length. It is slightly faster than eina_strbuf_common_insert() as + * it does not compute the size of @p str. It is useful when dealing + * with strings of known size, such as eina_strngshare. If @p buf + * can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + * + * @see eina_stringshare_length() + * @see eina_strbuf_common_insert() + * @see eina_strbuf_common_insert_n() + */ +Eina_Bool +eina_strbuf_common_insert_length(size_t csize, Eina_Strbuf *buf, const void *str, size_t length, size_t pos) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); + + if (pos >= buf->len) + return eina_strbuf_common_append_length(csize, buf, str, length); + + return _eina_strbuf_common_insert_length(csize, buf, str, length, pos); +} + +/** + * @brief Append a character to a string buffer, reallocating as + * necessary. + * + * @param buf The string buffer to append to. + * @param c The char to append. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p c to @p buf. If it can not insert it, + * #EINA_FALSE is returned, otherwise #EINA_TRUE is returned. + */ +Eina_Bool +eina_strbuf_common_append_char(size_t csize, Eina_Strbuf *buf, const void *c) +{ + + if (EINA_UNLIKELY(!_eina_strbuf_common_grow(csize, buf, buf->len + 1))) + return EINA_FALSE; + memcpy(buf->buf + ((buf->len)++ * csize), c, csize); + memset(buf->buf + (buf->len * csize), 0, csize); + return EINA_TRUE; +} + +/** + * @brief Insert a character to a string buffer, reallocating as + * necessary. + * + * @param buf The string buffer to insert to. + * @param c The char to insert. + * @param pos The position to insert the char. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function inserts @p c to @p buf at position @p pos. If @p buf + * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is + * returned. + */ +Eina_Bool +eina_strbuf_common_insert_char(size_t csize, Eina_Strbuf *buf, const void *c, size_t pos) +{ + + if (pos >= buf->len) + return eina_strbuf_common_append_char(csize, buf, c); + + return _eina_strbuf_common_insert_length(csize, buf, c, 1, pos); +} + +/** + * @brief Remove a slice of the given string buffer. + * + * @param buf The string buffer to remove a slice. + * @param start The initial (inclusive) slice position to start + * removing, in bytes. + * @param end The final (non-inclusive) slice position to finish + * removing, in bytes. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function removes a slice of @p buf, starting at @p start + * (inclusive) and ending at @p end (non-inclusive). Both values are + * in bytes. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. + */ +Eina_Bool +eina_strbuf_common_remove(size_t csize, Eina_Strbuf *buf, size_t start, size_t end) +{ + size_t remove_len, tail_len; + + if (end >= buf->len) + end = buf->len; + + if (end <= start) + return EINA_TRUE; + + remove_len = end - start; + if (remove_len == buf->len) + { + free(buf->buf); + return _eina_strbuf_common_init(csize, buf); + } + + tail_len = buf->len - end + 1; /* includes '\0' */ + memmove(buf->buf + (start * csize), buf->buf + (end * csize), tail_len * csize); + buf->len -= remove_len; + return _eina_strbuf_common_resize(csize, buf, buf->len); +} + +/** + * @brief Retrieve a pointer to the contents of a string buffer + * + * @param buf The string buffer. + * @return The current string in the string buffer. + * + * This function returns the string contained in @p buf. The returned + * value must not be modified and will no longer be valid if @p buf is + * modified. In other words, any eina_strbuf_common_append() or similar will + * make that pointer invalid. + * + * @see eina_strbuf_common_string_steal() + */ +const void * +eina_strbuf_common_string_get(const Eina_Strbuf *buf) +{ + return buf->buf; +} + +/** + * @brief Steal the contents of a string buffer. + * + * @param buf The string buffer to steal. + * @return The current string in the string buffer. + * + * This function returns the string contained in @p buf. @p buf is + * then initialized and does not own the returned string anymore. The + * caller must release the memory of the returned string by calling + * free(). + * + * @see eina_strbuf_common_string_get() + */ +void * +eina_strbuf_common_string_steal(size_t csize, Eina_Strbuf *buf) +{ + void *ret; + + ret = buf->buf; + // TODO: Check return value and do something clever + _eina_strbuf_common_init(csize, buf); + return ret; +} + +/** + * @brief Free the contents of a string buffer but not the buffer. + * + * @param buf The string buffer to free the string of. + * + * This function frees the string contained in @p buf without freeing + * @p buf. + */ +void +eina_strbuf_common_string_free(size_t csize, Eina_Strbuf *buf) +{ + free(buf->buf); + _eina_strbuf_common_init(csize, buf); +} + +/** + * @brief Retrieve the length of the string buffer content. + * + * @param buf The string buffer. + * @return The current length of the string, in bytes. + * + * This function returns the length of @p buf. + */ +size_t +eina_strbuf_common_length_get(const Eina_Strbuf *buf) +{ + return buf->len; +} +/** + * @endcond + */ + +/** + * @addtogroup Eina_Data_Types_Group Data Types + * + * @{ + */ +/** + * @addtogroup Eina_String_Buffer_Group String Buffer + * + * @brief These functions provide string buffers management. + * + * The String Buffer data type is designed to be a mutable string, + * allowing to append, prepend or insert a string to a buffer. + * + * @{ + */ +/*FIXME: Implementing them here is a hack! */ +#define _STRBUF_CSIZE 1 +#define _STRBUF_MAGIC EINA_MAGIC_STRBUF +static const char _STRBUF_MAGIC_STR[] = "Eina Strbuf"; + +/** + * @ brief Replace the n-th string with an other string. + * + * @param buf The string buffer to work with. + * @param str The string to replace. + * @param with The replaceing string. + * @param n The number of the fitting string. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function replaces the n-th occurence of @p str in @p buf with + * @p with. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. + */ +EAPI Eina_Bool +eina_strbuf_replace(Eina_Strbuf *buf, const char *str, const char *with, unsigned int n) +{ + size_t len1, len2; + char *spos; + size_t pos; + + EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(with, EINA_FALSE); + EINA_MAGIC_CHECK_STRBUF(buf, 0); + + if (n == 0) + return EINA_FALSE; + + spos = buf->buf; + while (n--) + { + spos = strstr(spos, str); + if (!spos || *spos == '\0') + return EINA_FALSE; + if (n) spos++; + } + + pos = spos - (const char *) buf->buf; + len1 = strlen(str); + len2 = strlen(with); + if (len1 != len2) + { + /* resize the buffer if necessary */ + if (EINA_UNLIKELY(!_eina_strbuf_common_grow(_STRBUF_CSIZE, buf, buf->len - len1 + len2))) + return EINA_FALSE; + /* move the existing text */ + memmove(buf->buf + pos + len2, buf->buf + pos + len1, + buf->len - pos - len1); + } + /* and now insert the given string */ + memcpy(buf->buf + pos, with, len2); + buf->len += len2 - len1; + memset((char *) buf->buf + buf->len, 0, 1); + + return EINA_TRUE; +} + +/** + * @brief Replace all strings with an other string. + + * @param buf the string buffer to work with. + * @param str The string to replace. + * @param with The replaceing string. + * @return How often the string was replaced. + * + * This function replaces all the occurences of @p str in @ buf with + * the string @p with. This function returns the number of times @p str + * has been replaced. On failure, it returns 0. + */ +EAPI int +eina_strbuf_replace_all(Eina_Strbuf *buf, const char *str, const char *with) +{ + size_t len1, len2, len; + char *tmp_buf = NULL; + char *spos; + size_t pos, start; + size_t pos_tmp, start_tmp; + int n = 0; + + EINA_SAFETY_ON_NULL_RETURN_VAL(str, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(with, 0); + EINA_MAGIC_CHECK_STRBUF(buf, 0); + + spos = strstr(buf->buf, str); + if (!spos || *spos == '\0') + return 0; + + len1 = strlen(str); + len2 = strlen(with); + + /* if the size of the two string is equal, it is fairly easy to replace them + * we don't need to resize the buffer or doing other calculations */ + if (len1 == len2) + { + while (spos) + { + memcpy(spos, with, len2); + spos = strstr(spos + len2, str); + n++; + } + return n; + } + + pos = pos_tmp = spos - (const char *) buf->buf; + tmp_buf = buf->buf; + buf->buf = malloc(buf->size); + if (EINA_UNLIKELY(!buf->buf)) + { + buf->buf = tmp_buf; + return 0; + } + start = start_tmp = 0; + len = buf->len; + + while (spos) + { + n++; + len = (len + len2) - len1; + /* resize the buffer if necessary */ + if (EINA_UNLIKELY(!_eina_strbuf_common_grow(_STRBUF_CSIZE, buf, len))) + { + /* we have to stop replacing here, because we haven't enough + * memory to go on */ + len = (len + len1) - len2; + break; + } + + /* copy the untouched text */ + memcpy(buf->buf + start, tmp_buf + start_tmp, pos - start); + /* copy the new string */ + memcpy(buf->buf + pos, with, len2); + + /* calculate the next positions */ + start_tmp = pos_tmp + len1; + start = pos + len2; + spos = strstr(tmp_buf + start_tmp, str); + /* this calculations don't make sense if spos == NULL, but the + * calculated values won't be used, because the loop will stop + * then */ + pos_tmp = spos - tmp_buf; + pos = start + pos_tmp - start_tmp; + } + /* and now copy the rest of the text */ + memcpy(buf->buf + start, tmp_buf + start_tmp, len - start); + buf->len = len; + memset((char *) buf->buf + buf->len, 0, 1); + + free(tmp_buf); + + return n; +} + +/** + * @} + */ +/** + * @} + */ diff --git a/legacy/eina/src/lib/eina_strbuf_common.h b/legacy/eina/src/lib/eina_strbuf_common.h new file mode 100644 index 0000000000..0b205ae5fb --- /dev/null +++ b/legacy/eina/src/lib/eina_strbuf_common.h @@ -0,0 +1,76 @@ +#ifndef EINA_STRBUF_COMMON_H +#define EINA_STRBUF_COMMON_H +#include + +#include "eina_private.h" +#include "eina_magic.h" + +struct _Eina_Strbuf +{ + void *buf; + size_t len; + size_t size; + size_t step; + + EINA_MAGIC +}; + +#define EINA_MAGIC_CHECK_STRBUF(d, ...) \ + do { \ + if (!EINA_MAGIC_CHECK((d), _STRBUF_MAGIC)) \ + { \ + EINA_MAGIC_FAIL((d), _STRBUF_MAGIC); \ + return __VA_ARGS__; \ + } \ + } while (0) + +Eina_Bool +eina_strbuf_common_init(void); + +Eina_Bool +eina_strbuf_common_shutdown(void); +Eina_Strbuf * +eina_strbuf_common_new(size_t csize); +void +eina_strbuf_common_free(Eina_Strbuf *buf); +void +eina_strbuf_common_reset(size_t csize, Eina_Strbuf *buf); +Eina_Bool +eina_strbuf_common_append(size_t csize, Eina_Strbuf *buf, const void *str, size_t len); +Eina_Bool +eina_strbuf_common_append_escaped(size_t csize, Eina_Strbuf *buf, const void *str); +Eina_Bool +eina_strbuf_common_append_n(size_t csize, Eina_Strbuf *buf, const void *str, size_t len, size_t maxlen); +Eina_Bool +eina_strbuf_common_append_length(size_t csize, Eina_Strbuf *buf, const void *str, size_t length); +Eina_Bool +eina_strbuf_common_insert(size_t csize, Eina_Strbuf *buf, const void *str, size_t len, size_t pos); +Eina_Bool +eina_strbuf_common_insert_escaped(size_t csize, Eina_Strbuf *buf, const void *str, + size_t len, size_t pos); +Eina_Bool +eina_strbuf_common_insert_n(size_t csize, Eina_Strbuf *buf, const void *str, size_t len, size_t maxlen, size_t pos); +Eina_Bool +eina_strbuf_common_insert_length(size_t csize, Eina_Strbuf *buf, const void *str, size_t length, size_t pos); +Eina_Bool +eina_strbuf_common_append_char(size_t csize, Eina_Strbuf *buf, const void *c); +Eina_Bool +eina_strbuf_common_insert_char(size_t csize, Eina_Strbuf *buf, const void *c, size_t pos); +Eina_Bool +eina_strbuf_common_remove(size_t csize, Eina_Strbuf *buf, size_t start, size_t end); +const void * +eina_strbuf_common_string_get(const Eina_Strbuf *buf); +void * +eina_strbuf_common_string_steal(size_t csize, Eina_Strbuf *buf); +void +eina_strbuf_common_string_free(size_t csize, Eina_Strbuf *buf); +size_t +eina_strbuf_common_length_get(const Eina_Strbuf *buf); + +Eina_Bool +_eina_strbuf_common_grow(size_t csize, Eina_Strbuf *buf, size_t size); +/** + * @} + */ + +#endif diff --git a/legacy/eina/src/lib/eina_strbuf_template_c.i b/legacy/eina/src/lib/eina_strbuf_template_c.i new file mode 100644 index 0000000000..b5d6e954d1 --- /dev/null +++ b/legacy/eina/src/lib/eina_strbuf_template_c.i @@ -0,0 +1,224 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +/* This file should be included from files implementing strbuf. The including file + * should define the following macros: + * _STRBUF_DATA_TYPE + * _STRBUF_CSIZE + * _STRBUF_STRUCT_NAME + * _STRBUF_STRLEN_FUNC(x) + * _STRBUF_STRESCAPE_FUNC(x) + * _STRBUF_STRSTR_FUNC(x, y) + * _STRBUF_MAGIC + * _STRBUF_MAGIC_STR + * See how it's done in eina_ustrbuf.c and eina_strbuf.c. This just makes things + * a lot easier since those are essentially the same just with different sizes. + */ + +#ifndef EINA_STRBUF_TEMPLATE_C_I +#define EINA_STRBUF_TEMPLATE_C_I + + +#include +#include "eina_strbuf_common.h" +#include "eina_unicode.h" + +/** + * @internal + * @brief Initialize the strbuf module. + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function sets up the strbuf module of Eina. It is called by + * eina_init(). + * + * @see eina_init() + */ +Eina_Bool +_FUNC_EXPAND(init)(void) +{ + eina_magic_string_static_set(_STRBUF_MAGIC, _STRBUF_MAGIC_STR); + return eina_strbuf_common_init(); +} + +/** + * @internal + * @brief Shut down the strbuf module. + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function shuts down the strbuf module set up by + * eina_ustrbuf_init(). It is called by eina_shutdown(). + * + * @see eina_shutdown() + */ +Eina_Bool +_FUNC_EXPAND(shutdown)(void) +{ + return eina_strbuf_common_shutdown(); +} + +/** + * @endcond + */ + +/*============================================================================* + * API * + *============================================================================*/ + +EAPI _STRBUF_STRUCT_NAME * +_FUNC_EXPAND(new)(void) +{ + _STRBUF_STRUCT_NAME *buf = eina_strbuf_common_new(_STRBUF_CSIZE); + EINA_MAGIC_SET(buf, _STRBUF_MAGIC); + return buf; +} + +EAPI void +_FUNC_EXPAND(free)(_STRBUF_STRUCT_NAME *buf) +{ + EINA_MAGIC_CHECK_STRBUF(buf); + EINA_MAGIC_SET(buf, EINA_MAGIC_NONE); + eina_strbuf_common_free(buf); +} + +EAPI void +_FUNC_EXPAND(reset)(_STRBUF_STRUCT_NAME *buf) +{ + EINA_MAGIC_CHECK_STRBUF(buf); + eina_strbuf_common_reset(_STRBUF_CSIZE, buf); +} + +EAPI Eina_Bool +_FUNC_EXPAND(append)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str) +{ + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + return eina_strbuf_common_append(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str)); +} + +EAPI Eina_Bool +_FUNC_EXPAND(append_escaped)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str) +{ + _STRBUF_DATA_TYPE *esc; + Eina_Bool ret; + + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + esc = _STRBUF_STRESCAPE_FUNC(str); + if (!esc) { + return _FUNC_EXPAND(append)(buf, str); + } + ret = _FUNC_EXPAND(append)(buf, esc); + if (esc) + free(esc); + + return ret; +} + +EAPI Eina_Bool +_FUNC_EXPAND(append_n)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t maxlen) +{ + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + return eina_strbuf_common_append_n(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str), maxlen); +} + +EAPI Eina_Bool +_FUNC_EXPAND(append_length)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t length) +{ + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + return eina_strbuf_common_append_length(_STRBUF_CSIZE, buf, (const void *) str, length); +} + +EAPI Eina_Bool +_FUNC_EXPAND(insert)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t pos) +{ + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + return eina_strbuf_common_insert(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str), pos); +} + +EAPI Eina_Bool +_FUNC_EXPAND(insert_escaped)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t pos) +{ + _STRBUF_DATA_TYPE *esc; + Eina_Bool ret; + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + + esc = _STRBUF_STRESCAPE_FUNC(str); + if (!esc) { + return _FUNC_EXPAND(insert)(buf, str, pos); + } + ret = _FUNC_EXPAND(insert)(buf, esc, pos); + if (esc) + free(esc); + + return ret; +} + +EAPI Eina_Bool +_FUNC_EXPAND(insert_n)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t maxlen, size_t pos) +{ + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + return eina_strbuf_common_insert_n(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str), maxlen, pos); +} + +EAPI Eina_Bool +_FUNC_EXPAND(insert_length)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t length, size_t pos) +{ + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + return eina_strbuf_common_insert_length(_STRBUF_CSIZE, buf, (const void *) str, length, pos); +} + +EAPI Eina_Bool +_FUNC_EXPAND(append_char)(_STRBUF_STRUCT_NAME *buf, _STRBUF_DATA_TYPE c) +{ + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + return eina_strbuf_common_append_char(_STRBUF_CSIZE, buf, (const void *) &c); +} + +EAPI Eina_Bool +_FUNC_EXPAND(insert_char)(_STRBUF_STRUCT_NAME *buf, _STRBUF_DATA_TYPE c, size_t pos) +{ + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + return eina_strbuf_common_insert_char(_STRBUF_CSIZE, buf, (const void *) &c, pos); +} + +EAPI Eina_Bool +_FUNC_EXPAND(remove)(_STRBUF_STRUCT_NAME *buf, size_t start, size_t end) +{ + EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); + return eina_strbuf_common_remove(_STRBUF_CSIZE, buf, start, end); +} + +EAPI const _STRBUF_DATA_TYPE * +_FUNC_EXPAND(string_get)(const _STRBUF_STRUCT_NAME *buf) +{ + EINA_MAGIC_CHECK_STRBUF(buf, NULL); + return (const _STRBUF_DATA_TYPE *) eina_strbuf_common_string_get(buf); +} + +EAPI _STRBUF_DATA_TYPE * +_FUNC_EXPAND(string_steal)(_STRBUF_STRUCT_NAME *buf) +{ + EINA_MAGIC_CHECK_STRBUF(buf, NULL); + return (_STRBUF_DATA_TYPE *) eina_strbuf_common_string_steal(_STRBUF_CSIZE, buf); +} + + +EAPI void +_FUNC_EXPAND(string_free)(_STRBUF_STRUCT_NAME *buf) +{ + EINA_MAGIC_CHECK_STRBUF(buf); + eina_strbuf_common_string_free(_STRBUF_CSIZE, buf); +} + +EAPI size_t +_FUNC_EXPAND(length_get)(const _STRBUF_STRUCT_NAME *buf) +{ + EINA_MAGIC_CHECK_STRBUF(buf, 0); + return eina_strbuf_common_length_get(buf); +} + +#else +#error Something went terribly wrong, shouldnt be included twice! + +#endif diff --git a/legacy/eina/src/lib/eina_ustrbuf.c b/legacy/eina/src/lib/eina_ustrbuf.c new file mode 100644 index 0000000000..55de552025 --- /dev/null +++ b/legacy/eina/src/lib/eina_ustrbuf.c @@ -0,0 +1,15 @@ +#include "eina_strbuf_common.h" +#include "eina_unicode.h" +#include "eina_ustrbuf.h" + +#define _STRBUF_DATA_TYPE Eina_Unicode +#define _STRBUF_CSIZE sizeof(_STRBUF_DATA_TYPE) +#define _STRBUF_STRUCT_NAME Eina_UStrbuf +#define _STRBUF_STRLEN_FUNC(x) eina_unicode_strlen(x) +#define _STRBUF_STRESCAPE_FUNC(x) eina_unicode_escape(x) +#define _STRBUF_MAGIC EINA_MAGIC_USTRBUF +static const char _STRBUF_MAGIC_STR[] = "Eina UStrbuf"; + +#define _FUNC_EXPAND(y) eina_ustrbuf_##y + +#include "eina_strbuf_template_c.i" \ No newline at end of file