tsf_bool_t tsf_buf_reader_read()

in benchmarks/JetStream2/wasm/TSF/tsf_buf_reader.c [70:175]


tsf_bool_t tsf_buf_reader_read(void *_buf,
                               void *data,
                               uint32_t len) {
    tsf_bool_t read_some=tsf_false;
#if defined(HAVE_READV)
    struct iovec iov[2];
#endif
    tsf_buf_rdr_t *buf=_buf;
    
    /* get as much as possible from the buffer */
    if (buf->puti>buf->geti) {
        uint32_t avail=buf->puti-buf->geti;
        
        read_some=tsf_true;
        
        if (avail>len) {
            /* can be satisfied entirely from the buffer */
            memcpy(data,buf->buf+buf->geti,len);
            buf->geti+=len;
            return tsf_true;
        }
        
        memcpy(data,buf->buf+buf->geti,avail);
        
        data=((uint8_t*)data)+avail;
        len-=avail;
    }

    buf->puti=0;
    buf->geti=0;
    
    if (!len) {
        return tsf_true;
    }
    
    /* now satisfy the rest of the request by issuing a new read */
#if defined(HAVE_READV)
    iov[0].iov_base=data;
    iov[0].iov_len=len;
    iov[1].iov_base=(void*)buf->buf;
    iov[1].iov_len=buf->size;
    
    for (;;) {
        int res=readv(buf->fd,iov,2);
        if (res<0) {
            if (errno==EINTR) {
                continue;
            }
            tsf_set_errno("Calling readv() in tsf_buf_reader_read()");
            return tsf_false;
        }
        if (res==0) {
            tsf_set_error(read_some?
                          TSF_E_ERRONEOUS_EOF:TSF_E_UNEXPECTED_EOF,
                          "Calling readv() in tsf_buf_reader_read()");
            return tsf_false;
        }
        read_some=tsf_true;
        if ((unsigned)res>=iov[0].iov_len) {
            buf->puti=res-iov[0].iov_len;
            break;
        }
        iov[0].iov_base+=res;
        iov[0].iov_len-=res;
    }
#else
    if (len>=buf->size) {
        tsf_bool_t res=tsf_fd_reader(&buf->fd,data,len);
        if (read_some && !res &&
            tsf_get_error_code()==TSF_E_UNEXPECTED_EOF) {
            tsf_set_error(TSF_E_ERRONEOUS_EOF,
                          "tsf_fd_reader() experienced an EOF");
        }
        return res;
    }
    
    /* idea is this: we keep reading until we have enough to satisfy the
     * current request, but we allow the read to overflow for as many bytes
     * as we have available in the buffer. */
    while (buf->puti<len) {
        int res=read(buf->fd,
                     buf->buf+buf->puti,
                     buf->size-buf->puti);
        if (res<0) {
            if (errno==EINTR) {
                continue;
            }
            tsf_set_errno("Calling read() in tsf_buf_reader_read()");
            return tsf_false;
        }
        if (res==0) {
            tsf_set_error(read_some?
                          TSF_E_ERRONEOUS_EOF:TSF_E_UNEXPECTED_EOF,
                          "Calling read() in tsf_buf_reader_read()");
            return tsf_false;
        }
        read_some=tsf_true;
        buf->puti+=res;
    }
    
    memcpy(data,buf->buf,len);
    buf->geti=len;
#endif
    
    return tsf_true;
}