Esempio n. 1
0
// Callback invoked by libuv after it copies the data into the buffer provided
// by `alloc_cb`. This is also called on EOF or when `alloc_cb` returns a
// 0-length buffer.
static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
{
    RStream *rstream = stream->data;

    if (cnt <= 0) {
        if (cnt != UV_ENOBUFS) {
            // Read error or EOF, either way stop the stream and invoke the callback
            // with eof == true
            uv_read_stop(stream);
            emit_read_event(rstream, true);
        }
        return;
    }

    // at this point we're sure that cnt is positive, no error occurred
    size_t nread = (size_t) cnt;

    // Data was already written, so all we need is to update 'wpos' to reflect
    // the space actually used in the buffer.
    rstream->wpos += nread;

    if (rstream->wpos == rstream->buffer_size) {
        // The last read filled the buffer, stop reading for now
        rstream_stop(rstream);
    }

    rstream->reading = false;
    emit_read_event(rstream, false);
}
Esempio n. 2
0
// Called by the by the 'idle' handle to emulate a reading event
static void fread_idle_cb(uv_idle_t *handle)
{
    uv_fs_t req;
    RStream *rstream = handle->data;

    rstream->uvbuf.base = rstream->buffer + rstream->wpos;
    rstream->uvbuf.len = rstream->buffer_size - rstream->wpos;

    // the offset argument to uv_fs_read is int64_t, could someone really try
    // to read more than 9 quintillion (9e18) bytes?
    // upcast is meant to avoid tautological condition warning on 32 bits
    uintmax_t fpos_intmax = rstream->fpos;
    assert(fpos_intmax <= INT64_MAX);

    // Synchronous read
    uv_fs_read(
        uv_default_loop(),
        &req,
        rstream->fd,
        &rstream->uvbuf,
        1,
        (int64_t) rstream->fpos,
        NULL);

    uv_fs_req_cleanup(&req);

    if (req.result <= 0) {
        uv_idle_stop(rstream->fread_idle);
        emit_read_event(rstream, true);
        return;
    }

    // no errors (req.result (ssize_t) is positive), it's safe to cast.
    size_t nread = (size_t) req.result;

    rstream->wpos += nread;
    rstream->fpos += nread;

    if (rstream->wpos == rstream->buffer_size) {
        // The last read filled the buffer, stop reading for now
        rstream_stop(rstream);
    }

    emit_read_event(rstream, false);
}
Esempio n. 3
0
// Called by the by the 'idle' handle to emulate a reading event
static void fread_idle_cb(uv_idle_t *handle)
{
  uv_fs_t req;
  RStream *rstream = handle->data;

  rstream->uvbuf.base = rstream->buffer + rstream->wpos;
  rstream->uvbuf.len = rstream->buffer_size - rstream->wpos;

  // the offset argument to uv_fs_read is int64_t, could someone really try
  // to read more than 9 quintillion (9e18) bytes?
  // DISABLED TO FIX BROKEN BUILD ON 32bit
  // TODO(elmart): Review types to allow assertion
  // assert(rstream->fpos <= INT64_MAX);

  // Synchronous read
  uv_fs_read(
      uv_default_loop(),
      &req,
      rstream->fd,
      &rstream->uvbuf,
      1,
      (int64_t) rstream->fpos,
      NULL);

  uv_fs_req_cleanup(&req);

  if (req.result <= 0) {
    uv_idle_stop(rstream->fread_idle);
    emit_read_event(rstream, true);
    return;
  }

  // no errors (req.result (ssize_t) is positive), it's safe to cast.
  size_t nread = (size_t) req.result;

  rstream->wpos += nread;
  rstream->fpos += nread;

  if (rstream->wpos == rstream->buffer_size) {
    // The last read filled the buffer, stop reading for now
    rstream_stop(rstream);
  }

  emit_read_event(rstream, false);
}