[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