From: Tsuda Kageyu <tsuda.kageyu@gmail.com>
Date: Wed, 27 May 2015 02:24:48 +0000 (+0900)
Subject: Fix inconsistent negative seek behavior between Linux and Windows.
X-Git-Tag: v1.10beta~15^2
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=642baca4ede1c20d71d62940aa656040e99974e3;p=taglib

Fix inconsistent negative seek behavior between Linux and Windows.
---

diff --git a/taglib/toolkit/tfilestream.cpp b/taglib/toolkit/tfilestream.cpp
index 4480c274..65f37d52 100644
--- a/taglib/toolkit/tfilestream.cpp
+++ b/taglib/toolkit/tfilestream.cpp
@@ -365,13 +365,10 @@ void FileStream::seek(long offset, Position p)
 
   SetLastError(NO_ERROR);
   SetFilePointer(d->file, offset, NULL, whence);
-  if(GetLastError() == ERROR_NEGATIVE_SEEK) {
-    SetLastError(NO_ERROR);
-    SetFilePointer(d->file, 0, NULL, FILE_BEGIN);
-  }
-  if(GetLastError() != NO_ERROR) {
+
+  const int lastError = GetLastError();
+  if(lastError != NO_ERROR && lastError != ERROR_NEGATIVE_SEEK)
     debug("FileStream::seek() -- Failed to set the file pointer.");
-  }
 
 #else
 
@@ -442,7 +439,7 @@ long FileStream::length()
   SetLastError(NO_ERROR);
   const DWORD fileSize = GetFileSize(d->file, NULL);
   if(GetLastError() == NO_ERROR) {
-    return static_cast<ulong>(fileSize);
+    return static_cast<long>(fileSize);
   }
   else {
     debug("FileStream::length() -- Failed to get the file size.");
diff --git a/tests/test_file.cpp b/tests/test_file.cpp
index b3751a26..d78d5faf 100644
--- a/tests/test_file.cpp
+++ b/tests/test_file.cpp
@@ -40,6 +40,7 @@ class TestFile : public CppUnit::TestFixture
   CPPUNIT_TEST_SUITE(TestFile);
   CPPUNIT_TEST(testFindInSmallFile);
   CPPUNIT_TEST(testRFindInSmallFile);
+  CPPUNIT_TEST(testSeek);
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -100,6 +101,30 @@ public:
     }
   }
 
+  void testSeek()
+  {
+    ScopedFileCopy copy("empty", ".ogg");
+    std::string name = copy.fileName();
+
+    PlainFile f(name.c_str());
+    CPPUNIT_ASSERT_EQUAL((long)0, f.tell());
+    CPPUNIT_ASSERT_EQUAL((long)4328, f.length());
+
+    f.seek(100, File::Beginning);
+    CPPUNIT_ASSERT_EQUAL((long)100, f.tell());
+    f.seek(100, File::Current);
+    CPPUNIT_ASSERT_EQUAL((long)200, f.tell());
+    f.seek(-300, File::Current);
+    CPPUNIT_ASSERT_EQUAL((long)200, f.tell());
+
+    f.seek(-100, File::End);
+    CPPUNIT_ASSERT_EQUAL((long)4228, f.tell());
+    f.seek(-100, File::Current);
+    CPPUNIT_ASSERT_EQUAL((long)4128, f.tell());
+    f.seek(300, File::Current);
+    CPPUNIT_ASSERT_EQUAL((long)4428, f.tell());
+  }
+
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestFile);