diff --git a/include/vlc_memstream.h b/include/vlc_memstream.h index 0d255bb6933ec3f9e61702d4a5756dc4274aa15b..eb665bffe15c9e4ca606f8943a9f30fd5f07c33f 100644 --- a/include/vlc_memstream.h +++ b/include/vlc_memstream.h @@ -24,6 +24,8 @@ # include <stdarg.h> # include <stdio.h> +#include <vlc_vector.h> + /** * \defgroup memstream In-memory byte streams * \ingroup cext @@ -42,7 +44,10 @@ struct vlc_memstream union { FILE *stream; - int error; + struct { + int error; + struct VLC_VECTOR(char) vector; + }; }; char *ptr; /**< Buffer start address */ size_t length; /**< Buffer length in bytes */ diff --git a/src/text/memstream.c b/src/text/memstream.c index af606e063b88c1ab37830e4ffc113eed944bc904..67a8a48f7bff1aacf1a03771e738875b9d265b63 100644 --- a/src/text/memstream.c +++ b/src/text/memstream.c @@ -114,53 +114,56 @@ int vlc_memstream_vprintf(struct vlc_memstream *ms, const char *fmt, } #else -#include <stdlib.h> +#include <vlc_vector.h> int vlc_memstream_open(struct vlc_memstream *ms) { ms->error = 0; - ms->ptr = calloc(1, 1); - if (unlikely(ms->ptr == NULL)) + vlc_vector_init(&ms->vector); + if (!vlc_vector_push(&ms->vector, '\0')) + { ms->error = EOF; + return EOF; + } + ms->ptr = NULL; ms->length = 0; - return ms->error; + return 0; } int vlc_memstream_flush(struct vlc_memstream *ms) { - return ms->error; + if (ms->error) + return ms->error; + ms->ptr = ms->vector.data; + ms->length = ms->vector.size - 1; + return 0; } int vlc_memstream_close(struct vlc_memstream *ms) { - if (ms->error) + if (vlc_memstream_flush(ms) == 0) { - free(ms->ptr); - ms->ptr = NULL; + vlc_vector_init(&ms->vector); + return 0; } + vlc_vector_clear(&ms->vector); + ms->ptr = NULL; + ms->length = 0; return ms->error; } size_t vlc_memstream_write(struct vlc_memstream *ms, const void *ptr, size_t len) { - size_t newlen; - if (len == 0) return 0; - if (unlikely(ckd_add(&newlen, ms->length, len)) - || unlikely(ckd_add(&newlen, newlen, 1))) - goto error; - - char *base = realloc(ms->ptr, newlen); - if (unlikely(base == NULL)) + size_t last = ms->vector.size; + if (!vlc_vector_push_hole(&ms->vector, len)) goto error; + memcpy(ms->vector.data + last - 1, ptr, len); + ms->vector.data[ms->vector.size - 1] = '\0'; - memcpy(base + ms->length, ptr, len); - ms->ptr = base; - ms->length += len; - base[ms->length] = '\0'; return len; error: @@ -183,26 +186,20 @@ int vlc_memstream_vprintf(struct vlc_memstream *ms, const char *fmt, va_list args) { va_list ap; - char *ptr; int len; - size_t newlen; va_copy(ap, args); len = vsnprintf(NULL, 0, fmt, ap); va_end(ap); - if (len < 0 - || unlikely(ckd_add(&newlen, ms->length, len)) - || unlikely(ckd_add(&newlen, newlen, 1))) + if (len < 0) goto error; - ptr = realloc(ms->ptr, newlen); - if (ptr == NULL) + size_t last = ms->vector.size; + if (!vlc_vector_push_hole(&ms->vector, len)) goto error; - vsnprintf(ptr + ms->length, len + 1, fmt, args); - ms->ptr = ptr; - ms->length += len; + len = vsnprintf(ms->vector.data + last - 1, len + 1, fmt, args); return len; error: