Changeset 6cc87c0
- Timestamp:
- Sep 20, 2021, 10:41:29 PM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- 3bf3b6b
- Parents:
- 6aa84e0
- Files:
-
- 4 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/containers/string_res.cfa
r6aa84e0 r6cc87c0 21 21 22 22 23 #ifdef VbyteDebug 24 extern HandleNode *HeaderPtr; 23 24 25 26 27 28 29 // DON'T COMMIT: 30 // #define VbyteDebug 31 32 33 34 35 36 #ifdef VbyteDebug 37 HandleNode *HeaderPtr; 25 38 #endif // VbyteDebug 26 39 … … 140 153 141 154 VbyteHeap HeapArea; 155 156 VbyteHeap * DEBUG_string_heap = & HeapArea; 157 158 size_t DEBUG_string_bytes_avail_until_gc( VbyteHeap * heap ) { 159 return ((char*)heap->ExtVbyte) - heap->EndVbyte; 160 } 161 162 const char * DEBUG_string_heap_start( VbyteHeap * heap ) { 163 return heap->StartVbyte; 164 } 165 142 166 143 167 // Returns the size of the string in bytes … … 225 249 void assign(string_res &this, const char* buffer, size_t bsize) { 226 250 251 // traverse the incumbent share-edit set (SES) to recover the range of a base string to which `this` belongs 252 string_res * shareEditSetStartPeer = & this; 253 string_res * shareEditSetEndPeer = & this; 254 for (string_res * editPeer = this.shareEditSet_next; editPeer != &this; editPeer = editPeer->shareEditSet_next) { 255 if ( editPeer->Handle.s < shareEditSetStartPeer->Handle.s ) { 256 shareEditSetStartPeer = editPeer; 257 } 258 if ( shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth < editPeer->Handle.s + editPeer->Handle.lnth) { 259 shareEditSetEndPeer = editPeer; 260 } 261 } 262 263 // full string is from start of shareEditSetStartPeer thru end of shareEditSetEndPeer 264 // `this` occurs in the middle of it, to be replaced 265 // build up the new text in `pasting` 266 267 string_res pasting = { 268 shareEditSetStartPeer->Handle.s, // start of SES 269 this.Handle.s - shareEditSetStartPeer->Handle.s }; // length of SES, before this 270 append( pasting, 271 buffer, // start of replacement for this 272 bsize ); // length of replacement for this 273 append( pasting, 274 this.Handle.s + this.Handle.lnth, // start of SES after this 275 shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - 276 (this.Handle.s + this.Handle.lnth) ); // length of SES, after this 277 278 // The above string building can trigger compaction. 279 // The reference points (that are arguments of the string building) may move during that building. 280 // From this point on, they are stable. 281 // So now, capture their values for use in the overlap cases, below. 282 // Do not factor these definitions with the arguments used above. 283 284 char * beforeBegin = shareEditSetStartPeer->Handle.s; 285 size_t beforeLen = this.Handle.s - beforeBegin; 286 227 287 char * afterBegin = this.Handle.s + this.Handle.lnth; 228 229 char * shareEditSetStart = this.Handle.s; 230 char * shareEditSetEnd = afterBegin; 231 for (string_res * editPeer = this.shareEditSet_next; editPeer != &this; editPeer = editPeer->shareEditSet_next) { 232 shareEditSetStart = min( shareEditSetStart, editPeer->Handle.s ); 233 shareEditSetEnd = max( shareEditSetStart, editPeer->Handle.s + editPeer->Handle.lnth); 234 } 235 236 char * beforeBegin = shareEditSetStart; 237 size_t beforeLen = this.Handle.s - shareEditSetStart; 238 size_t afterLen = shareEditSetEnd - afterBegin; 239 240 string_res pasting = { beforeBegin, beforeLen }; 241 append(pasting, buffer, bsize); 242 string_res after = { afterBegin, afterLen }; // juxtaposed with in-progress pasting 243 pasting += after; // optimized case 288 size_t afterLen = shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - afterBegin; 244 289 245 290 size_t oldLnth = this.Handle.lnth; … … 253 298 for (string_res * p = this.shareEditSet_next; p != &this; p = p->shareEditSet_next) { 254 299 assert (p->Handle.s >= beforeBegin); 255 if ( p->Handle.s < beforeBegin + beforeLen ) { 256 // p starts before the edit 257 if ( p->Handle.s + p->Handle.lnth < beforeBegin + beforeLen ) { 300 if ( p->Handle.s >= afterBegin ) { 301 assert ( p->Handle.s <= afterBegin + afterLen ); 302 assert ( p->Handle.s + p->Handle.lnth <= afterBegin + afterLen ); 303 // p starts after the edit 304 // take start and end as end-anchored 305 size_t startOffsetFromEnd = afterBegin + afterLen - p->Handle.s; 306 p->Handle.s = limit - startOffsetFromEnd; 307 // p->Handle.lnth unaffected 308 } else if ( p->Handle.s <= beforeBegin + beforeLen ) { 309 // p starts before, or at the start of, the edit 310 if ( p->Handle.s + p->Handle.lnth <= beforeBegin + beforeLen ) { 258 311 // p ends before the edit 259 312 // take end as start-anchored too 260 313 // p->Handle.lnth unaffected 261 314 } else if ( p->Handle.s + p->Handle.lnth < afterBegin ) { 262 // p ends during the edit 315 // p ends during the edit; p does not include the last character replaced 263 316 // clip end of p to end at start of edit 264 317 p->Handle.lnth = beforeLen - ( p->Handle.s - beforeBegin ); … … 274 327 size_t startOffsetFromStart = p->Handle.s - beforeBegin; 275 328 p->Handle.s = pasting.Handle.s + startOffsetFromStart; 276 } else if ( p->Handle.s < afterBegin ) { 329 } else { 330 assert ( p->Handle.s < afterBegin ); 277 331 // p starts during the edit 278 332 assert( p->Handle.s + p->Handle.lnth >= beforeBegin + beforeLen ); 279 333 if ( p->Handle.s + p->Handle.lnth < afterBegin ) { 280 // p ends during the edit 334 // p ends during the edit; p does not include the last character replaced 281 335 // set p to empty string at start of edit 282 336 p->Handle.s = this.Handle.s; 283 337 p->Handle.lnth = 0; 284 338 } else { 285 // p ends afterthe edit339 // p includes the end of the edit 286 340 // clip start of p to start at end of edit 341 int charsToClip = afterBegin - p->Handle.s; 287 342 p->Handle.s = this.Handle.s + this.Handle.lnth; 288 p->Handle.lnth += this.Handle.lnth; 289 p->Handle.lnth -= oldLnth; 343 p->Handle.lnth -= charsToClip; 290 344 } 291 } else {292 assert ( p->Handle.s <= afterBegin + afterLen );293 assert ( p->Handle.s + p->Handle.lnth <= afterBegin + afterLen );294 // p starts after the edit295 // take start and end as end-anchored296 size_t startOffsetFromEnd = afterBegin + afterLen - p->Handle.s;297 p->Handle.s = limit - startOffsetFromEnd;298 // p->Handle.lnth unaffected299 345 } 300 346 MoveThisAfter( p->Handle, pasting.Handle ); // move substring handle to maintain sorted order by string position … … 641 687 } // if 642 688 #ifdef VbyteDebug 643 serr | "exit:MoveThisAfter";644 689 { 645 690 serr | "HandleList:"; … … 650 695 serr | n->s[i]; 651 696 } // for 652 serr | "\" flink:" | n->flink | " blink:" | n->blink ;697 serr | "\" flink:" | n->flink | " blink:" | n->blink | nl; 653 698 } // for 654 699 serr | nlOn; 655 700 } 701 serr | "exit:MoveThisAfter"; 656 702 #endif // VbyteDebug 657 703 } // MoveThisAfter … … 662 708 663 709 //######################### VbyteHeap ######################### 664 665 #ifdef VbyteDebug666 HandleNode *HeaderPtr = 0p;667 #endif // VbyteDebug668 710 669 711 // Move characters from one location in the byte-string area to another. The routine handles the following situations: -
libcfa/src/containers/string_res.hfa
r6aa84e0 r6cc87c0 36 36 void ?{}( HandleNode &, VbyteHeap & ); // constructor for nodes in the handle list 37 37 void ^?{}( HandleNode & ); // destructor for handle nodes 38 39 extern VbyteHeap * DEBUG_string_heap; 40 size_t DEBUG_string_bytes_avail_until_gc( VbyteHeap * heap ); 41 const char * DEBUG_string_heap_start( VbyteHeap * heap ); 38 42 39 43
Note: See TracChangeset
for help on using the changeset viewer.