istream.c revision 7ef5ca6fb59a318c821a852ae48a2edbb671d7dd
183bea41fa640dc8117f3eb45ff935cd81377a84Timo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen _io_stream_ref(&stream->real_stream->iostream);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct _istream *_stream = (*stream)->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen _io_stream_unref(&(*stream)->real_stream->iostream);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct _istream *_stream = stream->real_stream;
4d4d6d4745682790c20d759ba93dbea46b812c5dTimo Sirainen _io_stream_close(&stream->real_stream->iostream);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size)
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen _io_stream_set_max_buffer_size(&stream->real_stream->iostream,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct _istream *_stream = stream->real_stream;
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count)
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen struct _istream *_stream = stream->real_stream;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen /* within buffer */
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen /* have to seek forward */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen _stream->seek(_stream, stream->v_offset + count, FALSE);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset)
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen struct _istream *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_stream_skip(stream, v_offset - stream->v_offset);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_seek_mark(struct istream *stream, uoff_t v_offset)
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen struct _istream *_stream = stream->real_stream;
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen struct _istream *_stream = stream->real_stream;
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainenconst struct stat *i_stream_stat(struct istream *stream, bool exact)
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen struct _istream *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenbool i_stream_have_bytes_left(struct istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct _istream *_stream = stream->real_stream;
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen return !stream->eof || _stream->skip != _stream->pos;
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainenstatic char *i_stream_next_line_finish(struct _istream *stream, size_t i)
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen /* modify the buffer directly */
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen ret = (char *)stream->w_buffer + stream->skip;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* use a temporary string to return it */
01230de017cd273de41143d88e9c18df1243ae8aTimo Sirainen stream->line_str = str_new(default_pool, 256);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen str_append_n(stream->line_str, stream->buffer + stream->skip,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenchar *i_stream_next_line(struct istream *stream)
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen struct _istream *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_error("i_stream_next_line() called for unmodifiable stream");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* @UNSAFE */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen for (i = _stream->skip; i < _stream->pos; i++) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret_buf = i_stream_next_line_finish(_stream, i);
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainenchar *i_stream_read_next_line(struct istream *stream)
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainenconst unsigned char *i_stream_get_data(struct istream *stream, size_t *size_r)
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen struct _istream *_stream = stream->real_stream;
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainenunsigned char *i_stream_get_modifiable_data(struct istream *stream,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct _istream *_stream = stream->real_stream;
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen if (_stream->skip >= _stream->pos || _stream->w_buffer == NULL) {
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainenint i_stream_read_data(struct istream *stream, const unsigned char **data_r,
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen /* we need more data */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen } while (ret > 0);
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainenvoid _i_stream_grow_buffer(struct _istream *stream, size_t bytes)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen pool_get_exp_grown_size(stream->iostream.pool,
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen stream->buffer_size > stream->max_buffer_size)
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen stream->buffer_size = stream->max_buffer_size;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen p_realloc(stream->iostream.pool, stream->w_buffer,
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen struct _istream *_stream = (struct _istream *) stream;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainenstatic const struct stat *
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen_stat(struct _istream *stream, bool exact __attr_unused__)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstruct istream *_i_stream_create(struct _istream *_stream, pool_t pool, int fd,
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen if (_stream->iostream.set_max_buffer_size == NULL)
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen _stream->iostream.set_max_buffer_size = _set_max_buffer_size;
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen memset(&_stream->statbuf, 0, sizeof(_stream->statbuf));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* gcc istream.c -o teststream liblib.a -Wall -DHAVE_CONFIG_H -DSTREAM_TEST -g */
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainenstatic void check_buffer(const unsigned char *data, size_t size, size_t offset)
047c00cd3f7f403672f81569413669238df8c15aTimo Sirainen for (i = 0; i < size; i++)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const unsigned char *data;
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen fd1 = open("teststream.1", O_RDWR | O_CREAT | O_TRUNC, 0600);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen fd2 = open("teststream.2", O_RDWR | O_CREAT | O_TRUNC, 0600);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen /* write initial data */
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen for (i = 0; i < sizeof(buf); i++)
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen /* test reading */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen input = i_stream_create_file(fd1, default_pool, 512, FALSE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(i_stream_get_size(input) == sizeof(buf));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen i_assert(i_stream_read_data(input, &data, &size, 512) == -2);
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* test moving data */
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen output1 = o_stream_create_file(fd1, default_pool, 512, FALSE);
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen output2 = o_stream_create_file(fd2, default_pool, 512, FALSE);
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen i_stream_seek(input, 1); size = sizeof(buf)-1;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen i_assert(o_stream_send_istream(output2, input) == size);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(read(fd2, buf, sizeof(buf)) == size);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(o_stream_send_istream(output1, input) == sizeof(buf));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* test moving with limits */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen l_input = i_stream_create_limit(default_pool, input,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(o_stream_send_istream(output1, l_input) == 512);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_stream_set_max_buffer_size(input, sizeof(buf));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, sizeof(buf)-1) > 0);
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen /* reading within limits */
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen i_assert(i_stream_read_data(l_input, &data, &size, 511) > 0);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert(i_stream_read_data(l_input, &data, &size, 512) == -2);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(i_stream_read_data(l_input, &data, &size, 0) > 0);