29 m_auto(config.eol().empty()) ,
31 m_warn_limit(config.warn()) ,
32 m_fmin(config.fmin()) ,
33 m_expect(config.expect()) ,
47 G_ASSERT( m_in.empty() && state().empty() ) ;
52 m_in.append( data , size ) ;
63 m_in.extend( data , size ) ;
68 m_in.discard( m_pos ) ;
74 G_ASSERT( m_pos <= m_in.size() ) ;
75 const std::size_t npos = std::string::npos ;
76 std::size_t pos = 0U ;
78 if( m_pos == m_in.size() )
86 else if( m_expect != 0U )
88 if( !transparent() && (m_pos+m_expect) <= m_in.size() )
92 output( m_expect , 0U ,
true ) ;
96 else if( fragments && !trivial(m_in.size()) )
100 G_ASSERT( m_in.size() > m_pos ) ;
101 std::size_t n = m_in.size() - m_pos ;
103 if( !transparent() ) m_expect -= n ;
119 else if( (pos=m_in.find(m_eol,m_pos)) != npos )
123 output( pos-m_pos , m_eol.size() ) ;
126 else if( fragments && (pos=m_in.findSubStringAtEnd(m_eol,m_pos)) != m_pos && !trivial(pos) )
130 pos = pos == npos ? m_in.size() : pos ;
131 output( pos-m_pos , 0U ) ;
142bool GNet::LineBuffer::trivial( std::size_t pos )
const
144 pos = pos == std::string::npos ? m_in.size() : pos ;
145 return ( pos - m_pos ) < m_fmin ;
148bool GNet::LineBuffer::detect()
150 const std::size_t npos = std::string::npos ;
153 std::size_t pos = m_in.find(
'\n' ) ;
156 if( pos > 0U && m_in.at(pos-1U) ==
'\r' )
157 m_eol = std::string(
"\r\n" , 2U ) ;
159 m_eol = std::string( 1U ,
'\n' ) ;
163 return !m_eol.empty() ;
173 return ( m_expect + 1U ) == 0U ;
181void GNet::LineBuffer::output( std::size_t size , std::size_t eolsize ,
bool force_next_is_start_of_line )
183 G_ASSERT( (size+eolsize) != 0U ) ;
184 m_pos += m_out.set( m_in , m_pos , size , eolsize ) ;
185 if( force_next_is_start_of_line )
186 m_out.m_first = true ;
190void GNet::LineBuffer::check(
const Output & out )
192 if( !m_warned && m_warn_limit != 0U && out.m_size > m_warn_limit )
194 G_WARNING(
"GNet::LineBuffer::check: very long line detected: " << out.m_size <<
" > " << m_warn_limit ) ;
201 G_ASSERT( m_out.m_data !=
nullptr ) ;
202 return m_out.m_data ;
212GNet::LineBuffer::Output::Output()
215std::size_t GNet::LineBuffer::Output::set(
LineStore & in , std::size_t pos , std::size_t size , std::size_t eolsize )
217 bool start = m_first || m_eolsize != 0U ;
221 m_eolsize = eolsize ;
222 if( start ) m_linesize = 0U ;
224 m_data = in.
data( pos , size+eolsize ) ;
225 if( start ) m_c0 = size == 0U ?
'\0' : m_data[0] ;
226 return size + eolsize ;
232 std::size_t fmin , std::size_t expect ) :
242 static constexpr std::size_t inf = ~(std::size_t(0)) ;
243 static_assert( (inf+1U) == 0U ,
"" ) ;
A configuration structure for GNet::LineBuffer.
static LineBufferConfig crlf()
Convenience factory function.
static LineBufferConfig transparent()
Convenience factory function.
static LineBufferConfig http()
Convenience factory function.
static LineBufferConfig autodetect()
Convenience factory function.
static LineBufferConfig newline()
Convenience factory function.
static LineBufferConfig pop()
Convenience factory function.
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.
static LineBufferConfig smtp()
Convenience factory function.
Provides information abount the state of a line buffer.
LineBuffer(const LineBufferConfig &)
Constructor.
void expect(std::size_t n)
Requests that the next 'n' bytes extracted be extracted in one contiguous block, without regard to li...
bool transparent() const
Returns true if the current expect() value is infinite.
void clear()
Clears the internal data.
void extensionStart(const char *, std::size_t)
A pseudo-private method used by the implementation of the apply() method template.
bool more(bool fragments=false)
Returns true if there is more data() to be had.
const char * data() const
Returns a pointer for the current line, expect()ed fixed-size block, or line fragment.
std::string eol() const
Returns the end-of-line string as passed in to the constructor, or as auto-detected.
void extensionEnd()
A pseudo-private method used by the implementation of the apply() method template.
void add(const std::string &data)
Adds a data segment.
LineBufferState state() const
Returns information about the current state of the line-buffer.
A pair of character buffers, one kept by value and the other being an ephemeral extension.
const char * data(std::size_t pos, std::size_t size) const
Returns a pointer for the data at the given position that is contiguous for the given size.