30 class LineStoreIterator ;
39 G_EXCEPTION( Error ,
"line buffer internal error" ) ;
44 m_pos(end?line_store.
size():0U)
60 swap( m_p , other.m_p ) ;
61 swap( m_pos , other.m_pos ) ;
84 return m_pos == other.m_pos ;
88 return m_pos != other.m_pos ;
92 return m_pos < other.m_pos ;
96 return m_pos <= other.m_pos ;
100 return m_pos > other.m_pos ;
104 return m_pos >= other.m_pos ;
106 char operator*()
const
108 G_ASSERT( m_p !=
nullptr ) ;
111 return m_p->
at( m_pos ) ;
113 char operator[]( std::size_t n )
const
115 G_ASSERT( m_p !=
nullptr ) ;
118 return m_p->
at( m_pos + n ) ;
120 void operator+=( ptrdiff_t n )
123 m_pos -=
static_cast<std::size_t
>(-n) ;
125 m_pos +=
static_cast<std::size_t
>(n) ;
127 void operator-=( ptrdiff_t n )
130 m_pos +=
static_cast<std::size_t
>(-n) ;
132 m_pos -=
static_cast<std::size_t
>(n) ;
136 if( other.m_pos >= m_pos )
137 return static_cast<ptrdiff_t
>(other.m_pos-m_pos) ;
139 return -
static_cast<ptrdiff_t
>(m_pos-other.m_pos) ;
141 std::size_t pos()
const
143 return ( m_p ==
nullptr || m_pos >= m_p->
size() ) ? std::string::npos : m_pos ;
148 std::size_t m_pos{0U} ;
159 inline LineStoreIterator operator-(
const LineStoreIterator & in , ptrdiff_t n )
161 LineStoreIterator result( in ) ;
165 inline LineStoreIterator operator+( ptrdiff_t n ,
const LineStoreIterator & in )
167 LineStoreIterator result( in ) ;
171 inline ptrdiff_t operator-(
const LineStoreIterator & a ,
const LineStoreIterator & b )
173 return a.distanceTo( b ) ;
175 inline void swap( LineStoreIterator & a , LineStoreIterator & b )
noexcept
183 namespace LineStoreImp
185 template <
typename T1,
typename T2>
bool std_equal( T1 p1 , T1 end1 , T2 p2 , T2 end2 )
188 for( ; p1 != end1 && p2 != end2 ; ++p1 , ++p2 )
193 return p1 == end1 && p2 == end2 ;
206 m_store.append( s ) ;
212 m_store.append( data , size ) ;
218 m_extra_data = data ;
219 m_extra_size = size ;
231 m_store.append( m_extra_data , m_extra_size ) ;
241 m_store.append( m_extra_data , m_extra_size ) ;
245 else if( n < m_store.size() )
247 m_store.erase( 0U , n ) ;
250 m_store.append( m_extra_data , m_extra_size ) ;
254 else if( n == m_store.size() )
259 m_store.assign( m_extra_data , m_extra_size ) ;
263 else if( n < size() )
265 std::size_t offset = n - m_store.size() ;
269 G_ASSERT( m_extra_size >= offset ) ;
270 m_store.assign( m_extra_data+offset , m_extra_size-offset ) ;
282 G_ASSERT( startpos <= size() ) ;
283 std::size_t result = std::string::npos ;
284 const std::size_t store_size = m_store.size() ;
285 if( startpos < store_size )
287 result = m_store.find( c , startpos ) ;
289 if( result == std::string::npos && m_extra_size != 0U )
291 const std::size_t offset = startpos > store_size ? (startpos-store_size) : 0U ;
292 const char *
const begin = m_extra_data + offset ;
293 const char *
const end = m_extra_data + m_extra_size ;
294 G_ASSERT( begin >= m_extra_data && begin <= end ) ;
295 const char * p = std::find( begin , end , c ) ;
297 result = store_size + std::distance(m_extra_data,p) ;
305 const std::size_t npos = std::string::npos ;
306 std::size_t result = npos ;
309 const char c0 = s[0] ;
310 const char c1 = s[1] ;
311 const std::size_t end = size() ;
312 for( std::size_t pos = startpos ; pos != npos ; ++pos )
314 pos = find( c0 , pos ) ;
315 if( pos == npos ) break ;
316 if( (pos+1U) != end && at(pos+1U) == c1 )
322 G_ASSERT( result == search(s.begin(),s.end(),startpos) ) ;
324 else if( s.size() == 1U )
326 result = find( s[0] , startpos ) ;
327 G_ASSERT( result == search(s.begin(),s.end(),startpos) ) ;
331 result = search( s.begin() , s.end() , startpos ) ;
336std::size_t GNet::LineStore::search( std::string::const_iterator begin , std::string::const_iterator end ,
337 std::size_t startpos )
const
344 namespace imp = LineStoreImp ;
351 std::size_t result = std::string::npos ;
352 std::size_t s_size = s.size() ;
353 std::string::const_iterator s_start = s.begin() ;
354 std::string::const_iterator s_end = s.end() ;
356 for( --s_size , --s_end ; s_start != s_end ; --s_size , --s_end )
358 if( (size()-startpos) >= s_size )
363 if( imp::std_equal(s_start,s_end,p,end) )
376 return (
const_cast<LineStore*
>(
this))->dataimp( pos , n ) ;
379const char * GNet::LineStore::dataimp( std::size_t pos , std::size_t n )
381 G_ASSERT( (n==0U && size()==0U) || (pos+n) <= size() ) ;
382 if( n == 0U && size() == 0U )
386 else if( n == 0U && pos == size() )
390 else if( (pos+n) <= m_store.size() )
392 return m_store.data() + pos ;
394 else if( pos >= m_store.size() )
396 std::size_t offset = pos - m_store.size() ;
397 return m_extra_data + offset ;
401 std::size_t nmove = pos + n - m_store.size() ;
402 m_store.append( m_extra_data , nmove ) ;
403 m_extra_data += nmove ;
404 m_extra_size -= nmove ;
405 return m_store.data() + pos ;
411 std::string result( m_store ) ;
413 result.append( m_extra_data , m_extra_size ) ;
420 if( result.size() < n && m_extra_size )
421 result.append( m_extra_data , std::min(n-result.size(),m_extra_size) ) ;
An iterator class for GNet::LineStore.
A pair of character buffers, one kept by value and the other being an ephemeral extension.
void discard(std::size_t n)
Discards the first 'n' bytes and consolidates the residue.
void append(const std::string &)
Appends to the store (by copying).
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.
std::string head(std::size_t n) const
Returns the leading sub-string of str() of up to 'n' characters.
void clear()
Clears all data.
LineStore()
Default constructor.
std::string str() const
Returns the complete string.
std::size_t find(char c, std::size_t startpos=0U) const
Finds the given character.
std::size_t size() const
Returns the overall size.
void consolidate()
Consolidates the extension into the store.
void extend(const char *, std::size_t)
Sets the extension.
std::size_t findSubStringAtEnd(const std::string &s, std::size_t startpos=0U) const
Finds a non-empty leading substring 's' that appears at the end of the data.
char at(std::size_t n) const
Returns the n'th character.
static std::string head(const std::string &in, std::size_t pos, const std::string &default_=std::string())
Returns the first part of the string up to just before the given position.