[Dovecot] istream_read like zlib, but without zlib

Alex Baule alexwbaule at gmail.com
Tue Aug 31 14:48:51 EEST 2010


Hy Timo !

I Made some modification in stream_read in zlib. I remove all zlib part,
because i don't need this, but i need to read a istream to change it.

Well, i create a size_t called supersize, with is a substitute for
stream->zs.avail_in.

The trouble is, my debug file have a lot of "READ Plugin\n", and i think
it's because my read becomes a loop, i think it's because i don't know to
identify the EOF from the istream.

you can help me to identify the EOF and set it ?

Tks .!!!

static ssize_t i_stream_emx_read(struct istream_private *stream)
{
    struct emx_istream *emxstream = (struct emx_istream *)stream;
    const unsigned char *data;
    uoff_t high_offset;
    size_t size;
    int ret;


    fprintf(emxstream->debug,"READ Plugin\n");
    fflush(emxstream->debug);


    high_offset = stream->istream.v_offset + (stream->pos - stream->skip);
    if (emxstream->eof_offset == high_offset) {
        i_assert(emxstream->high_pos == 0);
        stream->istream.eof = TRUE;
        return -1;
    }

    if (stream->pos < emxstream->high_pos) {
        /* we're here because we seeked back within the read buffer. */
        ret = emxstream->high_pos - stream->pos;
        stream->pos = emxstream->high_pos;
        emxstream->high_pos = 0;
        return ret;
    }
    emxstream->high_pos = 0;

    if (stream->pos + CHUNK_SIZE > stream->buffer_size) {
        /* try to keep at least CHUNK_SIZE available */
        if (!emxstream->marked && stream->skip > 0) {
            /* don't try to keep anything cached if we don't
               have a seek mark. */
            i_stream_compress(stream);
        }
        if (stream->max_buffer_size == 0 ||
            stream->buffer_size < stream->max_buffer_size)
            i_stream_grow_buffer(stream, CHUNK_SIZE);

        if (stream->pos == stream->buffer_size) {
            if (stream->skip > 0) {
                /* lose our buffer cache */
                i_stream_compress(stream);
            }

            if (stream->pos == stream->buffer_size)
                return -2; /* buffer full */
        }
    }

    if(emxstream->supersize == 0){
        /* need to read more data. try to read a full CHUNK_SIZE */
        i_stream_skip(stream->parent, emxstream->prev_size);
        if (i_stream_read_data(stream->parent, &data, &size, CHUNK_SIZE-1)
== -1 && size == 0) {
            if (stream->parent->stream_errno != 0) {
                stream->istream.stream_errno = stream->parent->stream_errno;
            } else {
                i_assert(stream->parent->eof);
                stream->istream.stream_errno = EPIPE;
            }
            return -1;
        }
        emxstream->prev_size = size;

        if (size == 0) {
            /* no more input */
            stream->istream.eof = TRUE;
            i_assert(!stream->istream.blocking);
            return 0;
        }

        fprintf(emxstream->debug,"READ =|%s|= Plugin\n",data);
        fflush(emxstream->debug);

        memcpy(stream->w_buffer + stream->pos, data,size);
        emxstream->supersize = size;
    }


    size = stream->buffer_size - stream->pos;
    stream->pos += size;

    if(stream->istream.eof == TRUE){
        emxstream->eof_offset = stream->istream.v_offset + stream->pos;
        i_stream_skip(stream->parent, emxstream->prev_size -
emxstream->supersize);
        emxstream->supersize = 0;
        emxstream->prev_size = 0;
    }

    if (size == 0) {
        /* read more input */
        return i_stream_emx_read(stream);
    }
    return size;
}


More information about the dovecot mailing list