// Low level input function int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt) { if (rbuffer_pending(input_buffer)) { return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen); } InbufPollResult result; if (ms >= 0) { if ((result = inbuf_poll(ms)) == kInputNone) { return 0; } } else { if ((result = inbuf_poll((int)p_ut)) == kInputNone) { if (trigger_cursorhold() && maxlen >= 3 && !typebuf_changed(tb_change_cnt)) { buf[0] = K_SPECIAL; buf[1] = KS_EXTRA; buf[2] = KE_CURSORHOLD; return 3; } before_blocking(); result = inbuf_poll(-1); } } // If input was put directly in typeahead buffer bail out here. if (typebuf_changed(tb_change_cnt)) { return 0; } if (rbuffer_pending(input_buffer)) { // Safe to convert rbuffer_read to int, it will never overflow since we use // relatively small buffers. return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen); } // If there are deferred events, return the keys directly if (event_has_deferred()) { return push_event_key(buf, maxlen); } if (result == kInputEof) { read_error_exit(); } return 0; }
static void read_cb(RStream *rstream, void *data, bool at_eof) { if (at_eof) { input_eof = true; } char *buf = rbuffer_read_ptr(read_buffer); size_t buf_size = rbuffer_pending(read_buffer); (void)rbuffer_write(input_buffer, buf, buf_size); rbuffer_consumed(read_buffer, buf_size); }
/// Reads data from a `RBuffer` instance into a raw buffer. /// /// @param rbuffer The `RBuffer` instance /// @param buffer The buffer which will receive the data /// @param count Number of bytes that `buffer` can accept /// @return The number of bytes copied into `buffer` size_t rbuffer_read(RBuffer *rbuffer, char *buffer, size_t count) { size_t read_count = rbuffer_pending(rbuffer); if (count < read_count) { read_count = count; } if (read_count > 0) { memcpy(buffer, rbuffer_read_ptr(rbuffer), read_count); rbuffer_consumed(rbuffer, read_count); } return read_count; }
static void process_interrupts(void) { if (mapped_ctrl_c) { return; } char *inbuf = rbuffer_read_ptr(input_buffer); size_t count = rbuffer_pending(input_buffer), consume_count = 0; for (int i = (int)count - 1; i >= 0; i--) { if (inbuf[i] == 3) { got_int = true; consume_count = (size_t)i; break; } } if (got_int) { // Remove everything typed before the CTRL-C rbuffer_consumed(input_buffer, consume_count); } }
/// Returns the number of bytes ready for consumption in `rstream` size_t rstream_pending(RStream *rstream) { return rbuffer_pending(rstream->buffer); }
// Check if there's pending input static bool input_ready(void) { return typebuf_was_filled || // API call filled typeahead rbuffer_pending(input_buffer) > 0 || // Input buffer filled event_has_deferred(); // Events must be processed }