It makes a great difference when decoding huge unsynchronized ID3v2 frames.
* Better handling of PCM WAV files with a 'fact' chunk.
* Better handling of corrupted APE tags.
+ * Efficient decoding of unsynchronized ID3v2 frames.
* Fixed text encoding when saving certain frames in ID3v2.3 tags.
* Several smaller bug fixes and performance improvements.
ByteVector SynchData::decode(const ByteVector &data)
{
+ // We have this optimized method instead of using ByteVector::replace(),
+ // since it makes a great difference when decoding huge unsynchronized frames.
+
+ if(data.size() < 2)
+ return data;
+
ByteVector result = data;
- ByteVector pattern(2, char(0));
- pattern[0] = '\xFF';
- pattern[1] = '\x00';
+ char *begin = result.data();
+ char *end = begin + result.size();
+
+ char *dst = begin;
+ const char *src = begin;
+
+ do {
+ *dst++ = *src++;
+
+ if(*(src - 1) == '\xff' && *src == '\x00')
+ src++;
+
+ } while (src < end);
+
+ result.resize(static_cast<unsigned int>(dst - begin));
- return result.replace(pattern, '\xFF');
+ return result;
}
CPPUNIT_TEST(testToUIntBrokenAndTooLarge);
CPPUNIT_TEST(testDecode1);
CPPUNIT_TEST(testDecode2);
+ CPPUNIT_TEST(testDecode3);
CPPUNIT_TEST_SUITE_END();
public:
CPPUNIT_ASSERT_EQUAL(ByteVector("\xff\x44", 2), a);
}
+ void testDecode3()
+ {
+ ByteVector a("\xff\xff\x00", 3);
+ a = ID3v2::SynchData::decode(a);
+ CPPUNIT_ASSERT_EQUAL((unsigned int)2, a.size());
+ CPPUNIT_ASSERT_EQUAL(ByteVector("\xff\xff", 2), a);
+ }
+
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2SynchData);