From 8f2711fba7a2817840038630d9cf9a2060ecbe8e Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 10 Jun 2011 23:47:05 +0300 Subject: [PATCH] Rework exceptions for IO --- source/io/buffered.cpp | 6 +++--- source/io/console.cpp | 26 ++++++++++++++------------ source/io/except.h | 22 ---------------------- source/io/file.cpp | 38 +++++++++++++++++--------------------- source/io/file.h | 8 ++++++++ source/io/memory.cpp | 16 +++++----------- source/io/mode.cpp | 13 +++++++++++++ source/io/mode.h | 9 +++++++++ source/io/pipe.cpp | 17 +++++++++-------- source/io/poll.cpp | 21 ++++++++++++--------- source/io/seek.cpp | 6 ++++-- source/io/serial.cpp | 40 ++++++++++++++++++++-------------------- 12 files changed, 114 insertions(+), 108 deletions(-) delete mode 100644 source/io/except.h create mode 100644 source/io/mode.cpp diff --git a/source/io/buffered.cpp b/source/io/buffered.cpp index f53d2fc..f725223 100644 --- a/source/io/buffered.cpp +++ b/source/io/buffered.cpp @@ -1,6 +1,6 @@ #include +#include #include "buffered.h" -#include "except.h" using namespace std; @@ -43,7 +43,7 @@ void Buffered::flush() begin=end = buf; if(len #include #endif -#include +#include #include "console.h" +using namespace std; + namespace { #ifndef WIN32 @@ -21,7 +23,7 @@ namespace IO { Console::Console(unsigned n) { if(n>2) - throw InvalidParameterValue("Invalid parameter for Console::Console"); + throw invalid_argument("Console::Console"); mode = (n==0 ? M_READ : M_WRITE); @@ -66,7 +68,7 @@ void Console::set_block(bool b) void Console::set_local_echo(bool e) { if(!(mode&M_READ)) - throw InvalidState("Local echo can only be set on input console"); + throw invalid_access(M_READ); #ifdef WIN32 DWORD m; @@ -83,7 +85,7 @@ void Console::set_local_echo(bool e) void Console::set_line_buffer(bool l) { if(!(mode&M_READ)) - throw InvalidState("Line buffering can only be set on input console"); + throw invalid_access(M_READ); #ifdef WIN32 DWORD m; @@ -101,7 +103,7 @@ void Console::set_line_buffer(bool l) void Console::get_size(unsigned &rows, unsigned &cols) { if(!(mode&M_WRITE)) - throw InvalidState("Size can only be queried from an output console"); + throw invalid_access(M_WRITE); #ifdef WIN32 // XXX Figure out how to do this @@ -118,16 +120,16 @@ void Console::get_size(unsigned &rows, unsigned &cols) unsigned Console::do_write(const char *buf, unsigned len) { if(!(mode&M_WRITE)) - throw InvalidState("Console is not writable"); + throw invalid_access(M_WRITE); #ifdef WIN32 DWORD ret; if(!WriteFile(handle, buf, len, &ret, 0)) - throw SystemError("Writing to console failed", GetLastError()); + throw system_error("WriteFile"); #else int ret = ::write(handle, buf, len); if(ret==-1) - throw SystemError("Writing to console failed", errno); + throw system_error("write"); #endif return ret; @@ -136,12 +138,12 @@ unsigned Console::do_write(const char *buf, unsigned len) unsigned Console::do_read(char *buf, unsigned len) { if(!(mode&M_READ)) - throw InvalidState("Console is not readable"); + throw invalid_access(M_READ); #ifdef WIN32 DWORD ret; if(!ReadFile(handle, buf, len, &ret, 0)) - throw SystemError("Reading from console failed", GetLastError()); + throw system_error("ReadFile"); #else int ret = ::read(handle, buf, len); if(ret==-1) @@ -149,7 +151,7 @@ unsigned Console::do_read(char *buf, unsigned len) if(errno==EAGAIN) return 0; else - throw SystemError("Reading from console failed", errno); + throw system_error("read"); } else if(ret==0) eof_flag = true; @@ -176,7 +178,7 @@ Console &Console::instance(unsigned n) case 2: return err; } - throw InvalidParameterValue("Unknown Console instance requested"); + throw invalid_argument("Console::instance"); } Console &cin = Console::instance(0); diff --git a/source/io/except.h b/source/io/except.h deleted file mode 100644 index 5770f64..0000000 --- a/source/io/except.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef MSP_IO_EXCEPT_H_ -#define MSP_IO_EXCEPT_H_ - -#include - -namespace Msp { -namespace IO { - -class FileNotFound: public Exception -{ -public: - FileNotFound(const std::string &w_, const std::string &f): Exception(w_), filename(f) { } - const std::string &get_filename() { return filename; } - ~FileNotFound() throw() { } -private: - std::string filename; -}; - -} // namespace IO -} // namespace Msp - -#endif diff --git a/source/io/file.cpp b/source/io/file.cpp index 2990d5c..727542f 100644 --- a/source/io/file.cpp +++ b/source/io/file.cpp @@ -3,8 +3,8 @@ #include #include #endif +#include #include -#include "except.h" #include "file.h" using namespace std; @@ -15,9 +15,9 @@ namespace IO { File::File(const string &fn, Mode m, CreateMode cm) { if(!(m&M_RDWR)) - throw InvalidParameterValue("Invalid read/write mode"); + throw invalid_argument("File::File mode"); if(cm&~(C_CREATE|C_TRUNCATE)) - throw InvalidParameterValue("Invalid create mode"); + throw invalid_argument("File::File create"); mode = m; @@ -45,9 +45,9 @@ File::File(const string &fn, Mode m, CreateMode cm) { int err = GetLastError(); if(err==ERROR_FILE_NOT_FOUND) - throw FileNotFound("Can't find file "+fn, fn); + throw file_not_found(fn); else - throw SystemError(format("Can't open file '%s'", fn), GetLastError()); + throw system_error(format("CreateFile(%s)", fn), err); } #else int flags = 0; @@ -76,9 +76,9 @@ File::File(const string &fn, Mode m, CreateMode cm) { int err = errno; if(err==ENOENT) - throw FileNotFound("Can't find file "+fn, fn); + throw file_not_found(fn); else - throw SystemError(format("Can't open file '%s'", fn), err); + throw system_error(format("open(%s)", fn), err); } #endif @@ -134,7 +134,7 @@ unsigned File::do_write(const char *buf, unsigned size) seek(0, S_END); DWORD ret; if(WriteFile(handle, buf, size, &ret, 0)==0) - throw SystemError("Writing to file failed", GetLastError()); + throw system_error("WriteFile"); #else int ret = ::write(handle, buf, size); if(ret==-1) @@ -142,7 +142,7 @@ unsigned File::do_write(const char *buf, unsigned size) if(errno==EAGAIN) return 0; else - throw SystemError("Writing to file failed", errno); + throw system_error("write"); } #endif @@ -159,7 +159,7 @@ unsigned File::do_read(char *buf, unsigned size) #ifdef WIN32 DWORD ret; if(ReadFile(handle, buf, size, &ret, 0)==0) - throw SystemError("Reading from file failed", GetLastError()); + throw system_error("ReadFile"); #else int ret = ::read(handle, buf, size); if(ret==-1) @@ -167,7 +167,7 @@ unsigned File::do_read(char *buf, unsigned size) if(errno==EAGAIN) return 0; else - throw SystemError("Reading from file failed", errno); + throw system_error("read"); } #endif @@ -199,11 +199,11 @@ int File::seek(int off, SeekType st) #ifdef WIN32 DWORD ret = SetFilePointer(handle, off, 0, type); if(ret==INVALID_SET_FILE_POINTER) - throw SystemError("Seek failed", GetLastError()); + throw system_error("SetFilePointer"); #else int ret = lseek(handle, off, type); if(ret==-1) - throw SystemError("Seek failed", errno); + throw system_error("lseek"); #endif eof_flag = false; @@ -218,11 +218,11 @@ int File::tell() const #ifdef WIN32 DWORD ret = SetFilePointer(handle, 0, 0, FILE_CURRENT); if(ret==INVALID_SET_FILE_POINTER) - throw SystemError("Tell failed", GetLastError()); + throw system_error("SetFilePointer"); #else int ret = lseek(handle, 0, SEEK_CUR); if(ret==-1) - throw SystemError("Tell failed", errno); + throw system_error("lseek"); #endif return ret; @@ -230,12 +230,8 @@ int File::tell() const 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"); + if(handle==MSP_IO_INVALID_HANDLE || (m && !(mode&m))) + throw invalid_access(m); } } // namespace IO diff --git a/source/io/file.h b/source/io/file.h index 05aaf95..4711160 100644 --- a/source/io/file.h +++ b/source/io/file.h @@ -1,6 +1,7 @@ #ifndef MSP_IO_FILE_H_ #define MSP_IO_FILE_H_ +#include #include #include "base.h" #include "buffered.h" @@ -10,6 +11,13 @@ namespace Msp { namespace IO { +class file_not_found: public std::runtime_error +{ +public: + file_not_found(const std::string &fn): std::runtime_error(fn) { } +}; + + /** A class for reading and writing files. diff --git a/source/io/memory.cpp b/source/io/memory.cpp index 6ea130b..79956cd 100644 --- a/source/io/memory.cpp +++ b/source/io/memory.cpp @@ -1,6 +1,5 @@ #include #include -#include "except.h" #include "memory.h" using namespace std; @@ -98,10 +97,10 @@ unsigned Memory::seek(int off, SeekType type) else if(type==S_END) new_pos = end+off; else - throw InvalidParameterValue("Invalid seek type"); + throw invalid_argument("Memory::seek"); if(new_posend) - throw InvalidParameterValue("Invalid seek offset"); + throw out_of_range("Memory::seek"); pos = new_pos; return pos-begin; @@ -109,18 +108,13 @@ unsigned Memory::seek(int off, SeekType type) Handle Memory::get_event_handle() { - throw Exception("Memory doesn't support events"); + throw logic_error("Memory doesn't support events"); } void Memory::check_mode(Mode m) const { - if(m==M_WRITE) - { - if(!(mode&M_WRITE)) - throw InvalidState("Memory is not writable"); - if(pos==end) - throw InvalidState("Attempt to write past end of Memory"); - } + if(m==M_WRITE && !(mode&M_WRITE)) + throw invalid_access(M_WRITE); } } // namespace IO diff --git a/source/io/mode.cpp b/source/io/mode.cpp new file mode 100644 index 0000000..71d956b --- /dev/null +++ b/source/io/mode.cpp @@ -0,0 +1,13 @@ +#include "mode.h" + +using namespace std; + +namespace Msp { +namespace IO { + +invalid_access::invalid_access(Mode m): + logic_error(m==M_READ ? "read" : m==M_WRITE ? "write" : "generic") +{ } + +} // namespace IO +} // namespace Msp diff --git a/source/io/mode.h b/source/io/mode.h index 5e103f2..5500dff 100644 --- a/source/io/mode.h +++ b/source/io/mode.h @@ -1,6 +1,8 @@ #ifndef MSP_IO_MODE_H_ #define MSP_IO_MODE_H_ +#include + namespace Msp { namespace IO { @@ -23,6 +25,13 @@ inline Mode operator&(Mode m, Mode n) inline Mode operator~(Mode m) { return Mode(~static_cast(m)); } + +class invalid_access: public std::logic_error +{ +public: + invalid_access(Mode); +}; + } // namespace IO } // namespace Msp diff --git a/source/io/pipe.cpp b/source/io/pipe.cpp index b3735aa..afa0c25 100644 --- a/source/io/pipe.cpp +++ b/source/io/pipe.cpp @@ -2,6 +2,7 @@ #include #include #endif +#include #include #include "pipe.h" @@ -16,14 +17,14 @@ Pipe::Pipe() string name = format("\\\\.\\pipe\\%u.%p", GetCurrentProcessId(), this); handle[0] = CreateNamedPipe(name.c_str(), PIPE_ACCESS_INBOUND|FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 1024, 1024, 0, 0); if(handle[0]==INVALID_HANDLE_VALUE) - throw SystemError("Unable to create pipe", GetLastError()); + throw system_error("CreateNamedPipe"); handle[1] = CreateFile(name.c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if(handle[1]==INVALID_HANDLE_VALUE) { unsigned err = GetLastError(); CloseHandle(handle[0]); - throw SystemError("Unable to create pipe", err); + throw system_error(format("CreateFile(%s)", name), err); } overlapped = 0; @@ -34,7 +35,7 @@ Pipe::Pipe() buf_next = buffer; #else if(pipe(handle)==-1) - throw SystemError("Unable to create pipe", errno); + throw system_error("pipe"); #endif set_events(P_INPUT); @@ -82,7 +83,7 @@ unsigned Pipe::do_write(const char *buf, unsigned size) #ifdef WIN32 DWORD ret; if(!WriteFile(handle[1], buf, size, &ret, 0)) - throw SystemError("Writing to pipe failed", GetLastError()); + throw system_error("WriteFile"); #else int ret = ::write(handle[1], buf, size); if(ret==-1) @@ -90,7 +91,7 @@ unsigned Pipe::do_write(const char *buf, unsigned size) if(errno==EAGAIN) return 0; else - throw SystemError("Writing to pipe failed", errno); + throw system_error("write"); } #endif @@ -110,7 +111,7 @@ unsigned Pipe::do_read(char *buf, unsigned size) { DWORD ret; if(!GetOverlappedResult(handle[0], overlapped, &ret, !buf_avail)) - throw SystemError("Reading from pipe failed", GetLastError()); + throw system_error("GetOverlappedResult"); else { buf_avail += ret; @@ -133,7 +134,7 @@ unsigned Pipe::do_read(char *buf, unsigned size) if(errno==EAGAIN) return 0; else - throw SystemError("Reading from pipe failed", errno); + throw system_error("read"); } #endif @@ -161,7 +162,7 @@ Handle Pipe::get_event_handle() { unsigned err = GetLastError(); if(err!=ERROR_IO_PENDING) - throw SystemError("Failed to start an overlapped read", err); + throw system_error("ReadFile"); } else { diff --git a/source/io/poll.cpp b/source/io/poll.cpp index dce1912..a0ccf84 100644 --- a/source/io/poll.cpp +++ b/source/io/poll.cpp @@ -1,10 +1,13 @@ #include +#include +#include #include #include -#include "except.h" #include "base.h" #include "poll.h" +using namespace std; + namespace { using namespace Msp; @@ -15,7 +18,7 @@ inline int sys_poll_event(PollEvent event) int result = 0; if(event&~(P_INPUT|P_PRIO|P_OUTPUT)) - throw InvalidParameterValue("Invalid poll events"); + throw invalid_argument("sys_poll_event"); #ifndef WIN32 if(event&P_INPUT) @@ -60,7 +63,7 @@ inline PollEvent do_poll(Base &obj, PollEvent pe, int timeout) if(ret==WAIT_OBJECT_0) return pe; else if(ret==WAIT_FAILED) - throw SystemError("Poll failed", GetLastError()); + throw system_error("WaitForSingleObject"); return P_NONE; #else @@ -72,7 +75,7 @@ inline PollEvent do_poll(Base &obj, PollEvent pe, int timeout) if(errno==EINTR) return P_NONE; else - throw SystemError("Poll failed", errno); + throw system_error("poll"); } return poll_event_from_sys(pfd.revents); @@ -108,7 +111,7 @@ void Poller::set_object(Base &obj, PollEvent ev) { #ifdef WIN32 if(objects.size()>=MAXIMUM_WAIT_OBJECTS) - throw InvalidState("Maximum number of wait objects reached"); + throw logic_error("Maximum number of wait objects reached"); #endif objects.insert(SlotMap::value_type(&obj, Slot(&obj, ev))); @@ -124,7 +127,7 @@ int Poller::poll() int Poller::poll(const Time::TimeDelta &timeout) { if(timeout(timeout/Time::msec)); } @@ -168,7 +171,7 @@ int Poller::do_poll(int timeout) return 1; } else if(ret==WAIT_FAILED) - throw SystemError("Poll failed", GetLastError()); + throw system_error("WaitForMultipleObjects"); return 0; #else @@ -178,7 +181,7 @@ int Poller::do_poll(int timeout) if(errno==EINTR) return 0; else - throw SystemError("Poll failed", errno); + throw system_error("poll"); } int n = ret; @@ -203,7 +206,7 @@ PollEvent poll(Base &obj, PollEvent pe) PollEvent poll(Base &obj, PollEvent pe, const Time::TimeDelta &timeout) { if(timeout(timeout/Time::msec)); } diff --git a/source/io/seek.cpp b/source/io/seek.cpp index b10c5a0..c0b65ca 100644 --- a/source/io/seek.cpp +++ b/source/io/seek.cpp @@ -1,9 +1,11 @@ #ifdef WIN32 #include #endif -#include "except.h" +#include #include "seek.h" +using namespace std; + namespace Msp { namespace IO { @@ -25,7 +27,7 @@ int sys_seek_type(SeekType st) return SEEK_END; #endif - throw InvalidParameterValue("Invalid seek type"); + throw invalid_argument("Invalid seek type"); } } // namespace IO diff --git a/source/io/serial.cpp b/source/io/serial.cpp index ec6a198..dbfee95 100644 --- a/source/io/serial.cpp +++ b/source/io/serial.cpp @@ -5,8 +5,8 @@ #include #include #endif +#include #include -#include "except.h" #include "serial.h" using namespace std; @@ -35,10 +35,10 @@ void set_state(Handle handle, DeviceState &state) { #ifdef WIN32 if(SetCommState(handle, &state)==0) - throw SystemError("Cannot set serial port parameters", GetLastError()); + throw system_error("SetCommState"); #else if(tcsetattr(handle, TCSADRAIN, &state)==-1) - throw SystemError("Cannot set serial port parameters", errno); + throw system_error("tcsetattr"); #endif } @@ -69,7 +69,7 @@ void set_baud_rate(DeviceState &state, unsigned baud) case 57600: speed = B57600; break; case 115200: speed = B115200; break; case 230400: speed = B230400; break; - default: throw InvalidParameterValue("Invalid baud rate"); + default: throw invalid_argument("set_baud_rate"); } cfsetospeed(&state, speed); @@ -89,7 +89,7 @@ void set_data_bits(DeviceState &state, unsigned bits) case 6: flag = CS6; break; case 7: flag = CS7; break; case 8: flag = CS8; break; - default: throw InvalidParameterValue("Invalid data bit count"); + default: throw invalid_argument("set_data_bits"); } state.c_cflag = (state.c_cflag&~CSIZE)|flag; @@ -104,7 +104,7 @@ void set_parity(DeviceState &state, Serial::Parity par) case Serial::NONE: state.Parity = NOPARITY; break; case Serial::EVEN: state.Parity = EVENPARITY; break; case Serial::ODD: state.Parity = ODDPARITY; break; - default: throw InvalidParameterValue("Invalid parity"); + default: throw invalid_argument("set_parity"); } #else tcflag_t flag; @@ -113,7 +113,7 @@ void set_parity(DeviceState &state, Serial::Parity par) case Serial::NONE: flag = 0; break; case Serial::EVEN: flag = PARENB; break; case Serial::ODD: flag = PARENB|PARODD; break; - default: throw InvalidParameterValue("Invalid parity"); + default: throw invalid_argument("set_parity"); } state.c_cflag = (state.c_cflag&~(PARENB|PARODD))|flag; @@ -127,7 +127,7 @@ void set_stop_bits(DeviceState &state, unsigned bits) { case 1: state.StopBits = ONESTOPBIT; break; case 2: state.StopBits = TWOSTOPBITS; break; - default: throw InvalidParameterValue("Invalid stop bit count"); + default: throw invalid_argument("set_stop_bits"); } #else tcflag_t flag; @@ -135,7 +135,7 @@ void set_stop_bits(DeviceState &state, unsigned bits) { case 1: flag = 0; break; case 2: flag = CSTOPB; break; - default: throw InvalidParameterValue("Invalid stop bit count"); + default: throw invalid_argument("set_stop_bits"); } state.c_cflag = (state.c_cflag&~CSTOPB)|flag; @@ -158,7 +158,7 @@ Serial::Serial(const string &descr) handle = CreateFile(port.c_str(), GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if(handle==INVALID_HANDLE_VALUE) - throw SystemError(format("Can't open serial port '%s'", port), GetLastError()); + throw system_error(format("CreateFile(%s)", port)); mode = M_READ|M_WRITE; COMMTIMEOUTS timeouts; @@ -174,7 +174,7 @@ Serial::Serial(const string &descr) handle = open(port.c_str(), O_RDWR); if(handle==-1) - throw SystemError(format("Can't open serial port '%s'", port), errno); + throw system_error(format("open(%s)", port)); mode = M_READ|M_WRITE; termios t; @@ -264,13 +264,13 @@ void Serial::set_parameters(const string ¶ms) unsigned i; for(i=0; i'8') - throw InvalidParameterValue("Invalid data bit count"); + throw invalid_argument("Serial::set_parameters data_bits"); if(params[i+2]!='N' && params[i+2]!='E' && params[i+2]!='O') - throw InvalidParameterValue("Invalid parity"); + throw invalid_argument("Serial::set_parameters parity"); if(params[i+3]!='1' && params[i+3]!='2') - throw InvalidParameterValue("Invalid stop bit count"); + throw invalid_argument("Serial::set_parameters stop_bits"); DeviceState state; get_state(handle, state); @@ -289,7 +289,7 @@ unsigned Serial::do_write(const char *buf, unsigned size) #ifdef WIN32 DWORD ret; if(WriteFile(handle, buf, size, &ret, 0)==0) - throw SystemError("Writing to serial port failed", GetLastError()); + throw system_error("WriteFile"); #else int ret = ::write(handle, buf, size); if(ret==-1) @@ -297,7 +297,7 @@ unsigned Serial::do_write(const char *buf, unsigned size) if(errno==EAGAIN) return 0; else - throw SystemError("Writing to serial port failed", errno); + throw system_error("write"); } #endif @@ -312,7 +312,7 @@ unsigned Serial::do_read(char *buf, unsigned size) #ifdef WIN32 DWORD ret; if(ReadFile(handle, buf, size, &ret, 0)==0) - throw SystemError("Reading from serial port failed", GetLastError()); + throw system_error("ReadFile"); #else int ret = ::read(handle, buf, size); if(ret==-1) @@ -320,7 +320,7 @@ unsigned Serial::do_read(char *buf, unsigned size) if(errno==EAGAIN) return 0; else - throw SystemError("Reading from serial port failed", errno); + throw system_error("read"); } #endif @@ -330,7 +330,7 @@ unsigned Serial::do_read(char *buf, unsigned size) Handle Serial::get_event_handle() { #ifdef WIN32 - throw Exception("Serial port events not supported on win32 yet"); + throw logic_error("Serial port events not supported on win32 yet"); #else return handle; #endif -- 2.43.0