From 642baca4ede1c20d71d62940aa656040e99974e3 Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Wed, 27 May 2015 11:24:48 +0900 Subject: [PATCH] Fix inconsistent negative seek behavior between Linux and Windows. --- taglib/toolkit/tfilestream.cpp | 11 ++++------- tests/test_file.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) 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(fileSize); + return static_cast(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); -- 2.40.0