bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen#include "lib.h"
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen#include "hash-method.h"
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen#include "ostream-private.h"
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen#include "ostream-hash.h"
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainenstruct hash_ostream {
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen struct ostream_private ostream;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen const struct hash_method *method;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen void *hash_context;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen};
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainenstatic ssize_t
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Siraineno_stream_hash_sendv(struct ostream_private *stream,
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen const struct const_iovec *iov, unsigned int iov_count)
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen{
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen struct hash_ostream *hstream = (struct hash_ostream *)stream;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen unsigned int i;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen size_t bytes_left, block_len;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen ssize_t ret;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen if ((ret = o_stream_sendv(stream->parent, iov, iov_count)) < 0) {
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen o_stream_copy_error_from_parent(stream);
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen return -1;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen }
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen if (ret > 0) {
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen bytes_left = ret;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen for (i = 0; i < iov_count && bytes_left > 0; i++) {
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen block_len = iov[i].iov_len <= bytes_left ?
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen iov[i].iov_len : bytes_left;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen hstream->method->loop(hstream->hash_context,
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen iov[i].iov_base, block_len);
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen bytes_left -= block_len;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen }
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen }
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen stream->ostream.offset += ret;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen return ret;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen}
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainenstruct ostream *
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Siraineno_stream_create_hash(struct ostream *output, const struct hash_method *method,
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen void *hash_context)
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen{
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen struct hash_ostream *hstream;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen hstream = i_new(struct hash_ostream, 1);
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen hstream->ostream.sendv = o_stream_hash_sendv;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen hstream->method = method;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen hstream->hash_context = hash_context;
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen return o_stream_create(&hstream->ostream, output,
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen o_stream_get_fd(output));
2e5d4199ae0f51de146480d13780530c7dd9e3e4Timo Sirainen}