]> granicus.if.org Git - taglib/commitdiff
Save ASF attributes larger than 64k to the metadata library object
authorLukáš Lalinský <lalinsky@gmail.com>
Fri, 2 Apr 2010 11:53:28 +0000 (11:53 +0000)
committerLukáš Lalinský <lalinsky@gmail.com>
Fri, 2 Apr 2010 11:53:28 +0000 (11:53 +0000)
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110205 283d02a7-25f6-0310-bc7c-ecb5cbfe19da

taglib/asf/asfattribute.cpp
taglib/asf/asfattribute.h
taglib/asf/asffile.cpp
tests/test_asf.cpp

index a4a4c178c146a4c17af75839bb6867dcc61c4c04..85db872b21129d9dc3446cac0c7fd3eba7be60b4 100644 (file)
@@ -30,6 +30,7 @@
 #ifdef WITH_ASF
 
 #include <taglib.h>
+#include <tdebug.h>
 #include "asfattribute.h"
 #include "asffile.h"
 
@@ -197,6 +198,10 @@ ASF::Attribute::parse(ASF::File &f, int kind)
     name = f.readString(nameLength);
   }
 
+  if(kind != 2 && size > 65535) {
+    debug("ASF::Attribute::parse() -- Value larger than 64kB");
+  }
+
   switch(d->type) {
   case WordType:
     d->shortValue = f.readWORD();
@@ -232,6 +237,27 @@ ASF::Attribute::parse(ASF::File &f, int kind)
   return name;
 }
 
+int
+ASF::Attribute::dataSize() const
+{
+  switch (d->type) {
+  case WordType:
+    return 2;
+  case BoolType:
+    return 4;
+  case DWordType:
+    return 4;
+  case QWordType:
+    return 5;
+  case UnicodeType:
+    return d->stringValue.size() * 2 + 2;
+  case BytesType:
+  case GuidType:
+    return d->byteVectorValue.size();
+  }
+  return 0;
+}
+
 ByteVector
 ASF::Attribute::render(const String &name, int kind) const
 {
index 6c702c5d199a27013b3b43b485f60bdf958bf279..975238949f7a674b0c79d7aa9e29ed893f32f26d 100644 (file)
@@ -165,6 +165,9 @@ namespace TagLib
       String parse(ASF::File &file, int kind = 0);
 #endif
 
+      //! Returns the size of the stored data
+      int dataSize() const;
+
     private:
       friend class File;
 
index e403934b215e870541034f3dabd2ea6f2d3d6b7f..012f39b498a4cd3c11238aa09c09c68e420a6386 100644 (file)
@@ -480,11 +480,12 @@ bool ASF::File::save()
     bool inMetadataObject = false;
     for(unsigned int j = 0; j < attributes.size(); j++) {
       const Attribute &attribute = attributes[j];
-      if(!inExtendedContentDescriptionObject && attribute.language() == 0 && attribute.stream() == 0) {
+      bool largeValue = attribute.dataSize() > 65535;
+      if(!inExtendedContentDescriptionObject && !largeValue && attribute.language() == 0 && attribute.stream() == 0) {
         d->extendedContentDescriptionObject->attributeData.append(attribute.render(name));
         inExtendedContentDescriptionObject = true;
       }
-      else if(!inMetadataObject && attribute.language() == 0 && attribute.stream() != 0) {
+      else if(!inMetadataObject && !largeValue && attribute.language() == 0 && attribute.stream() != 0) {
         d->metadataObject->attributeData.append(attribute.render(name, 1));
         inMetadataObject = true;
       }
index 16fae66372b67c3b3e35fa15f1d5ad501c23b942..5094f0f07cdce789e3e9174c6ca8db4c1977e1b9 100644 (file)
@@ -19,6 +19,7 @@ class TestASF : public CppUnit::TestFixture
   CPPUNIT_TEST(testSaveStream);
   CPPUNIT_TEST(testSaveLanguage);
   CPPUNIT_TEST(testDWordTrackNumber);
+  CPPUNIT_TEST(testSaveLargeValue);
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -122,6 +123,24 @@ public:
     delete f;
   }
 
+  void testSaveLargeValue()
+  {
+    ScopedFileCopy copy("silence-1", ".wma");
+    string newname = copy.fileName();
+
+    ASF::File *f = new ASF::File(newname.c_str());
+    ASF::AttributeList values;
+    ASF::Attribute attr(ByteVector(70000, 'x'));
+    values.append(attr);
+    f->tag()->attributeListMap()["WM/Blob"] = values;
+    f->save();
+    delete f;
+
+    f = new ASF::File(newname.c_str());
+    CPPUNIT_ASSERT_EQUAL(ByteVector(70000, 'x'), f->tag()->attributeListMap()["WM/Blob"][0].toByteVector());
+    delete f;
+  }
+
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestASF);