]> git.tdb.fi Git - libs/core.git/blob - 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
1 #ifndef WIN32
2 #define _LARGEFILE64_SOURCE
3 #else
4 #include <windows.h>
5 #endif
6 #include <stdexcept>
7 #include <msp/core/systemerror.h>
8 #include "handle.h"
9 #include "handle_private.h"
10 #include "seekable.h"
11
12 using namespace std;
13
14 namespace {
15
16 using namespace Msp::IO;
17
18 int sys_seek_type(SeekType st)
19 {
20 #ifdef WIN32
21         if(st==S_BEG)
22                 return FILE_BEGIN;
23         else if(st==S_CUR)
24                 return FILE_CURRENT;
25         else if(st==S_END)
26                 return FILE_END;
27 #else
28         if(st==S_BEG)
29                 return SEEK_SET;
30         else if(st==S_CUR)
31                 return SEEK_CUR;
32         else if(st==S_END)
33                 return SEEK_END;
34 #endif
35
36         throw invalid_argument("sys_seek_type");
37 }
38
39 } // namespace
40
41
42 namespace Msp {
43 namespace IO {
44
45 SeekOffset sys_seek(Handle &handle, SeekOffset offset, SeekType type)
46 {
47 #ifdef WIN32
48         LONG high = offset>>32;
49         DWORD ret = SetFilePointer(*handle, offset, &high, sys_seek_type(type));
50         if(ret==INVALID_SET_FILE_POINTER)
51         {
52                 DWORD err = GetLastError();
53                 if(err!=NO_ERROR)
54                         throw system_error("SetFilePointer");
55         }
56
57         return (SeekOffset(high)<<32) | ret;
58 #else
59         off64_t ret = lseek64(*handle, offset, sys_seek_type(type));
60         if(ret==(off64_t)-1)
61                 throw system_error("lseek64");
62
63         return ret;
64 #endif
65 }
66
67 } // namespace IO
68 } // namespace Msp