mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-06 03:20:26 +00:00
space_for_read(), read_input_nblock()
This commit is contained in:
parent
165e61e4c0
commit
6f8afb1610
84
src/lib/in.c
84
src/lib/in.c
@ -28,8 +28,10 @@ typedef struct inputctx {
|
||||
#endif
|
||||
unsigned char ibuf[BUFSIZ]; // we dump raw reads into this ringbuffer, and
|
||||
// process them all post-read
|
||||
int ibufvalid, ibufwrite; // our bookkeeping for ibuf;
|
||||
// we mustn't read() if ibufvalid == sizeof(ibuf)
|
||||
int ibufvalid; // we mustn't read() if ibufvalid == sizeof(ibuf)
|
||||
int ibufwrite; // we write here next
|
||||
int ibufread; // first valid byte here (if any are valid)
|
||||
|
||||
cursorloc* csrs; // cursor reports are dumped here
|
||||
ncinput* inputs; // processed input is dumped here
|
||||
int csize, isize; // total number of slots in csrs/inputs
|
||||
@ -51,11 +53,14 @@ create_inputctx(tinfo* ti){
|
||||
i->isize = BUFSIZ;
|
||||
if( (i->inputs = malloc(sizeof(*i->inputs) * i->isize)) ){
|
||||
// FIXME set up infd/handle
|
||||
i->termfd = -1;
|
||||
i->stdinfd = -1;
|
||||
i->ti = ti;
|
||||
i->cvalid = i->ivalid = 0;
|
||||
i->cwrite = i->iwrite = 0;
|
||||
i->cread = i->iread = 0;
|
||||
i->ibufvalid = i->ibufwrite = 0;
|
||||
i->ibufread = 0;
|
||||
return i;
|
||||
}
|
||||
free(i->csrs);
|
||||
@ -75,14 +80,81 @@ free_inputctx(inputctx* i){
|
||||
}
|
||||
}
|
||||
|
||||
// how many bytes can a single read fill in the ibuf? this might be fewer than
|
||||
// the actual number of free bytes, due to reading on the right or left side.
|
||||
static inline size_t
|
||||
space_for_read(inputctx* ictx){
|
||||
// if we are valid everywhere, there's no space to read into.
|
||||
if(ictx->ibufvalid == sizeof(ictx->ibuf)){
|
||||
return 0;
|
||||
}
|
||||
// if we are valid nowhere, we can read into the head of the buffer
|
||||
if(ictx->ibufvalid == 0){
|
||||
ictx->ibufread = 0;
|
||||
ictx->ibufwrite = 0;
|
||||
return sizeof(ictx->ibuf);
|
||||
}
|
||||
// otherwise, we can read either from ibufwrite to the end of the buffer,
|
||||
// or from ibufwrite to ibufread.
|
||||
if(ictx->ibufwrite < ictx->ibufread){
|
||||
return ictx->ibufread - ictx->ibufwrite;
|
||||
}
|
||||
return sizeof(ictx->ibuf) - ictx->ibufwrite;
|
||||
}
|
||||
|
||||
// populate the ibuf with any new data from the specified file descriptor.
|
||||
static void
|
||||
read_input_nblock(inputctx* ictx, int fd){
|
||||
if(fd >= 0){
|
||||
size_t space = space_for_read(ictx);
|
||||
if(space == 0){
|
||||
return;
|
||||
}
|
||||
ssize_t r = read(fd, ictx->ibuf + ictx->ibufwrite, space);
|
||||
if(r >= 0){
|
||||
ictx->ibufwrite += r;
|
||||
if(ictx->ibufwrite == sizeof(ictx->ibuf)){
|
||||
ictx->ibufwrite = 0;
|
||||
}
|
||||
ictx->ibufvalid += r;
|
||||
space -= r;
|
||||
loginfo("read %lldB from %d (%lluB left)\n", (long long)r, fd, (unsigned long long)space);
|
||||
if(space == 0){
|
||||
return;
|
||||
}
|
||||
// might have been falsely limited by space (only reading on the right).
|
||||
// this will recurse one time at most.
|
||||
if(ictx->ibufwrite == 0){
|
||||
read_input_nblock(ictx, fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// walk the matching automaton from wherever we were.
|
||||
static void
|
||||
process_ibuf(inputctx* ictx){
|
||||
// FIXME
|
||||
}
|
||||
|
||||
// populate the ibuf with any new data, up through its size, but do not block.
|
||||
// don't loop around this call without some kind of readiness notification.
|
||||
static void
|
||||
read_inputs_nblock(inputctx* ictx){
|
||||
// first we read from the terminal, if that's a distinct source.
|
||||
read_input_nblock(ictx, ictx->termfd);
|
||||
// now read bulk, possibly with term escapes intermingled within (if there
|
||||
// was not a distinct terminal source).
|
||||
read_input_nblock(ictx, ictx->stdinfd);
|
||||
}
|
||||
|
||||
static void*
|
||||
input_thread(void* vmarshall){
|
||||
inputctx* ictx = vmarshall;
|
||||
for(;;){
|
||||
if(ictx->ibufvalid == sizeof(ictx->ibuf)){
|
||||
// we can't read any more. need clients to clear their buffers.
|
||||
// sleep on condvar FIXME
|
||||
}
|
||||
read_inputs_nblock(ictx);
|
||||
// process anything we've read
|
||||
process_ibuf(ictx);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user