From: Timo Sirainen Date: Mon, 9 Sep 2013 01:34:58 +0000 (+0300) Subject: liblib: Added istream-hash, similar to ostream-hash. X-Git-Tag: 2.2.6~104 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3157f61431f19e01173e2e0d270c28af86dc97aa;p=thirdparty%2Fdovecot%2Fcore.git liblib: Added istream-hash, similar to ostream-hash. --- diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index eec3376f17..054996b608 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -62,6 +62,7 @@ liblib_la_SOURCES = \ istream-crlf.c \ istream-data.c \ istream-file.c \ + istream-hash.c \ istream-jsonstr.c \ istream-limit.c \ istream-mmap.c \ @@ -189,6 +190,7 @@ headers = \ istream-chain.h \ istream-concat.h \ istream-crlf.h \ + istream-hash.h \ istream-jsonstr.h \ istream-private.h \ istream-rawlog.h \ diff --git a/src/lib/istream-hash.c b/src/lib/istream-hash.c new file mode 100644 index 0000000000..855e30b49c --- /dev/null +++ b/src/lib/istream-hash.c @@ -0,0 +1,60 @@ +/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "hash-method.h" +#include "istream-private.h" +#include "istream-hash.h" + +struct hash_istream { + struct istream_private istream; + + const struct hash_method *method; + void *hash_context; +}; + +static ssize_t +i_stream_hash_read(struct istream_private *stream) +{ + struct hash_istream *hstream = (struct hash_istream *)stream; + const unsigned char *data; + size_t size; + ssize_t ret; + + i_stream_seek(stream->parent, stream->parent_start_offset + + stream->istream.v_offset); + + ret = i_stream_read_copy_from_parent(&stream->istream); + if (ret > 0 && hstream->hash_context != NULL) { + data = i_stream_get_data(&stream->istream, &size); + i_assert((size_t)ret <= size); + hstream->method->loop(hstream->hash_context, + data+(size-ret), ret); + } else if (ret < 0) { + /* we finished hashing it. don't access it anymore, because + the memory pointed by the hash may be freed before the + istream itself */ + hstream->hash_context = NULL; + } + return ret; +} + +struct istream * +i_stream_create_hash(struct istream *input, const struct hash_method *method, + void *hash_context) +{ + struct hash_istream *hstream; + + hstream = i_new(struct hash_istream, 1); + hstream->istream.max_buffer_size = input->real_stream->max_buffer_size; + hstream->istream.stream_size_passthrough = TRUE; + + hstream->istream.read = i_stream_hash_read; + + hstream->istream.istream.blocking = input->blocking; + hstream->istream.istream.seekable = FALSE; + + hstream->method = method; + hstream->hash_context = hash_context; + return i_stream_create(&hstream->istream, input, + i_stream_get_fd(input)); +} diff --git a/src/lib/istream-hash.h b/src/lib/istream-hash.h new file mode 100644 index 0000000000..bd22201220 --- /dev/null +++ b/src/lib/istream-hash.h @@ -0,0 +1,12 @@ +#ifndef ISTREAM_HASH_H +#define ISTREAM_HASH_H + +struct hash_method; + +/* hash_context must be allocated and initialized by caller. This istream will + simply call method->loop() for all the data going through the istream. */ +struct istream * +i_stream_create_hash(struct istream *input, const struct hash_method *method, + void *hash_context); + +#endif