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 if( data !=
nullptr && size != 0U )
53 m_in.append( data , size ) ;
66 m_in.extend( data , size ) ;
71 m_in.discard( m_pos ) ;
77 G_ASSERT( m_pos <= m_in.size() ) ;
78 const std::size_t npos = std::string::npos ;
79 std::size_t pos = 0U ;
81 if( m_pos == m_in.size() )
89 else if( m_expect != 0U )
91 if( !transparent() && (m_pos+m_expect) <= m_in.size() )
95 output( m_expect , 0U ,
true ) ;
99 else if( fragments && !trivial(m_in.size()) )
103 G_ASSERT( m_in.size() > m_pos ) ;
104 std::size_t n = m_in.size() - m_pos ;
106 if( !transparent() ) m_expect -= n ;
122 else if( (pos=m_in.find(m_eol,m_pos)) != npos )
126 output( pos-m_pos , m_eol.size() ) ;
129 else if( fragments && (pos=m_in.findSubStringAtEnd(m_eol,m_pos)) != m_pos && !trivial(pos) )
133 pos = pos == npos ? m_in.size() : pos ;
134 output( pos-m_pos , 0U ) ;
147 return !m_in.empty() && !m_eol.empty() && !transparent() && m_in.find(m_eol,m_pos) != std::string::npos ;
150bool GNet::LineBuffer::trivial( std::size_t pos )
const
152 pos = pos == std::string::npos ? m_in.size() : pos ;
153 return ( pos - m_pos ) < m_fmin ;
156bool GNet::LineBuffer::detect()
158 const std::size_t npos = std::string::npos ;
161 std::size_t pos = m_in.find(
'\n' ) ;
164 if( pos > 0U && m_in.at(pos-1U) ==
'\r' )
165 m_eol.assign(
"\r\n" , 2U ) ;
167 m_eol.assign( 1U ,
'\n' ) ;
171 return !m_eol.empty() ;
181 return ( m_expect + 1U ) == 0U ;
189void GNet::LineBuffer::output( std::size_t size , std::size_t eolsize ,
bool force_next_is_start_of_line )
191 G_ASSERT( (size+eolsize) != 0U ) ;
193 m_pos += m_out.set( m_in , m_pos , size , eolsize ) ;
195 if( force_next_is_start_of_line )
196 m_out.m_first = true ;
198 if( m_out.m_eolsize && m_out.m_size > m_warn_limit && !m_warned && m_warn_limit != 0U )
200 G_WARNING(
"GNet::LineBuffer::output: very long line detected: " << m_out.m_size <<
" > " << m_warn_limit ) ;
207 G_ASSERT( m_out.m_data !=
nullptr ) ;
208 return m_out.m_data ;
218GNet::LineBuffer::Output::Output()
221std::size_t GNet::LineBuffer::Output::set(
LineStore & in , std::size_t pos , std::size_t size , std::size_t eolsize )
223 bool start = m_first || m_eolsize != 0U ;
227 m_eolsize = eolsize ;
228 if( start ) m_linesize = 0U ;
230 m_data = in.
data( pos , size+eolsize ) ;
231 if( start ) m_c0 = size == 0U ?
'\0' : m_data[0] ;
232 return size + eolsize ;
239 return Config().set_expect( inf ) ;
249 return Config().set_eol( {} ) ;
254 return Config().set_eol( {
"\r\n",2U} ) ;
259 return Config().set_eol( {
"\r\n",2U} ).set_warn( 998U+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.