00001 #ifndef IOF_EXCEPTIONS_H
00002 #define IOF_EXCEPTIONS_H
00003
00016 #include <sstream>
00017 #include <stdexcept>
00018
00019 namespace iof
00020 {
00021
00022
00023 namespace iof_private
00024 {
00025
00026
00027
00028
00029
00030
00031
00032 class failure
00033 {
00034 public:
00035 enum err_type
00036 {
00037 IO_FAILURE,
00038 MARKER_NOT_CLOSED
00039 };
00040
00041 failure(const char* problem, err_type type = IO_FAILURE)
00042 : problem(problem), errType(type) {}
00043
00044 const char* const problem;
00045 const err_type errType;
00046
00047 };
00048
00049 }
00050
00051
00056 class except: public std::runtime_error
00057 {
00058 public:
00059 except(const std::string& msg): std::runtime_error(msg) {}
00060 };
00061
00062
00069 class marker_not_closed: public iof::except
00070 {
00071 public:
00072 marker_not_closed(const iof_private::failure& fail, const std::string& fmt,
00073 const std::string& msg): except(msg),
00074 start(fail.problem ? fail.problem - fmt.c_str() : -1), fmt(fmt) {}
00075
00076 const size_t start;
00077 const std::string& fmt;
00078 };
00079
00080
00082 class marker_not_closed_fmt: public marker_not_closed
00083 {
00084 public:
00085 marker_not_closed_fmt(const iof_private::failure& fail, const std::string& fmt)
00086 : marker_not_closed(fail, fmt, "Unclosed format marker") {}
00087 };
00088
00090 class marker_not_closed_skip: public marker_not_closed
00091 {
00092 public:
00093 marker_not_closed_skip(const iof_private::failure& fail, const std::string& fmt)
00094 : marker_not_closed(fail, fmt, "Unclosed skip marker") {}
00095 };
00096
00097
00099 class in_failure: public std::ios::failure
00100 {
00101 public:
00102 in_failure(size_t pos, const std::ios::failure& fail)
00103 : std::ios::failure(msg(pos, fail)), pos(pos) {}
00104
00105 static std::string msg(size_t pos, const std::ios::failure&) {return msg(pos);}
00106
00107 static std::string msg(size_t pos)
00108 {
00109 std::ostringstream msg;
00110 msg << "Pos " << (unsigned int)(pos) << " of fmt string caused input exception";
00111 return msg.str();
00112 }
00113
00114 const size_t pos;
00115
00116 };
00117
00118
00122 class too_many_markers: public iof::except
00123 {
00124 public:
00125 too_many_markers(size_t pos, const char* fmt)
00126 : except(msg(pos, fmt)), pos(pos) {}
00127
00128 static std::string msg(size_t pos, const char* fmt)
00129 {
00130 std::ostringstream msg;
00131 msg << "Too many format markers, starting at pos "
00132 << (unsigned int)(pos) << " of '" << fmt << "'";
00133 return msg.str();
00134 }
00135
00136 const size_t pos;
00137 };
00138
00139
00144 class fmt_no_effect: public iof::except
00145 {
00146 public:
00147 static inline int getPos(const char* next, const char* fmt) {return next ? int(next - fmt): -1;}
00148
00149 fmt_no_effect(const char* next, const char* fmt)
00150 : except(msg(getPos(next, fmt), fmt)), pos(getPos(next, fmt)) {}
00151
00152 static std::string msg(int pos, const char* fmt)
00153 {
00154 std::ostringstream msg;
00155 std::ostringstream posStr;
00156 if (pos >= 0) posStr << "pos " << pos;
00157 else posStr << "end";
00158 msg << "fmt_spec obj used at " << posStr.str() << " of '" << fmt
00159 << "' needs to be persistent to have an effect";
00160 return msg.str();
00161 }
00162
00163 const size_t pos;
00164 };
00165
00166
00167 }
00168
00169 #endif // IOF_EXCEPTIONS_H