/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "istream-private.h" #include "fs-api-private.h" #include "istream-fs-file.h" struct fs_file_istream { struct istream_private istream; struct fs_file *file; }; static void i_stream_fs_file_close(struct iostream_private *stream, bool close_parent ATTR_UNUSED) { struct fs_file_istream *fstream = (struct fs_file_istream *)stream; i_stream_destroy(&fstream->istream.parent); fs_file_deinit(&fstream->file); } static ssize_t i_stream_fs_file_read(struct istream_private *stream) { struct fs_file_istream *fstream = (struct fs_file_istream *)stream; struct istream *input; if (fstream->istream.parent == NULL) { input = fs_read_stream(fstream->file, i_stream_get_max_buffer_size(&stream->istream)); i_stream_init_parent(stream, input); i_stream_unref(&input); } i_stream_seek(stream->parent, stream->parent_start_offset + stream->istream.v_offset); return i_stream_read_copy_from_parent(&stream->istream); } struct istream * i_stream_create_fs_file(struct fs_file **file, size_t max_buffer_size) { struct fs_file_istream *fstream; struct istream *input; fstream = i_new(struct fs_file_istream, 1); fstream->file = *file; fstream->istream.iostream.close = i_stream_fs_file_close; fstream->istream.max_buffer_size = max_buffer_size; fstream->istream.read = i_stream_fs_file_read; fstream->istream.stream_size_passthrough = TRUE; fstream->istream.istream.blocking = ((*file)->flags & FS_OPEN_FLAG_ASYNC) == 0; fstream->istream.istream.seekable = ((*file)->flags & FS_OPEN_FLAG_SEEKABLE) != 0; input = i_stream_create(&fstream->istream, NULL, -1, 0); i_stream_set_name(input, fs_file_path(*file)); *file = NULL; return input; }