E-MailRelay

glinebuffer.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file glinebuffer.h
19///
20
21#ifndef G_NET_LINE_BUFFER_H
22#define G_NET_LINE_BUFFER_H
23
24#include "gdef.h"
25#include "gexception.h"
26#include "glinestore.h"
27#include "gcall.h"
28#include <string>
29
30 namespace GNet
31{
32 class LineBuffer ;
33 class LineBufferConfig ;
34 class LineBufferIterator ;
35 class LineBufferState ;
36}
37
38//| \class GNet::LineBuffer
39/// A class that does line buffering, supporting auto-detection of
40/// line endings and fixed-size block extraction. Raw data is
41/// added, and newline-delimited lines are extracted, optionally
42/// via an iterator.
43///
44/// Usage:
45/// \code
46/// {
47/// GNet::LineBuffer buffer( (GNet::LineBufferConfig()) ) ;
48/// buffer.add("abc") ;
49/// buffer.add("def\nABC\nDE") ;
50/// buffer.add("F\n") ;
51///
52/// GNet::LineBufferIterator iter( buffer ) ;
53/// while( iter.more() )
54/// cout << iter.line() << endl ;
55/// }
56/// \endcode
57///
58/// A callback mechanism (apply()) can be used that combines
59/// adding and extracting. This has the benefit of less data
60/// copying, especially if the caller allows incomplete line
61/// fragments to be delivered.
62///
63/// \code
64/// {
65/// struct Callback { bool operator()( const char * , std::size_t size , std::size_t eolsize , std::size_t linesize , char c0 ) {...} } callback ;
66/// GNet::LineBuffer buffer( (GNet::LineBufferConfig()) ) ;
67/// for( std::string s : std::vector<std::string> { "foo" , "bar\r" , "\n" } )
68/// buffer.apply( s.data() , s.size() , callback , true ) ;
69/// }
70/// \endcode
71///
72/// The expect() method allows for handling fixed-size blocks
73/// that are not line-structured (think http content-length).
74/// While the expect() value is in force the line buffer is in
75/// a transparent mode, delivering data() with a zero eolsize().
76///
77/// Note that a line buffer that is configured as 'transparent'
78/// at run-time is essentially zero cost when using apply()
79/// with the 'fragments' option: data passes directly from
80/// apply() to the callback.
81///
82 class GNet::LineBuffer
83{
84 public:
85 G_EXCEPTION( ErrorOverflow , "line buffer overflow" ) ;
86
87 explicit LineBuffer( const LineBufferConfig & ) ;
88 ///< Constructor.
89
90 void clear() ;
91 ///< Clears the internal data.
92
93 void add( const std::string & data ) ;
94 ///< Adds a data segment.
95
96 void add( const char * data , std::size_t size ) ;
97 ///< Adds a data segment by copying.
98 ///< See also apply().
99
100 void expect( std::size_t n ) ;
101 ///< Requests that the next 'n' bytes extracted be extracted
102 ///< in one contiguous block, without regard to line endings.
103 ///< Once the expected number of bytes have been extracted
104 ///< the line buffering returns to normal.
105 ///<
106 ///< This method can be used during a data-transfer phase to
107 ///< obtain a chunk of data of known size, as in http with a
108 ///< known content-length.
109 ///<
110 ///< A parameter value of zero switches back to normal line
111 ///< buffering immediately.
112 ///<
113 ///< A parameter value of std::size_t(-1) can be used to represent
114 ///< an infinite expectation that is never fully satisfied.
115 ///< This is only sensible when extracting fragments and
116 ///< results in full transparency.
117
118 std::string eol() const ;
119 ///< Returns the end-of-line string as passed in to the
120 ///< constructor, or as auto-detected. Returns the empty
121 ///< string if auto-detection by iteration has not yet
122 ///< occurred.
123
124 template <typename Tfn>
125 void apply( const char * data , std::size_t data_size , Tfn sink_fn , bool fragments = false ) ;
126 ///< Adds the data and passes complete lines to the sink
127 ///< function with line-data, line-size, eol-size and
128 ///< c0 parameters. Stops if the sink function returns false.
129 ///< The data can be nullptr in order to flush any existing
130 ///< data to the sink function. This method is zero-copy if
131 ///< the supplied data contains complete lines or if allowing
132 ///< line fragments.
133 ///<
134 ///< \code
135 ///< void Foo::onData( const char * data , std::size_t size )
136 ///< {
137 ///< apply( data , size , onLine , false ) ;
138 ///< }
139 ///< bool onLine( const char * data , std::size_t size , std::size_t , std::size_t , char )
140 ///< {
141 ///< process( std::string(data,size) ) ;
142 ///< }
143 ///< \endcode
144
145 template <typename Tsink, typename Tmemfun>
146 void apply( Tsink sink_p , Tmemfun sink_memfun , const char * data , std::size_t data_size , bool fragments = false ) ;
147 ///< Overload that calls out to a member function.
148 ///<
149 ///< \code
150 ///< void Foo::onData( const char * data , std::size_t size )
151 ///< {
152 ///< apply( this , &Foo::onLine , data , size , false ) ;
153 ///< }
154 ///< bool Foo::onLine( const char * data , std::size_t size , std::size_t , std::size_t , char )
155 ///< {
156 ///< process( std::string(data,size) ) ;
157 ///< }
158 ///< \endcode
159
160 template <typename Tsink, typename Tmemfun, typename Tmemfun2>
161 void apply( Tsink sink_p , Tmemfun sink_memfun , const char * data , std::size_t data_size , Tmemfun2 fragments_memfun ) ;
162 ///< Overload where the 'fragments' flag comes from calling a member
163 ///< function on the sink object, allowing the flag to change
164 ///< dynamically as each line is delivered.
165
166 template <typename Tfn>
167 void apply( const std::string & , Tfn sink_fn , bool fragments = false ) ;
168 ///< Overload taking a string as its data input, used in
169 ///< testing.
170
171 bool more( bool fragments = false ) ;
172 ///< Returns true if there is more data() to be had.
173 ///< This advances the implied iterator.
174 ///<
175 ///< If the fragments parameter is true then incomplete
176 ///< lines will be returned (with eolsize zero), but
177 ///< those fragments will explicitly exclude anything
178 ///< that might be part of the line ending.
179
180 const char * data() const ;
181 ///< Returns a pointer for the current line, expect()ed
182 ///< fixed-size block, or line fragment. This includes
183 ///< eolsize() bytes of line-ending.
184 ///< Precondition: more()
185
186 std::size_t size() const ;
187 ///< Returns the size of the current data(), excluding the
188 ///< line ending.
189 ///< Precondition: more()
190
191 std::size_t eolsize() const ;
192 ///< Returns the size of line-ending associated with the
193 ///< current data(). This will be zero for a fixed-size
194 ///< block or non-terminal line fragment. (It will never
195 ///< be zero as a result of auto-detection because the
196 ///< precondition means that auto-detection has already
197 ///< happened.)
198 ///< Precondition: more()
199
200 std::size_t linesize() const ;
201 ///< Returns the current size of all the line fragments
202 ///< making up the current line.
203 ///< Precondition: more()
204
205 char c0() const ;
206 ///< Returns the first character of the current line.
207 ///< This can be useful in the case of line fragments
208 ///< where treatment of the fragment depends on the
209 ///< first character of the complete line (as in SMTP
210 ///< data transfer).
211 ///< Precondition: linesize() != 0U
212
213 bool transparent() const ;
214 ///< Returns true if the current expect() value is
215 ///< infinite.
216
217 LineBufferState state() const ;
218 ///< Returns information about the current state of the
219 ///< line-buffer.
220
221 public:
222 void extensionStart( const char * , std::size_t ) ;
223 ///< A pseudo-private method used by the implementation
224 ///< of the apply() method template.
225
226 void extensionEnd() ;
227 ///< A pseudo-private method used by the implementation
228 ///< of the apply() method template.
229
230 private:
231 struct Output
232 {
233 bool m_first{true} ;
234 const char * m_data{nullptr} ;
235 std::size_t m_size{0U} ;
236 std::size_t m_eolsize{0U} ;
237 std::size_t m_linesize{0U} ;
238 char m_c0{'\0'} ;
239 Output() ;
240 std::size_t set( LineStore & , std::size_t pos , std::size_t size , std::size_t eolsize ) ;
241 } ;
242 struct Extension
243 {
244 Extension( LineBuffer * , const char * , std::size_t ) ;
245 ~Extension() ;
246 Extension( const Extension & ) = delete ;
247 Extension( Extension && ) = delete ;
248 void operator=( const Extension & ) = delete ;
249 void operator=( Extension && ) = delete ;
250 bool valid() const ;
251 LineBuffer * m_line_buffer ;
252 G::CallFrame m_call_frame ;
253 } ;
254
255 public:
256 ~LineBuffer() = default ;
257 LineBuffer( const LineBuffer & ) = delete ;
258 LineBuffer( LineBuffer && ) = delete ;
259 void operator=( const LineBuffer & ) = delete ;
260 void operator=( LineBuffer && ) = delete ;
261
262 private:
263 friend class LineBufferState ;
264 void check( const Output & ) ;
265 void output( std::size_t size , std::size_t eolsize , bool = false ) ;
266 bool detect() ;
267 bool trivial( std::size_t pos ) const ;
268 bool finite() const ;
269 std::size_t insize() const ; // for LineBufferState
270 std::string head() const ; // for LineBufferState
271
272 private:
273 friend struct Extension ;
274 G::CallStack m_call_stack ;
275 bool m_auto ;
276 std::string m_eol ;
277 std::size_t m_warn_limit ;
278 std::size_t m_fmin ;
279 std::size_t m_expect ;
280 bool m_warned ;
281 LineStore m_in ;
282 Output m_out ;
283 std::size_t m_pos ;
284} ;
285
286//| \class GNet::LineBufferIterator
287/// Syntactic sugar for calling GNet::LineBuffer iteration methods.
288///
289 class GNet::LineBufferIterator
290{
291 public:
292 explicit LineBufferIterator( LineBuffer & buffer ) ;
293 ///< Constructor.
294
295 bool more() ;
296 ///< See LineBuffer::more().
297
298 const char * data() const ;
299 ///< See LineBuffer::data().
300
301 std::size_t size() const ;
302 ///< See LineBuffer::size().
303
304 std::size_t eolsize() const ;
305 ///< See LineBuffer::eolsize().
306
307 std::string line() const ;
308 ///< Returns the current line (of length size()).
309
310 public:
311 ~LineBufferIterator() = default ;
312 LineBufferIterator( const LineBufferIterator & ) = delete ;
313 LineBufferIterator( LineBufferIterator && ) = delete ;
314 void operator=( const LineBufferIterator & ) = delete ;
315 void operator=( LineBufferIterator && ) = delete ;
316
317 private:
318 LineBuffer & m_line_buffer ;
319} ;
320
321//| \class GNet::LineBufferConfig
322/// A configuration structure for GNet::LineBuffer.
323///
324 class GNet::LineBufferConfig
325{
326 public:
327 explicit LineBufferConfig( const std::string & eol = std::string(1U,'\n') ,
328 std::size_t warn = 0U , std::size_t fmin = 0U , std::size_t initial_expect = 0U ) ;
329 ///< Constructor. An empty end-of-line string detects either
330 ///< LF or CR-LF. The default end-of-line string is newline.
331 ///< A non-zero warn-limit generates a one-shot warning when
332 ///< breached. The fmin value can be used to prevent trivially
333 ///< small line fragments from being returned. This is useful
334 ///< for SMTP where a fragment containing a single dot character
335 ///< and no end-of-line can cause confusion with respect to
336 ///< the end-of-text marker. The initial-expect parameter
337 ///< is useful for defining transparent operation.
338
339 const std::string & eol() const ;
340 ///< Returns the end-of-line string as passed to the constructor.
341
342 std::size_t warn() const ;
343 ///< Returns the warn-limit, as passed to the constructor.
344
345 std::size_t fmin() const ;
346 ///< Returns the minimum fragment size, as passed to the constructor.
347
348 std::size_t expect() const ;
349 ///< Returns the initial expect value, as passed to the constructor.
350
351 static LineBufferConfig transparent() ;
352 ///< Convenience factory function.
353
354 static LineBufferConfig http() ;
355 ///< Convenience factory function.
356
357 static LineBufferConfig smtp() ;
358 ///< Convenience factory function.
359
360 static LineBufferConfig pop() ;
361 ///< Convenience factory function.
362
363 static LineBufferConfig crlf() ;
364 ///< Convenience factory function.
365
366 static LineBufferConfig newline() ;
367 ///< Convenience factory function.
368
369 static LineBufferConfig autodetect() ;
370 ///< Convenience factory function.
371
372 private:
373 std::string m_eol ;
374 std::size_t m_warn ;
375 std::size_t m_fmin ;
376 std::size_t m_expect ;
377} ;
378
379//| \class GNet::LineBufferState
380/// Provides information abount the state of a line buffer.
381///
382 class GNet::LineBufferState
383{
384 public:
385 explicit LineBufferState( const LineBuffer & ) ;
386 ///< Constructor.
387
388 bool transparent() const ;
389 ///< Returns LineBuffer::transparent().
390
391 std::string eol() const ;
392 ///< Returns LineBuffer::eol().
393
394 std::size_t size() const ;
395 ///< Returns the number of bytes currently buffered up.
396
397 bool empty() const ;
398 ///< Returns true iff size() is zero.
399
400 std::string head() const ;
401 ///< Returns the first bytes of buffered data up to a limit
402 ///< of sixteen bytes.
403
404 private:
405 bool m_transparent ;
406 std::string m_eol ;
407 std::size_t m_size ;
408 std::string m_head ;
409} ;
410
411// ==
412
413 inline
414GNet::LineBuffer::Extension::Extension( LineBuffer * line_buffer , const char * data , std::size_t size ) :
415 m_line_buffer(line_buffer) ,
416 m_call_frame(line_buffer->m_call_stack)
417{
418 m_line_buffer->extensionStart( data , size ) ;
419}
420
421 inline
422GNet::LineBuffer::Extension::~Extension()
423{
424 if( m_call_frame.valid() )
425 m_line_buffer->extensionEnd() ;
426}
427
428 inline
429 bool GNet::LineBuffer::Extension::valid() const
430{
431 return m_call_frame.valid() ;
432}
433
434// ==
435
436 inline
437std::size_t GNet::LineBuffer::size() const
438{
439 return m_out.m_size ;
440}
441
442 inline
443std::size_t GNet::LineBuffer::insize() const
444{
445 return m_in.size() ;
446}
447
448 inline
449std::string GNet::LineBuffer::head() const
450{
451 return m_in.head( 16U ) ;
452}
453
454 inline
455std::size_t GNet::LineBuffer::eolsize() const
456{
457 return m_out.m_eolsize ;
458}
459
460 inline
461std::size_t GNet::LineBuffer::linesize() const
462{
463 return m_out.m_linesize ;
464}
465
466 inline
467 char GNet::LineBuffer::c0() const
468{
469 return m_out.m_c0 ;
470}
471
472 template <typename Tfn>
473 void GNet::LineBuffer::apply( const char * data_in , std::size_t size_in , Tfn sink_fn , bool with_fragments )
474{
475 Extension e( this , data_in , size_in ) ;
476 while( e.valid() && more(with_fragments) )
477 {
478 if( !sink_fn( data() , size() , eolsize() , linesize() , c0() ) )
479 break ;
480 }
481}
482
483 template <typename Tsink, typename Tmemfun>
484 void GNet::LineBuffer::apply( Tsink sink_p , Tmemfun memfun , const char * data_in , std::size_t size_in , bool with_fragments )
485{
486 Extension e( this , data_in , size_in ) ;
487 while( e.valid() && more(with_fragments) )
488 {
489 if( !(sink_p->*memfun)( data() , size() , eolsize() , linesize() , c0() ) )
490 break ;
491 }
492}
493
494 template <typename Tsink, typename Tmemfun, typename Tmemfun2>
495 void GNet::LineBuffer::apply( Tsink sink_p , Tmemfun memfun , const char * data_in , std::size_t size_in , Tmemfun2 fragments_memfun )
496{
497 Extension e( this , data_in , size_in ) ;
498 while( e.valid() && more( (sink_p->*fragments_memfun)() ) )
499 {
500 if( !(sink_p->*memfun)( data() , size() , eolsize() , linesize() , c0() ) )
501 break ;
502 }
503}
504
505 template <typename T>
506 inline
507 void GNet::LineBuffer::apply( const std::string & data , T sink , bool with_fragments )
508{
509 return apply( data.data() , data.size() , sink , with_fragments ) ;
510}
511
512// ==
513
514 inline
515 const std::string & GNet::LineBufferConfig::eol() const
516{
517 return m_eol ;
518}
519
520 inline
521std::size_t GNet::LineBufferConfig::warn() const
522{
523 return m_warn ;
524}
525
526 inline
527std::size_t GNet::LineBufferConfig::fmin() const
528{
529 return m_fmin ;
530}
531
532 inline
533std::size_t GNet::LineBufferConfig::expect() const
534{
535 return m_expect ;
536}
537
538// ==
539
540 inline
541 GNet::LineBufferIterator::LineBufferIterator( LineBuffer & line_buffer ) :
542 m_line_buffer(line_buffer)
543{
544}
545
546 inline
547 bool GNet::LineBufferIterator::more()
548{
549 return m_line_buffer.more() ;
550}
551
552 inline
553std::string GNet::LineBufferIterator::line() const
554{
555 return std::string( m_line_buffer.data() , m_line_buffer.size() ) ;
556}
557
558 inline
559 const char * GNet::LineBufferIterator::data() const
560{
561 return m_line_buffer.data() ;
562}
563
564 inline
565std::size_t GNet::LineBufferIterator::size() const
566{
567 return m_line_buffer.size() ;
568}
569
570 inline
571std::size_t GNet::LineBufferIterator::eolsize() const
572{
573 return m_line_buffer.eolsize() ;
574}
575
576// ==
577
578 inline
579 GNet::LineBufferState::LineBufferState( const LineBuffer & line_buffer ) :
580 m_transparent(line_buffer.transparent()) ,
581 m_eol(line_buffer.eol()) ,
582 m_size(line_buffer.insize()) ,
583 m_head(line_buffer.head())
584{
585}
586
587 inline
588std::string GNet::LineBufferState::eol() const
589{
590 return m_eol ;
591}
592
593 inline
594 bool GNet::LineBufferState::transparent() const
595{
596 return m_transparent ;
597}
598
599 inline
600std::size_t GNet::LineBufferState::size() const
601{
602 return m_size ;
603}
604
605 inline
606 bool GNet::LineBufferState::empty() const
607{
608 return m_size == 0U ;
609}
610
611 inline
612std::string GNet::LineBufferState::head() const
613{
614 return m_head ;
615}
616
617#endif
GNet::LineBufferConfig
A configuration structure for GNet::LineBuffer.
Definition: glinebuffer.h:325
GNet::LineBufferConfig::crlf
static LineBufferConfig crlf()
Convenience factory function.
Definition: glinebuffer.cpp:257
GNet::LineBufferConfig::warn
std::size_t warn() const
Returns the warn-limit, as passed to the constructor.
Definition: glinebuffer.h:521
GNet::LineBufferConfig::expect
std::size_t expect() const
Returns the initial expect value, as passed to the constructor.
Definition: glinebuffer.h:533
GNet::LineBufferConfig::fmin
std::size_t fmin() const
Returns the minimum fragment size, as passed to the constructor.
Definition: glinebuffer.h:527
GNet::LineBufferConfig::transparent
static LineBufferConfig transparent()
Convenience factory function.
Definition: glinebuffer.cpp:240
GNet::LineBufferConfig::http
static LineBufferConfig http()
Convenience factory function.
Definition: glinebuffer.cpp:272
GNet::LineBufferConfig::eol
const std::string & eol() const
Returns the end-of-line string as passed to the constructor.
Definition: glinebuffer.h:515
GNet::LineBufferConfig::autodetect
static LineBufferConfig autodetect()
Convenience factory function.
Definition: glinebuffer.cpp:252
GNet::LineBufferConfig::newline
static LineBufferConfig newline()
Convenience factory function.
Definition: glinebuffer.cpp:247
GNet::LineBufferConfig::pop
static LineBufferConfig pop()
Convenience factory function.
Definition: glinebuffer.cpp:267
GNet::LineBufferConfig::LineBufferConfig
LineBufferConfig(const std::string &eol=std::string(1U,'\n'), std::size_t warn=0U, std::size_t fmin=0U, std::size_t initial_expect=0U)
Constructor.
Definition: glinebuffer.cpp:231
GNet::LineBufferConfig::smtp
static LineBufferConfig smtp()
Convenience factory function.
Definition: glinebuffer.cpp:262
GNet::LineBufferIterator
Syntactic sugar for calling GNet::LineBuffer iteration methods.
Definition: glinebuffer.h:290
GNet::LineBufferIterator::LineBufferIterator
LineBufferIterator(LineBuffer &buffer)
Constructor.
Definition: glinebuffer.h:541
GNet::LineBufferIterator::line
std::string line() const
Returns the current line (of length size()).
Definition: glinebuffer.h:553
GNet::LineBufferIterator::data
const char * data() const
See LineBuffer::data().
Definition: glinebuffer.h:559
GNet::LineBufferIterator::eolsize
std::size_t eolsize() const
See LineBuffer::eolsize().
Definition: glinebuffer.h:571
GNet::LineBufferIterator::more
bool more()
See LineBuffer::more().
Definition: glinebuffer.h:547
GNet::LineBufferIterator::size
std::size_t size() const
See LineBuffer::size().
Definition: glinebuffer.h:565
GNet::LineBufferState
Provides information abount the state of a line buffer.
Definition: glinebuffer.h:383
GNet::LineBufferState::head
std::string head() const
Returns the first bytes of buffered data up to a limit of sixteen bytes.
Definition: glinebuffer.h:612
GNet::LineBufferState::empty
bool empty() const
Returns true iff size() is zero.
Definition: glinebuffer.h:606
GNet::LineBufferState::transparent
bool transparent() const
Returns LineBuffer::transparent().
Definition: glinebuffer.h:594
GNet::LineBufferState::size
std::size_t size() const
Returns the number of bytes currently buffered up.
Definition: glinebuffer.h:600
GNet::LineBufferState::LineBufferState
LineBufferState(const LineBuffer &)
Constructor.
Definition: glinebuffer.h:579
GNet::LineBufferState::eol
std::string eol() const
Returns LineBuffer::eol().
Definition: glinebuffer.h:588
GNet::LineBuffer
A class that does line buffering, supporting auto-detection of line endings and fixed-size block extr...
Definition: glinebuffer.h:83
GNet::LineBuffer::LineBuffer
LineBuffer(const LineBufferConfig &)
Constructor.
Definition: glinebuffer.cpp:28
GNet::LineBuffer::expect
void expect(std::size_t n)
Requests that the next 'n' bytes extracted be extracted in one contiguous block, without regard to li...
Definition: glinebuffer.cpp:166
GNet::LineBuffer::transparent
bool transparent() const
Returns true if the current expect() value is infinite.
Definition: glinebuffer.cpp:171
GNet::LineBuffer::linesize
std::size_t linesize() const
Returns the current size of all the line fragments making up the current line.
Definition: glinebuffer.h:461
GNet::LineBuffer::clear
void clear()
Clears the internal data.
Definition: glinebuffer.cpp:39
GNet::LineBuffer::extensionStart
void extensionStart(const char *, std::size_t)
A pseudo-private method used by the implementation of the apply() method template.
Definition: glinebuffer.cpp:60
GNet::LineBuffer::more
bool more(bool fragments=false)
Returns true if there is more data() to be had.
Definition: glinebuffer.cpp:72
GNet::LineBuffer::size
std::size_t size() const
Returns the size of the current data(), excluding the line ending.
Definition: glinebuffer.h:437
GNet::LineBuffer::eolsize
std::size_t eolsize() const
Returns the size of line-ending associated with the current data().
Definition: glinebuffer.h:455
GNet::LineBuffer::data
const char * data() const
Returns a pointer for the current line, expect()ed fixed-size block, or line fragment.
Definition: glinebuffer.cpp:199
GNet::LineBuffer::apply
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
GNet::LineBuffer::eol
std::string eol() const
Returns the end-of-line string as passed in to the constructor, or as auto-detected.
Definition: glinebuffer.cpp:176
GNet::LineBuffer::extensionEnd
void extensionEnd()
A pseudo-private method used by the implementation of the apply() method template.
Definition: glinebuffer.cpp:66
GNet::LineBuffer::add
void add(const std::string &data)
Adds a data segment.
Definition: glinebuffer.cpp:55
GNet::LineBuffer::apply
void apply(const std::string &, Tfn sink_fn, bool fragments=false)
Overload taking a string as its data input, used in testing.
GNet::LineBuffer::c0
char c0() const
Returns the first character of the current line.
Definition: glinebuffer.h:467
GNet::LineBuffer::state
LineBufferState state() const
Returns information about the current state of the line-buffer.
Definition: glinebuffer.cpp:205
G::CallFrame
An object to represent a nested execution context.
Definition: gcall.h:87
G::CallStack
A linked list of CallFrame pointers.
Definition: gcall.h:58
gcall.h
gexception.h
glinestore.h
GNet
Network classes.
Definition: gdef.h:1115