istream.c revision 37ab3cde96bfa4bc5304c0c348fc420aec79572d
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "lib.h"
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen#include "istream-internal.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid i_stream_ref(struct istream *stream)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen _io_stream_ref(&stream->real_stream->iostream);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid i_stream_unref(struct istream *stream)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen _io_stream_unref(&stream->real_stream->iostream);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenint i_stream_get_fd(struct istream *stream)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct _istream *_stream = stream->real_stream;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return _stream->fd;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid i_stream_close(struct istream *stream)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen _io_stream_close(&stream->real_stream->iostream);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen stream->closed = TRUE;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen _io_stream_set_max_buffer_size(&stream->real_stream->iostream,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen max_size);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid i_stream_set_blocking(struct istream *stream, int timeout_msecs,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen void (*timeout_cb)(void *), void *context)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen _io_stream_set_blocking(&stream->real_stream->iostream, timeout_msecs,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen timeout_cb, context);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenssize_t i_stream_read(struct istream *stream)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct _istream *_stream = stream->real_stream;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (stream->closed)
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen return -1;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen stream->disconnected = FALSE;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return _stream->read(_stream);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count)
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen{
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen struct _istream *_stream = stream->real_stream;
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen size_t data_size;
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen data_size = _stream->pos - _stream->skip;
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen if (count <= data_size) {
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen /* within buffer */
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen stream->v_offset += count;
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen _stream->skip += count;
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen return;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* have to seek forward */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen count -= data_size;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen _stream->skip = _stream->pos;
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen stream->v_offset += data_size;
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen if (stream->closed)
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen return;
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen _stream->seek(_stream, stream->v_offset + count);
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen}
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct _istream *_stream = stream->real_stream;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen if (v_offset > stream->v_offset) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_stream_skip(stream, v_offset - stream->v_offset);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return;
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen }
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen if (stream->closed)
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen return;
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen stream->disconnected = FALSE;
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen _stream->seek(_stream, v_offset);
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen}
fc8d5f0ac909cca77840538e8beef98a8d40c21cTimo Sirainen
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainenuoff_t i_stream_get_size(struct istream *stream)
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen{
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen struct _istream *_stream = stream->real_stream;
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen return _stream->get_size(_stream);
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen}
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainenchar *i_stream_next_line(struct istream *stream)
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen{
fc8d5f0ac909cca77840538e8beef98a8d40c21cTimo Sirainen struct _istream *_stream = stream->real_stream;
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen char *ret_buf;
fc8d5f0ac909cca77840538e8beef98a8d40c21cTimo Sirainen size_t i;
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen
fc8d5f0ac909cca77840538e8beef98a8d40c21cTimo Sirainen i_assert(stream != NULL);
33dd58ab84a020c4f061d2f6031eb6d4c168df1bTimo Sirainen
33dd58ab84a020c4f061d2f6031eb6d4c168df1bTimo Sirainen if (_stream->skip >= _stream->pos) {
33dd58ab84a020c4f061d2f6031eb6d4c168df1bTimo Sirainen stream->stream_errno = 0;
33dd58ab84a020c4f061d2f6031eb6d4c168df1bTimo Sirainen return NULL;
33dd58ab84a020c4f061d2f6031eb6d4c168df1bTimo Sirainen }
5d4855d7b4dcffb6975ed8e3c9c376dac74e5c8aTimo Sirainen
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen if (_stream->w_buffer == NULL) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_error("i_stream_next_line() called for unmodifyable stream");
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen return NULL;
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen /* @UNSAFE */
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen ret_buf = NULL;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen for (i = _stream->skip; i < _stream->pos; i++) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (_stream->buffer[i] == 10) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* got it */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (i > 0 && _stream->buffer[i-1] == '\r')
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen _stream->w_buffer[i-1] = '\0';
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen else
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen _stream->w_buffer[i] = '\0';
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen ret_buf = (char *) _stream->w_buffer + _stream->skip;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i++;
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainen stream->v_offset += i - _stream->skip;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen _stream->skip = i;
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainen break;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen }
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen }
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen return ret_buf;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen}
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenchar *i_stream_read_next_line(struct istream *stream)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen char *line;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen line = i_stream_next_line(stream);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (line != NULL)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return line;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (i_stream_read(stream) > 0)
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen line = i_stream_next_line(stream);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen return line;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen}
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainenconst unsigned char *i_stream_get_data(struct istream *stream, size_t *size)
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen{
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen struct _istream *_stream = stream->real_stream;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen if (_stream->skip >= _stream->pos) {
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen *size = 0;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen return NULL;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen }
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen *size = _stream->pos - _stream->skip;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen return _stream->buffer + _stream->skip;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen}
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainenunsigned char *i_stream_get_modifyable_data(struct istream *stream,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen size_t *size)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen{
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen struct _istream *_stream = stream->real_stream;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (_stream->skip >= _stream->pos || _stream->w_buffer == NULL) {
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen *size = 0;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen return NULL;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen *size = _stream->pos - _stream->skip;
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen return _stream->w_buffer + _stream->skip;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen}
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenint i_stream_read_data(struct istream *stream, const unsigned char **data,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen size_t *size, size_t threshold)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen ssize_t ret = 0;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen do {
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen *data = i_stream_get_data(stream, size);
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen if (*size > threshold)
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen return 1;
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen /* we need more data */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen ret = i_stream_read(stream);
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen } while (ret >= 0);
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen return ret == -2 ? -2 :
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen *size > 0 ? 0 : -1;
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen}
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainenstruct istream *_i_stream_create(struct _istream *_stream, pool_t pool, int fd,
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen uoff_t abs_start_offset)
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen{
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen _stream->fd = fd;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen _stream->abs_start_offset = abs_start_offset;
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen _stream->istream.real_stream = _stream;
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen _io_stream_init(pool, &_stream->iostream);
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen return &_stream->istream;
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen}
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen
4376643cd2c7110e752c09f838f2c4eee6ed8ac6Timo Sirainen#ifdef STREAM_TEST
938835576b218f6bb9498d829cef9514f8609c6fTimo Sirainen/* gcc istream.c -o teststream liblib.a -Wall -DHAVE_CONFIG_H -DSTREAM_TEST -g */
938835576b218f6bb9498d829cef9514f8609c6fTimo Sirainen
938835576b218f6bb9498d829cef9514f8609c6fTimo Sirainen#include <fcntl.h>
938835576b218f6bb9498d829cef9514f8609c6fTimo Sirainen#include <unistd.h>
938835576b218f6bb9498d829cef9514f8609c6fTimo Sirainen#include "ostream.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen#define BUF_VALUE(offset) \
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen (((offset) % 256) ^ ((offset) / 256))
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainenstatic void check_buffer(const unsigned char *data, size_t size, size_t offset)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen{
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen size_t i;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen for (i = 0; i < size; i++)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_assert(data[i] == BUF_VALUE(i+offset));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenint main(void)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct istream *input, *l_input;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct ostream *output1, *output2;
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen int i, fd1, fd2;
e2a700d0628e395d64cbcef4b5b4510816bf51c4Timo Sirainen unsigned char buf[1024];
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen const unsigned char *data;
e2a700d0628e395d64cbcef4b5b4510816bf51c4Timo Sirainen size_t size;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen lib_init();
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen fd1 = open("teststream.1", O_RDWR | O_CREAT | O_TRUNC, 0600);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (fd1 < 0)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen i_fatal("open() failed: %m");
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen fd2 = open("teststream.2", O_RDWR | O_CREAT | O_TRUNC, 0600);
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen if (fd2 < 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_fatal("open() failed: %m");
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* write initial data */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen for (i = 0; i < sizeof(buf); i++)
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen buf[i] = BUF_VALUE(i);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen write(fd1, buf, sizeof(buf));
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen /* test reading */
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen input = i_stream_create_file(fd1, default_pool, 512, FALSE);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen i_assert(i_stream_get_size(input) == sizeof(buf));
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
e2a700d0628e395d64cbcef4b5b4510816bf51c4Timo Sirainen i_assert(size == 512);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen check_buffer(data, size, 0);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e2a700d0628e395d64cbcef4b5b4510816bf51c4Timo Sirainen i_stream_seek(input, 256);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen i_assert(size == 512);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen check_buffer(data, size, 256);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen i_stream_seek(input, 0);
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 512) == -2);
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen i_assert(size == 512);
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen check_buffer(data, size, 0);
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen i_stream_skip(input, 900);
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen i_assert(size == sizeof(buf) - 900);
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen check_buffer(data, size, 900);
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* test moving data */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen output1 = o_stream_create_file(fd1, default_pool, 512, FALSE);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen output2 = o_stream_create_file(fd2, default_pool, 512, FALSE);
484e12acec34f16e5a8adc001e23ae48f1dda8c7Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_stream_seek(input, 1); size = sizeof(buf)-1;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(o_stream_send_istream(output2, input) == size);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen o_stream_flush(output2);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen lseek(fd2, 0, SEEK_SET);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(read(fd2, buf, sizeof(buf)) == size);
484e12acec34f16e5a8adc001e23ae48f1dda8c7Timo Sirainen check_buffer(buf, size, 1);
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_stream_seek(input, 0);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen o_stream_seek(output1, sizeof(buf));
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(o_stream_send_istream(output1, input) == sizeof(buf));
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen /* test moving with limits */
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen l_input = i_stream_create_limit(default_pool, input,
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen sizeof(buf)/2, 512);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_stream_seek(l_input, 0);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen o_stream_seek(output1, 10);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(o_stream_send_istream(output1, l_input) == 512);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_stream_set_max_buffer_size(input, sizeof(buf));
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_stream_seek(input, 0);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, sizeof(buf)-1) > 0);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(size == sizeof(buf));
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen check_buffer(data, 10, 0);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen check_buffer(data + 10, 512, sizeof(buf)/2);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen check_buffer(data + 10 + 512,
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen size - (10 + 512), 10 + 512);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen /* reading within limits */
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_stream_seek(l_input, 0);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(i_stream_read_data(l_input, &data, &size, 511) > 0);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(size == 512);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(i_stream_read_data(l_input, &data, &size, 512) == -2);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(size == 512);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_stream_skip(l_input, 511);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(i_stream_read_data(l_input, &data, &size, 0) > 0);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(size == 1);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_stream_skip(l_input, 1);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(i_stream_read_data(l_input, &data, &size, 0) == -1);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen i_assert(size == 0);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen unlink("teststream.1");
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen unlink("teststream.2");
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen return 0;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen}
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen#endif
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen