diff options
author | wm4 <wm4@nowhere> | 2013-06-21 21:06:36 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-06-25 00:11:55 +0200 |
commit | a40ae2de846d6f3e4fd6356c4914678c0588e083 (patch) | |
tree | b5755ac4d684d93ca729ad0fc28d5534fd20cb15 /stream/stream.c | |
parent | 3993f551df715447223ee77cd79e8504d89e7862 (diff) | |
download | mpv-a40ae2de846d6f3e4fd6356c4914678c0588e083.tar.bz2 mpv-a40ae2de846d6f3e4fd6356c4914678c0588e083.tar.xz |
stream: add stream_peek function
Makes probing easier, and this is perhaps a simpler interface than
stream_unread_buffer().
Diffstat (limited to 'stream/stream.c')
-rw-r--r-- | stream/stream.c | 34 |
1 files changed, 34 insertions, 0 deletions
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; |