00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00023
00033
00034
00035 #ifndef _CTTL_XTL_REGION_MAP_H_INCLUDED_
00036 #define _CTTL_XTL_REGION_MAP_H_INCLUDED_
00037
00038 #include <vector>
00039 #include <map>
00040 #include <string>
00041
00042 namespace cttl_impl {
00043
00051 class xtl_region_map
00052 {
00054 std::map< size_t, size_t > m_map_region;
00055
00056 public:
00058 xtl_region_map()
00059 {
00060 }
00061
00075 void adjust( size_t after_offset_, int delta_offset_ )
00076 {
00077 if ( !delta_offset_ )
00078 return;
00079
00080 std::map< size_t, size_t >::iterator from_iter =
00081 m_map_region.lower_bound( after_offset_ );
00082
00083 if ( from_iter != m_map_region.end() ) {
00084 std::vector< std::pair< size_t, size_t > > adjustment_vector;
00085 std::back_insert_iterator< std::vector< std::pair< size_t, size_t > > >
00086 vector_back_inserter( adjustment_vector );
00087
00088 std::copy( from_iter, m_map_region.end(), vector_back_inserter );
00089 m_map_region.erase( from_iter, m_map_region.end() );
00090
00091 for ( size_t i = 0; i < adjustment_vector.size(); ++i ) {
00092 if ( adjustment_vector[ i ].first > after_offset_ )
00093 adjustment_vector[ i ].first += delta_offset_;
00094
00095 if ( adjustment_vector[ i ].second > after_offset_ )
00096 adjustment_vector[ i ].second += delta_offset_;
00097
00098 m_map_region.insert( adjustment_vector[ i ] );
00099 }
00100 }
00101 }
00102
00112 void insert( size_t from_offset_, size_t to_offset_ )
00113 {
00114
00115 if ( from_offset_ == to_offset_ )
00116 return;
00117
00118 size_t invalid_from = 0;
00119 size_t invalid_to = 0;
00120
00121 std::map< size_t, size_t >::const_iterator iter =
00122 m_map_region.lower_bound( from_offset_ );
00123
00124 if ( iter != m_map_region.end() ) {
00125 invalid_from = iter->second;
00126 invalid_to = iter->first;
00127
00128 if ( ( invalid_from <= from_offset_ ) && ( from_offset_ <= invalid_to ) ) {
00129
00130 from_offset_ = invalid_from;
00131 }
00132 }
00133
00134 iter = m_map_region.lower_bound( to_offset_ );
00135
00136 if ( iter != m_map_region.end() ) {
00137 invalid_from = iter->second;
00138 invalid_to = iter->first;
00139
00140 if ( ( invalid_from <= to_offset_ ) && ( to_offset_ < invalid_to ) ) {
00141
00142 to_offset_ = invalid_to;
00143 }
00144 }
00145
00146
00147
00148 erase( from_offset_, to_offset_ );
00149
00150 m_map_region[ to_offset_ ] = from_offset_;
00151 }
00152
00154 void erase( size_t from_offset_, size_t to_offset_ )
00155 {
00156 if ( from_offset_ == to_offset_ )
00157 return;
00158
00159 if ( m_map_region.empty() )
00160 return;
00161
00162 std::map< size_t, size_t >::iterator from_iter =
00163 m_map_region.lower_bound( from_offset_ );
00164
00165 if ( from_iter != m_map_region.end() ) {
00166 std::map< size_t, size_t >::iterator to_iter =
00167 m_map_region.upper_bound( to_offset_ );
00168
00169 m_map_region.erase( from_iter, to_iter );
00170 }
00171 }
00172
00179 bool intersection( size_t offset_ ) const
00180 {
00181 if ( m_map_region.empty() )
00182 return false;
00183
00184
00185 std::map< size_t, size_t >::const_iterator iter =
00186 m_map_region.lower_bound( offset_ );
00187
00188
00189 if ( iter == m_map_region.end() )
00190 return false;
00191
00192 size_t invalid_from = iter->second;
00193 size_t invalid_to = iter->first;
00194
00195 if ( ( invalid_from <= offset_ ) && ( offset_ < invalid_to ) )
00196 return true;
00197
00198 return false;
00199 }
00200
00216 size_t find_not_region( size_t offset_, size_t str_length_ ) const
00217 {
00218 if ( offset_ > str_length_ )
00219 return str_length_;
00220
00221 if ( m_map_region.empty() )
00222 return offset_;
00223
00224
00225 std::map< size_t, size_t >::const_iterator iter =
00226 m_map_region.lower_bound( offset_ );
00227
00228
00229 if ( iter != m_map_region.end() ) {
00230
00231 size_t invalid_from = iter->second;
00232 size_t invalid_to = iter->first;
00233
00234 if ( ( invalid_from <= offset_ ) && ( offset_ < invalid_to ) )
00235
00236
00237
00238 offset_ = invalid_to;
00239 }
00240
00241 return offset_;
00242 }
00243
00252 size_t find_upper_boundary( size_t offset_, size_t str_length_, size_t default_offset_ ) const
00253 {
00254
00255
00256
00257 ++offset_;
00258 if ( offset_ >= str_length_ )
00259 return default_offset_;
00260
00261 if ( m_map_region.empty() )
00262 return default_offset_;
00263
00264
00265 std::map< size_t, size_t >::const_iterator iter =
00266 m_map_region.lower_bound( offset_ );
00267
00268 if ( iter != m_map_region.end() )
00269 return iter->second;
00270
00271 return default_offset_;
00272 }
00273
00274
00281 size_t find_lower_boundary( size_t offset_, size_t str_length_, size_t default_offset_ ) const
00282 {
00283
00284
00285
00286 ++offset_;
00287 if ( offset_ >= str_length_ )
00288 return default_offset_;
00289
00290 if ( m_map_region.empty() )
00291 return default_offset_;
00292
00293
00294 std::map< size_t, size_t >::const_iterator iter =
00295 m_map_region.lower_bound( offset_ );
00296
00297 if ( iter != m_map_region.end() )
00298 return iter->first;
00299
00300 return default_offset_;
00301 }
00302
00303
00311 std::pair< size_t, size_t > find_region( size_t offset_, size_t str_length_, size_t default_offset_ ) const
00312 {
00313
00314
00315 ++offset_;
00316 if ( offset_ >= str_length_ )
00317 return std::make_pair( default_offset_, default_offset_ );
00318
00319 if ( m_map_region.empty() )
00320 return std::make_pair( default_offset_, default_offset_ );
00321
00322
00323 std::map< size_t, size_t >::const_iterator iter =
00324 m_map_region.lower_bound( offset_ );
00325
00326 if ( iter != m_map_region.end() )
00327 return std::make_pair( iter->second, iter->first );
00328
00329 return std::make_pair( default_offset_, default_offset_ );
00330 }
00331
00333 void clear()
00334 {
00335 m_map_region.clear();
00336 }
00337
00339 bool empty() const
00340 {
00341 return m_map_region.empty();
00342 }
00343
00344
00346 bool intersection( size_t from_offset_, size_t to_offset_ ) const
00347 {
00348 if ( m_map_region.empty() )
00349 return false;
00350
00351 std::map< size_t, size_t >::const_iterator from_iter =
00352 m_map_region.lower_bound( from_offset_ );
00353
00354 if ( from_iter != m_map_region.end() ) {
00355
00356
00357 if ( ( from_offset_ <= from_iter->second ) && ( from_iter->second < to_offset_ ) )
00358 return true;
00359 if ( ( from_iter->second <= from_offset_ ) && ( from_offset_ < from_iter->first ) )
00360 return true;
00361 }
00362
00363 std::map< size_t, size_t >::const_iterator to_iter =
00364 m_map_region.upper_bound( to_offset_ );
00365
00366 if ( to_iter != m_map_region.end() ) {
00367
00368
00369 if ( ( from_offset_ <= to_iter->second ) && ( to_iter->second < to_offset_ ) )
00370 return true;
00371 if ( ( to_iter->second <= from_offset_ ) && ( from_offset_ < to_iter->first ) )
00372 return true;
00373 }
00374
00375 return false;
00376 }
00377
00379 bool contains( size_t from_offset_, size_t to_offset_ ) const
00380 {
00381 if ( m_map_region.empty() )
00382 return false;
00383
00384 std::map< size_t, size_t >::const_iterator from_iter =
00385 m_map_region.lower_bound( from_offset_ );
00386
00387 if ( from_iter != m_map_region.end() ) {
00388
00389
00390 if ( ( from_iter->second <= from_offset_ ) && ( from_offset_ < from_iter->first )
00391 && ( from_iter->second <= to_offset_ ) && ( to_offset_ <= from_iter->first ) )
00392 return true;
00393 }
00394
00395 std::map< size_t, size_t >::const_iterator to_iter =
00396 m_map_region.upper_bound( to_offset_ );
00397
00398 if ( to_iter != m_map_region.end() ) {
00399
00400
00401 if ( ( to_iter->second <= from_offset_ ) && ( from_offset_ < to_iter->first )
00402 && ( to_iter->second <= to_offset_ ) && ( to_offset_ <= to_iter->first ) )
00403 return true;
00404 }
00405
00406 return false;
00407 }
00408
00410 template< typename StringT >
00411 StringT text_difference( StringT const& str_, size_t from_offset_, size_t to_offset_ ) const
00412 {
00413 if ( from_offset_ == to_offset_ )
00414 return StringT();
00415
00416 StringT str_difference;
00417
00418 std::map< size_t, size_t >::const_iterator map_iter = m_map_region.lower_bound( from_offset_ );
00419 if ( map_iter == m_map_region.end() )
00420 return str_.substr( from_offset_, to_offset_ - from_offset_ );
00421
00422 size_t current_offset_from = from_offset_;
00423 size_t current_offset_to = to_offset_;
00424
00425 for ( ; map_iter != m_map_region.end(); ++map_iter ) {
00426 size_t region_from = map_iter->second;
00427 size_t region_to = map_iter->first;
00428
00429 if ( ( region_from <= current_offset_from ) && ( current_offset_from < region_to ) ) {
00430 current_offset_from = region_to;
00431 continue;
00432 }
00433
00434 if ( ( region_from <= current_offset_to ) && ( current_offset_to < region_to ) )
00435 current_offset_to = region_from;
00436
00437 if ( ( current_offset_from <= region_from ) && ( region_from < current_offset_to ) )
00438 current_offset_to = region_from;
00439
00440 if ( current_offset_from > current_offset_to )
00441 return str_difference;
00442
00443 if ( current_offset_to > to_offset_ )
00444 return str_difference;
00445
00446 str_difference += str_.substr( current_offset_from, current_offset_to - current_offset_from );
00447
00448 if ( current_offset_to < region_from )
00449 return str_difference;
00450
00451 current_offset_from = region_to;
00452 current_offset_to = to_offset_;
00453 }
00454
00455 if ( current_offset_from < current_offset_to )
00456 str_difference += str_.substr( current_offset_from, current_offset_to - current_offset_from );
00457
00458 return str_difference;
00459 }
00460
00461 };
00462
00463 }
00464
00465 #endif // _CTTL_XTL_REGION_MAP_H_INCLUDED_