6 #include <msp/strings/format.h>
7 #include <msp/core/systemerror.h>
9 #include "handle_private.h"
16 File::File(const string &fn, Mode m, CreateMode cm)
19 throw invalid_argument("File::File mode");
20 if(cm&~(C_CREATE|C_TRUNCATE))
21 throw invalid_argument("File::File create");
27 int create_flags = OPEN_EXISTING;
30 flags |= GENERIC_READ;
33 flags |= GENERIC_WRITE;
35 switch(static_cast<int>(cm))
37 case C_NONE: create_flags = OPEN_EXISTING; break;
38 case C_CREATE: create_flags = OPEN_ALWAYS; break;
39 case C_TRUNCATE: create_flags = TRUNCATE_EXISTING; break;
40 case C_CREATE+C_TRUNCATE: create_flags = CREATE_ALWAYS; break;
44 *handle = CreateFile(fn.c_str(), flags, 0, 0, create_flags, FILE_ATTRIBUTE_NORMAL, 0);
47 int err = GetLastError();
48 if(err==ERROR_FILE_NOT_FOUND)
49 throw file_not_found(fn);
51 throw system_error(format("CreateFile(%s)", fn), err);
57 case M_READ: flags |= O_RDONLY; break;
58 case M_WRITE: flags |= O_WRONLY; break;
59 case M_RDWR: flags |= O_RDWR; break;
75 *handle = ::open(fn.c_str(), flags, 0666);
80 throw file_not_found(fn);
82 throw system_error(format("open(%s)", fn), err);
97 signal_flush_required.emit();
100 CloseHandle(*handle);
106 signal_closed.emit();
109 void File::set_block(bool b)
111 check_access(M_NONE);
113 mode = (mode&~M_NONBLOCK);
115 mode = (mode|M_NONBLOCK);
117 int flags = fcntl(*handle, F_GETFD);
118 fcntl(*handle, F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK));
122 unsigned File::do_write(const char *buf, unsigned size)
124 check_access(M_WRITE);
133 if(WriteFile(*handle, buf, size, &ret, 0)==0)
134 throw system_error("WriteFile");
136 int ret = ::write(*handle, buf, size);
142 throw system_error("write");
149 unsigned File::do_read(char *buf, unsigned size)
151 check_access(M_READ);
158 if(ReadFile(*handle, buf, size, &ret, 0)==0)
159 throw system_error("ReadFile");
161 int ret = ::read(*handle, buf, size);
167 throw system_error("read");
174 signal_end_of_file.emit();
183 signal_flush_required.emit();
189 unsigned File::seek(int off, SeekType st)
191 check_access(M_NONE);
193 signal_flush_required.emit();
195 int type = sys_seek_type(st);
197 DWORD ret = SetFilePointer(*handle, off, 0, type);
198 if(ret==INVALID_SET_FILE_POINTER)
199 throw system_error("SetFilePointer");
201 off_t ret = lseek(*handle, off, type);
203 throw system_error("lseek");
211 unsigned File::tell() const
213 check_access(M_NONE);
216 DWORD ret = SetFilePointer(*handle, 0, 0, FILE_CURRENT);
217 if(ret==INVALID_SET_FILE_POINTER)
218 throw system_error("SetFilePointer");
220 off_t ret = lseek(*handle, 0, SEEK_CUR);
222 throw system_error("lseek");
228 void File::check_access(Mode m) const
230 if(!handle || (m && !(mode&m)))
231 throw invalid_access(m);