summaryrefslogtreecommitdiffstats
path: root/src/lib/istream-private.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/istream-private.h140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/lib/istream-private.h b/src/lib/istream-private.h
new file mode 100644
index 0000000..b612b9c
--- /dev/null
+++ b/src/lib/istream-private.h
@@ -0,0 +1,140 @@
+#ifndef ISTREAM_PRIVATE_H
+#define ISTREAM_PRIVATE_H
+
+#include "istream.h"
+#include "iostream-private.h"
+
+#define I_STREAM_MIN_SIZE IO_BLOCK_SIZE
+
+struct io;
+
+struct istream_private {
+/* inheritance: */
+ struct iostream_private iostream;
+
+/* methods: */
+ ssize_t (*read)(struct istream_private *stream);
+ void (*seek)(struct istream_private *stream,
+ uoff_t v_offset, bool mark);
+ void (*sync)(struct istream_private *stream);
+ int (*stat)(struct istream_private *stream, bool exact);
+ int (*get_size)(struct istream_private *stream, bool exact, uoff_t *size_r);
+ void (*switch_ioloop_to)(struct istream_private *stream,
+ struct ioloop *ioloop);
+ struct istream_snapshot *
+ (*snapshot)(struct istream_private *stream,
+ struct istream_snapshot *prev_snapshot);
+
+/* data: */
+ struct istream istream;
+
+ int fd;
+ uoff_t start_offset;
+ struct stat statbuf;
+ /* added by io_add_istream() -> i_stream_set_io() */
+ struct io *io;
+
+ const unsigned char *buffer;
+ unsigned char *w_buffer; /* may be NULL */
+
+ size_t buffer_size, max_buffer_size, init_buffer_size, data_limit;
+ size_t skip, pos;
+ /* If seeking backwards within the buffer, the next read() will
+ return again pos..high_pos */
+ size_t high_pos;
+
+ struct istream *parent; /* for filter streams */
+ uoff_t parent_start_offset;
+ /* Initially UOFF_T_MAX. Otherwise it's the exact known stream size,
+ which can be used by stat() / get_size(). */
+ uoff_t cached_stream_size;
+
+ /* parent stream's expected offset is kept here. i_stream_read()
+ always seeks parent stream to here before calling read(). */
+ uoff_t parent_expected_offset;
+
+ struct memarea *memarea;
+ struct istream_snapshot *prev_snapshot;
+ /* increased every time the stream is changed (e.g. seek, read).
+ this way streams can check if their parent streams have been
+ accessed behind them. */
+ unsigned int access_counter;
+ /* Timestamp when read() last returned >0 */
+ struct timeval last_read_timeval;
+
+ string_t *line_str; /* for i_stream_next_line() if w_buffer == NULL */
+ bool line_crlf:1;
+ bool return_nolf_line:1;
+ bool stream_size_passthrough:1; /* stream is parent's size */
+ bool nonpersistent_buffers:1;
+ bool io_pending:1;
+};
+
+struct istream_snapshot {
+ struct istream_snapshot *prev_snapshot;
+ struct memarea *old_memarea;
+ struct istream *istream;
+ void (*free)(struct istream_snapshot *snapshot);
+};
+
+enum istream_create_flag {
+ /* The stream guarantees that the buffer pointer stays valid when it
+ returns <= 0. */
+ ISTREAM_CREATE_FLAG_NOOP_SNAPSHOT = 0x01,
+};
+
+struct istream * ATTR_NOWARN_UNUSED_RESULT
+i_stream_create(struct istream_private *stream, struct istream *parent, int fd,
+ enum istream_create_flag flags) ATTR_NULL(2);
+/* Initialize parent lazily after i_stream_create() has already been called. */
+void i_stream_init_parent(struct istream_private *_stream,
+ struct istream *parent);
+
+void i_stream_compress(struct istream_private *stream);
+void i_stream_grow_buffer(struct istream_private *stream, size_t bytes);
+bool ATTR_NOWARN_UNUSED_RESULT
+i_stream_try_alloc(struct istream_private *stream,
+ size_t wanted_size, size_t *size_r);
+/* Like i_stream_try_alloc(), but compress only if it's the only way to get
+ more space. This can be useful when stream is marked with
+ i_stream_seek_mark() */
+bool ATTR_NOWARN_UNUSED_RESULT
+i_stream_try_alloc_avoid_compress(struct istream_private *stream,
+ size_t wanted_size, size_t *size_r);
+void *i_stream_alloc(struct istream_private *stream, size_t size);
+/* Detach istream from its current memarea. This unreferences the memarea and
+ resets the w_buffer to empty. This can be used to make sure i_stream_*alloc()
+ won't return a pointer to memory referenced to in a snapshot. */
+void i_stream_memarea_detach(struct istream_private *stream);
+/* Free memory allocated by i_stream_*alloc() */
+void i_stream_free_buffer(struct istream_private *stream);
+ssize_t i_stream_read_copy_from_parent(struct istream *istream);
+void i_stream_default_seek_nonseekable(struct istream_private *stream,
+ uoff_t v_offset, bool mark);
+/* Returns FALSE if seeking must be done by starting from the beginning.
+ The caller is then expected to reset the stream and call this function
+ again, which should work then. If TRUE is returned, the seek was either
+ successfully done or stream_errno is set. */
+bool i_stream_nonseekable_try_seek(struct istream_private *stream,
+ uoff_t v_offset);
+
+/* Default snapshot handling: use memarea if it exists, otherwise snapshot
+ parent stream. */
+struct istream_snapshot *
+i_stream_default_snapshot(struct istream_private *stream,
+ struct istream_snapshot *prev_snapshot);
+void i_stream_snapshot_free(struct istream_snapshot **snapshot);
+
+struct istream *i_stream_get_root_io(struct istream *stream);
+void i_stream_set_io(struct istream *stream, struct io *io);
+void i_stream_unset_io(struct istream *stream, struct io *io);
+
+/* Filter istreams should be calling this instead of i_stream_read() to avoid
+ unnecessarily referencing memareas. After this call any pointers to the
+ parent istream's content must be considered as potentially invalid and have
+ to be updated, even if the return value is <=0. */
+ssize_t i_stream_read_memarea(struct istream *stream);
+int i_stream_read_more_memarea(struct istream *stream,
+ const unsigned char **data_r, size_t *size_r);
+
+#endif