istream.c revision daf029d2a627daa39d05507140f385162828172e
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen/*
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen istream.c : Input stream handling
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen Copyright (c) 2002 Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen Permission is hereby granted, free of charge, to any person obtaining
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen a copy of this software and associated documentation files (the
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen "Software"), to deal in the Software without restriction, including
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen without limitation the rights to use, copy, modify, merge, publish,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen distribute, sublicense, and/or sell copies of the Software, and to
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen permit persons to whom the Software is furnished to do so, subject to
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen the following conditions:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen The above copyright notice and this permission notice shall be
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen included in all copies or substantial portions of the Software.
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen*/
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen#include "lib.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "istream-internal.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid i_stream_ref(struct istream *stream)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _io_stream_ref(&stream->real_stream->iostream);
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid i_stream_unref(struct istream *stream)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _io_stream_unref(&stream->real_stream->iostream);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint i_stream_get_fd(struct istream *stream)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct _istream *_stream = stream->real_stream;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return _stream->fd;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid i_stream_close(struct istream *stream)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _io_stream_close(&stream->real_stream->iostream);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->closed = TRUE;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _io_stream_set_max_buffer_size(&stream->real_stream->iostream,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen max_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid i_stream_set_blocking(struct istream *stream, int timeout_msecs,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen void (*timeout_cb)(void *), void *context)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _io_stream_set_blocking(&stream->real_stream->iostream, timeout_msecs,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen timeout_cb, context);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid i_stream_set_start_offset(struct istream *stream, uoff_t offset)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct _istream *_stream = stream->real_stream;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen off_t diff;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(stream->v_size == 0 ||
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen offset <= stream->start_offset + stream->v_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (offset == stream->start_offset)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen diff = (off_t)stream->start_offset - (off_t)offset;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->start_offset = offset;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->v_offset += diff;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (stream->v_size != 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->v_size += diff;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->v_limit += diff;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* reset buffer data */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->skip = _stream->pos = 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid i_stream_set_read_limit(struct istream *stream, uoff_t v_offset)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct _istream *_stream = stream->real_stream;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uoff_t max_pos;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(stream->v_size == 0 || v_offset <= stream->v_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (v_offset == 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->v_limit = stream->v_size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen else {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(v_offset >= stream->v_offset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->v_limit = v_offset;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen max_pos = v_offset - stream->v_offset + _stream->skip;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (_stream->pos > max_pos)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->pos = max_pos;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenssize_t i_stream_read(struct istream *stream)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct _istream *_stream = stream->real_stream;
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (stream->closed)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen return _stream->read(_stream);
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen}
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count)
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen{
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen struct _istream *_stream = stream->real_stream;
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen size_t data_size;
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen i_assert(stream->v_size == 0 ||
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->v_offset + count <= stream->v_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (count <= _stream->pos - _stream->skip) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->v_offset += count;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->skip += count;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (stream->closed)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen data_size = _stream->pos - _stream->skip;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->skip = _stream->pos;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen count -= data_size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->v_offset += data_size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->skip_count(_stream, count);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct _istream *_stream = stream->real_stream;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(v_offset <= stream->v_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (stream->closed)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->seek(_stream, v_offset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenchar *i_stream_next_line(struct istream *stream)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct _istream *_stream = stream->real_stream;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen char *ret_buf;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen size_t i;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen i_assert(stream != NULL);
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen if (_stream->skip >= _stream->pos)
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen return NULL;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (_stream->w_buffer == NULL) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_error("i_stream_next_line() called for unmodifyable stream");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return NULL;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* @UNSAFE */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen ret_buf = NULL;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (i = _stream->skip; i < _stream->pos; i++) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (_stream->buffer[i] == 10) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* got it */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (i > 0 && _stream->buffer[i-1] == '\r')
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->w_buffer[i-1] = '\0';
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen else
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->w_buffer[i] = '\0';
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen ret_buf = (char *) _stream->w_buffer + _stream->skip;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i++;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen stream->v_offset += i - _stream->skip;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen _stream->skip = i;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return ret_buf;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenconst unsigned char *i_stream_get_data(struct istream *stream, size_t *size)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct _istream *_stream = stream->real_stream;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (_stream->skip >= _stream->pos) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *size = 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return NULL;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *size = _stream->pos - _stream->skip;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return _stream->buffer + _stream->skip;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenunsigned char *i_stream_get_modifyable_data(struct istream *stream,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen size_t *size)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct _istream *_stream = stream->real_stream;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (_stream->skip >= _stream->pos || _stream->w_buffer == NULL) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *size = 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return NULL;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *size = _stream->pos - _stream->skip;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return _stream->w_buffer + _stream->skip;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint i_stream_read_data(struct istream *stream, const unsigned char **data,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen size_t *size, size_t threshold)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct _istream *_stream = stream->real_stream;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen ssize_t ret = 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen while (_stream->pos - _stream->skip <= threshold) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* we need more data */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen ret = _stream->read(_stream);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (ret < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *data = i_stream_get_data(stream, size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return *size > threshold ? 1 :
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen ret == -2 ? -2 :
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *size > 0 ? 0 : -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstruct istream *_i_stream_create(struct _istream *_stream, pool_t pool, int fd,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uoff_t start_offset, uoff_t v_size)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->fd = fd;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->istream.start_offset = start_offset;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->istream.v_size = v_size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->istream.v_limit = v_size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _stream->istream.real_stream = _stream;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _io_stream_init(pool, &_stream->iostream);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return &_stream->istream;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen