[FFmpeg-devel] [PATCH 1/4] lavu/bprint: implement av_bprint_strftime().

Clément Bœsch ubitux at gmail.com
Wed Nov 14 00:30:15 CET 2012


On Sun, Nov 11, 2012 at 06:56:42PM +0100, Nicolas George wrote:
> 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;

nit++: can be local to the loop

> +    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;

maybe add a comment somewhere saying the loop is for guessing the size of
big enough buffer; it's not that obvious at first glance what's going on
here.

> +        if (!room)
> +            room = strlen(fmt) / 2 + 1;
> +        if (av_bprint_alloc(buf, room <= INT_MAX / 2 ? room * 2 : INT_MAX)) {
> +            /* 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) {
> +                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 */
> +            }
> +            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;
> +/**
> + * Append a formated date and time to a print buffer.
> + * Note: due to poor design of the standard strftime function, it can only
> + * be used when no overflow is possible (size_max huge).

I don't understand what this "size_max" means…

> + */
> +void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm);
> +
>  /**
>   * Allocate bytes in the buffer for external use.
>   *
> diff --git a/tests/ref/fate/bprint b/tests/ref/fate/bprint
> index e027fa1..b33c1ae 100644
> --- a/tests/ref/fate/bprint
> +++ b/tests/ref/fate/bprint
> @@ -12,3 +12,5 @@ Short text in automatic buffer: 174/174
>  Long text in automatic buffer: 1000/2834
>  Long text count only buffer: 0/2834
>  Long text count only buffer: 255/2834
> +strftime full: 255/10 "2000-12-20"
> +strftime truncated: 255/10 "2000-12"

Still looks OK to me.

-- 
Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20121114/11b32132/attachment.asc>


More information about the ffmpeg-devel mailing list