Mercurial > dovecot > core-2.2
view src/lib/ostream-escaped.c @ 22664:fea53c2725c0
director: Fix director_max_parallel_moves/kicks type
Should be uint, not time.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 09 Nov 2017 12:24:16 +0200 |
parents | 2e2563132d5f |
children | cb108f786fb4 |
line wrap: on
line source
/* Copyright (c) 2016-2017 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "ostream.h" #include "ostream-private.h" #include "ostream-escaped.h" struct escaped_ostream { struct ostream_private ostream; ostream_escaped_escape_formatter_t format; string_t *buf; bool flushed; }; static ssize_t o_stream_escaped_send_outbuf(struct escaped_ostream *estream) { ssize_t ret; if (estream->flushed) return 1; /* nothing to send */ ret = o_stream_send(estream->ostream.parent, str_data(estream->buf), str_len(estream->buf)); if (ret < 0) { o_stream_copy_error_from_parent(&estream->ostream); return -1; } if ((size_t)ret != str_len(estream->buf)) { /* move data */ str_delete(estream->buf, 0, ret); return 0; } str_truncate(estream->buf, 0); estream->flushed = TRUE; return 1; } static ssize_t o_stream_escaped_send_chunk(struct escaped_ostream *estream, const unsigned char *data, size_t len) { size_t i, max_buffer_size; ssize_t ret; max_buffer_size = I_MIN(o_stream_get_max_buffer_size(estream->ostream.parent), estream->ostream.max_buffer_size); if (max_buffer_size > IO_BLOCK_SIZE) { /* avoid using up too much memory in case of large buffers */ max_buffer_size = IO_BLOCK_SIZE; } for (i = 0; i < len; i++) { if (str_len(estream->buf) + 2 > max_buffer_size) { /* escaping takes at least two bytes */ ret = o_stream_escaped_send_outbuf(estream); if (ret < 0) { estream->ostream.ostream.offset += i; return ret; } if (ret == 0) break; } estream->format(estream->buf, data[i]); estream->flushed = FALSE; } estream->ostream.ostream.offset += i; return i; } static ssize_t o_stream_escaped_sendv(struct ostream_private *stream, const struct const_iovec *iov, unsigned int iov_count) { struct escaped_ostream *estream = (struct escaped_ostream *)stream; unsigned int iov_cur; ssize_t ret, bytes = 0; for (iov_cur = 0; iov_cur < iov_count; iov_cur++) { ret = o_stream_escaped_send_chunk(estream, iov[iov_cur].iov_base, iov[iov_cur].iov_len); if (ret < 0) return ret; bytes += ret; if ((size_t)ret != iov[iov_cur].iov_len) break; } if (o_stream_escaped_send_outbuf(estream) < 0) return -1; return bytes; } static int o_stream_escaped_flush(struct ostream_private *stream) { struct escaped_ostream *estream = (struct escaped_ostream *)stream; int ret; if ((ret = o_stream_escaped_send_outbuf(estream)) <= 0) return ret; if ((ret = o_stream_flush(stream->parent)) < 0) o_stream_copy_error_from_parent(stream); return ret; } static void o_stream_escaped_destroy(struct iostream_private *stream) { struct escaped_ostream *estream = (struct escaped_ostream *)stream; str_free(&estream->buf); o_stream_unref(&estream->ostream.parent); } void ostream_escaped_hex_format(string_t *dest, unsigned char chr) { str_printfa(dest, "%02x", chr); } struct ostream * o_stream_create_escaped(struct ostream *output, ostream_escaped_escape_formatter_t format) { struct escaped_ostream *estream; estream = i_new(struct escaped_ostream, 1); estream->ostream.sendv = o_stream_escaped_sendv; estream->ostream.flush = o_stream_escaped_flush; estream->ostream.max_buffer_size = o_stream_get_max_buffer_size(output); estream->ostream.iostream.destroy = o_stream_escaped_destroy; estream->buf = str_new(default_pool, 512); estream->format = format; estream->flushed = FALSE; return o_stream_create(&estream->ostream, output, o_stream_get_fd(output)); }