void *context);
void (*flush_pending)(struct ostream_private *stream, bool set);
size_t (*get_used_size)(const struct ostream_private *stream);
+ size_t (*get_buffer_used_size)(const struct ostream_private *stream);
+ size_t (*get_buffer_avail_size)(const struct ostream_private *stream);
int (*seek)(struct ostream_private *stream, uoff_t offset);
ssize_t (*sendv)(struct ostream_private *stream,
const struct const_iovec *iov,
{
const struct ostream_private *_stream = stream->real_stream;
+ if (_stream->get_buffer_used_size != NULL)
+ return _stream->get_buffer_used_size(_stream);
+
return _stream->get_used_size(_stream);
}
size_t o_stream_get_buffer_avail_size(const struct ostream *stream)
{
- size_t used = o_stream_get_buffer_used_size(stream);
+ const struct ostream_private *_stream = stream->real_stream;
- return stream->real_stream->max_buffer_size <= used ? 0 :
- stream->real_stream->max_buffer_size - used;
+ return _stream->get_buffer_avail_size(_stream);
}
int o_stream_seek(struct ostream *stream, uoff_t offset)
return o_stream_get_buffer_used_size(_stream->parent);
}
+static size_t
+o_stream_default_get_buffer_avail_size(const struct ostream_private *_stream)
+{
+ /* This default implementation assumes that the returned buffer size is
+ between 0..max_buffer_size. There's no assert though, in case the
+ max_buffer_size changes. */
+ size_t used = o_stream_get_buffer_used_size(&_stream->ostream);
+
+ return _stream->max_buffer_size <= used ? 0 :
+ _stream->max_buffer_size - used;
+}
+
static int
o_stream_default_seek(struct ostream_private *_stream,
uoff_t offset ATTR_UNUSED)
_stream->flush_pending = o_stream_default_set_flush_pending;
if (_stream->get_used_size == NULL)
_stream->get_used_size = o_stream_default_get_used_size;
+ if (_stream->get_buffer_avail_size == NULL) {
+ _stream->get_buffer_avail_size =
+ o_stream_default_get_buffer_avail_size;
+ }
if (_stream->seek == NULL)
_stream->seek = o_stream_default_seek;
if (_stream->sendv == NULL)
/* Set "flush pending" state of stream. If set, the flush callback is called
when more data is allowed to be sent, even if the buffer itself is empty. */
void o_stream_set_flush_pending(struct ostream *stream, bool set);
-/* Returns number of bytes currently in buffer. */
+/* Returns the number of bytes currently in all the pending write buffers of
+ this ostream, including its parent streams. This function is commonly used
+ by callers to determine when they've filled up the ostream so they can stop
+ writing to it. Because of this, the return value shouldn't include buffers
+ that are expected to be filled up before they send anything to their parent
+ stream. Otherwise the callers may stop writing to the stream too early and
+ hang. Such an example could be a compression ostream that won't send
+ anything to its parent stream before an internal compression buffer is
+ full. */
size_t o_stream_get_buffer_used_size(const struct ostream *stream) ATTR_PURE;
-/* Returns number of bytes we can still write without failing. */
+/* Returns the (minimum) number of bytes we can still write without failing.
+ This is commonly used by callers to find out how many bytes they're
+ guaranteed to be able to send, and then generate that much data and send
+ it. */
size_t o_stream_get_buffer_avail_size(const struct ostream *stream) ATTR_PURE;
/* Seek to specified position from beginning of file. This works only for