summaryrefslogtreecommitdiffstats
path: root/stream/stream.c
diff options
context:
space:
mode:
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 6f35252e3d..86dd61389e 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -29,6 +29,8 @@
#include <fcntl.h>
#include <strings.h>
+#include "talloc.h"
+
#include "config.h"
#if HAVE_WINSOCK2_H
@@ -658,3 +660,35 @@ unsigned char* stream_read_line(stream_t *s,unsigned char* mem, int max, int utf
if(s->eof && ptr == mem) return NULL;
return mem;
}
+
+struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
+ int max_size, int padding_bytes)
+{
+ if (max_size > 1000000000)
+ abort();
+
+ int bufsize;
+ int total_read = 0;
+ int padding = FFMAX(padding_bytes, 1);
+ char *buf = NULL;
+ if (s->end_pos > max_size)
+ return (struct bstr){NULL, 0};
+ if (s->end_pos > 0)
+ bufsize = s->end_pos + padding;
+ else
+ bufsize = 1000;
+ while (1) {
+ buf = talloc_realloc_size(talloc_ctx, buf, bufsize);
+ int readsize = stream_read(s, buf + total_read, bufsize - total_read);
+ total_read += readsize;
+ if (total_read < bufsize)
+ break;
+ if (bufsize > max_size) {
+ talloc_free(buf);
+ return (struct bstr){NULL, 0};
+ }
+ bufsize = FFMIN(bufsize + (bufsize >> 1), max_size + padding);
+ }
+ buf = talloc_realloc_size(talloc_ctx, buf, total_read + padding);
+ return (struct bstr){buf, total_read};
+}