class nbbio

Non-blocking buffered i/o: Trivial FIFO class for holding bytes on their way to or from a nonblocking socket.

Public Methods

[more] nbbio()
Constructor just calls init().
[more]void init()
Init just zeroes things out
[more]int bytesUsed()
Number of bytes used so far
[more]int bytesFree()
Number of bytes still available
[more]bool isEmpty()
TRUE if no more bytes can be pulled out
[more]bool isFull()
TRUE if no more bytes can be put in
[more]int put(const char* p, int n)
Call this to put bytes into the buffer.
[more]int readc()
Call this to read a single char from the buffer.
[more]int readline(char* linebuf, int maxlen)
Call this to read a line from the buffer.
[more]int flushTo(int fd)
For output buffers, call this periodically to write part or all of the buffer to a nonblocking file descriptor (typically a socket, the same one every time).
[more]int fillFrom(int fd)
For input buffers, call this periodically to fill the buffer by reading from a nonblocking file descriptor (typically a socket, the same one every time).
[more]int contigBytesUsed()
Number of contiguous bytes used from the m_getFrom to the m_putTo or the wraparound, whichever comes first.
[more]int contigBytesFree()
Number of contiguous bytes free from the m_putTo to the m_getFrom or the wraparound, whichever comes first.


Documentation

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.

o nbbio()
Constructor just calls init().

ovoid init()
Init just zeroes things out

oint bytesUsed()
Number of bytes used so far

oint bytesFree()
Number of bytes still available

obool isEmpty()
TRUE if no more bytes can be pulled out

obool isFull()
TRUE if no more bytes can be put in

oint put(const char* p, int n)
Call this to put bytes into the buffer. Returns 0 on success, unix error code on failure.

oint readc()
Call this to read a single char from the buffer. Only call when buffer is not empty. Returns character.

oint readline(char* linebuf, int maxlen)
Call this to read a line from the buffer. Expects the line to end in CR LF (but allows them to end in just CR or LF). Strips the CR LF and null terminates the line during copy.

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.

oint flushTo(int fd)
For output buffers, call this periodically to write part or all of the buffer to a nonblocking file descriptor (typically a socket, the same one every time). (Typically called after put(), and after ::poll() says fd is ready for reading.) Returns 0 on success, unix error code on failure.

oint fillFrom(int fd)
For input buffers, call this periodically to fill the buffer by reading from a nonblocking file descriptor (typically a socket, the same one every time). (Typically called after ::poll() says fd is ready for reading, and is followed by one or more calls to readline().) Returns 0 on success, unix error code on failure. In particular, returns EPIPE if the peer has disconnected.

Like put(), except that the data comes from a file descriptor rather than the caller's buffer.

oint contigBytesUsed()
Number of contiguous bytes used from the m_getFrom to the m_putTo or the wraparound, whichever comes first. Used to calculate bytes available for linear I/O. Tells you how many bytes you can pass to write() in a single call when flushing the buffer. Public to make the self-test easier.

oint contigBytesFree()
Number of contiguous bytes free from the m_putTo to the m_getFrom or the wraparound, whichever comes first. Used to calculate bytes available for linear I/O. Tells you how many bytes you can read() in a single call when filling the buffer. Public to make the self-test easier.


This class has no child classes.

Alphabetic index HTML hierarchy of classes or Java



This page was generated with the help of DOC++.