E-MailRelay
|
A class that does line buffering, supporting auto-detection of line endings and fixed-size block extraction. More...
#include <glinebuffer.h>
Classes | |
struct | Config |
A configuration structure for GNet::LineBuffer. More... | |
Public Types | |
using | SinkArgs = std::tuple< const char *, std::size_t, std::size_t, std::size_t, char, bool > |
using | SinkFn = std::function< bool(const SinkArgs &)> |
using | FragmentsFn = std::function< bool()> |
Public Member Functions | |
LineBuffer (const Config &) | |
Constructor. More... | |
void | clear () |
Clears the internal data. More... | |
void | add (const std::string &data) |
Adds a data segment. More... | |
void | add (const char *data, std::size_t size) |
Adds a data segment by copying. More... | |
void | expect (std::size_t n) |
Requests that the next 'n' bytes are extracted in one contiguous block, without regard to line endings. More... | |
std::string | eol () const |
Returns the end-of-line string as passed in to the constructor, or as auto-detected. More... | |
template<typename Tfn > | |
void | apply (const char *data, std::size_t data_size, Tfn sink_fn, bool fragments=false) |
Adds the data and passes complete lines to the sink function with line-data, line-size, eol-size and c0 parameters. More... | |
template<typename Tsink , typename Tmemfun > | |
void | apply (Tsink sink_p, Tmemfun sink_memfun, const char *data, std::size_t data_size, bool fragments=false) |
Overload that calls out to a member function. More... | |
template<typename Tsink , typename Tmemfun , typename Tmemfun2 > | |
void | apply (Tsink sink_p, Tmemfun sink_memfun, const char *data, std::size_t data_size, Tmemfun2 fragments_memfun) |
Overload where the 'fragments' flag comes from calling a member function on the sink object, allowing the flag to change dynamically as each line is delivered. More... | |
bool | apply (SinkFn sink_fn, std::string_view data, FragmentsFn fragments_fn) |
Overload for std::function. More... | |
template<typename Tfn > | |
void | apply (const std::string &, Tfn sink_fn, bool fragments=false) |
Overload taking a string as its data input, used in testing. | |
bool | more (bool fragments=false) |
Returns true if there is more data() to be had. More... | |
const char * | data () const |
Returns a pointer for the current line, expect()ed fixed-size block, or line fragment. More... | |
std::size_t | size () const |
Returns the size of the current data(), excluding the line ending. More... | |
std::size_t | eolsize () const |
Returns the size of line-ending associated with the current data(). More... | |
std::size_t | linesize () const |
Returns the current size of all the line fragments making up the current line. More... | |
char | c0 () const |
Returns the first character of the current line. More... | |
bool | transparent () const |
Returns true if the current expect() value is infinite. More... | |
LineBufferState | state () const |
Returns information about the current state of the line-buffer. More... | |
std::size_t | buffersize () const |
Returns the total number of bytes buffered up. More... | |
bool | peekmore () const |
Returns true if there is a line available after the current line or expect()ation. More... | |
void | extensionStart (const char *, std::size_t) |
A pseudo-private method used by the implementation of the apply() method template. More... | |
void | extensionEnd () |
A pseudo-private method used by the implementation of the apply() method template. More... | |
LineBuffer (const LineBuffer &)=delete | |
LineBuffer (LineBuffer &&)=delete | |
LineBuffer & | operator= (const LineBuffer &)=delete |
LineBuffer & | operator= (LineBuffer &&)=delete |
template<typename T > | |
void | apply (const std::string &data, T sink, bool with_fragments) |
Friends | |
class | LineBufferState |
struct | Extension |
A class that does line buffering, supporting auto-detection of line endings and fixed-size block extraction.
Raw data is added, and newline-delimited lines are extracted, optionally via an iterator.
Usage:
A callback mechanism (apply()) can be used that combines adding and extracting. This has the benefit of less data copying, especially if the caller allows incomplete line fragments to be delivered.
The expect() method allows for handling fixed-size blocks that are not line-structured (think http content-length). While the expect() value is in force the line buffer is in a transparent mode, delivering data() with a zero eolsize().
Note that a line buffer that is configured as 'transparent' at run-time is essentially zero cost when using apply() with the 'fragments' option: data passes directly from apply() to the callback.
Definition at line 83 of file glinebuffer.h.
using GNet::LineBuffer::FragmentsFn = std::function<bool()> |
Definition at line 89 of file glinebuffer.h.
using GNet::LineBuffer::SinkArgs = std::tuple<const char*,std::size_t,std::size_t,std::size_t,char,bool> |
Definition at line 87 of file glinebuffer.h.
using GNet::LineBuffer::SinkFn = std::function<bool(const SinkArgs&)> |
Definition at line 88 of file glinebuffer.h.
|
explicit |
Constructor.
Definition at line 28 of file glinebuffer.cpp.
void GNet::LineBuffer::add | ( | const char * | data, |
std::size_t | size | ||
) |
Adds a data segment by copying.
Does nothing if data is null or size is zero. See also apply().
Definition at line 48 of file glinebuffer.cpp.
void GNet::LineBuffer::add | ( | const std::string & | data | ) |
Adds a data segment.
Definition at line 55 of file glinebuffer.cpp.
void GNet::LineBuffer::apply | ( | const char * | data, |
std::size_t | data_size, | ||
Tfn | sink_fn, | ||
bool | fragments = false |
||
) |
Adds the data and passes complete lines to the sink function with line-data, line-size, eol-size and c0 parameters.
Stops if the sink function returns false. The data can be nullptr in order to flush any existing data to the sink function. This method is zero-copy if the supplied data contains complete lines or if allowing line fragments.
Definition at line 444 of file glinebuffer.h.
|
inline |
Definition at line 490 of file glinebuffer.h.
|
inline |
Overload for std::function.
This overload provides extra parameter 'more' to the sink function that is true if there is another complete line buffered-up after the current one (and eolsize is non-zero).
Returns false iff the sink function returned false.
Definition at line 477 of file glinebuffer.h.
void GNet::LineBuffer::apply | ( | Tsink | sink_p, |
Tmemfun | sink_memfun, | ||
const char * | data, | ||
std::size_t | data_size, | ||
bool | fragments = false |
||
) |
Overload that calls out to a member function.
Definition at line 455 of file glinebuffer.h.
void GNet::LineBuffer::apply | ( | Tsink | sink_p, |
Tmemfun | sink_memfun, | ||
const char * | data, | ||
std::size_t | data_size, | ||
Tmemfun2 | fragments_memfun | ||
) |
Overload where the 'fragments' flag comes from calling a member function on the sink object, allowing the flag to change dynamically as each line is delivered.
Definition at line 466 of file glinebuffer.h.
|
inline |
Returns the total number of bytes buffered up.
Definition at line 414 of file glinebuffer.h.
|
inline |
Returns the first character of the current line.
This can be useful in the case of line fragments where treatment of the fragment depends on the first character of the complete line (as in SMTP data transfer). Precondition: linesize() != 0U
Definition at line 438 of file glinebuffer.h.
void GNet::LineBuffer::clear | ( | ) |
Clears the internal data.
Definition at line 37 of file glinebuffer.cpp.
const char * GNet::LineBuffer::data | ( | ) | const |
Returns a pointer for the current line, expect()ed fixed-size block, or line fragment.
This includes eolsize() bytes of line-ending. Precondition: more()
Definition at line 203 of file glinebuffer.cpp.
std::string GNet::LineBuffer::eol | ( | ) | const |
Returns the end-of-line string as passed in to the constructor, or as auto-detected.
Returns the empty string if auto-detection by iteration has not yet occurred.
Definition at line 182 of file glinebuffer.cpp.
|
inline |
Returns the size of line-ending associated with the current data().
This will be zero for a fixed-size block or non-terminal line fragment. (It will never be zero as a result of auto-detection because the precondition means that auto-detection has already happened.) Precondition: more()
Definition at line 426 of file glinebuffer.h.
void GNet::LineBuffer::expect | ( | std::size_t | n | ) |
Requests that the next 'n' bytes are extracted in one contiguous block, without regard to line endings.
Once the expected number of bytes have been extracted the line buffering returns to normal.
This method can be used during a data-transfer phase to obtain a chunk of data of known size, as in http with a known content-length.
A parameter value of zero switches back to normal line buffering immediately.
A parameter value of std::size_t(-1) can be used to represent an infinite expectation that is never fully satisfied. This is only sensible when extracting fragments with apply(), and it results in full transparency.
Definition at line 172 of file glinebuffer.cpp.
void GNet::LineBuffer::extensionEnd | ( | ) |
A pseudo-private method used by the implementation of the apply() method template.
Definition at line 67 of file glinebuffer.cpp.
void GNet::LineBuffer::extensionStart | ( | const char * | data, |
std::size_t | size | ||
) |
A pseudo-private method used by the implementation of the apply() method template.
Definition at line 61 of file glinebuffer.cpp.
|
inline |
Returns the current size of all the line fragments making up the current line.
Precondition: more()
Definition at line 432 of file glinebuffer.h.
bool GNet::LineBuffer::more | ( | bool | fragments = false | ) |
Returns true if there is more data() to be had.
This advances the implied iterator.
If the fragments parameter is true then incomplete lines will be returned (with eolsize zero), but those fragments will explicitly exclude anything that might be part of the line ending.
Definition at line 73 of file glinebuffer.cpp.
bool GNet::LineBuffer::peekmore | ( | ) | const |
Returns true if there is a line available after the current line or expect()ation.
Precondition: more()
Definition at line 143 of file glinebuffer.cpp.
|
inline |
Returns the size of the current data(), excluding the line ending.
Precondition: more()
Definition at line 408 of file glinebuffer.h.
GNet::LineBufferState GNet::LineBuffer::state | ( | ) | const |
Returns information about the current state of the line-buffer.
Definition at line 209 of file glinebuffer.cpp.
bool GNet::LineBuffer::transparent | ( | ) | const |
Returns true if the current expect() value is infinite.
Definition at line 177 of file glinebuffer.cpp.
|
friend |
Definition at line 324 of file glinebuffer.h.
|
friend |
Definition at line 316 of file glinebuffer.h.