summaryrefslogtreecommitdiffstats
path: root/misc
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-03-23 22:00:16 +0100
committerwm4 <wm4@nowhere>2016-03-23 22:00:35 +0100
commitf9084c7bcea608be641f00123257a57b9f1e4ccc (patch)
treef7005347413b13746ec65a63da562f293d259505 /misc
parentc7f802ee45ad16d74bfae1510d395d3be36d4de2 (diff)
downloadmpv-f9084c7bcea608be641f00123257a57b9f1e4ccc.tar.bz2
mpv-f9084c7bcea608be641f00123257a57b9f1e4ccc.tar.xz
bstr: avoid redundant vsnprintf calls
Until now, bstr_xappend_vasprintf() called vsnprintf() always twice: once to determine how much output the call would produce, and a second time to actually output the data to the (possibly resized) target memory. Change this so that it tries to output to the already allocated memory first, and repeat the call only if allocation is required. This is especially helpful, as bstr_xappend_vasprintf() is designed to avoid reallocation when building strings. Usually, the second vsnprintf() will happen only at the beginning, when the buffer hasn't been extended to his largest needed size yet. Not sure if there is a need to optimize this; but see the next commit.
Diffstat (limited to 'misc')
-rw-r--r--misc/bstr.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/misc/bstr.c b/misc/bstr.c
index 13441eede9..1a2676c537 100644
--- a/misc/bstr.c
+++ b/misc/bstr.c
@@ -401,15 +401,21 @@ void bstr_xappend_vasprintf(void *talloc_ctx, bstr *s, const char *fmt,
int size;
va_list copy;
va_copy(copy, ap);
+ size_t avail = talloc_get_size(s->start) - s->len;
+ char *dest = s->start ? s->start + s->len : NULL;
char c;
- size = vsnprintf(&c, 1, fmt, copy);
+ if (avail < 1)
+ dest = &c;
+ size = vsnprintf(dest, MPMAX(avail, 1), fmt, copy);
va_end(copy);
if (size < 0)
abort();
- resize_append(talloc_ctx, s, size + 1);
- vsnprintf(s->start + s->len, size + 1, fmt, ap);
+ if (avail < 1 || size + 1 > avail) {
+ resize_append(talloc_ctx, s, size + 1);
+ vsnprintf(s->start + s->len, size + 1, fmt, ap);
+ }
s->len += size;
}