30 class LineStoreIterator ;
39 G_EXCEPTION( Error ,
tx(
"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 ) ;
109 return m_p ? m_p->
at( m_pos ) :
'\0' ;
111 char operator[]( std::size_t n )
const
113 G_ASSERT( m_p !=
nullptr ) ;
114 return m_p ? m_p->
at( m_pos + n ) :
'\0' ;
116 void operator+=( ptrdiff_t n )
119 m_pos -=
static_cast<std::size_t
>(-n) ;
121 m_pos +=
static_cast<std::size_t
>(n) ;
123 void operator-=( ptrdiff_t n )
126 m_pos +=
static_cast<std::size_t
>(-n) ;
128 m_pos -=
static_cast<std::size_t
>(n) ;
132 if( other.m_pos >= m_pos )
133 return static_cast<ptrdiff_t
>(other.m_pos-m_pos) ;
135 return -
static_cast<ptrdiff_t
>(m_pos-other.m_pos) ;
137 std::size_t pos()
const
139 return ( m_p ==
nullptr || m_pos >= m_p->
size() ) ? std::string::npos : m_pos ;
144 std::size_t m_pos{0U} ;
155 inline LineStoreIterator operator-(
const LineStoreIterator & in , ptrdiff_t n )
157 LineStoreIterator result( in ) ;
161 inline LineStoreIterator operator+( ptrdiff_t n ,
const LineStoreIterator & in )
163 LineStoreIterator result( in ) ;
167 inline ptrdiff_t operator-(
const LineStoreIterator & a ,
const LineStoreIterator & b )
169 return a.distanceTo( b ) ;
171 inline void swap( LineStoreIterator & a , LineStoreIterator & b )
noexcept
179 namespace LineStoreImp
181 template <
typename T1,
typename T2>
bool std_equal( T1 p1 , T1 end1 , T2 p2 , T2 end2 )
184 for( ; p1 != end1 && p2 != end2 ; ++p1 , ++p2 )
189 return p1 == end1 && p2 == end2 ;
202 m_store.append( s ) ;
208 m_store.append( data , size ) ;
214 m_extra_data = data ;
215 m_extra_size = size ;
227 m_store.append( m_extra_data , m_extra_size ) ;
237 m_store.append( m_extra_data , m_extra_size ) ;
241 else if( n < m_store.size() )
243 m_store.erase( 0U , n ) ;
246 m_store.append( m_extra_data , m_extra_size ) ;
250 else if( n == m_store.size() )
255 m_store.assign( m_extra_data , m_extra_size ) ;
259 else if( n < size() )
261 std::size_t offset = n - m_store.size() ;
265 G_ASSERT( m_extra_size >= offset ) ;
266 m_store.assign( m_extra_data+offset , m_extra_size-offset ) ;
278 G_ASSERT( startpos <= size() ) ;
279 std::size_t result = std::string::npos ;
280 const std::size_t store_size = m_store.size() ;
281 if( startpos < store_size )
283 result = m_store.find( c , startpos ) ;
285 if( result == std::string::npos && m_extra_size != 0U )
287 const std::size_t offset = startpos > store_size ? (startpos-store_size) : 0U ;
288 const char *
const begin = m_extra_data + offset ;
289 const char *
const end = m_extra_data + m_extra_size ;
290 G_ASSERT( begin >= m_extra_data && begin <= end ) ;
291 const char * p = std::find( begin , end , c ) ;
293 result = store_size + std::distance(m_extra_data,p) ;
301 const std::size_t npos = std::string::npos ;
302 std::size_t result = npos ;
305 const char c0 = s[0] ;
306 const char c1 = s[1] ;
307 const std::size_t end = size() ;
308 for( std::size_t pos = startpos ; pos != npos ; ++pos )
310 pos = find( c0 , pos ) ;
311 if( pos == npos ) break ;
312 if( (pos+1U) != end && at(pos+1U) == c1 )
318 G_ASSERT( result == search(s.begin(),s.end(),startpos) ) ;
320 else if( s.size() == 1U )
322 result = find( s[0] , startpos ) ;
323 G_ASSERT( result == search(s.begin(),s.end(),startpos) ) ;
327 result = search( s.begin() , s.end() , startpos ) ;
332std::size_t GNet::LineStore::search( std::string::const_iterator begin , std::string::const_iterator end ,
333 std::size_t startpos )
const
340 namespace imp = LineStoreImp ;
347 std::size_t result = std::string::npos ;
348 std::size_t s_size = s.size() ;
349 std::string::const_iterator s_start = s.begin() ;
350 std::string::const_iterator s_end = s.end() ;
352 for( --s_size , --s_end ; s_start != s_end ; --s_size , --s_end )
354 if( (size()-startpos) >= s_size )
359 if( imp::std_equal(s_start,s_end,p,end) )
372 return (
const_cast<LineStore*
>(
this))->dataimp( pos , n ) ;
375const char * GNet::LineStore::dataimp( std::size_t pos , std::size_t n )
377 G_ASSERT( (n==0U && size()==0U) || (pos+n) <= size() ) ;
378 if( n == 0U && size() == 0U )
382 else if( n == 0U && pos == size() )
386 else if( (pos+n) <= m_store.size() )
388 return m_store.data() + pos ;
390 else if( pos >= m_store.size() )
392 std::size_t offset = pos - m_store.size() ;
393 return m_extra_data + offset ;
397 std::size_t nmove = pos + n - m_store.size() ;
398 m_store.append( m_extra_data , nmove ) ;
399 m_extra_data += nmove ;
400 m_extra_size -= nmove ;
401 return m_store.data() + pos ;
408 std::string result( m_store ) ;
410 result.append( m_extra_data , m_extra_size ) ;
418 if( result.size() < n && m_extra_size )
419 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
Tries to find some leading sub-string of 's' that appears right at the end of the data,...
char at(std::size_t n) const
Returns the n'th character.
static std::string head(string_view in, std::size_t pos, string_view default_={})
Returns the first part of the string up to just before the given position.
constexpr const char * tx(const char *p)
A briefer alternative to G::gettext_noop().