X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fio%2Ffile.cpp;h=1b4a73884d7b5891a43c461d79901bd7e9d1a147;hp=c9e5d4978c5255e418c12d7794146e2d062f0667;hb=5a32939eb6e576c223e1be5f80226d9e628a2398;hpb=c21ab7e49852585df01b4cc19599e25a918b581b diff --git a/source/io/file.cpp b/source/io/file.cpp index c9e5d49..1b4a738 100644 --- a/source/io/file.cpp +++ b/source/io/file.cpp @@ -1,10 +1,3 @@ -#ifndef WIN32 -#include -#include -#include -#endif -#include -#include #include "file.h" #include "handle_private.h" @@ -17,106 +10,26 @@ File::File(const string &fn, Mode m, CreateMode cm) { if(!(m&M_RDWR)) throw invalid_argument("File::File mode"); - if(cm&~(C_CREATE|C_TRUNCATE)) + 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; -#ifdef WIN32 - int flags = 0; - int create_flags = OPEN_EXISTING; - - if(mode&M_READ) - flags |= GENERIC_READ; - else if(mode&M_WRITE) - { - flags |= GENERIC_WRITE; - - switch(static_cast(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; - } - } - - *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 file_not_found(fn); - else - throw system_error(format("CreateFile(%s)", fn), err); - } -#else - int flags = 0; - switch(mode&M_RDWR) - { - case M_READ: flags |= O_RDONLY; break; - case M_WRITE: flags |= O_WRONLY; break; - case M_RDWR: flags |= O_RDWR; break; - default:; - } - - if(mode&M_WRITE) - { - if(cm&C_CREATE) - flags |= O_CREAT; - if(cm&C_TRUNCATE) - flags |= O_TRUNC; - } - if(mode&M_APPEND) - flags |= O_APPEND; - if(mode&M_NONBLOCK) - flags |= O_NONBLOCK; - - *handle = ::open(fn.c_str(), flags, 0666); - if(!handle) - { - int err = errno; - if(err==ENOENT) - throw file_not_found(fn); - else - throw system_error(format("open(%s)", fn), err); - } -#endif + platform_init(fn, cm); } File::~File() { - close(); -} - -void File::close() -{ - if(!handle) - return; - signal_flush_required.emit(); - -#ifdef WIN32 - CloseHandle(*handle); -#else - ::close(*handle); -#endif - - handle = 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)); -#endif + mode = b?(mode&~M_NONBLOCK):(mode|M_NONBLOCK); + sys_set_blocking(handle, b); } unsigned File::do_write(const char *buf, unsigned size) @@ -126,24 +39,12 @@ unsigned File::do_write(const char *buf, unsigned size) if(size==0) return 0; -#ifdef WIN32 +#ifdef _WIN32 if(mode&M_APPEND) seek(0, S_END); - DWORD ret; - if(WriteFile(*handle, buf, size, &ret, 0)==0) - throw system_error("WriteFile"); -#else - int ret = ::write(*handle, buf, size); - if(ret==-1) - { - if(errno==EAGAIN) - return 0; - else - throw system_error("write"); - } #endif - return ret; + return sys_write(handle, buf, size); } unsigned File::do_read(char *buf, unsigned size) @@ -153,82 +54,92 @@ 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 system_error("ReadFile"); -#else - int ret = ::read(*handle, buf, size); - if(ret==-1) - { - if(errno==EAGAIN) - return 0; - else - throw system_error("read"); - } -#endif - + unsigned ret = sys_read(handle, buf, size); if(ret==0) - { - eof_flag = true; - signal_end_of_file.emit(); - } + set_eof(); return ret; } -void File::sync() +SeekOffset File::seek(SeekOffset off, SeekType type) { -#ifndef WIN32 signal_flush_required.emit(); + off = sys_seek(handle, off, type); + eof_flag = false; - fsync(*handle); -#endif + return off; } -unsigned File::seek(int off, SeekType st) +SeekOffset File::tell() const { - check_access(M_NONE); + return sys_seek(const_cast(handle), 0, S_CUR); +} - signal_flush_required.emit(); +const Handle &File::get_handle(Mode m) +{ + check_access(m); + return handle; +} - 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 - eof_flag = false; +BufferedFile::BufferedFile(const string &fn, Mode m, File::CreateMode cm): + file(fn, m, cm), + buffer(file), + position(0) +{ + mode = m; + file.signal_end_of_file.connect(sigc::mem_fun(this, &BufferedFile::set_eof)); +} +unsigned BufferedFile::do_write(const char *buf, unsigned size) +{ + unsigned ret = buffer.write(buf, size); + position += ret; return ret; } -unsigned File::tell() const +unsigned BufferedFile::do_read(char *buf, unsigned size) { - 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 + unsigned ret = buffer.read(buf, size); + position += ret; + return ret; +} + +unsigned BufferedFile::put(char c) +{ + unsigned ret = buffer.put(c); + position += ret; + return ret; +} + +bool BufferedFile::getline(string &line) +{ + bool ret = buffer.getline(line); + if(ret) + position += line.size(); + return ret; +} +int BufferedFile::get() +{ + int ret = buffer.get(); + if(ret>=0) + ++position; return ret; } -void File::check_access(Mode m) const +SeekOffset BufferedFile::seek(SeekOffset offset, SeekType type) { - if(!handle || (m && !(mode&m))) - throw invalid_access(m); + if(type==S_CUR) + { + offset += position; + type = S_BEG; + } + + signal_flush_required.emit(); + position = file.seek(offset, type); + eof_flag = false; + return position; } } // namespace IO