From a40ae2de846d6f3e4fd6356c4914678c0588e083 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 21 Jun 2013 21:06:36 +0200 Subject: stream: add stream_peek function Makes probing easier, and this is perhaps a simpler interface than stream_unread_buffer(). --- stream/stream.c | 34 ++++++++++++++++++++++++++++++++++ stream/stream.h | 1 + 2 files changed, 35 insertions(+) (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index c70a593294..1523a1017e 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -466,6 +466,40 @@ int stream_read(stream_t *s, char *mem, int total) return total - len; } +// Read ahead at most len bytes without changing the read position. Return a +// pointer to the internal buffer, starting from the current read position. +// Can read ahead at most STREAM_MAX_BUFFER_SIZE bytes. +// The returned buffer becomes invalid on the next stream call, and you must +// not write to it. +struct bstr stream_peek(stream_t *s, int len) +{ + assert(len >= 0); + assert(len <= STREAM_MAX_BUFFER_SIZE); + // Logically like: stream_read(); stream_unread_buffer(); return buffer; + if (s->buf_len - s->buf_pos < len) { + // Move to front to guarantee we really can read up to max size. + int buf_valid = s->buf_len - s->buf_pos; + memmove(s->buffer, &s->buffer[s->buf_pos], buf_valid); + // Fill rest of the buffer. + while (buf_valid < len) { + int chunk = len - buf_valid; + if (s->sector_size) + chunk = STREAM_BUFFER_SIZE; + assert(buf_valid + chunk <= TOTAL_BUFFER_SIZE); + int read = stream_read_unbuffered(s, &s->buffer[buf_valid], chunk); + if (read == 0) + break; // EOF + buf_valid += read; + } + s->buf_pos = 0; + s->buf_len = buf_valid; + if (s->buf_len) + s->eof = 0; + } + return (bstr){.start = &s->buffer[s->buf_pos], + .len = FFMIN(len, s->buf_len - s->buf_pos)}; +} + int stream_write_buffer(stream_t *s, unsigned char *buf, int len) { int rd; diff --git a/stream/stream.h b/stream/stream.h index cee7fdc248..3ebba85199 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -297,6 +297,7 @@ 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 bstr stream_peek(stream_t *s, int len); struct MPOpts; -- cgit v1.2.3