[FFmpeg-devel] [PATCH] lavu: add av_bprintf and related [WIP].
Nicolas George
nicolas.george at normalesup.org
Wed Feb 1 20:39:40 CET 2012
Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
---
libavutil/avstring.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++
libavutil/avstring.h | 40 +++++++++++++++++++++++++++++
2 files changed, 109 insertions(+), 0 deletions(-)
This is work in progress for the bit of API I was talking with Clément. As a
test bed, I am about to try to adapt graphdump to use this API.
Regards,
--
Nicolas George
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index 76f6bb2..754254e 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -210,6 +210,75 @@ int av_strncasecmp(const char *a, const char *b, size_t n)
return c1 - c2;
}
+int av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
+{
+ char *str = NULL;
+
+ if (size_init) {
+ if (size_max < size_init)
+ return AVERROR(EINVAL);
+ str = av_malloc(size_init);
+ if (!str)
+ return AVERROR(ENOMEM);
+ *str = 0;
+ } else {
+ if (size_max)
+ return AVERROR(EINVAL);
+ }
+ buf->str = str;
+ buf->len = 0;
+ buf->size = size_init;
+ buf->size_max = size_max;
+ return 0;
+}
+
+void av_bprintf(AVBPrint *buf, const char *fmt, ...)
+{
+ unsigned room, new_size;
+ char *dst, *new_str;
+ va_list vl;
+ int add;
+
+ while (1) {
+ room = buf->size - FFMIN(buf->len, buf->size);
+ dst = room ? buf->str + buf->len : NULL;
+ va_start(vl, fmt);
+ add = vsnprintf(dst, room, fmt, vl);
+ va_end(vl);
+ if (add <= 0)
+ return;
+ if (add < room || buf->size == buf->size_max)
+ break;
+ new_size = buf->size > buf->size_max/2 ? buf->size_max : buf->size * 2;
+ new_str = av_realloc(buf->str, buf->size);
+ if (!new_str)
+ break;
+ buf->str = new_str;
+ buf->size = new_size;
+ }
+ add = FFMIN(add, UINT_MAX - 5 - buf->len);
+ buf->len += add;
+}
+
+void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
+{
+ /* beurk */
+ while(n--)
+ av_bprintf(buf, "%c", c);
+}
+
+void av_bprint_shrink(AVBPrint *buf)
+{
+
+ if (buf->len + 1 < buf->size) {
+ char *str;
+ buf->size = buf->size_max = buf->len + 1;
+ str = av_realloc(buf->str, buf->size);
+ if (str)
+ buf->str = str;
+ }
+}
+
#ifdef TEST
#undef printf
diff --git a/libavutil/avstring.h b/libavutil/avstring.h
index f73d6e7..8917ec8 100644
--- a/libavutil/avstring.h
+++ b/libavutil/avstring.h
@@ -203,6 +203,46 @@ int av_strcasecmp(const char *a, const char *b);
int av_strncasecmp(const char *a, const char *b, size_t n);
/**
+ * Buffer to print data progressively
+ * The string buffer grows as necessary and is always 0-terminated.
+ * The length of the string can go beyond the allocated size: the buffer is
+ * then truncated, but the functions still keep account of the required
+ * size.
+ * The string buffer can be stolen and/or freed using av_free.
+ * If size == 0, no allocation is made, the system only counts the size.
+ */
+typedef struct AVBPrint {
+ char *str; /** string so far; or NULL if size == 0 */
+ unsigned len; /** length so far */
+ unsigned size; /** allocated memory */
+ unsigned size_max; /** maximum allocated memory */
+} AVBPrint;
+
+/**
+ * Init a print buffer
+ * @param buf buffer to init
+ * @param size_init initial size (including the final 0)
+ * @param size_max maximum size
+ * @return 0 or error code (probably AVERROR(ENOMEM))
+ */
+int av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max);
+
+/**
+ * Append a formated string to a print buffer
+ */
+void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3);
+
+/**
+ * Append n times char c to a print buffer
+ */
+void av_bprint_chars(AVBPrint *buf, char c, unsigned n);
+
+/**
+ * Shrinks the allocated buffer to fit the string.
+ */
+void av_bprint_shrink(AVBPrint *buf);
+
+/**
* @}
*/
--
1.7.8.3
More information about the ffmpeg-devel
mailing list