From 6dc8d701a8db9a39799f5dea3aedb7104143eb1d Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Tue, 4 Aug 2015 13:50:09 +0900 Subject: [PATCH] Avoid writing duplicate tags when saving ASF files. Reduce memory reallocations and copies when saving ASF files. --- taglib/asf/asffile.cpp | 20 +++++++++++++++----- tests/test_asf.cpp | 16 ++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/taglib/asf/asffile.cpp b/taglib/asf/asffile.cpp index 02fe83c3..a5e5ea84 100644 --- a/taglib/asf/asffile.cpp +++ b/taglib/asf/asffile.cpp @@ -50,7 +50,7 @@ public: class MetadataLibraryObject; FilePrivate(): - size(0), + headerSize(0), tag(0), properties(0), contentDescriptionObject(0), @@ -68,7 +68,7 @@ public: delete properties; } - unsigned long long size; + unsigned long long headerSize; ASF::Tag *tag; ASF::Properties *properties; @@ -556,6 +556,10 @@ bool ASF::File::save() d->headerExtensionObject->objects.append(d->metadataLibraryObject); } + d->extendedContentDescriptionObject->attributeData.clear(); + d->metadataObject->attributeData.clear(); + d->metadataLibraryObject->attributeData.clear(); + const AttributeListMap allAttributes = d->tag->attributeListMap(); for(AttributeListMap::ConstIterator it = allAttributes.begin(); it != allAttributes.end(); ++it) { @@ -591,8 +595,14 @@ bool ASF::File::save() data.append((*it)->render(this)); } - data = headerGuid + ByteVector::fromLongLong(data.size() + 30, false) + ByteVector::fromUInt(d->objects.size(), false) + ByteVector("\x01\x02", 2) + data; - insert(data, 0, (TagLib::ulong)d->size); + seek(16); + writeBlock(ByteVector::fromLongLong(data.size() + 30, false)); + writeBlock(ByteVector::fromUInt(d->objects.size(), false)); + writeBlock(ByteVector("\x01\x02", 2)); + + insert(data, 30, static_cast(d->headerSize - 30)); + + d->headerSize = data.size() + 30; return true; } @@ -617,7 +627,7 @@ void ASF::File::read() d->properties = new ASF::Properties(); bool ok; - d->size = readQWORD(this, &ok); + d->headerSize = readQWORD(this, &ok); if(!ok) { setValid(false); return; diff --git a/tests/test_asf.cpp b/tests/test_asf.cpp index 663ae583..37614b0c 100644 --- a/tests/test_asf.cpp +++ b/tests/test_asf.cpp @@ -25,6 +25,7 @@ class TestASF : public CppUnit::TestFixture CPPUNIT_TEST(testSavePicture); CPPUNIT_TEST(testSaveMultiplePictures); CPPUNIT_TEST(testProperties); + CPPUNIT_TEST(testRepeatedSave); CPPUNIT_TEST_SUITE_END(); public: @@ -270,6 +271,21 @@ public: CPPUNIT_ASSERT_EQUAL(StringList("3"), tags["DISCNUMBER"]); } + void testRepeatedSave() + { + ScopedFileCopy copy("silence-1", ".wma"); + + { + ASF::File f(copy.fileName().c_str()); + f.tag()->setTitle(std::string(128 * 1024, 'X').c_str()); + f.save(); + CPPUNIT_ASSERT_EQUAL(297578L, f.length()); + f.tag()->setTitle(std::string(16 * 1024, 'X').c_str()); + f.save(); + CPPUNIT_ASSERT_EQUAL(68202L, f.length()); + } + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestASF); -- 2.40.0