X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fio%2Ffile.cpp;h=d4b2da3454f0a29e3ba32808256780ba6aa8954d;hp=2990d5c1c728a618012b0310f5451d671957e8c7;hb=8642ac1b4478419630911a51a53fe8ef5fb46647;hpb=6e0fd758970bcb5bad5e3f2454b694cc4d7b4b66 diff --git a/source/io/file.cpp b/source/io/file.cpp index 2990d5c..d4b2da3 100644 --- a/source/io/file.cpp +++ b/source/io/file.cpp @@ -3,9 +3,10 @@ #include #include #endif -#include -#include "except.h" +#include +#include #include "file.h" +#include "handle_private.h" using namespace std; @@ -15,9 +16,11 @@ namespace IO { File::File(const string &fn, Mode m, CreateMode cm) { if(!(m&M_RDWR)) - throw InvalidParameterValue("Invalid read/write mode"); - if(cm&~(C_CREATE|C_TRUNCATE)) - throw InvalidParameterValue("Invalid create mode"); + throw invalid_argument("File::File mode"); + if(cm&~(C_CREATE|C_TRUNCATE|C_EXCLUSIVE)) + throw invalid_argument("File::File create"); + if((cm&C_EXCLUSIVE) && (!(cm&C_CREATE) || (cm&C_TRUNCATE))) + throw invalid_argument("File::File create"); mode = m; @@ -36,18 +39,21 @@ File::File(const string &fn, Mode m, CreateMode cm) case C_NONE: create_flags = OPEN_EXISTING; break; case C_CREATE: create_flags = OPEN_ALWAYS; break; case C_TRUNCATE: create_flags = TRUNCATE_EXISTING; break; - case C_CREATE+C_TRUNCATE: create_flags = CREATE_ALWAYS; break; + case C_OVERWRITE: create_flags = CREATE_ALWAYS; break; + case C_NEW: create_flags = CREATE_NEW; break; } } - handle = CreateFile(fn.c_str(), flags, 0, 0, create_flags, FILE_ATTRIBUTE_NORMAL, 0); - if(handle==INVALID_HANDLE_VALUE) + *handle = CreateFile(fn.c_str(), flags, 0, 0, create_flags, FILE_ATTRIBUTE_NORMAL, 0); + if(!handle) { int err = GetLastError(); if(err==ERROR_FILE_NOT_FOUND) - throw FileNotFound("Can't find file "+fn, fn); + throw file_not_found(fn); + else if(err==ERROR_FILE_EXISTS) + throw file_already_exists(fn); else - throw SystemError(format("Can't open file '%s'", fn), GetLastError()); + throw system_error(format("CreateFile(%s)", fn), err); } #else int flags = 0; @@ -65,60 +71,42 @@ File::File(const string &fn, Mode m, CreateMode cm) flags |= O_CREAT; if(cm&C_TRUNCATE) flags |= O_TRUNC; + if(cm&C_EXCLUSIVE) + flags |= O_EXCL; } if(mode&M_APPEND) flags |= O_APPEND; if(mode&M_NONBLOCK) flags |= O_NONBLOCK; - handle = ::open(fn.c_str(), flags, 0666); - if(handle==-1) + *handle = ::open(fn.c_str(), flags, 0666); + if(!handle) { int err = errno; if(err==ENOENT) - throw FileNotFound("Can't find file "+fn, fn); + throw file_not_found(fn); + else if(err==EEXIST) + throw file_already_exists(fn); else - throw SystemError(format("Can't open file '%s'", fn), err); + throw system_error(format("open(%s)", fn), err); } #endif - - set_events(P_INPUT); } File::~File() { - close(); -} - -void File::close() -{ - if(handle==MSP_IO_INVALID_HANDLE) - return; - - set_events(P_NONE); - signal_flush_required.emit(); - -#ifdef WIN32 - CloseHandle(handle); -#else - ::close(handle); -#endif - - handle = MSP_IO_INVALID_HANDLE; - signal_closed.emit(); + sys_close(handle); } void File::set_block(bool b) { - check_access(M_NONE); - mode = (mode&~M_NONBLOCK); if(b) mode = (mode|M_NONBLOCK); #ifndef WIN32 - int flags = fcntl(handle, F_GETFD); - fcntl(handle, F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK)); + int flags = fcntl(*handle, F_GETFD); + fcntl(*handle, F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK)); #endif } @@ -132,21 +120,9 @@ unsigned File::do_write(const char *buf, unsigned size) #ifdef WIN32 if(mode&M_APPEND) seek(0, S_END); - DWORD ret; - if(WriteFile(handle, buf, size, &ret, 0)==0) - throw SystemError("Writing to file failed", GetLastError()); -#else - int ret = ::write(handle, buf, size); - if(ret==-1) - { - if(errno==EAGAIN) - return 0; - else - throw SystemError("Writing to file failed", errno); - } #endif - return ret; + return sys_write(handle, buf, size); } unsigned File::do_read(char *buf, unsigned size) @@ -156,26 +132,9 @@ unsigned File::do_read(char *buf, unsigned size) if(size==0) return 0; -#ifdef WIN32 - DWORD ret; - if(ReadFile(handle, buf, size, &ret, 0)==0) - throw SystemError("Reading from file failed", GetLastError()); -#else - int ret = ::read(handle, buf, size); - if(ret==-1) - { - if(errno==EAGAIN) - return 0; - else - throw SystemError("Reading from file failed", errno); - } -#endif - + unsigned ret = sys_read(handle, buf, size); if(ret==0) - { - eof_flag = true; - signal_end_of_file.emit(); - } + set_eof(); return ret; } @@ -185,57 +144,28 @@ void File::sync() #ifndef WIN32 signal_flush_required.emit(); - fsync(handle); + fsync(*handle); #endif } -int 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 SystemError("Seek failed", GetLastError()); -#else - int ret = lseek(handle, off, type); - if(ret==-1) - throw SystemError("Seek failed", errno); -#endif - + off = sys_seek(handle, off, type); eof_flag = false; - return ret; + return off; } -int 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 SystemError("Tell failed", GetLastError()); -#else - int ret = lseek(handle, 0, SEEK_CUR); - if(ret==-1) - throw SystemError("Tell failed", errno); -#endif - - return ret; + return sys_seek(const_cast(handle), 0, S_CUR); } -void File::check_access(Mode m) const +const Handle &File::get_handle(Mode m) { - if(handle==MSP_IO_INVALID_HANDLE) - throw InvalidState("File is not open"); - if(m==M_READ && !(mode&M_READ)) - throw InvalidState("File is not readable"); - if(m==M_WRITE && !(mode&M_WRITE)) - throw InvalidState("File is not writable"); + check_access(m); + return handle; } } // namespace IO