6 #include <msp/strings/formatter.h>
15 File::File(const string &fn, Mode m, CreateMode cm)
18 throw InvalidParameterValue("Invalid read/write mode");
19 if(cm&~(C_CREATE|C_TRUNCATE))
20 throw InvalidParameterValue("Invalid create mode");
26 int create_flags = OPEN_EXISTING;
29 flags |= GENERIC_READ;
32 flags |= GENERIC_WRITE;
34 switch(static_cast<int>(cm))
36 case C_NONE: create_flags = OPEN_EXISTING; break;
37 case C_CREATE: create_flags = OPEN_ALWAYS; break;
38 case C_TRUNCATE: create_flags = TRUNCATE_EXISTING; break;
39 case C_CREATE+C_TRUNCATE: create_flags = CREATE_ALWAYS; break;
43 handle = CreateFile(fn.c_str(), flags, 0, 0, create_flags, FILE_ATTRIBUTE_NORMAL, 0);
44 if(handle==INVALID_HANDLE_VALUE)
46 int err = GetLastError();
47 if(err==ERROR_FILE_NOT_FOUND)
48 throw FileNotFound("Can't find file "+fn, fn);
50 throw SystemError(format("Can't open file '%s'", fn), GetLastError());
56 case M_READ: flags |= O_RDONLY; break;
57 case M_WRITE: flags |= O_WRONLY; break;
58 case M_RDWR: flags |= O_RDWR; break;
74 handle = ::open(fn.c_str(), flags, 0666);
79 throw FileNotFound("Can't find file "+fn, fn);
81 throw SystemError(format("Can't open file '%s'", fn), err);
95 if(handle==MSP_IO_INVALID_HANDLE)
100 signal_flush_required.emit();
108 handle = MSP_IO_INVALID_HANDLE;
109 signal_closed.emit();
112 void File::set_block(bool b)
114 check_access(M_NONE);
116 mode = (mode&~M_NONBLOCK);
118 mode = (mode|M_NONBLOCK);
120 int flags = fcntl(handle, F_GETFD);
121 fcntl(handle, F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK));
125 unsigned File::do_write(const char *buf, unsigned size)
127 check_access(M_WRITE);
136 if(WriteFile(handle, buf, size, &ret, 0)==0)
137 throw SystemError("Writing to file failed", GetLastError());
139 int ret = ::write(handle, buf, size);
145 throw SystemError("Writing to file failed", errno);
152 unsigned File::do_read(char *buf, unsigned size)
154 check_access(M_READ);
161 if(ReadFile(handle, buf, size, &ret, 0)==0)
162 throw SystemError("Reading from file failed", GetLastError());
164 int ret = ::read(handle, buf, size);
170 throw SystemError("Reading from file failed", errno);
177 signal_end_of_file.emit();
186 signal_flush_required.emit();
192 int File::seek(int off, SeekType st)
194 check_access(M_NONE);
196 signal_flush_required.emit();
198 int type = sys_seek_type(st);
200 DWORD ret = SetFilePointer(handle, off, 0, type);
201 if(ret==INVALID_SET_FILE_POINTER)
202 throw SystemError("Seek failed", GetLastError());
204 int ret = lseek(handle, off, type);
206 throw SystemError("Seek failed", errno);
214 int File::tell() const
216 check_access(M_NONE);
219 DWORD ret = SetFilePointer(handle, 0, 0, FILE_CURRENT);
220 if(ret==INVALID_SET_FILE_POINTER)
221 throw SystemError("Tell failed", GetLastError());
223 int ret = lseek(handle, 0, SEEK_CUR);
225 throw SystemError("Tell failed", errno);
231 void File::check_access(Mode m) const
233 if(handle==MSP_IO_INVALID_HANDLE)
234 throw InvalidState("File is not open");
235 if(m==M_READ && !(mode&M_READ))
236 throw InvalidState("File is not readable");
237 if(m==M_WRITE && !(mode&M_WRITE))
238 throw InvalidState("File is not writable");