istream.c revision 2526d52441ef368215ab6bf04fd0356d3b09d235
5e0ce63bb65db34d7f48b34bbb5545fa791781c4Timo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
daf029d2a627daa39d05507140f385162828172eTimo Sirainen _io_stream_ref(&stream->real_stream->iostream);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct _istream *_stream = (*stream)->real_stream;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen _io_stream_unref(&(*stream)->real_stream->iostream);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen struct _istream *_stream = stream->real_stream;
daf029d2a627daa39d05507140f385162828172eTimo Sirainen _io_stream_close(&stream->real_stream->iostream);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size)
daf029d2a627daa39d05507140f385162828172eTimo Sirainen _io_stream_set_max_buffer_size(&stream->real_stream->iostream,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen struct _istream *_stream = stream->real_stream;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count)
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen struct _istream *_stream = stream->real_stream;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* within buffer */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* have to seek forward */
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen _stream->seek(_stream, stream->v_offset + count, FALSE);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset)
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen struct _istream *_stream = stream->real_stream;
601f5f14c6cde28f0e0c6ca7c5d735315d3d48dfTimo Sirainen i_stream_skip(stream, v_offset - stream->v_offset);
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainenvoid i_stream_seek_mark(struct istream *stream, uoff_t v_offset)
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen struct _istream *_stream = stream->real_stream;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen struct _istream *_stream = stream->real_stream;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenconst struct stat *i_stream_stat(struct istream *stream, bool exact)
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct _istream *_stream = stream->real_stream;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool i_stream_have_bytes_left(struct istream *stream)
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen struct _istream *_stream = stream->real_stream;
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen return !stream->eof || _stream->skip != _stream->pos;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainenstatic char *i_stream_next_line_finish(struct _istream *stream, size_t i)
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen /* modify the buffer directly */
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen ret = (char *)stream->w_buffer + stream->skip;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen /* use a temporary string to return it */
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen stream->line_str = str_new(default_pool, 256);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen str_append_n(stream->line_str, stream->buffer + stream->skip,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenchar *i_stream_next_line(struct istream *stream)
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen struct _istream *_stream = stream->real_stream;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen i_error("i_stream_next_line() called for unmodifiable stream");
5254d77805cd35b9356d072ba325c356c43b0d51Timo Sirainen /* @UNSAFE */
3e25b17126e9536736d5da03697613e4c3af5f76Timo Sirainen for (i = _stream->skip; i < _stream->pos; i++) {
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen ret_buf = i_stream_next_line_finish(_stream, i);
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainenchar *i_stream_read_next_line(struct istream *stream)
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainenconst unsigned char *i_stream_get_data(struct istream *stream, size_t *size_r)
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen struct _istream *_stream = stream->real_stream;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainenunsigned char *i_stream_get_modifiable_data(struct istream *stream,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen struct _istream *_stream = stream->real_stream;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (_stream->skip >= _stream->pos || _stream->w_buffer == NULL) {
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainenint i_stream_read_data(struct istream *stream, const unsigned char **data_r,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* we need more data */
abe8754852e70763e92f74caabbcc13d0917714cTimo Sirainen } while (ret > 0);
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainenvoid _i_stream_compress(struct _istream *stream)
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen memmove(stream->w_buffer, stream->w_buffer + stream->skip,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainenvoid _i_stream_grow_buffer(struct _istream *stream, size_t bytes)
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen stream->buffer_size = nearest_power(stream->buffer_size);
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen stream->buffer_size > stream->max_buffer_size)
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen stream->buffer_size = stream->max_buffer_size;
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen i_realloc(stream->w_buffer, old_size, stream->buffer_size);
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen struct _istream *_stream = (struct _istream *) stream;
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainenstatic const struct stat *
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen_stat(struct _istream *stream, bool exact __attr_unused__)
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen_i_stream_create(struct _istream *_stream, int fd, uoff_t abs_start_offset)
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen if (_stream->iostream.set_max_buffer_size == NULL)
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen _stream->iostream.set_max_buffer_size = _set_max_buffer_size;
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen memset(&_stream->statbuf, 0, sizeof(_stream->statbuf));
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen/* gcc istream.c -o teststream liblib.a -Wall -DHAVE_CONFIG_H -DSTREAM_TEST -g */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainenstatic void check_buffer(const unsigned char *data, size_t size, size_t offset)
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen for (i = 0; i < size; i++)
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen const unsigned char *data;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen fd1 = open("teststream.1", O_RDWR | O_CREAT | O_TRUNC, 0600);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen fd2 = open("teststream.2", O_RDWR | O_CREAT | O_TRUNC, 0600);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* write initial data */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen for (i = 0; i < sizeof(buf); i++)
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* test reading */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(i_stream_get_size(input) == sizeof(buf));
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 512) == -2);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* test moving data */
2526d52441ef368215ab6bf04fd0356d3b09d235Timo Sirainen output1 = o_stream_create_fd(fd1, 512, FALSE);
2526d52441ef368215ab6bf04fd0356d3b09d235Timo Sirainen output2 = o_stream_create_fd(fd2, 512, FALSE);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_stream_seek(input, 1); size = sizeof(buf)-1;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(o_stream_send_istream(output2, input) == size);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(read(fd2, buf, sizeof(buf)) == size);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(o_stream_send_istream(output1, input) == sizeof(buf));
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* test moving with limits */
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen l_input = i_stream_create_limit(input, sizeof(buf)/2, 512);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(o_stream_send_istream(output1, l_input) == 512);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_stream_set_max_buffer_size(input, sizeof(buf));
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, sizeof(buf)-1) > 0);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* reading within limits */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(i_stream_read_data(l_input, &data, &size, 511) > 0);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(i_stream_read_data(l_input, &data, &size, 512) == -2);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen i_assert(i_stream_read_data(l_input, &data, &size, 0) > 0);