Exemplo n.º 1
0
// Called by libuv to allocate memory for reading.
static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
{
  RStream *rstream = handle_get_rstream(handle);

  buf->len = rbuffer_available(rstream->buffer);
  buf->base = rbuffer_write_ptr(rstream->buffer);
}
Exemplo n.º 2
0
/// Copies data to `rbuffer` read queue.
///
/// @param rbuffer the `RBuffer` instance
/// @param buffer The buffer containing data to be copied
/// @param count Number of bytes that should be copied
/// @return The number of bytes actually copied
size_t rbuffer_write(RBuffer *rbuffer, char *buffer, size_t count)
{
  size_t write_count = rbuffer_available(rbuffer);

  if (count < write_count) {
    write_count = count;
  }

  if (write_count > 0) {
    memcpy(rbuffer_write_ptr(rbuffer), buffer, write_count);
    rbuffer_produced(rbuffer, write_count);
  }

  return write_count;
}
Exemplo n.º 3
0
size_t input_enqueue(String keys)
{
  char *ptr = keys.data, *end = ptr + keys.size;

  while (rbuffer_available(input_buffer) >= 6 && ptr < end) {
    uint8_t buf[6] = {0};
    unsigned int new_size = trans_special((uint8_t **)&ptr, buf, true);

    if (new_size) {
      new_size = handle_mouse_event(&ptr, buf, new_size);
      rbuffer_write(input_buffer, (char *)buf, new_size);
      continue;
    }

    if (*ptr == '<') {
      // Invalid key sequence, skip until the next '>' or until *end
      do {
        ptr++;
      } while (ptr < end && *ptr != '>');
      ptr++;
      continue;
    }

    // copy the character, escaping CSI and K_SPECIAL
    if ((uint8_t)*ptr == CSI) {
      rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KS_EXTRA}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KE_CSI}, 1);
    } else if ((uint8_t)*ptr == K_SPECIAL) {
      rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KS_SPECIAL}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KE_FILLER}, 1);
    } else {
      rbuffer_write(input_buffer, ptr, 1);
    }
    ptr++;
  }

  size_t rv = (size_t)(ptr - keys.data);
  process_interrupts();
  return rv;
}
Exemplo n.º 4
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_get_rstream((uv_handle_t *)handle);

  rstream->uvbuf.len = rbuffer_available(rstream->buffer);
  rstream->uvbuf.base = rbuffer_write_ptr(rstream->buffer);

  // 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;
  if (fpos_intmax > INT64_MAX) {
    ELOG("stream offset overflow");
    preserve_exit();
  }

  // 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);
    return;
  }

  // no errors (req.result (ssize_t) is positive), it's safe to cast.
  size_t nread = (size_t) req.result;
  rbuffer_produced(rstream->buffer, nread);
  rstream->fpos += nread;
}