istream.c revision abe8754852e70763e92f74caabbcc13d0917714c
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include "lib.h"
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen#include "istream-internal.h"
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenvoid i_stream_ref(struct istream *stream)
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wang{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen _io_stream_ref(&stream->real_stream->iostream);
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wangvoid i_stream_unref(struct istream *stream)
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen{
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen _io_stream_unref(&stream->real_stream->iostream);
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen}
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen
998395f6743fbecc07ee65ae08c416fa6cea9e09Teemu Huovilaint i_stream_get_fd(struct istream *stream)
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wang{
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wang struct _istream *_stream = stream->real_stream;
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wang
eb568e46e82bc814ca3384236a483691a12f9c54Baofeng Wang return _stream->fd;
eb568e46e82bc814ca3384236a483691a12f9c54Baofeng Wang}
eb568e46e82bc814ca3384236a483691a12f9c54Baofeng Wang
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainenvoid i_stream_close(struct istream *stream)
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen{
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen _io_stream_close(&stream->real_stream->iostream);
3448096d5b1cd324ed5132045de0345cd7120a25Timo Sirainen stream->closed = TRUE;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen}
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size)
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody{
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody _io_stream_set_max_buffer_size(&stream->real_stream->iostream,
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody max_size);
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen}
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainenssize_t i_stream_read(struct istream *stream)
b04e76cbc807707d299055be79500f8ff131da43Timo Sirainen{
b04e76cbc807707d299055be79500f8ff131da43Timo Sirainen struct _istream *_stream = stream->real_stream;
72c4ef3b44c50c662b37bba93b463b0caeb63a4fTimo Sirainen
0c5854b6891c59c1c3f443569bc823d7db571582Teemu Huovila if (stream->closed)
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody return -1;
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen stream->eof = FALSE;
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen return _stream->read(_stream);
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen}
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count)
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen{
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen struct _istream *_stream = stream->real_stream;
202468f94e6c6c8b5d3d98ee74e01bb0d0bb04aaTimo Sirainen size_t data_size;
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen data_size = _stream->pos - _stream->skip;
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen if (count <= data_size) {
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen /* within buffer */
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen stream->v_offset += count;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen _stream->skip += count;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen return;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen }
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen /* have to seek forward */
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen count -= data_size;
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila _stream->skip = _stream->pos;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen stream->v_offset += data_size;
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila if (stream->closed)
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen return;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen _stream->seek(_stream, stream->v_offset + count);
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen}
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset)
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen{
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen struct _istream *_stream = stream->real_stream;
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen if (v_offset >= stream->v_offset) {
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen i_stream_skip(stream, v_offset - stream->v_offset);
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen return;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen }
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if (stream->closed)
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen return;
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen stream->eof = FALSE;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen _stream->seek(_stream, v_offset);
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen}
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainenuoff_t i_stream_get_size(struct istream *stream)
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wang{
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen struct _istream *_stream = stream->real_stream;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainen return _stream->get_size(_stream);
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wang}
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainenchar *i_stream_next_line(struct istream *stream)
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen{
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen struct _istream *_stream = stream->real_stream;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen char *ret_buf;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen size_t i;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen i_assert(stream != NULL);
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainen
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wang if (_stream->skip >= _stream->pos) {
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen stream->stream_errno = 0;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen return NULL;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen }
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainen
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wang if (_stream->w_buffer == NULL) {
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen i_error("i_stream_next_line() called for unmodifyable stream");
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen return NULL;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen }
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen /* @UNSAFE */
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen ret_buf = NULL;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen for (i = _stream->skip; i < _stream->pos; i++) {
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if (_stream->buffer[i] == 10) {
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen /* got it */
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if (i > 0 && _stream->buffer[i-1] == '\r')
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainen _stream->w_buffer[i-1] = '\0';
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wang else
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen _stream->w_buffer[i] = '\0';
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen ret_buf = (char *) _stream->w_buffer + _stream->skip;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainen i++;
507ea0bc5b25efb4c96033a19dec66689a50ebd0Baofeng Wang stream->v_offset += i - _stream->skip;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen _stream->skip = i;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen break;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen }
0c5854b6891c59c1c3f443569bc823d7db571582Teemu Huovila }
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen return ret_buf;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen}
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainenchar *i_stream_read_next_line(struct istream *stream)
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen{
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen char *line;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen line = i_stream_next_line(stream);
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen if (line != NULL)
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen return line;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen if (i_stream_read(stream) > 0)
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen line = i_stream_next_line(stream);
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen return line;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenconst unsigned char *i_stream_get_data(struct istream *stream, size_t *size)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct _istream *_stream = stream->real_stream;
3448096d5b1cd324ed5132045de0345cd7120a25Timo Sirainen
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if (_stream->skip >= _stream->pos) {
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen *size = 0;
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody return NULL;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen }
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen
78f87ea1d30f3f54bdf8560ea947ab7ee094283aTeemu Huovila *size = _stream->pos - _stream->skip;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen return _stream->buffer + _stream->skip;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
b04e76cbc807707d299055be79500f8ff131da43Timo Sirainen
b04e76cbc807707d299055be79500f8ff131da43Timo Sirainenunsigned char *i_stream_get_modifyable_data(struct istream *stream,
0c5854b6891c59c1c3f443569bc823d7db571582Teemu Huovila size_t *size)
0c5854b6891c59c1c3f443569bc823d7db571582Teemu Huovila{
0c5854b6891c59c1c3f443569bc823d7db571582Teemu Huovila struct _istream *_stream = stream->real_stream;
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen if (_stream->skip >= _stream->pos || _stream->w_buffer == NULL) {
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen *size = 0;
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen return NULL;
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen }
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen *size = _stream->pos - _stream->skip;
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen return _stream->w_buffer + _stream->skip;
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen}
202468f94e6c6c8b5d3d98ee74e01bb0d0bb04aaTimo Sirainen
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainenint i_stream_read_data(struct istream *stream, const unsigned char **data,
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen size_t *size, size_t threshold)
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen{
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen ssize_t ret = 0;
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen do {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen *data = i_stream_get_data(stream, size);
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen if (*size > threshold)
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen return 1;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen /* we need more data */
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila ret = i_stream_read(stream);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila } while (ret > 0);
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen *data = i_stream_get_data(stream, size);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return ret == -2 ? -2 :
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen *size > 0 ? 0 : -1;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainenstruct istream *_i_stream_create(struct _istream *_stream, pool_t pool, int fd,
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen uoff_t abs_start_offset)
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen{
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen _stream->fd = fd;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen _stream->abs_start_offset = abs_start_offset;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen _stream->istream.real_stream = _stream;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen _io_stream_init(pool, &_stream->iostream);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return &_stream->istream;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen#ifdef STREAM_TEST
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen/* gcc istream.c -o teststream liblib.a -Wall -DHAVE_CONFIG_H -DSTREAM_TEST -g */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include <fcntl.h>
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include <unistd.h>
3448096d5b1cd324ed5132045de0345cd7120a25Timo Sirainen#include "ostream.h"
fdf70410de49eadfbb77997bb60ebba19aee4752Teemu Huovila
fdf70410de49eadfbb77997bb60ebba19aee4752Teemu Huovila#define BUF_VALUE(offset) \
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody (((offset) % 256) ^ ((offset) / 256))
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainenstatic void check_buffer(const unsigned char *data, size_t size, size_t offset)
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen{
fdf70410de49eadfbb77997bb60ebba19aee4752Teemu Huovila size_t i;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
b04e76cbc807707d299055be79500f8ff131da43Timo Sirainen for (i = 0; i < size; i++)
b04e76cbc807707d299055be79500f8ff131da43Timo Sirainen i_assert(data[i] == BUF_VALUE(i+offset));
0c5854b6891c59c1c3f443569bc823d7db571582Teemu Huovila}
0c5854b6891c59c1c3f443569bc823d7db571582Teemu Huovila
0c5854b6891c59c1c3f443569bc823d7db571582Teemu Huovilaint main(void)
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody{
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen struct istream *input, *l_input;
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen struct ostream *output1, *output2;
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen int i, fd1, fd2;
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen unsigned char buf[1024];
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen const unsigned char *data;
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen size_t size;
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen
b6b06530d654f0436bfbaefc1e988d53fff0cbeeTimo Sirainen lib_init();
202468f94e6c6c8b5d3d98ee74e01bb0d0bb04aaTimo Sirainen
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen fd1 = open("teststream.1", O_RDWR | O_CREAT | O_TRUNC, 0600);
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen if (fd1 < 0)
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen i_fatal("open() failed: %m");
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen fd2 = open("teststream.2", O_RDWR | O_CREAT | O_TRUNC, 0600);
83172e28d4ac684dfed83f7c9db933493d7c5922Timo Sirainen if (fd2 < 0)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_fatal("open() failed: %m");
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen /* write initial data */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen for (i = 0; i < sizeof(buf); i++)
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen buf[i] = BUF_VALUE(i);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen write(fd1, buf, sizeof(buf));
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen /* test reading */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen input = i_stream_create_file(fd1, default_pool, 512, FALSE);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_assert(i_stream_get_size(input) == sizeof(buf));
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen i_assert(size == 512);
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen check_buffer(data, size, 0);
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_stream_seek(input, 256);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_assert(size == 512);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen check_buffer(data, size, 256);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_stream_seek(input, 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(i_stream_read_data(input, &data, &size, 512) == -2);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(size == 512);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila check_buffer(data, size, 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_stream_skip(input, 900);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(size == sizeof(buf) - 900);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila check_buffer(data, size, 900);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody /* test moving data */
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila output1 = o_stream_create_file(fd1, default_pool, 512, FALSE);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila output2 = o_stream_create_file(fd2, default_pool, 512, FALSE);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_stream_seek(input, 1); size = sizeof(buf)-1;
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(o_stream_send_istream(output2, input) == size);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila o_stream_flush(output2);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila lseek(fd2, 0, SEEK_SET);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(read(fd2, buf, sizeof(buf)) == size);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila check_buffer(buf, size, 1);
19ed8f08b23d6ed204e6b27e5d1c0c6fe6bb11ddPhil Carmody
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_stream_seek(input, 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila o_stream_seek(output1, sizeof(buf));
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(o_stream_send_istream(output1, input) == sizeof(buf));
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila /* test moving with limits */
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila l_input = i_stream_create_limit(default_pool, input,
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila sizeof(buf)/2, 512);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_stream_seek(l_input, 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila o_stream_seek(output1, 10);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(o_stream_send_istream(output1, l_input) == 512);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_stream_set_max_buffer_size(input, sizeof(buf));
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_stream_seek(input, 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(i_stream_read_data(input, &data, &size, sizeof(buf)-1) > 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(size == sizeof(buf));
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila check_buffer(data, 10, 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila check_buffer(data + 10, 512, sizeof(buf)/2);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila check_buffer(data + 10 + 512,
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila size - (10 + 512), 10 + 512);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila /* reading within limits */
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_stream_seek(l_input, 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(i_stream_read_data(l_input, &data, &size, 511) > 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(size == 512);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(i_stream_read_data(l_input, &data, &size, 512) == -2);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(size == 512);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_stream_skip(l_input, 511);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(i_stream_read_data(l_input, &data, &size, 0) > 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(size == 1);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_stream_skip(l_input, 1);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(i_stream_read_data(l_input, &data, &size, 0) == -1);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila i_assert(size == 0);
3a54211bd6c4dc3f8687c16020770551cf83a548Teemu Huovila
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen unlink("teststream.1");
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen unlink("teststream.2");
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen return 0;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen#endif
af177be2664018e8074d69449b9c6a2d9741ec25Teemu Huovila