From 4abec2f7b2021d493d1aeefba5419963e6da698b Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 27 May 2013 21:53:40 +0200 Subject: [PATCH] stream: add partial read function This is a nice way to avoid an additional copy of the data when reading with stream_read(). --- stream/stream.c | 44 +++++++++++++++++++++++++++----------------- stream/stream.h | 1 + 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/stream/stream.c b/stream/stream.c index 60b3571b82..230f08a198 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -432,28 +432,38 @@ int stream_fill_buffer(stream_t *s) return len; } +// Read between 1..buf_size bytes of data, return how much data has been read. +// Return <= 0 on EOF, error, of if buf_size was 0. +int stream_read_partial(stream_t *s, char *buf, int buf_size) +{ + assert(s->buf_pos <= s->buf_len); + assert(buf_size >= 0); + if (s->buf_pos == s->buf_len && buf_size > 0) { + s->buf_pos = s->buf_len = 0; + // Do a direct read, but only if there's no sector alignment requirement + // Also, small reads will be more efficient with buffering & copying + if (!s->sector_size && buf_size >= STREAM_BUFFER_SIZE) + return stream_read_unbuffered(s, buf, buf_size); + if (!stream_fill_buffer(s)) + return 0; + } + int len = FFMIN(buf_size, s->buf_len - s->buf_pos); + memcpy(buf, &s->buffer[s->buf_pos], len); + s->buf_pos += len; + return len; +} + int stream_read(stream_t *s, char *mem, int total) { int len = total; while (len > 0) { - int x; - x = s->buf_len - s->buf_pos; - if (x == 0) { - if (!stream_fill_buffer(s)) - return total - len; // EOF - x = s->buf_len - s->buf_pos; - } - if (s->buf_pos > s->buf_len) - mp_msg(MSGT_DEMUX, MSGL_WARN, - "stream_read: WARNING! s->buf_pos>s->buf_len\n"); - if (x > len) - x = len; - memcpy(mem, &s->buffer[s->buf_pos], x); - s->buf_pos += x; - mem += x; - len -= x; + int read = stream_read_partial(s, mem, len); + if (read <= 0) + break; // EOF + mem += read; + len -= read; } - return total; + return total - len; } int stream_write_buffer(stream_t *s, unsigned char *buf, int len) diff --git a/stream/stream.h b/stream/stream.h index 12ef430b28..68e22725b6 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -301,6 +301,7 @@ inline static int64_t stream_tell(stream_t *s) int stream_skip(stream_t *s, int64_t len); int stream_seek(stream_t *s, int64_t pos); int stream_read(stream_t *s, char *mem, int total); +int stream_read_partial(stream_t *s, char *buf, int buf_size); struct MPOpts; /*