[FFmpeg-devel] [PATCH 1/4] lavu/bprint: implement av_bprint_strftime().
Stefano Sabatini
stefasab at gmail.com
Thu Nov 15 01:35:28 CET 2012
On date Sunday 2012-11-11 18:56:42 +0100, Nicolas George encoded:
> TODO bump & APIchanges
>
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
> libavutil/bprint.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> libavutil/bprint.h | 8 ++++++++
> tests/ref/fate/bprint | 2 ++
> 3 files changed, 56 insertions(+)
>
> diff --git a/libavutil/bprint.c b/libavutil/bprint.c
> index 9d8e7c1..633064d 100644
> --- a/libavutil/bprint.c
> +++ b/libavutil/bprint.c
> @@ -21,6 +21,7 @@
> #include <stdarg.h>
> #include <stdio.h>
> #include <string.h>
> +#include <time.h>
> #include "avassert.h"
> #include "bprint.h"
> #include "common.h"
> @@ -129,6 +130,41 @@ void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
> av_bprint_grow(buf, n);
> }
>
> +void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm)
> +{
> + unsigned room;
> + size_t l;
> +
> + if (!*fmt)
> + return;
> + while (1) {
> + room = av_bprint_room(buf);
> + if (room && (l = strftime(buf->str + buf->len, room, fmt, tm)))
> + break;
> + if (!room)
> + room = strlen(fmt) / 2 + 1;
> + if (av_bprint_alloc(buf, room <= INT_MAX / 2 ? room * 2 : INT_MAX)) {
This is a bit weird, you divide by 2 and then multiply room by 2, I'd
find more readable if you just store the wanted room value (checked
for overflow) in room.
Note: a <0 check looks more robust in case the function is extended to
return >= 0 in case of success.
> + /* impossible to grow, try to manage something useful anyway */
> + room = av_bprint_room(buf);
> + if (room < 1024) {
> + char buf2[1024];
> + if ((l = strftime(buf2, sizeof(buf2), fmt, tm))) {
> + av_bprintf(buf, "%s", buf2);
> + return;
> + }
> + }
> + if (room) {
else? If not (room < 1024) this is always true.
> + static const char txt[] = "[truncated strftime output]";
> + memset(buf->str + buf->len, '!', room);
> + memcpy(buf->str + buf->len, txt, FFMIN(sizeof(txt) - 1, room));
> + av_bprint_grow(buf, room); /* force truncation */
> + }
Also why the <1024 case?
> + return;
> + }
> + }
> + av_bprint_grow(buf, l);
> +}
> +
> void av_bprint_get_buffer(AVBPrint *buf, unsigned size,
> unsigned char **mem, unsigned *actual_size)
> {
> @@ -201,6 +237,7 @@ int main(void)
> {
> AVBPrint b;
> char buf[256];
> + struct tm testtime = { .tm_year = 100, .tm_mon = 11, .tm_mday = 20 };
>
> av_bprint_init(&b, 0, -1);
> bprint_pascal(&b, 5);
> @@ -235,6 +272,15 @@ int main(void)
> bprint_pascal(&b, 25);
> printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(buf), b.len);
>
> + av_bprint_init(&b, 0, -1);
> + av_bprint_strftime(&b, "%Y-%m-%d", &testtime);
> + printf("strftime full: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str);
> + av_bprint_finalize(&b, NULL);
> +
> + av_bprint_init(&b, 0, 8);
> + av_bprint_strftime(&b, "%Y-%m-%d", &testtime);
> + printf("strftime truncated: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str);
> +
> return 0;
> }
>
> diff --git a/libavutil/bprint.h b/libavutil/bprint.h
> index c09b61f..44bc7b3 100644
> --- a/libavutil/bprint.h
> +++ b/libavutil/bprint.h
> @@ -125,6 +125,14 @@ void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3);
> */
> void av_bprint_chars(AVBPrint *buf, char c, unsigned n);
>
> +struct tm;
Since this is going to be used together with struct tm, maybe it would
be a good idea to add the header which defined struct tm.
> +/**
> + * Append a formated date and time to a print buffer.
"formatted" ?
> + * Note: due to poor design of the standard strftime function, it can only
> + * be used when no overflow is possible (size_max huge).
Uhm, this is not very clear (why can it overflow, what is "size_max huge"?).
> + */
> +void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm);
[...]
--
FFmpeg = Faithful & Fanciful Mean Philosophical Enhancing Gargoyle
More information about the ffmpeg-devel
mailing list