29 m_auto(config.eol().empty()) ,
31 m_warn_limit(config.warn()) ,
32 m_fmin(config.fmin()) ,
33 m_expect(config.expect())
45 G_ASSERT( m_in.empty() && state().empty() ) ;
50 if( data !=
nullptr && size != 0U )
51 m_in.append( data , size ) ;
64 m_in.extend( data , size ) ;
69 m_in.discard( m_pos ) ;
75 G_ASSERT( m_pos <= m_in.size() ) ;
76 const std::size_t npos = std::string::npos ;
77 std::size_t pos = 0U ;
79 if( m_pos == m_in.size() )
87 else if( m_expect != 0U )
89 if( !transparent() && (m_pos+m_expect) <= m_in.size() )
93 output( m_expect , 0U ,
true ) ;
97 else if( fragments && !trivial(m_in.size()) )
101 G_ASSERT( m_in.size() > m_pos ) ;
102 std::size_t n = m_in.size() - m_pos ;
104 if( !transparent() ) m_expect -= n ;
120 else if( (pos=m_in.find(m_eol,m_pos)) != npos )
124 output( pos-m_pos , m_eol.size() ) ;
127 else if( fragments && (pos=m_in.findSubStringAtEnd(m_eol,m_pos)) != m_pos && !trivial(pos) )
131 pos = pos == npos ? m_in.size() : pos ;
132 output( pos-m_pos , 0U ) ;
145 return !m_in.empty() && !m_eol.empty() && !transparent() && m_in.find(m_eol,m_pos) != std::string::npos ;
148bool GNet::LineBuffer::trivial( std::size_t pos )
const
150 pos = pos == std::string::npos ? m_in.size() : pos ;
151 return ( pos - m_pos ) < m_fmin ;
154bool GNet::LineBuffer::detect()
156 const std::size_t npos = std::string::npos ;
159 std::size_t pos = m_in.find(
'\n' ) ;
162 if( pos > 0U && m_in.at(pos-1U) ==
'\r' )
163 m_eol.assign(
"\r\n" , 2U ) ;
165 m_eol.assign( 1U ,
'\n' ) ;
169 return !m_eol.empty() ;
179 return ( m_expect + 1U ) == 0U ;
187void GNet::LineBuffer::output( std::size_t size , std::size_t eolsize ,
bool force_next_is_start_of_line )
189 G_ASSERT( (size+eolsize) != 0U ) ;
191 m_pos += m_out.set( m_in , m_pos , size , eolsize ) ;
193 if( force_next_is_start_of_line )
194 m_out.m_first = true ;
196 if( m_out.m_eolsize && m_out.m_size > m_warn_limit && !m_warned && m_warn_limit != 0U )
198 G_WARNING(
"GNet::LineBuffer::output: very long line detected: " << m_out.m_size <<
" > " << m_warn_limit ) ;
205 G_ASSERT( m_out.m_data !=
nullptr ) ;
206 return m_out.m_data ;
216GNet::LineBuffer::Output::Output()
219std::size_t GNet::LineBuffer::Output::set(
LineStore & in , std::size_t pos , std::size_t size , std::size_t eolsize )
221 bool start = m_first || m_eolsize != 0U ;
225 m_eolsize = eolsize ;
226 if( start ) m_linesize = 0U ;
228 m_data = in.
data( pos , size+eolsize ) ;
229 if( start ) m_c0 = size == 0U ?
'\0' : m_data[0] ;
230 return size + eolsize ;
237 return Config().set_expect( inf ) ;
247 return Config().set_eol( {} ) ;
252 return Config().set_eol( {
"\r\n",2U} ) ;
257 static constexpr unsigned int soft_limit = 998U ;
258 return Config().set_eol( {
"\r\n",2U} ).set_warn(soft_limit+2U).set_fmin(2U) ;
Provides information about the state of a line buffer.
void expect(std::size_t n)
Requests that the next 'n' bytes are extracted in one contiguous block, without regard to line ending...
bool transparent() const
Returns true if the current expect() value is infinite.
void clear()
Clears the internal data.
LineBuffer(const Config &)
Constructor.
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.
bool peekmore() const
Returns true if there is a line available after the current line or expect()ation.
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.
A configuration structure for GNet::LineBuffer.