struct buffer_ostream {
struct ostream_private ostream;
buffer_t *buf;
- size_t max_buffer_size;
};
-static void
-o_stream_buffer_set_max_buffer_size(struct iostream_private *stream,
- size_t max_size)
-{
- struct buffer_ostream *bstream = (struct buffer_ostream *)stream;
-
- bstream->max_buffer_size = max_size;
-}
-
-static void o_stream_buffer_cork(struct ostream_private *stream ATTR_UNUSED,
- bool set ATTR_UNUSED)
-{
-}
-
-static int o_stream_buffer_flush(struct ostream_private *stream ATTR_UNUSED)
-{
- return 1;
-}
-
-static void
-o_stream_buffer_flush_pending(struct ostream_private *stream ATTR_UNUSED,
- bool set ATTR_UNUSED)
-{
-}
-
-static size_t
-o_stream_buffer_get_used_size(const struct ostream_private *stream ATTR_UNUSED)
-{
- return 0;
-}
-
static int o_stream_buffer_seek(struct ostream_private *stream, uoff_t offset)
{
stream->ostream.offset = offset;
unsigned int i;
for (i = 0; i < iov_count; i++) {
- left = bstream->max_buffer_size - stream->ostream.offset;
+ left = bstream->ostream.max_buffer_size -
+ stream->ostream.offset;
n = I_MIN(left, iov[i].iov_len);
buffer_write(bstream->buf, stream->ostream.offset,
iov[i].iov_base, n);
return ret;
}
-static off_t o_stream_buffer_send_istream(struct ostream_private *outstream,
- struct istream *instream)
-{
- return io_stream_copy(&outstream->ostream, instream, 1024);
-}
-
struct ostream *o_stream_create_buffer(buffer_t *buf)
{
struct buffer_ostream *bstream;
bstream = i_new(struct buffer_ostream, 1);
- bstream->ostream.iostream.set_max_buffer_size =
- o_stream_buffer_set_max_buffer_size;
-
- bstream->ostream.cork = o_stream_buffer_cork;
- bstream->ostream.flush = o_stream_buffer_flush;
- bstream->ostream.flush_pending = o_stream_buffer_flush_pending;
- bstream->ostream.get_used_size = o_stream_buffer_get_used_size;
+ bstream->ostream.max_buffer_size = (size_t)-1;
bstream->ostream.seek = o_stream_buffer_seek;
bstream->ostream.sendv = o_stream_buffer_sendv;
bstream->ostream.write_at = o_stream_buffer_write_at;
- bstream->ostream.send_istream = o_stream_buffer_send_istream;
bstream->buf = buf;
- bstream->max_buffer_size = (size_t)-1;
return o_stream_create(&bstream->ostream);
}
uoff_t real_offset;
unsigned char *buffer; /* ring-buffer */
- size_t buffer_size, max_buffer_size, optimal_block_size;
+ size_t buffer_size, optimal_block_size;
size_t head, tail; /* first unsent/unused byte */
unsigned int full:1; /* if head == tail, is buffer empty or full? */
i_free(fstream->buffer);
}
-static void
-o_stream_file_set_max_buffer_size(struct iostream_private *stream,
- size_t max_size)
-{
- struct file_ostream *fstream = (struct file_ostream *)stream;
-
- fstream->max_buffer_size = max_size;
-}
-
static size_t file_buffer_get_used_size(struct file_ostream *fstream)
{
if (fstream->head == fstream->tail)
size_t size, new_size, end_size;
size = nearest_power(fstream->buffer_size + bytes);
- if (size > fstream->max_buffer_size) {
+ if (size > fstream->ostream.max_buffer_size) {
/* limit the size */
- size = fstream->max_buffer_size;
+ size = fstream->ostream.max_buffer_size;
} else if (fstream->corked) {
/* try to use optimal buffer size with corking */
new_size = I_MIN(fstream->optimal_block_size,
- fstream->max_buffer_size);
+ fstream->ostream.max_buffer_size);
if (new_size > size)
size = new_size;
}
}
optimal_size = I_MIN(fstream->optimal_block_size,
- fstream->max_buffer_size);
+ fstream->ostream.max_buffer_size);
if (IS_STREAM_EMPTY(fstream) &&
(!fstream->corked || size >= optimal_size)) {
/* send immediately */
fstream->ostream.iostream.close = o_stream_file_close;
fstream->ostream.iostream.destroy = o_stream_file_destroy;
- fstream->ostream.iostream.set_max_buffer_size =
- o_stream_file_set_max_buffer_size;
fstream->ostream.cork = o_stream_file_cork;
fstream->ostream.flush = o_stream_file_flush;
off_t offset;
fstream = o_stream_create_fd_common(fd, autoclose_fd);
- fstream->max_buffer_size = max_buffer_size;
+ fstream->ostream.max_buffer_size = max_buffer_size;
ostream = o_stream_create(&fstream->ostream);
offset = lseek(fd, 0, SEEK_CUR);
}
if (max_buffer_size == 0)
- fstream->max_buffer_size = fstream->optimal_block_size;
+ fstream->ostream.max_buffer_size = fstream->optimal_block_size;
return ostream;
}
fstream = o_stream_create_fd_common(fd, autoclose_fd);
fstream_init_file(fstream);
- fstream->max_buffer_size = fstream->optimal_block_size;
+ fstream->ostream.max_buffer_size = fstream->optimal_block_size;
fstream->real_offset = offset;
fstream->buffer_offset = offset;
/* data: */
struct ostream ostream;
+ size_t max_buffer_size;
stream_flush_callback_t *callback;
void *context;
void o_stream_set_max_buffer_size(struct ostream *stream, size_t max_size)
{
- io_stream_set_max_buffer_size(&stream->real_stream->iostream, max_size);
+ if (stream->real_stream->iostream.set_max_buffer_size != NULL) {
+ io_stream_set_max_buffer_size(&stream->real_stream->iostream,
+ max_size);
+ } else {
+ stream->real_stream->max_buffer_size = max_size;
+ }
}
void o_stream_cork(struct ostream *stream)
if (unlikely(stream->closed))
return;
- _stream->cork(_stream, TRUE);
+ if (_stream->cork != NULL)
+ _stream->cork(_stream, TRUE);
}
void o_stream_uncork(struct ostream *stream)
if (unlikely(stream->closed))
return;
- _stream->cork(_stream, FALSE);
+ if (_stream->cork != NULL)
+ _stream->cork(_stream, FALSE);
}
int o_stream_flush(struct ostream *stream)
{
struct ostream_private *_stream = stream->real_stream;
- int ret;
+ int ret = 1;
if (unlikely(stream->closed))
return -1;
stream->stream_errno = 0;
- if (unlikely((ret = _stream->flush(_stream)) < 0)) {
- i_assert(stream->stream_errno != 0);
- stream->last_failed_errno = stream->stream_errno;
+ if (_stream->flush != NULL) {
+ if (unlikely((ret = _stream->flush(_stream)) < 0)) {
+ i_assert(stream->stream_errno != 0);
+ stream->last_failed_errno = stream->stream_errno;
+ }
}
return ret;
}
if (unlikely(stream->closed))
return;
- _stream->flush_pending(_stream, set);
+ if (_stream->flush_pending != NULL)
+ _stream->flush_pending(_stream, set);
}
size_t o_stream_get_buffer_used_size(const struct ostream *stream)
{
const struct ostream_private *_stream = stream->real_stream;
- return _stream->get_used_size(_stream);
+ return _stream->get_used_size == NULL ? 0 :
+ _stream->get_used_size(_stream);
}
int o_stream_seek(struct ostream *stream, uoff_t offset)
return -1;
stream->stream_errno = 0;
- if (unlikely(_stream->seek(_stream, offset) < 0)) {
- i_assert(stream->stream_errno != 0);
- stream->last_failed_errno = stream->stream_errno;
+ if (_stream->seek != NULL) {
+ if (unlikely(_stream->seek(_stream, offset) < 0)) {
+ i_assert(stream->stream_errno != 0);
+ stream->last_failed_errno = stream->stream_errno;
+ }
+ } else {
+ stream->stream_errno = EPIPE;
+ stream->last_failed_errno = EPIPE;
+ return -1;
}
return 1;
}
return ret;
}
+static off_t o_stream_default_send_istream(struct ostream_private *outstream,
+ struct istream *instream)
+{
+ return io_stream_copy(&outstream->ostream, instream, 1024);
+}
+
struct ostream *o_stream_create(struct ostream_private *_stream)
{
_stream->ostream.real_stream = _stream;
+ if (_stream->send_istream == NULL)
+ _stream->send_istream = o_stream_default_send_istream;
io_stream_init(&_stream->iostream);
return &_stream->ostream;