]> git.tdb.fi Git - libs/core.git/commitdiff
Wrap seek in a helper function and make it compatible with 64-bit offsets
authorMikko Rasa <tdb@tdb.fi>
Sat, 11 Jun 2011 17:16:33 +0000 (20:16 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 12 Jun 2011 14:17:14 +0000 (17:17 +0300)
source/io/file.cpp
source/io/file.h
source/io/memory.cpp
source/io/memory.h
source/io/seekable.cpp
source/io/seekable.h

index 1b207a25971f960ef99fa5f4481a0be23239e38d..0f5652ad9484cf460a2e266f666470c00b67dd02 100644 (file)
@@ -156,43 +156,22 @@ void File::sync()
 #endif
 }
 
-unsigned File::seek(int off, SeekType st)
+SeekOffset File::seek(SeekOffset off, SeekType type)
 {
        check_access(M_NONE);
 
        signal_flush_required.emit();
-
-       int type = sys_seek_type(st);
-#ifdef WIN32
-       DWORD ret = SetFilePointer(*handle, off, 0, type);
-       if(ret==INVALID_SET_FILE_POINTER)
-               throw system_error("SetFilePointer");
-#else
-       off_t ret = lseek(*handle, off, type);
-       if(ret==(off_t)-1)
-               throw system_error("lseek");
-#endif
-
+       off = sys_seek(handle, off, type);
        eof_flag = false;
 
-       return ret;
+       return off;
 }
 
-unsigned File::tell() const
+SeekOffset File::tell() const
 {
        check_access(M_NONE);
 
-#ifdef WIN32
-       DWORD ret = SetFilePointer(*handle, 0, 0, FILE_CURRENT);
-       if(ret==INVALID_SET_FILE_POINTER)
-               throw system_error("SetFilePointer");
-#else
-       off_t ret = lseek(*handle, 0, SEEK_CUR);
-       if(ret==(off_t)-1)
-               throw system_error("lseek");
-#endif
-
-       return ret;
+       return sys_seek(const_cast<Handle &>(handle), 0, S_CUR);
 }
 
 void File::check_access(Mode m) const
index ed0a3f8336ac42ff0237e2cfcb4e95d2f7b97d07..ee83554cff806bc4ba47d0e1383cbcb426b5f153 100644 (file)
@@ -56,8 +56,8 @@ protected:
 public:
        virtual void sync();
 
-       virtual unsigned seek(int, SeekType);
-       virtual unsigned tell() const;
+       virtual SeekOffset seek(SeekOffset, SeekType);
+       virtual SeekOffset tell() const;
 
 private:
        void check_access(Mode) const;
index af6ef3d44ce386ce2bd7d2caaf8b1a8de24a9fa7..4a6296b44a907321a5e04a585e229523ff7caf86 100644 (file)
@@ -88,7 +88,7 @@ int Memory::get()
        return static_cast<unsigned char>(*pos++);
 }
 
-unsigned Memory::seek(int off, SeekType type)
+SeekOffset Memory::seek(SeekOffset off, SeekType type)
 {
        char *new_pos;
        if(type==S_BEG)
index ebd57eda09d1af492d32df338737edac7eb98fc1..ca92a7588a7ab406498b691682e7bfcc7be03d5b 100644 (file)
@@ -28,8 +28,8 @@ public:
        virtual bool getline(std::string &);
        virtual int get();
 
-       virtual unsigned seek(int, SeekType);
-       virtual unsigned tell() const { return pos-begin; }
+       virtual SeekOffset seek(SeekOffset, SeekType);
+       virtual SeekOffset tell() const { return pos-begin; }
 
 private:
        void check_mode(Mode) const;
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
index cabb9dcdfc7ffc50b979163e447443fdd100e3e2..9522311f55b32ae2f75bd2f62f9e233a3f28a6fd 100644 (file)
@@ -6,6 +6,14 @@
 namespace Msp {
 namespace IO {
 
+class Handle;
+
+#ifdef MSVC
+typedef __int64 SeekOffset;
+#else
+typedef long long SeekOffset;
+#endif
+
 enum SeekType
 {
        S_BEG,
@@ -13,8 +21,6 @@ enum SeekType
        S_END
 };
 
-int sys_seek_type(SeekType);
-
 
 class Seekable: public Base
 {
@@ -23,12 +29,15 @@ protected:
 
 public:
        /** Changes the read/write offset.  Returns the new offset. */
-       virtual unsigned seek(int, SeekType) = 0;
+       virtual SeekOffset seek(SeekOffset, SeekType) = 0;
        
        /** Returns the current read/write offset. */
-       virtual unsigned tell() const = 0;
+       virtual SeekOffset tell() const = 0;
 };
 
+
+SeekOffset sys_seek(Handle &, SeekOffset, SeekType);
+
 } // namespace IO
 } // namespace Msp