#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
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;
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)
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;
-#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)
{
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
namespace Msp {
namespace IO {
+class Handle;
+
+#ifdef MSVC
+typedef __int64 SeekOffset;
+#else
+typedef long long SeekOffset;
+#endif
+
enum SeekType
{
S_BEG,
S_END
};
-int sys_seek_type(SeekType);
-
class Seekable: public Base
{
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