summaryrefslogtreecommitdiffstats
path: root/stream/stream.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-21 21:06:36 +0200
committerwm4 <wm4@nowhere>2013-06-25 00:11:55 +0200
commita40ae2de846d6f3e4fd6356c4914678c0588e083 (patch)
treeb5755ac4d684d93ca729ad0fc28d5534fd20cb15 /stream/stream.c
parent3993f551df715447223ee77cd79e8504d89e7862 (diff)
downloadmpv-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.c34
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;