E-MailRelay
Classes | Public Member Functions | Friends | List of all members
GNet::LineBuffer Class Reference

A class that does line buffering, supporting auto-detection of line endings and fixed-size block extraction. More...

#include <glinebuffer.h>

Public Member Functions

 LineBuffer (const LineBufferConfig &)
 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 extracted be 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...
 
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...
 
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
 
void operator= (const LineBuffer &)=delete
 
void operator= (LineBuffer &&)=delete
 
template<typename T >
void apply (const std::string &data, T sink, bool with_fragments)
 

Friends

class LineBufferState
 
struct Extension
 

Detailed Description

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:

{
buffer.add("abc") ;
buffer.add("def\nABC\nDE") ;
buffer.add("F\n") ;
GNet::LineBufferIterator iter( buffer ) ;
while( iter.more() )
cout << iter.line() << endl ;
}
A configuration structure for GNet::LineBuffer.
Definition: glinebuffer.h:325
Syntactic sugar for calling GNet::LineBuffer iteration methods.
Definition: glinebuffer.h:290
A class that does line buffering, supporting auto-detection of line endings and fixed-size block extr...
Definition: glinebuffer.h:83

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.

{
struct Callback { bool operator()( const char * , std::size_t size , std::size_t eolsize , std::size_t linesize , char c0 ) {...} } callback ;
for( std::string s : std::vector<std::string> { "foo" , "bar\r" , "\n" } )
buffer.apply( s.data() , s.size() , callback , true ) ;
}
std::size_t linesize() const
Returns the current size of all the line fragments making up the current line.
Definition: glinebuffer.h:461
std::size_t size() const
Returns the size of the current data(), excluding the line ending.
Definition: glinebuffer.h:437
std::size_t eolsize() const
Returns the size of line-ending associated with the current data().
Definition: glinebuffer.h:455
char c0() const
Returns the first character of the current line.
Definition: glinebuffer.h:467

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 82 of file glinebuffer.h.

Constructor & Destructor Documentation

◆ LineBuffer()

GNet::LineBuffer::LineBuffer ( const LineBufferConfig config)
explicit

Constructor.

Definition at line 28 of file glinebuffer.cpp.

Member Function Documentation

◆ add() [1/2]

void GNet::LineBuffer::add ( const char *  data,
std::size_t  size 
)

Adds a data segment by copying.

See also apply().

Definition at line 50 of file glinebuffer.cpp.

◆ add() [2/2]

void GNet::LineBuffer::add ( const std::string &  data)

Adds a data segment.

Definition at line 55 of file glinebuffer.cpp.

◆ apply() [1/4]

template<typename Tfn >
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.

< void Foo::onData( const char * data , std::size_t size )
< {
< apply( data , size , onLine , false ) ;
< }
< bool onLine( const char * data , std::size_t size , std::size_t , std::size_t , char )
< {
< process( std::string(data,size) ) ;
< }
<
const char * data() const
Returns a pointer for the current line, expect()ed fixed-size block, or line fragment.
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,...
Definition: glinebuffer.h:473

Definition at line 473 of file glinebuffer.h.

◆ apply() [2/4]

template<typename T >
void GNet::LineBuffer::apply ( const std::string &  data,
sink,
bool  with_fragments 
)
inline

Definition at line 507 of file glinebuffer.h.

◆ apply() [3/4]

template<typename Tsink , typename Tmemfun >
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.

< void Foo::onData( const char * data , std::size_t size )
< {
< apply( this , &Foo::onLine , data , size , false ) ;
< }
< bool Foo::onLine( const char * data , std::size_t size , std::size_t , std::size_t , char )
< {
< process( std::string(data,size) ) ;
< }
<

Definition at line 484 of file glinebuffer.h.

◆ apply() [4/4]

template<typename Tsink , typename Tmemfun , typename Tmemfun2 >
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 495 of file glinebuffer.h.

◆ c0()

char GNet::LineBuffer::c0 ( ) const
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 467 of file glinebuffer.h.

◆ clear()

void GNet::LineBuffer::clear ( )

Clears the internal data.

Definition at line 39 of file glinebuffer.cpp.

◆ data()

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 199 of file glinebuffer.cpp.

◆ eol()

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 176 of file glinebuffer.cpp.

◆ eolsize()

std::size_t GNet::LineBuffer::eolsize ( ) const
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 455 of file glinebuffer.h.

◆ expect()

void GNet::LineBuffer::expect ( std::size_t  n)

Requests that the next 'n' bytes extracted be 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 and results in full transparency.

Definition at line 166 of file glinebuffer.cpp.

◆ extensionEnd()

void GNet::LineBuffer::extensionEnd ( )

A pseudo-private method used by the implementation of the apply() method template.

Definition at line 66 of file glinebuffer.cpp.

◆ extensionStart()

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 60 of file glinebuffer.cpp.

◆ linesize()

std::size_t GNet::LineBuffer::linesize ( ) const
inline

Returns the current size of all the line fragments making up the current line.

Precondition: more()

Definition at line 461 of file glinebuffer.h.

◆ more()

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 72 of file glinebuffer.cpp.

◆ size()

std::size_t GNet::LineBuffer::size ( ) const
inline

Returns the size of the current data(), excluding the line ending.

Precondition: more()

Definition at line 437 of file glinebuffer.h.

◆ state()

GNet::LineBufferState GNet::LineBuffer::state ( ) const

Returns information about the current state of the line-buffer.

Definition at line 205 of file glinebuffer.cpp.

◆ transparent()

bool GNet::LineBuffer::transparent ( ) const

Returns true if the current expect() value is infinite.

Definition at line 171 of file glinebuffer.cpp.

Friends And Related Function Documentation

◆ Extension

friend struct Extension
friend

Definition at line 273 of file glinebuffer.h.

◆ LineBufferState

friend class LineBufferState
friend

Definition at line 263 of file glinebuffer.h.


The documentation for this class was generated from the following files: