]> granicus.if.org Git - taglib/commitdiff
fixed mod property names and added unit test for xm
authorMathias Panzenböck <grosser.meister.morti@gmx.net>
Sat, 18 Jun 2011 01:31:49 +0000 (03:31 +0200)
committerMathias Panzenböck <grosser.meister.morti@gmx.net>
Sat, 18 Jun 2011 01:31:49 +0000 (03:31 +0200)
18 files changed:
taglib/it/itfile.cpp
taglib/it/itproperties.cpp
taglib/it/itproperties.h
taglib/mod/modfile.cpp
taglib/mod/modproperties.cpp
taglib/mod/modproperties.h
taglib/s3m/s3mfile.cpp
taglib/s3m/s3mproperties.cpp
taglib/s3m/s3mproperties.h
taglib/xm/xmfile.cpp
taglib/xm/xmproperties.cpp
taglib/xm/xmproperties.h
tests/CMakeLists.txt
tests/data/changed_title.xm [new file with mode: 0644]
tests/data/test.xm [new file with mode: 0644]
tests/test_mod.cpp
tests/test_xm.cpp [new file with mode: 0644]
tests/utils.h

index 31af0ba77bbc73468f9f41b0bedf2d0b85a0c454..e3d880be2fd12baa5b4d075bbafa1bc3f383b521 100644 (file)
@@ -98,7 +98,7 @@ void IT::File::read(bool)
   READ_U16L_AS(instrumentCount);
   READ_U16L_AS(sampleCount);
     
-  d->properties.setSampleLength(length);
+  d->properties.setTableLength(length);
   d->properties.setInstrumentCount(instrumentCount);
   d->properties.setSampleCount(sampleCount);
   READ_U16L(d->properties.setPatternCount);
index 61f9758c23d032c4b1d572bbd3fc104d613c53a0..565184a34106253d42a1b4d0576cca94e9931140 100644 (file)
@@ -28,7 +28,7 @@ class IT::Properties::PropertiesPrivate
 {
 public:
   PropertiesPrivate() :
-    sampleLength(0),
+    tableLength(0),
     stereo(false),
     instrumentCount(0),
     sampleCount(0),
@@ -43,7 +43,7 @@ public:
   {
   }
 
-  ushort sampleLength;
+  ushort tableLength;
   bool   stereo;
   ushort instrumentCount;
   ushort sampleCount;
@@ -88,9 +88,9 @@ int IT::Properties::channels() const
   return d->stereo ? 2 : 1;
 }
 
-ushort IT::Properties::sampleLength() const
+ushort IT::Properties::tableLength() const
 {
-  return d->sampleLength;
+  return d->tableLength;
 }
 
 bool IT::Properties::stereo() const
@@ -148,9 +148,9 @@ uchar IT::Properties::bpmSpeed() const
   return d->bpmSpeed;
 }
 
-void IT::Properties::setSampleLength(ushort sampleLength)
+void IT::Properties::setTableLength(ushort tableLength)
 {
-  d->sampleLength = sampleLength;
+  d->tableLength = tableLength;
 }
 
 void IT::Properties::setStereo(bool stereo)
index eed08d2737be23e86ac268176a8d85f036258041..3a72e05dc4ded050f9e879c38ddef4ea7219e1b9 100644 (file)
@@ -38,7 +38,7 @@ namespace TagLib {
       int sampleRate() const;
       int channels()   const;
 
-      ushort sampleLength()    const;
+      ushort tableLength()    const;
       bool   stereo()          const;
       ushort instrumentCount() const;
       ushort sampleCount()     const;
@@ -52,7 +52,7 @@ namespace TagLib {
       uchar  bpmSpeed()        const;
 
     protected:
-      void setSampleLength(ushort sampleLength);
+      void setTableLength(ushort tableLength);
       void setStereo(bool stereo);
 
       void setInstrumentCount(ushort instrumentCount);
index bab83a69d3513235c937e6cb2acd3a62a10cc22e..28c28675bc8d7778a29e3e0987202925b5bf01e3 100644 (file)
@@ -78,8 +78,6 @@ bool Mod::File::save()
     return false;
   }
   seek(0);
-  // Even though the spec says the title is padded with space
-  // common tracker padd with '\0', so why shouldn't I?
   writeString(d->tag.title(), 20);
   // TODO: write comment as instrument names
   return true;
@@ -148,7 +146,8 @@ void Mod::File::read(bool)
   for(int i = 0; i < instruments; ++ i)
   {
     READ_STRING_AS(instrumentName, 22);
-    READ_U16B_AS(instrumentLength);
+    // value in words, * 2 (<< 1) for bytes:
+    READ_U16B_AS(sampleLength);
 
     READ_BYTE_AS(fineTuneByte);
     int fineTune = fineTuneByte & 0xF;
@@ -157,16 +156,17 @@ void Mod::File::read(bool)
 
     READ_BYTE_AS(volume);
     if(volume > 64) volume = 64;
+    // volume in decibels: 20 * log10(volume / 64)
 
+    // value in words, * 2 (<< 1) for bytes:
     READ_U16B_AS(repeatStart);
-    // (int)repatStart << 1;
+    // value in words, * 2 (<< 1) for bytes:
     READ_U16B_AS(repatLength);
-    // (int)repatLength << 1;
 
     comment.append(instrumentName);
   }
 
-  READ_BYTE(d->properties.setPatternCount);
+  READ_BYTE(d->properties.setTableLength);
 
   d->tag.setComment(comment.toString("\n"));
 }
index a8b5746cb4773e5512abf5228af91a9da7617b7f..65215d16690cedfcee4d4abc855cc79c618c236c 100644 (file)
@@ -30,13 +30,13 @@ public:
   PropertiesPrivate() :
     channels(0),
     instrumentCount(0),
-    patternCount(0)
+    tableLength(0)
   {
   }
   
   int  channels;
   uint instrumentCount;
-  uint patternCount;
+  uint tableLength;
 };
 
 Mod::Properties::Properties(AudioProperties::ReadStyle propertiesStyle) :
@@ -75,9 +75,9 @@ uint Mod::Properties::instrumentCount() const
   return d->instrumentCount;
 }
 
-uint Mod::Properties::patternCount() const
+uint Mod::Properties::tableLength() const
 {
-  return d->patternCount;
+  return d->tableLength;
 }
 
 void Mod::Properties::setChannels(int channels)
@@ -90,7 +90,7 @@ void Mod::Properties::setInstrumentCount(uint instrumentCount)
   d->instrumentCount = instrumentCount;
 }
 
-void Mod::Properties::setPatternCount(uint patternCount)
+void Mod::Properties::setTableLength(uint tableLength)
 {
-  d->patternCount = patternCount;
+  d->tableLength = tableLength;
 }
index 8305557319017a5d29283be6bfadc003bae39b7c..c92fd0228fddaa6e24833024dbb8ba79c10c7687 100644 (file)
@@ -39,13 +39,13 @@ namespace TagLib {
       int channels()   const;
 
       uint instrumentCount() const;
-      uint patternCount()    const;
+      uint tableLength()     const;
 
     protected:
       void setChannels(int channels);
 
       void setInstrumentCount(uint sampleCount);
-      void setPatternCount(uint patternCount);
+      void setTableLength(uint tableLength);
 
     private:
       Properties(const Properties&);
index 45556cc614e038a12c2b34f3de94c9e89c71fccf..2b13d6e361853ec68ec242722c899078ef1129bf 100644 (file)
@@ -101,7 +101,7 @@ void S3M::File::read(bool)
   READ_U16L_AS(length);
   READ_U16L_AS(sampleCount);
 
-  d->properties.setSampleLength(length);
+  d->properties.setTableLength(length);
   d->properties.setSampleCount(sampleCount);
 
   READ_U16L(d->properties.setPatternCount);
index 65763a3dbc876ead951a77534eb655467d54688a..88ed87970d1f626a26003bafca37b6952f4d3d48 100644 (file)
@@ -28,7 +28,7 @@ class S3M::Properties::PropertiesPrivate
 {
 public:
   PropertiesPrivate() :
-    sampleLength(0),
+    tableLength(0),
     channels(0),
     stereo(0),
     sampleCount(0),
@@ -42,7 +42,7 @@ public:
     ultraClick(0),
     usePanningValues(false) {}
   
-  ushort sampleLength;
+  ushort tableLength;
   int    channels;
   bool   stereo;
   ushort sampleCount;
@@ -88,9 +88,9 @@ int S3M::Properties::channels() const
   return d->channels;
 }
 
-ushort S3M::Properties::sampleLength() const
+ushort S3M::Properties::tableLength() const
 {
-  return d->sampleLength;
+  return d->tableLength;
 }
 
 bool S3M::Properties::stereo() const
@@ -148,9 +148,9 @@ bool S3M::Properties::usePanningValues() const
   return d->usePanningValues;
 }
 
-void S3M::Properties::setSampleLength(ushort sampleLength)
+void S3M::Properties::setTableLength(ushort tableLength)
 {
-  d->sampleLength = sampleLength;
+  d->tableLength = tableLength;
 }
 
 void S3M::Properties::setChannels(int channels)
index 5e549ce0add6255aef7412b6cec8999f6b1c89c2..80ab4aa266b7f4c8c2886681d616417a1ee63d60 100644 (file)
@@ -38,7 +38,7 @@ namespace TagLib {
       int sampleRate() const;
       int channels()   const;
 
-      ushort sampleLength() const;
+      ushort tableLength()  const;
       bool   stereo()       const;
       ushort sampleCount()  const;
       ushort patternCount() const;
@@ -52,7 +52,7 @@ namespace TagLib {
       bool   usePanningValues() const;
 
     protected:
-      void setSampleLength(ushort sampleLength);
+      void setTableLength(ushort tableLength);
       void setChannels(int channels);
 
       void setStereo      (bool stereo);
index 57b6be7b535577a4cd16d4d303f18b8c210b9579..5efc2204e01a28903f446e18b250d0102075e994 100644 (file)
@@ -101,7 +101,7 @@ void XM::File::read(bool)
   READ_STRING(d->tag.setTrackerName, 20);
   READ_U16L(d->properties.setVersion);
   READ_U32L_AS(headerSize);
-  READ_U16L(d->properties.setSampleLength);
+  READ_U16L(d->properties.setTableLength);
   READ_U16L(d->properties.setRestartPosition);
   READ_U16L(d->properties.setChannels);
   READ_U16L_AS(patternCount);
index bde9604913710cafa127f8526347b09c3d5d6670..b7466f88e5e80fe010976eeeaa5b4ed23307d072 100644 (file)
@@ -28,7 +28,7 @@ class XM::Properties::PropertiesPrivate
 {
 public:
   PropertiesPrivate() :
-    sampleLength(0),
+    tableLength(0),
     channels(0),
     version(0),
     restartPosition(0),
@@ -40,7 +40,7 @@ public:
   {
   }
   
-  ushort sampleLength;
+  ushort tableLength;
   int    channels;
   ushort version;
   ushort restartPosition;
@@ -82,9 +82,9 @@ int XM::Properties::channels() const
   return d->channels;
 }
 
-ushort XM::Properties::sampleLength() const
+ushort XM::Properties::tableLength() const
 {
-  return d->sampleLength;
+  return d->tableLength;
 }
 
 ushort XM::Properties::version() const
@@ -122,9 +122,9 @@ ushort XM::Properties::bpmSpeed() const
   return d->bpmSpeed;
 }
 
-void XM::Properties::setSampleLength(int sampleLength)
+void XM::Properties::setTableLength(ushort tableLength)
 {
-  d->sampleLength = sampleLength;
+  d->tableLength = tableLength;
 }
 
 void XM::Properties::setChannels(int channels)
index 94be5b40416a655f460e4885e8d23abf94e70199..208e166cdf924acdd5e57d3917fc768a3c0460f5 100644 (file)
@@ -39,7 +39,7 @@ namespace TagLib {
       int sampleRate() const;
       int channels()   const;
 
-      ushort sampleLength()    const;
+      ushort tableLength()     const;
       ushort version()         const;
       ushort restartPosition() const;
       ushort patternCount()    const;
@@ -49,7 +49,7 @@ namespace TagLib {
       ushort bpmSpeed()        const;
 
     protected:
-      void setSampleLength(int sampleLength);
+      void setTableLength(ushort tableLength);
       void setChannels(int channels);
 
       void setVersion(ushort version);
index 295e6c7ba3ee40ee9544534f838020dac4e03054..28f621fae1b44dd2ba83c74eca1e843f4fa14be7 100644 (file)
@@ -52,6 +52,7 @@ SET(test_runner_SRCS
   test_wav.cpp
   test_wavpack.cpp
   test_mod.cpp
+  test_xm.cpp
 )
 IF(WITH_MP4)
    SET(test_runner_SRCS ${test_runner_SRCS}
diff --git a/tests/data/changed_title.xm b/tests/data/changed_title.xm
new file mode 100644 (file)
index 0000000..e4b5f6d
Binary files /dev/null and b/tests/data/changed_title.xm differ
diff --git a/tests/data/test.xm b/tests/data/test.xm
new file mode 100644 (file)
index 0000000..b09d913
Binary files /dev/null and b/tests/data/test.xm differ
index f1de1bcd473724096212a9f3927d794a3e00bf7a..e1b5ba0110c4c2f51a05847e4f289056a61a706c 100644 (file)
@@ -1,9 +1,27 @@
+/***************************************************************************
+    copyright           : (C) 2011 by Mathias Panzenböck
+    email               : grosser.meister.morti@gmx.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *   This library is free software; you can redistribute it and/or modify  *
+ *   it  under the terms of the GNU Lesser General Public License version  *
+ *   2.1 as published by the Free Software Foundation.                     *
+ *                                                                         *
+ *   This library is distributed in the hope that it will be useful, but   *
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
+ *   Lesser General Public License for more details.                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU Lesser General Public      *
+ *   License along with this library; if not, write to the Free Software   *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,            *
+ *   MA  02110-1301  USA                                                   *
+ ***************************************************************************/
+
 #include <cppunit/extensions/HelperMacros.h>
 #include <string>
-#include <stdio.h>
-#include <string.h>
 #include <modfile.h>
-#include <stdlib.h>
 #include "utils.h"
 
 using namespace std;
@@ -11,116 +29,67 @@ using namespace TagLib;
 
 class TestMod : public CppUnit::TestFixture
 {
-       CPPUNIT_TEST_SUITE(TestMod);
-       CPPUNIT_TEST(testRead);
-       CPPUNIT_TEST(testChangeTitle);
-       CPPUNIT_TEST_SUITE_END();
+  CPPUNIT_TEST_SUITE(TestMod);
+  CPPUNIT_TEST(testRead);
+  CPPUNIT_TEST(testChangeTitle);
+  CPPUNIT_TEST_SUITE_END();
 
 public:
-       void testRead()
-       {
-               testRead(TEST_FILE_PATH_C("test.mod"), "title of song");
-       }
-
-       void testChangeTitle()
-       {
-               ScopedFileCopy copy("test", ".mod");
-               {
-                       Mod::File file(copy.fileName().c_str());
-                       CPPUNIT_ASSERT(file.tag() != 0);
-                       file.tag()->setTitle("changed title");
-                       CPPUNIT_ASSERT(file.save());
-               }
-               {
-                       testRead(copy.fileName().c_str(), "changed title");
-               }
-               {
-                       assertFileEqual(
-                               copy.fileName().c_str(),
-                               TEST_FILE_PATH_C("changed_title.mod"));
-               }
-       }
+  void testRead()
+  {
+    testRead(TEST_FILE_PATH_C("test.mod"), "title of song");
+  }
+
+  void testChangeTitle()
+  {
+    ScopedFileCopy copy("test", ".mod");
+    {
+      Mod::File file(copy.fileName().c_str());
+      CPPUNIT_ASSERT(file.tag() != 0);
+      file.tag()->setTitle("changed title");
+      CPPUNIT_ASSERT(file.save());
+    }
+    testRead(copy.fileName().c_str(), "changed title");
+    CPPUNIT_ASSERT(fileEqual(
+      copy.fileName(),
+      TEST_FILE_PATH_C("changed_title.mod")));
+  }
 
 private:
-       class Closer
-       {
-       public:
-               Closer(FILE *stream) : m_stream(stream)
-               {
-               }
-
-               ~Closer()
-               {
-                       if (m_stream)
-                       {
-                               fclose(m_stream);
-                       }
-               }
-       private:
-               FILE *m_stream;
-       };
-
-       void assertFileEqual(const char *file1, const char *file2)
-       {
-               char buf1[BUFSIZ];
-               char buf2[BUFSIZ];
-
-               FILE *stream1 = fopen(file1, "rb");
-               FILE *stream2 = fopen(file2, "rb");
-
-               Closer closer1(stream1);
-               Closer closer2(stream2);
-
-               CPPUNIT_ASSERT(stream1 != 0);
-               CPPUNIT_ASSERT(stream2 != 0);
-
-               for (;;)
-               {
-                       size_t n1 = fread(buf1, 1, BUFSIZ, stream1);
-                       size_t n2 = fread(buf2, 1, BUFSIZ, stream2);
-
-                       CPPUNIT_ASSERT_EQUAL(n1, n2);
-
-                       if (n1 == 0) break;
-
-                       CPPUNIT_ASSERT(memcmp(buf1, buf2, n1) == 0);
-               }
-       }
-
-       void testRead(FileName fileName, const String &title)
-       {
-               Mod::File file(fileName);
-
-               CPPUNIT_ASSERT(file.isValid());
-
-               Mod::Properties *p = file.audioProperties();
-               Mod::Tag *t = file.tag();
-               
-               CPPUNIT_ASSERT(0 != p);
-               CPPUNIT_ASSERT(0 != t);
-
-               CPPUNIT_ASSERT_EQUAL(0, p->length());
-               CPPUNIT_ASSERT_EQUAL(0, p->bitrate());
-               CPPUNIT_ASSERT_EQUAL(0, p->sampleRate());
-               CPPUNIT_ASSERT_EQUAL(8, p->channels());
-               CPPUNIT_ASSERT_EQUAL(31U, p->instrumentCount());
-               CPPUNIT_ASSERT_EQUAL(1U, p->patternCount());
-               CPPUNIT_ASSERT_EQUAL(title, t->title());
-               CPPUNIT_ASSERT_EQUAL(String::null, t->artist());
-               CPPUNIT_ASSERT_EQUAL(String::null, t->album());
-               CPPUNIT_ASSERT_EQUAL(String(
-                       "Instrument names\n"
-                       "are abused as\n"
-                       "comments in\n"
-                       "module file formats.\n"
-                       "-+-+-+-+-+-+-+-+-+-+-+\n"
-                       "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
-               ), t->comment());
-               CPPUNIT_ASSERT_EQUAL(String::null, t->genre());
-               CPPUNIT_ASSERT_EQUAL(0U, t->year());
-               CPPUNIT_ASSERT_EQUAL(0U, t->track());
-               CPPUNIT_ASSERT_EQUAL(String("StarTrekker"), t->trackerName());
-       }
+  void testRead(FileName fileName, const String &title)
+  {
+    Mod::File file(fileName);
+
+    CPPUNIT_ASSERT(file.isValid());
+
+    Mod::Properties *p = file.audioProperties();
+    Mod::Tag *t = file.tag();
+    
+    CPPUNIT_ASSERT(0 != p);
+    CPPUNIT_ASSERT(0 != t);
+
+    CPPUNIT_ASSERT_EQUAL(0, p->length());
+    CPPUNIT_ASSERT_EQUAL(0, p->bitrate());
+    CPPUNIT_ASSERT_EQUAL(0, p->sampleRate());
+    CPPUNIT_ASSERT_EQUAL(8, p->channels());
+    CPPUNIT_ASSERT_EQUAL(31U, p->instrumentCount());
+    CPPUNIT_ASSERT_EQUAL(1U, p->tableLength());
+    CPPUNIT_ASSERT_EQUAL(title, t->title());
+    CPPUNIT_ASSERT_EQUAL(String::null, t->artist());
+    CPPUNIT_ASSERT_EQUAL(String::null, t->album());
+    CPPUNIT_ASSERT_EQUAL(String(
+      "Instrument names\n"
+      "are abused as\n"
+      "comments in\n"
+      "module file formats.\n"
+      "-+-+-+-+-+-+-+-+-+-+-+\n"
+      "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+    ), t->comment());
+    CPPUNIT_ASSERT_EQUAL(String::null, t->genre());
+    CPPUNIT_ASSERT_EQUAL(0U, t->year());
+    CPPUNIT_ASSERT_EQUAL(0U, t->track());
+    CPPUNIT_ASSERT_EQUAL(String("StarTrekker"), t->trackerName());
+  }
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestMod);
diff --git a/tests/test_xm.cpp b/tests/test_xm.cpp
new file mode 100644 (file)
index 0000000..28d94b3
--- /dev/null
@@ -0,0 +1,110 @@
+/***************************************************************************
+    copyright           : (C) 2011 by Mathias Panzenböck
+    email               : grosser.meister.morti@gmx.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *   This library is free software; you can redistribute it and/or modify  *
+ *   it  under the terms of the GNU Lesser General Public License version  *
+ *   2.1 as published by the Free Software Foundation.                     *
+ *                                                                         *
+ *   This library is distributed in the hope that it will be useful, but   *
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
+ *   Lesser General Public License for more details.                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU Lesser General Public      *
+ *   License along with this library; if not, write to the Free Software   *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,            *
+ *   MA  02110-1301  USA                                                   *
+ ***************************************************************************/
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <string>
+#include <xmfile.h>
+#include "utils.h"
+
+using namespace std;
+using namespace TagLib;
+
+class TestXM : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE(TestXM);
+  CPPUNIT_TEST(testRead);
+  CPPUNIT_TEST(testChangeTitle);
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void testRead()
+  {
+    testRead(TEST_FILE_PATH_C("test.xm"), "title of song");
+  }
+
+  void testChangeTitle()
+  {
+    ScopedFileCopy copy("test", ".xm");
+    {
+      XM::File file(copy.fileName().c_str());
+      CPPUNIT_ASSERT(file.tag() != 0);
+      file.tag()->setTitle("changed title");
+      CPPUNIT_ASSERT(file.save());
+    }
+    testRead(copy.fileName().c_str(), "changed title");
+    CPPUNIT_ASSERT(fileEqual(
+      copy.fileName(),
+      TEST_FILE_PATH_C("changed_title.xm")));
+  }
+
+private:
+  void testRead(FileName fileName, const String &title)
+  {
+    XM::File file(fileName);
+
+    CPPUNIT_ASSERT(file.isValid());
+
+    XM::Properties *p = file.audioProperties();
+    Mod::Tag *t = file.tag();
+    
+    CPPUNIT_ASSERT(0 != p);
+    CPPUNIT_ASSERT(0 != t);
+
+    CPPUNIT_ASSERT_EQUAL(0, p->length());
+    CPPUNIT_ASSERT_EQUAL(0, p->bitrate());
+    CPPUNIT_ASSERT_EQUAL(0, p->sampleRate());
+    CPPUNIT_ASSERT_EQUAL(8, p->channels());
+       CPPUNIT_ASSERT_EQUAL((TagLib::ushort)  1, p->tableLength());
+       CPPUNIT_ASSERT_EQUAL((TagLib::ushort)260, p->version());
+       CPPUNIT_ASSERT_EQUAL((TagLib::ushort)  0, p->restartPosition());
+    CPPUNIT_ASSERT_EQUAL((TagLib::ushort)  1, p->patternCount());
+    CPPUNIT_ASSERT_EQUAL((TagLib::ushort)128, p->instrumentCount());
+    CPPUNIT_ASSERT_EQUAL((TagLib::ushort)  1, p->flags());
+    CPPUNIT_ASSERT_EQUAL((TagLib::ushort)  6, p->tempo());
+    CPPUNIT_ASSERT_EQUAL((TagLib::ushort)125, p->bpmSpeed());
+    CPPUNIT_ASSERT_EQUAL(title, t->title());
+    CPPUNIT_ASSERT_EQUAL(String::null, t->artist());
+    CPPUNIT_ASSERT_EQUAL(String::null, t->album());
+    CPPUNIT_ASSERT_EQUAL(String(
+      "Instrument names\n"
+      "are abused as\n"
+      "comments in\n"
+      "module file formats.\n"
+      "-+-+-+-+-+-+-+-+-+-+-+\n"
+         "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+         "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+         "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+         "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+         "\n\n\n"
+         "Sample\n"
+         "names\n"
+         "are sometimes\n"
+         "also abused as\n"
+         "comments."
+    ), t->comment());
+    CPPUNIT_ASSERT_EQUAL(String::null, t->genre());
+    CPPUNIT_ASSERT_EQUAL(0U, t->year());
+    CPPUNIT_ASSERT_EQUAL(0U, t->track());
+    CPPUNIT_ASSERT_EQUAL(String("MilkyTracker        "), t->trackerName());
+  }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(TestXM);
index 57226efc95807dac8a9dc93b6b6c86ede00f1531..39e15ce93fc96230ba17da9a3130eca02c886152 100644 (file)
@@ -9,7 +9,9 @@
 #include <sys/fcntl.h>
 #endif
 #include <stdio.h>
+#include <string.h>
 #include <string>
+#include <fstream>
 
 using namespace std;
 
@@ -45,6 +47,35 @@ inline void deleteFile(const string &filename)
   remove(filename.c_str());
 }
 
+inline bool fileEqual(const string &filename1, const string &filename2)
+{
+  char buf1[BUFSIZ];
+  char buf2[BUFSIZ];
+
+  ifstream stream1(filename1.c_str(), ios_base::in | ios_base::binary);
+  ifstream stream2(filename2.c_str(), ios_base::in | ios_base::binary);
+
+  if(!stream1 && !stream2) return true;
+  if(!stream1 || !stream2) return false;
+
+  for(;;)
+  {
+    stream1.read(buf1, BUFSIZ);
+    stream2.read(buf2, BUFSIZ);
+
+    streamsize n1 = stream1.gcount();
+    streamsize n2 = stream2.gcount();
+
+    if(n1 != n2) return false;
+
+    if(n1 == 0) break;
+
+    if(memcmp(buf1, buf2, n1) != 0) return false;
+  }
+
+  return stream1.good() == stream2.good();
+}
+
 class ScopedFileCopy
 {
 public: