From: Marek Olšák <marek.ol...@amd.com> This one is much faster when you don't need vsprintf. --- src/util/ralloc.c | 25 +++++++++++++++++++++++++ src/util/ralloc.h | 24 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+)
diff --git a/src/util/ralloc.c b/src/util/ralloc.c index 980e4e4..7976ca6 100644 --- a/src/util/ralloc.c +++ b/src/util/ralloc.c @@ -522,20 +522,45 @@ ralloc_vasprintf_rewrite_tail(char **str, size_t *start, const char *fmt, ptr = resize(*str, *start + new_length + 1); if (unlikely(ptr == NULL)) return false; vsnprintf(ptr + *start, new_length + 1, fmt, args); *str = ptr; *start += new_length; return true; } +bool +ralloc_sprint_rewrite_tail(char **str, size_t *start, const char *text, + unsigned text_length) +{ + char *ptr; + + assert(str != NULL); + + if (unlikely(*str == NULL)) { + /* Assuming a NULL context is probably bad, but it's expected behavior. */ + *str = ralloc_strdup(NULL, text); + *start = strlen(*str); + return true; + } + + ptr = resize(*str, *start + text_length + 1); + if (unlikely(ptr == NULL)) + return false; + + memcpy(ptr + *start, text, text_length + 1); /* also copy '\0' */ + *str = ptr; + *start += text_length; + return true; +} + /*************************************************************************** * Linear allocator for short-lived allocations. *************************************************************************** * * The allocator consists of a parent node (2K buffer), which requires * a ralloc parent, and child nodes (allocations). Child nodes can't be freed * directly, because the parent doesn't track them. You have to release * the parent node in order to release all its children. * * The allocator uses a fixed-sized buffer with a monotonically increasing diff --git a/src/util/ralloc.h b/src/util/ralloc.h index 3e2d342..6c31a6d 100644 --- a/src/util/ralloc.h +++ b/src/util/ralloc.h @@ -401,20 +401,44 @@ bool ralloc_asprintf_append (char **str, const char *fmt, ...) * \sa ralloc_strcat * * \p str will be updated to the new pointer unless allocation fails. * * \return True unless allocation failed. */ bool ralloc_vasprintf_append(char **str, const char *fmt, va_list args); /// @} /** + * Rewrite the tail of an existing string, starting at a given index. + * + * Overwrites the contents of *str starting at \p start with "text", + * including a new null-terminator. Allocates more memory as necessary. + * + * This can be used to append formatted text when the length of the existing + * string is already known, saving a strlen() call. + * + * \sa ralloc_asprintf_rewrite_tail + * + * \param str The string to be updated. + * \param start The index to start appending new data at. + * \param text The input string terminated by zero. + * \param text_length The length of the input string. + * + * \p str will be updated to the new pointer unless allocation fails. + * \p start will be increased by the length of the newly formatted text. + * + * \return True unless allocation failed. + */ +bool ralloc_sprint_rewrite_tail(char **str, size_t *start, const char *text, + unsigned text_length); + +/** * Declare C++ new and delete operators which use ralloc. * * Placing this macro in the body of a class makes it possible to do: * * TYPE *var = new(mem_ctx) TYPE(...); * delete var; * * which is more idiomatic in C++ than calling ralloc. */ #define DECLARE_ALLOC_CXX_OPERATORS_TEMPLATE(TYPE, ALLOC_FUNC) \ -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev