Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 516342
Collapse All | Expand All

(-)a/taglib/toolkit/tbytevector.cpp (-49 / +28 lines)
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
}
(-)a/tests/test_bytevector.cpp (-1 / +5 lines)
Lines 239-244 class TestByteVector : public CppUnit::TestFixture Link Here
239
      a.replace(ByteVector("ab"), ByteVector());
239
      a.replace(ByteVector("ab"), ByteVector());
240
      CPPUNIT_ASSERT_EQUAL(ByteVector("cdf"), a);
240
      CPPUNIT_ASSERT_EQUAL(ByteVector("cdf"), a);
241
    }
241
    }
242
    {
243
      ByteVector a("abcdabf");
244
      a.replace(ByteVector("bf"), ByteVector("x"));
245
      CPPUNIT_ASSERT_EQUAL(ByteVector("abcdax"), a);
246
    }
242
  }
247
  }
243
248
244
};
249
};
245
- 

Return to bug 516342