Commit 4cd74c81 authored by Nicolas George's avatar Nicolas George

lavu/bprint: implement av_bprint_strftime().

parent f96a6531
...@@ -15,6 +15,9 @@ libavutil: 2012-10-22 ...@@ -15,6 +15,9 @@ libavutil: 2012-10-22
API changes, most recent first: API changes, most recent first:
2012-11-17 - xxxxxxx - lavu 52.8.100 - bprint.h
Add av_bprint_strftime().
2012-11-15 - xxxxxxx - lavu 52.7.100 - opt.h 2012-11-15 - xxxxxxx - lavu 52.7.100 - opt.h
Add av_opt_get_key_value(). Add av_opt_get_key_value().
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h>
#include "avassert.h" #include "avassert.h"
#include "bprint.h" #include "bprint.h"
#include "common.h" #include "common.h"
...@@ -129,6 +130,48 @@ void av_bprint_chars(AVBPrint *buf, char c, unsigned n) ...@@ -129,6 +130,48 @@ void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
av_bprint_grow(buf, 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;
/* strftime does not tell us how much room it would need: let us
retry with twice as much until the buffer is large enough */
room = !room ? strlen(fmt) + 1 :
room <= INT_MAX / 2 ? room * 2 : INT_MAX;
if (av_bprint_alloc(buf, room)) {
/* impossible to grow, try to manage something useful anyway */
room = av_bprint_room(buf);
if (room < 1024) {
/* if strftime fails because the buffer has (almost) reached
its maximum size, let us try in a local buffer; 1k should
be enough to format any real date+time string */
char buf2[1024];
if ((l = strftime(buf2, sizeof(buf2), fmt, tm))) {
av_bprintf(buf, "%s", buf2);
return;
}
}
if (room) {
/* if anything else failed and the buffer is not already
truncated, let us add a stock string and force truncation */
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, void av_bprint_get_buffer(AVBPrint *buf, unsigned size,
unsigned char **mem, unsigned *actual_size) unsigned char **mem, unsigned *actual_size)
{ {
...@@ -201,6 +244,7 @@ int main(void) ...@@ -201,6 +244,7 @@ int main(void)
{ {
AVBPrint b; AVBPrint b;
char buf[256]; char buf[256];
struct tm testtime = { .tm_year = 100, .tm_mon = 11, .tm_mday = 20 };
av_bprint_init(&b, 0, -1); av_bprint_init(&b, 0, -1);
bprint_pascal(&b, 5); bprint_pascal(&b, 5);
...@@ -235,6 +279,15 @@ int main(void) ...@@ -235,6 +279,15 @@ int main(void)
bprint_pascal(&b, 25); bprint_pascal(&b, 25);
printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(buf), b.len); 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; return 0;
} }
......
...@@ -116,7 +116,7 @@ void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max); ...@@ -116,7 +116,7 @@ void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max);
void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size); void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size);
/** /**
* Append a formated string to a print buffer. * Append a formatted string to a print buffer.
*/ */
void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3); void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3);
...@@ -125,6 +125,20 @@ void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3); ...@@ -125,6 +125,20 @@ void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3);
*/ */
void av_bprint_chars(AVBPrint *buf, char c, unsigned n); void av_bprint_chars(AVBPrint *buf, char c, unsigned n);
struct tm;
/**
* Append a formatted date and time to a print buffer.
*
* param buf bprint buffer to use
* param fmt date and time format string, see strftime()
* param tm broken-down time structure to translate
*
* @note due to poor design of the standard strftime function, it may
* produce poor results if the format string expands to a very long text and
* the bprint buffer is near the limit stated by the size_max option.
*/
void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm);
/** /**
* Allocate bytes in the buffer for external use. * Allocate bytes in the buffer for external use.
* *
......
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
*/ */
#define LIBAVUTIL_VERSION_MAJOR 52 #define LIBAVUTIL_VERSION_MAJOR 52
#define LIBAVUTIL_VERSION_MINOR 7 #define LIBAVUTIL_VERSION_MINOR 8
#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
......
...@@ -12,3 +12,5 @@ Short text in automatic buffer: 174/174 ...@@ -12,3 +12,5 @@ Short text in automatic buffer: 174/174
Long text in automatic buffer: 1000/2834 Long text in automatic buffer: 1000/2834
Long text count only buffer: 0/2834 Long text count only buffer: 0/2834
Long text count only buffer: 255/2834 Long text count only buffer: 255/2834
strftime full: 255/10 "2000-12-20"
strftime truncated: 255/10 "2000-12"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment