Non-blocking buffered i/o: Trivial FIFO class for holding bytes on their way to or from a nonblocking socket.
Non-blocking buffered i/o: Trivial FIFO class for holding bytes on their way to or from a nonblocking socket. Also provides a way to read a CRLF terminated line of ASCII text from the buffer. Kind of like stdio from C, or like a combination of BufferedOutputStream, BufferedInputStream, and BufferedReader in Java, except that none of the methods in this class sleep or take more than a few microseconds to execute.All I/O is nonblocking to make this class usable inside a many-client-per-thread server. (Nonblocking functions, by definition, always return immediately; they often queue requests to be processed later, or return the error code EWOULDBLOCK advising the caller to try again later.) These methods are not threadsafe; by design, only one thread at a time should call these methods on any one instance of this class.
Note: this class is usually used either as an input buffer, in which case only the methods fillFrom() and readline() are used, or as an output buffer, in which case only the methods put() and flushTo() are used. One could argue this class should be split into two to reflect this.
This implementation of a FIFO circular buffer will be familliar to assembly language programmers who have written interrupt-driven serial I/O programs. m_buf holds the bytes to be buffered. Bytes are added to the buffer by copying to the offset m_putTo and then updating m_putTo. Bytes are removed from the buffer by copying from the offset m_getFrom and then updating m_getFrom. The buffer is empty if both indices are equal; it is full if they would become equal after putting one more byte into the buffer.
The buffer is a fixed size; this design does not let it grow or shrink. The size of the buffer must be a power of two because I have chosen to use "& (BUFLEN-1)" to keep the indices within bounds after each update rather than "% BUFLEN" or "if > BUFLEN". These used to be standard practices back on 8-bit CPU's which had no memory allocator and were slow at division, and I've grown attached to the idiom. Simplicity is its main advantage.
Note: weird interface: If it can't read a whole line, it reads part of the line into linebuf, and returns EWOULDBLOCK, in which case the caller should try again later (after calling fillFrom()). The caller must not touch linebuf until readline returns zero, as this routine uses linebuf as temporary storage.
Returns 0 on success, unix error code on failure.
Like put(), except that the data comes from a file descriptor rather than the caller's buffer.
Alphabetic index HTML hierarchy of classes or Java