]> git.tdb.fi Git - libs/core.git/blobdiff - source/io/seekable.cpp
Wrap seek in a helper function and make it compatible with 64-bit offsets
[libs/core.git] / source / io / seekable.cpp
index 101676e0ef304a5d56efada803808d3e990b5065..12ff6aa11dc26bc9bc4ffe5af5d5e07150e62443 100644 (file)
@@ -1,13 +1,19 @@
-#ifdef WIN32
+#ifndef WIN32
+#define _LARGEFILE64_SOURCE
+#else
 #include <windows.h>
 #endif
 #include <stdexcept>
+#include <msp/core/systemerror.h>
+#include "handle.h"
+#include "handle_private.h"
 #include "seekable.h"
 
 using namespace std;
 
-namespace Msp {
-namespace IO {
+namespace {
+
+using namespace Msp::IO;
 
 int sys_seek_type(SeekType st)
 {
@@ -30,5 +36,33 @@ int sys_seek_type(SeekType st)
        throw invalid_argument("sys_seek_type");
 }
 
+} // namespace
+
+
+namespace Msp {
+namespace IO {
+
+SeekOffset sys_seek(Handle &handle, SeekOffset offset, SeekType type)
+{
+#ifdef WIN32
+       LONG high = offset>>32;
+       DWORD ret = SetFilePointer(*handle, offset, &high, sys_seek_type(type));
+       if(ret==INVALID_SET_FILE_POINTER)
+       {
+               DWORD err = GetLastError();
+               if(err!=NO_ERROR)
+                       throw system_error("SetFilePointer");
+       }
+
+       return (SeekOffset(high)<<32) | ret;
+#else
+       off64_t ret = lseek64(*handle, offset, sys_seek_type(type));
+       if(ret==(off64_t)-1)
+               throw system_error("lseek64");
+
+       return ret;
+#endif
+}
+
 } // namespace IO
 } // namespace Msp