Lines 31-36
Link Here
|
31 |
#include <iostream> |
31 |
#include <iostream> |
32 |
#include <cstdio> |
32 |
#include <cstdio> |
33 |
#include <cstring> |
33 |
#include <cstring> |
|
|
34 |
#include <cstddef> |
34 |
|
35 |
|
35 |
#include <tstring.h> |
36 |
#include <tstring.h> |
36 |
#include <tdebug.h> |
37 |
#include <tdebug.h> |
Lines 508-569
ByteVector &ByteVector::replace(const ByteVector &pattern, const ByteVector &wit
Link Here
|
508 |
if(pattern.size() == 0 || pattern.size() > size()) |
509 |
if(pattern.size() == 0 || pattern.size() > size()) |
509 |
return *this; |
510 |
return *this; |
510 |
|
511 |
|
511 |
const uint withSize = with.size(); |
512 |
const size_t withSize = with.size(); |
512 |
const uint patternSize = pattern.size(); |
513 |
const size_t patternSize = pattern.size(); |
513 |
int offset = 0; |
514 |
const ptrdiff_t diff = withSize - patternSize; |
|
|
515 |
|
516 |
size_t offset = 0; |
517 |
while (true) |
518 |
{ |
519 |
offset = find(pattern, offset); |
520 |
if(offset == static_cast<size_t>(-1)) // Use npos in taglib2. |
521 |
break; |
514 |
|
522 |
|
515 |
if(withSize == patternSize) { |
|
|
516 |
// I think this case might be common enough to optimize it |
517 |
detach(); |
523 |
detach(); |
518 |
offset = find(pattern); |
|
|
519 |
while(offset >= 0) { |
520 |
::memcpy(data() + offset, with.data(), withSize); |
521 |
offset = find(pattern, offset + withSize); |
522 |
} |
523 |
return *this; |
524 |
} |
525 |
|
524 |
|
526 |
// calculate new size: |
525 |
if(diff < 0) { |
527 |
uint newSize = 0; |
526 |
::memmove( |
528 |
for(;;) { |
527 |
data() + offset + withSize, |
529 |
int next = find(pattern, offset); |
528 |
data() + offset + patternSize, |
530 |
if(next < 0) { |
529 |
size() - offset - patternSize); |
531 |
if(offset == 0) |
530 |
resize(size() + diff); |
532 |
// pattern not found, do nothing: |
|
|
533 |
return *this; |
534 |
newSize += size() - offset; |
535 |
break; |
536 |
} |
531 |
} |
537 |
newSize += (next - offset) + withSize; |
532 |
else if(diff > 0) { |
538 |
offset = next + patternSize; |
533 |
resize(size() + diff); |
539 |
} |
534 |
::memmove( |
540 |
|
535 |
data() + offset + withSize, |
541 |
// new private data of appropriate size: |
536 |
data() + offset + patternSize, |
542 |
ByteVectorPrivate *newData = new ByteVectorPrivate(newSize, 0); |
537 |
size() - diff - offset - patternSize); |
543 |
char *target = DATA(newData); |
|
|
544 |
const char *source = data(); |
545 |
|
546 |
// copy modified data into new private data: |
547 |
offset = 0; |
548 |
for(;;) { |
549 |
int next = find(pattern, offset); |
550 |
if(next < 0) { |
551 |
::memcpy(target, source + offset, size() - offset); |
552 |
break; |
553 |
} |
538 |
} |
554 |
int chunkSize = next - offset; |
|
|
555 |
::memcpy(target, source + offset, chunkSize); |
556 |
target += chunkSize; |
557 |
::memcpy(target, with.data(), withSize); |
558 |
target += withSize; |
559 |
offset += chunkSize + patternSize; |
560 |
} |
561 |
|
539 |
|
562 |
// replace private data: |
540 |
::memcpy(data() + offset, with.data(), with.size()); |
563 |
if(d->deref()) |
|
|
564 |
delete d; |
565 |
|
541 |
|
566 |
d = newData; |
542 |
offset += withSize; |
|
|
543 |
if(offset > size() - patternSize) |
544 |
break; |
545 |
} |
567 |
|
546 |
|
568 |
return *this; |
547 |
return *this; |
569 |
} |
548 |
} |