-
Notifications
You must be signed in to change notification settings - Fork 0
Netbuf
Netbuf architecture is inspired by LwIP netbuf and pbuf as well as general DMA architecture.
A netbuf is one or more raw buffers organized in a sequential manner. One can think of it as a linked list of buffer pointers, though underlying implementation can differ.
Netbuf use template metaprogramming so that they may compile-time optimize down to the same footprint as the native code in which they wrap.
One netbuf
is comprised of a chain
of many buffers. TBD what each buffer is called, either chunk
or chain-buffer
.
Referred to as netbuf mk2
Since C++ concepts
are still relatively new, it's important to specify the calling surface:
bool next()
Moves to next already-allocated buffer in netbuf chain, if one is available. Returns whether this actually happened
ExpandResult expand(size_type by_amount, bool move_to_next)
Attempts to allocate a new buffer in the next position, sizing by the specified by_amount
void* data()
Acquire pointer to current buffer in netbuf chain
void reset()
Reposition netbuf chain to the very first buffer
bool last()
Queries whether this is the last allocated chain buffer in the netbuf
size_type size() const
Returns the size in bytes of the current buffer
size_type total_size() const
Returnsthe size in bytes of the entire netbuf, ultimately the same as totaling every size()
call for each chained buffer
shrink(size_type to_size)
(optional and experimental)
This experimental call mirrors what PBUF shrink does - specifically it reduces the memory allocation of the netbuf to precisely to_size
. This includes, if necessary, iterating over any chain of buffers and potentially deallocating trailing ones completely.
This is useful for protocols like CoAP who derive the message size by the size of the buffer itself
Referred to as netbuf mk1
Prototype versions of netbuf also included a pos
index in which a position within the current netbuf was tracked. This duty has been moved out to classes like NetBufReader/NetBufWriter and streambuf wrappers
The tracking of pos
also necessitated the notions of unprocessed
and processed
calls which made the pos
+ data()
interact
Lastly, an advance
mechanism existed to move that pos
forward
Unfortunately, there are 3 different buffer mechanisms to content with:
- Legacy/earlier netbufs
- New-style netbufs
- streambuf
For the transition from 1 to 2, internal::NetBufWrapper
appears to wrap up a new-style to operate as a legacy netbuf. Not so bad, but the name could be more clear