X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fio%2Fseekable.cpp;h=35ab5a05104fef55fbe625a3e55cdff2d1b18590;hp=101676e0ef304a5d56efada803808d3e990b5065;hb=42ff7c629b2aa7411963bdcc2259a06b1d1de6d3;hpb=86e0004bd195bc7f7478cf736871339bddf38127 diff --git a/source/io/seekable.cpp b/source/io/seekable.cpp index 101676e..35ab5a0 100644 --- a/source/io/seekable.cpp +++ b/source/io/seekable.cpp @@ -1,13 +1,21 @@ -#ifdef WIN32 +#ifndef WIN32 +#define _LARGEFILE64_SOURCE +#include +#include +#else #include #endif -#include +#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 +38,46 @@ int sys_seek_type(SeekType st) throw invalid_argument("sys_seek_type"); } +} // namespace + + +namespace Msp { +namespace IO { + +bad_seek::bad_seek(SeekOffset offset, SeekType type): + runtime_error(type==S_BEG ? lexical_cast(offset) : + type==S_CUR ? format("CUR%+d", offset) : + type==S_END ? format("END%+d", offset) : + format("SeekType(%d)", type)) +{ } + + +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) + { + if(errno==EINVAL) + throw bad_seek(offset, type); + else + throw system_error("lseek64"); + } + + return ret; +#endif +} + } // namespace IO } // namespace Msp