[FFmpeg-devel] [PATCH 1/2] lavu: add av_bprintf and related.
Nicolas George
nicolas.george at normalesup.org
Wed Feb 1 21:37:00 CET 2012
Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
---
libavutil/avstring.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++
libavutil/avstring.h | 40 ++++++++++++++++++++++
2 files changed, 131 insertions(+), 0 deletions(-)
Sorry for the noise, I did not think I would have time to finish it so soon
and did not want to risk someone else working on the same thing at the same
time.
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index 76f6bb2..17d9b72 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -210,6 +210,97 @@ 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;
+}
+
+static int av_bprint_grow(AVBPrint *buf)
+{
+ unsigned new_size = buf->size > buf->size_max / 2 ? buf->size_max :
+ buf->size * 2;
+ char *new_str = av_realloc(buf->str, new_size);
+ if (!new_str)
+ return -1;
+ buf->str = new_str;
+ buf->size = new_size;
+ return 0;
+}
+
+#define av_bprint_room(buf) ((buf)->size - FFMIN((buf)->len, (buf)->size))
+
+void av_bprintf(AVBPrint *buf, const char *fmt, ...)
+{
+ unsigned room;
+ char *dst;
+ va_list vl;
+ int add;
+
+ while (1) {
+ room = av_bprint_room(buf);
+ 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;
+ if (av_bprint_grow(buf))
+ break;
+ }
+ add = FFMIN(add, UINT_MAX - 5 - buf->len);
+ buf->len += add;
+}
+
+void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
+{
+ unsigned room, real_n;
+
+ while (1) {
+ room = av_bprint_room(buf);
+ if (n < room || buf->size == buf->size_max)
+ break;
+ if (av_bprint_grow(buf))
+ break;
+ }
+ if (room) {
+ real_n = FFMIN(n, room - 1);
+ memset(buf->str + buf->len, c, real_n);
+ buf->str[buf->len + real_n] = 0;
+ }
+ buf->len += FFMIN(n, UINT_MAX - 5 - buf->len);
+}
+
+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