istream.c revision fe363b433b8038a69b55169da9dca27892ad7d18
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2002-2003 Timo Sirainen */
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen _io_stream_ref(&stream->real_stream->iostream);
8a8a3b43987b5ade914f22765e51c9e3de8179d3Timo Sirainen struct _istream *_stream = (*stream)->real_stream;
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen _io_stream_unref(&(*stream)->real_stream->iostream);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen struct _istream *_stream = stream->real_stream;
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen _io_stream_close(&stream->real_stream->iostream);
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size)
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen _io_stream_set_max_buffer_size(&stream->real_stream->iostream,
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen struct _istream *_stream = stream->real_stream;
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count)
46b823ac3bce2c0f9f0fc73911e48d3a77b04fbeTimo Sirainen struct _istream *_stream = stream->real_stream;
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen /* within buffer */
e245fb1302121d2bc2580f61e040c2c8a558ee9eTimo Sirainen /* have to seek forward */
d97f081a3de44852197ced772e21560c108895a6Timo Sirainen _stream->seek(_stream, stream->v_offset + count, FALSE);
d97f081a3de44852197ced772e21560c108895a6Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset)
d97f081a3de44852197ced772e21560c108895a6Timo Sirainen struct _istream *_stream = stream->real_stream;
d97f081a3de44852197ced772e21560c108895a6Timo Sirainen i_stream_skip(stream, v_offset - stream->v_offset);
d97f081a3de44852197ced772e21560c108895a6Timo Sirainenvoid i_stream_seek_mark(struct istream *stream, uoff_t v_offset)
d97f081a3de44852197ced772e21560c108895a6Timo Sirainen struct _istream *_stream = stream->real_stream;
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen struct _istream *_stream = stream->real_stream;
d97f081a3de44852197ced772e21560c108895a6Timo Sirainenconst struct stat *i_stream_stat(struct istream *stream, bool exact)
d97f081a3de44852197ced772e21560c108895a6Timo Sirainen struct _istream *_stream = stream->real_stream;
d97f081a3de44852197ced772e21560c108895a6Timo Sirainenbool i_stream_have_bytes_left(struct istream *stream)
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen struct _istream *_stream = stream->real_stream;
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen return !stream->eof || _stream->skip != _stream->pos;
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainenstatic char *i_stream_next_line_finish(struct _istream *stream, size_t i)
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen /* modify the buffer directly */
25ec868bd8b5375e1c1c4c3331d761667ddfe26cTimo Sirainen ret = (char *)stream->w_buffer + stream->skip;
25ec868bd8b5375e1c1c4c3331d761667ddfe26cTimo Sirainen /* use a temporary string to return it */
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen stream->line_str = str_new(default_pool, 256);
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen str_append_n(stream->line_str, stream->buffer + stream->skip,
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainenchar *i_stream_next_line(struct istream *stream)
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen struct _istream *_stream = stream->real_stream;
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen i_error("i_stream_next_line() called for unmodifiable stream");
c076ad69e28e7d41af83ada84e12019793ffcfa2Timo Sirainen /* @UNSAFE */
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen for (i = _stream->skip; i < _stream->pos; i++) {
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen ret_buf = i_stream_next_line_finish(_stream, i);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainenchar *i_stream_read_next_line(struct istream *stream)
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainenconst unsigned char *i_stream_get_data(struct istream *stream, size_t *size_r)
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen struct _istream *_stream = stream->real_stream;
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainenunsigned char *i_stream_get_modifiable_data(struct istream *stream,
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen struct _istream *_stream = stream->real_stream;
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen if (_stream->skip >= _stream->pos || _stream->w_buffer == NULL) {
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainenint i_stream_read_data(struct istream *stream, const unsigned char **data_r,
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen /* we need more data */
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen } while (ret > 0);
fb176cdc122707cda985ab3c09c02ccf3cec0af1Timo Sirainenvoid _i_stream_compress(struct _istream *stream)
fb176cdc122707cda985ab3c09c02ccf3cec0af1Timo Sirainen memmove(stream->w_buffer, stream->w_buffer + stream->skip,
fb176cdc122707cda985ab3c09c02ccf3cec0af1Timo Sirainenvoid _i_stream_grow_buffer(struct _istream *stream, size_t bytes)
fb176cdc122707cda985ab3c09c02ccf3cec0af1Timo Sirainen stream->buffer_size = nearest_power(stream->buffer_size);
153ed0fbca1f5f944b70937dfd71911db172ca97Timo Sirainen stream->buffer_size > stream->max_buffer_size)
153ed0fbca1f5f944b70937dfd71911db172ca97Timo Sirainen stream->buffer_size = stream->max_buffer_size;
153ed0fbca1f5f944b70937dfd71911db172ca97Timo Sirainen i_realloc(stream->w_buffer, old_size, stream->buffer_size);
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
2f4f603d4cebab2cc956c72164efb02da83515c5Timo Sirainen struct _istream *_stream = (struct _istream *) stream;
2f4f603d4cebab2cc956c72164efb02da83515c5Timo Sirainenstatic const struct stat *
8a8a3b43987b5ade914f22765e51c9e3de8179d3Timo Sirainen_stat(struct _istream *stream, bool exact __attr_unused__)
8a8a3b43987b5ade914f22765e51c9e3de8179d3Timo Sirainen_i_stream_create(struct _istream *_stream, int fd, uoff_t abs_start_offset)
da574ef2db96f258d24bc4c89a77833036d13a95Timo Sirainen if (_stream->iostream.set_max_buffer_size == NULL)
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen _stream->iostream.set_max_buffer_size = _set_max_buffer_size;
fb176cdc122707cda985ab3c09c02ccf3cec0af1Timo Sirainen memset(&_stream->statbuf, 0, sizeof(_stream->statbuf));
2f4f603d4cebab2cc956c72164efb02da83515c5Timo Sirainen/* gcc istream.c -o teststream liblib.a -Wall -DHAVE_CONFIG_H -DSTREAM_TEST -g */
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainenstatic void check_buffer(const unsigned char *data, size_t size, size_t offset)
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen for (i = 0; i < size; i++)
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen const unsigned char *data;
2f4f603d4cebab2cc956c72164efb02da83515c5Timo Sirainen fd1 = open("teststream.1", O_RDWR | O_CREAT | O_TRUNC, 0600);
d28179fd78550a58be44dcb1e3e830ab7d33172dTimo Sirainen fd2 = open("teststream.2", O_RDWR | O_CREAT | O_TRUNC, 0600);
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen /* write initial data */
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen for (i = 0; i < sizeof(buf); i++)
bace943c67e6cd14ce6c994f533d82a3caad5bf1Timo Sirainen /* test reading */
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen input = i_stream_create_file(fd1, 512, FALSE);
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen i_assert(i_stream_get_size(input) == sizeof(buf));
baf346e71ebd7b44fcba4b48f4d39845453b778bTimo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
e44028b5df7045dd9e7f324175e73e3ff490cb5dTimo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
bace943c67e6cd14ce6c994f533d82a3caad5bf1Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 512) == -2);
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen i_assert(i_stream_read_data(input, &data, &size, 0) > 0);
2f4f603d4cebab2cc956c72164efb02da83515c5Timo Sirainen /* test moving data */
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen output1 = o_stream_create_file(fd1, 512, FALSE);
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen output2 = o_stream_create_file(fd2, 512, FALSE);
cf636afb3826f0d8e15c248aa1fc04ce72820e08Timo Sirainen i_stream_seek(input, 1); size = sizeof(buf)-1;