From: Mikko Rasa Date: Sat, 11 Jun 2011 17:16:33 +0000 (+0300) Subject: Wrap seek in a helper function and make it compatible with 64-bit offsets X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=a56e05106571f28dc3044296849ccd5127d7d859;p=libs%2Fcore.git Wrap seek in a helper function and make it compatible with 64-bit offsets --- diff --git a/source/io/file.cpp b/source/io/file.cpp index 1b207a2..0f5652a 100644 --- a/source/io/file.cpp +++ b/source/io/file.cpp @@ -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), 0, S_CUR); } void File::check_access(Mode m) const diff --git a/source/io/file.h b/source/io/file.h index ed0a3f8..ee83554 100644 --- a/source/io/file.h +++ b/source/io/file.h @@ -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; diff --git a/source/io/memory.cpp b/source/io/memory.cpp index af6ef3d..4a6296b 100644 --- a/source/io/memory.cpp +++ b/source/io/memory.cpp @@ -88,7 +88,7 @@ int Memory::get() return static_cast(*pos++); } -unsigned Memory::seek(int off, SeekType type) +SeekOffset Memory::seek(SeekOffset off, SeekType type) { char *new_pos; if(type==S_BEG) diff --git a/source/io/memory.h b/source/io/memory.h index ebd57ed..ca92a75 100644 --- a/source/io/memory.h +++ b/source/io/memory.h @@ -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; diff --git a/source/io/seekable.cpp b/source/io/seekable.cpp index 101676e..12ff6aa 100644 --- a/source/io/seekable.cpp +++ b/source/io/seekable.cpp @@ -1,13 +1,19 @@ -#ifdef WIN32 +#ifndef WIN32 +#define _LARGEFILE64_SOURCE +#else #include #endif #include +#include +#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 diff --git a/source/io/seekable.h b/source/io/seekable.h index cabb9dc..9522311 100644 --- a/source/io/seekable.h +++ b/source/io/seekable.h @@ -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