X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Ffile.cpp;h=2990d5c1c728a618012b0310f5451d671957e8c7;hp=9b1e433662c63e9fddfa8295fd7719789d471522;hb=b97d4e9f86e90254ab9edef7ee62a910f6333c78;hpb=c0861d1f8e3869f058bc8b152cd35a08e5b03e73 diff --git a/source/file.cpp b/source/file.cpp index 9b1e433..2990d5c 100644 --- a/source/file.cpp +++ b/source/file.cpp @@ -1,16 +1,10 @@ -/* $Id$ - -This file is part of libmspio -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ #ifndef WIN32 #include #include #include #endif #include -#include "error.h" +#include "except.h" #include "file.h" using namespace std; @@ -18,15 +12,6 @@ using namespace std; namespace Msp { namespace IO { -/** -Creates a new file object and opens it. If the -create flag is true and write access is requested and the file does exist, it -is created. Otherwise a missing file is an error. - -@param fn Name of the file to open -@param m Open mode -@param cm Flags controlling creation of a new file -*/ File::File(const string &fn, Mode m, CreateMode cm) { if(!(m&M_RDWR)) @@ -34,56 +19,62 @@ File::File(const string &fn, Mode m, CreateMode cm) if(cm&~(C_CREATE|C_TRUNCATE)) throw InvalidParameterValue("Invalid create mode"); - mode=m; + mode = m; #ifdef WIN32 - int flags=0; - int create_flags=OPEN_EXISTING; + int flags = 0; + int create_flags = OPEN_EXISTING; if(mode&M_READ) - flags|=GENERIC_READ; + flags |= GENERIC_READ; else if(mode&M_WRITE) { - flags|=GENERIC_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; + 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); + handle = CreateFile(fn.c_str(), flags, 0, 0, create_flags, FILE_ATTRIBUTE_NORMAL, 0); if(handle==INVALID_HANDLE_VALUE) - throw SystemError(format("Can't open file '%s'", fn), GetLastError()); + { + int err = GetLastError(); + if(err==ERROR_FILE_NOT_FOUND) + throw FileNotFound("Can't find file "+fn, fn); + else + throw SystemError(format("Can't open file '%s'", fn), GetLastError()); + } #else - int flags=0; + 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; + 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; + flags |= O_CREAT; if(cm&C_TRUNCATE) - flags|=O_TRUNC; + flags |= O_TRUNC; } if(mode&M_APPEND) - flags|=O_APPEND; + flags |= O_APPEND; if(mode&M_NONBLOCK) - flags|=O_NONBLOCK; + flags |= O_NONBLOCK; - handle=::open(fn.c_str(), flags, 0666); + handle = ::open(fn.c_str(), flags, 0666); if(handle==-1) { - int err=errno; + int err = errno; if(err==ENOENT) throw FileNotFound("Can't find file "+fn, fn); else @@ -94,10 +85,11 @@ File::File(const string &fn, Mode m, CreateMode cm) set_events(P_INPUT); } -/** -Closes the file. Any attempt to access the file after this will cause an -exception to be thrown. -*/ +File::~File() +{ + close(); +} + void File::close() { if(handle==MSP_IO_INVALID_HANDLE) @@ -105,7 +97,7 @@ void File::close() set_events(P_NONE); - signal_closing.emit(); + signal_flush_required.emit(); #ifdef WIN32 CloseHandle(handle); @@ -113,98 +105,23 @@ void File::close() ::close(handle); #endif - handle=MSP_IO_INVALID_HANDLE; + handle = MSP_IO_INVALID_HANDLE; signal_closed.emit(); } -/** -Sets the blocking state of the file. If blocking is disabled, all operations -will return immediately, even if they can't be fully completed. -*/ void File::set_block(bool b) { check_access(M_NONE); - mode=(mode&~M_NONBLOCK); + mode = (mode&~M_NONBLOCK); if(b) - mode=(mode|M_NONBLOCK); + mode = (mode|M_NONBLOCK); #ifndef WIN32 - int flags=fcntl(handle, F_GETFD); + int flags = fcntl(handle, F_GETFD); fcntl(handle, F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK)); #endif } -/** -Seeks the file to the given byte offset. - -@param off Offset in bytes -@param st Seek type - -@return The resulting offset -*/ -int File::seek(int off, SeekType st) -{ - check_access(M_NONE); - - 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 - - eof_flag=false; - - return ret; -} - -/** -Returns the current read/write offset of the file. -*/ -int 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; -} - -File::~File() -{ - close(); -} - -void File::check_access(Mode m) const -{ - 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"); -} - -/** -Writes data from a buffer to the file. - -@param buf Buffer to write from. -@param size Length of data to write. - -@return The number of bytes written -*/ unsigned File::do_write(const char *buf, unsigned size) { check_access(M_WRITE); @@ -219,7 +136,7 @@ unsigned File::do_write(const char *buf, unsigned size) if(WriteFile(handle, buf, size, &ret, 0)==0) throw SystemError("Writing to file failed", GetLastError()); #else - int ret=::write(handle, buf, size); + int ret = ::write(handle, buf, size); if(ret==-1) { if(errno==EAGAIN) @@ -232,21 +149,6 @@ unsigned File::do_write(const char *buf, unsigned size) return ret; } -void File::sync() -{ -#ifndef WIN32 - fsync(handle); -#endif -} - -/** -Reads data from the file. - -@param buf Buffer to read data into. -@param size Maximum size of data to read. - -@return The number of bytes read, possibly zero -*/ unsigned File::do_read(char *buf, unsigned size) { check_access(M_READ); @@ -259,7 +161,7 @@ unsigned File::do_read(char *buf, unsigned size) if(ReadFile(handle, buf, size, &ret, 0)==0) throw SystemError("Reading from file failed", GetLastError()); #else - int ret=::read(handle, buf, size); + int ret = ::read(handle, buf, size); if(ret==-1) { if(errno==EAGAIN) @@ -271,12 +173,70 @@ unsigned File::do_read(char *buf, unsigned size) if(ret==0) { - eof_flag=true; + eof_flag = true; signal_end_of_file.emit(); } return ret; } +void File::sync() +{ +#ifndef WIN32 + signal_flush_required.emit(); + + fsync(handle); +#endif +} + +int File::seek(int off, SeekType st) +{ + 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 + + eof_flag = false; + + return ret; +} + +int 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; +} + +void File::check_access(Mode m) const +{ + 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"); +} + } // namespace IO } // namespace Msp