Avoid writing duplicate tags when saving ASF files.

Reduce memory reallocations and copies when saving ASF files.
This commit is contained in:
Tsuda Kageyu 2015-08-04 13:50:09 +09:00
parent 779f904940
commit 6dc8d701a8
2 changed files with 31 additions and 5 deletions

View File

@ -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<ulong>(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;

View File

@ -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);