diff options
| author | Tim Redfern <tim@eclectronics.org> | 2014-02-17 13:36:38 +0000 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2014-02-17 13:36:38 +0000 |
| commit | 22e28216336da876e1fd17f380ce42eaf1446769 (patch) | |
| tree | 444dad3dc7e2656992d29f34f7bce31970c122a5 /ffmpeg/libavutil/bprint.c | |
| parent | ae5e8541f6e06e64c28719467cdf366ac57aff31 (diff) | |
chasing indexing error
Diffstat (limited to 'ffmpeg/libavutil/bprint.c')
| -rw-r--r-- | ffmpeg/libavutil/bprint.c | 381 |
1 files changed, 0 insertions, 381 deletions
diff --git a/ffmpeg/libavutil/bprint.c b/ffmpeg/libavutil/bprint.c deleted file mode 100644 index 7786e3b..0000000 --- a/ffmpeg/libavutil/bprint.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2012 Nicolas George - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include "avassert.h" -#include "avstring.h" -#include "bprint.h" -#include "common.h" -#include "compat/va_copy.h" -#include "error.h" -#include "mem.h" - -#define av_bprint_room(buf) ((buf)->size - FFMIN((buf)->len, (buf)->size)) -#define av_bprint_is_allocated(buf) ((buf)->str != (buf)->reserved_internal_buffer) - -static int av_bprint_alloc(AVBPrint *buf, unsigned room) -{ - char *old_str, *new_str; - unsigned min_size, new_size; - - if (buf->size == buf->size_max) - return AVERROR(EIO); - if (!av_bprint_is_complete(buf)) - return AVERROR_INVALIDDATA; /* it is already truncated anyway */ - min_size = buf->len + 1 + FFMIN(UINT_MAX - buf->len - 1, room); - new_size = buf->size > buf->size_max / 2 ? buf->size_max : buf->size * 2; - if (new_size < min_size) - new_size = FFMIN(buf->size_max, min_size); - old_str = av_bprint_is_allocated(buf) ? buf->str : NULL; - new_str = av_realloc(old_str, new_size); - if (!new_str) - return AVERROR(ENOMEM); - if (!old_str) - memcpy(new_str, buf->str, buf->len + 1); - buf->str = new_str; - buf->size = new_size; - return 0; -} - -static void av_bprint_grow(AVBPrint *buf, unsigned extra_len) -{ - /* arbitrary margin to avoid small overflows */ - extra_len = FFMIN(extra_len, UINT_MAX - 5 - buf->len); - buf->len += extra_len; - if (buf->size) - buf->str[FFMIN(buf->len, buf->size - 1)] = 0; -} - -void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max) -{ - unsigned size_auto = (char *)buf + sizeof(*buf) - - buf->reserved_internal_buffer; - - if (size_max == 1) - size_max = size_auto; - buf->str = buf->reserved_internal_buffer; - buf->len = 0; - buf->size = FFMIN(size_auto, size_max); - buf->size_max = size_max; - *buf->str = 0; - if (size_init > buf->size) - av_bprint_alloc(buf, size_init - 1); -} - -void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size) -{ - buf->str = buffer; - buf->len = 0; - buf->size = size; - buf->size_max = size; - *buf->str = 0; -} - -void av_bprintf(AVBPrint *buf, const char *fmt, ...) -{ - unsigned room; - char *dst; - va_list vl; - int extra_len; - - while (1) { - room = av_bprint_room(buf); - dst = room ? buf->str + buf->len : NULL; - va_start(vl, fmt); - extra_len = vsnprintf(dst, room, fmt, vl); - va_end(vl); - if (extra_len <= 0) - return; - if (extra_len < room) - break; - if (av_bprint_alloc(buf, extra_len)) - break; - } - av_bprint_grow(buf, extra_len); -} - -void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg) -{ - unsigned room; - char *dst; - int extra_len; - va_list vl; - - while (1) { - room = av_bprint_room(buf); - dst = room ? buf->str + buf->len : NULL; - va_copy(vl, vl_arg); - extra_len = vsnprintf(dst, room, fmt, vl); - va_end(vl); - if (extra_len <= 0) - return; - if (extra_len < room) - break; - if (av_bprint_alloc(buf, extra_len)) - break; - } - av_bprint_grow(buf, extra_len); -} - -void av_bprint_chars(AVBPrint *buf, char c, unsigned n) -{ - unsigned room, real_n; - - while (1) { - room = av_bprint_room(buf); - if (n < room) - break; - if (av_bprint_alloc(buf, n)) - break; - } - if (room) { - real_n = FFMIN(n, room - 1); - memset(buf->str + buf->len, c, real_n); - } - av_bprint_grow(buf, n); -} - -void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size) -{ - unsigned room, real_n; - - while (1) { - room = av_bprint_room(buf); - if (size < room) - break; - if (av_bprint_alloc(buf, size)) - break; - } - if (room) { - real_n = FFMIN(size, room - 1); - memcpy(buf->str + buf->len, data, real_n); - } - av_bprint_grow(buf, size); -} - -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, - unsigned char **mem, unsigned *actual_size) -{ - if (size > av_bprint_room(buf)) - av_bprint_alloc(buf, size); - *actual_size = av_bprint_room(buf); - *mem = *actual_size ? buf->str + buf->len : NULL; -} - -void av_bprint_clear(AVBPrint *buf) -{ - if (buf->len) { - *buf->str = 0; - buf->len = 0; - } -} - -int av_bprint_finalize(AVBPrint *buf, char **ret_str) -{ - unsigned real_size = FFMIN(buf->len + 1, buf->size); - char *str; - int ret = 0; - - if (ret_str) { - if (av_bprint_is_allocated(buf)) { - str = av_realloc(buf->str, real_size); - if (!str) - str = buf->str; - buf->str = NULL; - } else { - str = av_malloc(real_size); - if (str) - memcpy(str, buf->str, real_size); - else - ret = AVERROR(ENOMEM); - } - *ret_str = str; - } else { - if (av_bprint_is_allocated(buf)) - av_freep(&buf->str); - } - buf->size = real_size; - return ret; -} - -#define WHITESPACES " \n\t" - -void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars, - enum AVEscapeMode mode, int flags) -{ - const char *src0 = src; - - if (mode == AV_ESCAPE_MODE_AUTO) - mode = AV_ESCAPE_MODE_BACKSLASH; /* TODO: implement a heuristic */ - - switch (mode) { - case AV_ESCAPE_MODE_QUOTE: - /* enclose the string between '' */ - av_bprint_chars(dstbuf, '\'', 1); - for (; *src; src++) { - if (*src == '\'') - av_bprintf(dstbuf, "'\\''"); - else - av_bprint_chars(dstbuf, *src, 1); - } - av_bprint_chars(dstbuf, '\'', 1); - break; - - /* case AV_ESCAPE_MODE_BACKSLASH or unknown mode */ - default: - /* \-escape characters */ - for (; *src; src++) { - int is_first_last = src == src0 || !*(src+1); - int is_ws = !!strchr(WHITESPACES, *src); - int is_strictly_special = special_chars && strchr(special_chars, *src); - int is_special = - is_strictly_special || strchr("'\\", *src) || - (is_ws && (flags & AV_ESCAPE_FLAG_WHITESPACE)); - - if (is_strictly_special || - (!(flags & AV_ESCAPE_FLAG_STRICT) && - (is_special || (is_ws && is_first_last)))) - av_bprint_chars(dstbuf, '\\', 1); - av_bprint_chars(dstbuf, *src, 1); - } - break; - } -} - -#ifdef TEST - -#undef printf - -static void bprint_pascal(AVBPrint *b, unsigned size) -{ - unsigned i, j; - unsigned p[42]; - - av_assert0(size < FF_ARRAY_ELEMS(p)); - - p[0] = 1; - av_bprintf(b, "%8d\n", 1); - for (i = 1; i <= size; i++) { - p[i] = 1; - for (j = i - 1; j > 0; j--) - p[j] = p[j] + p[j - 1]; - for (j = 0; j <= i; j++) - av_bprintf(b, "%8d", p[j]); - av_bprintf(b, "\n"); - } -} - -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); - printf("Short text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len); - printf("%s\n", b.str); - av_bprint_finalize(&b, NULL); - - av_bprint_init(&b, 0, -1); - bprint_pascal(&b, 25); - printf("Long text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len); - av_bprint_finalize(&b, NULL); - - av_bprint_init(&b, 0, 2048); - bprint_pascal(&b, 25); - printf("Long text in limited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len); - av_bprint_finalize(&b, NULL); - - av_bprint_init(&b, 0, 1); - bprint_pascal(&b, 5); - printf("Short text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str), b.len); - - av_bprint_init(&b, 0, 1); - bprint_pascal(&b, 25); - printf("Long text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str)/8*8, b.len); - /* Note that the size of the automatic buffer is arch-dependant. */ - - av_bprint_init(&b, 0, 0); - bprint_pascal(&b, 25); - printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(b.str), b.len); - - av_bprint_init_for_buffer(&b, buf, sizeof(buf)); - 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; -} - -#endif |
