/src/mcl/include/cybozu/exception.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | /** |
3 | | @file |
4 | | @brief definition of abstruct exception class |
5 | | @author MITSUNARI Shigeo(@herumi) |
6 | | */ |
7 | | #ifdef CYBOZU_MINIMUM_EXCEPTION |
8 | | |
9 | | #include <cybozu/inttype.hpp> |
10 | | |
11 | | namespace cybozu { |
12 | | |
13 | | namespace exception { |
14 | | inline const char *makeString(const char *, size_t) |
15 | | { |
16 | | return ""; |
17 | | } |
18 | | |
19 | | } // cybozu::exception |
20 | | |
21 | | class Exception { |
22 | | public: |
23 | | explicit Exception(const char* = 0, bool = true) |
24 | | { |
25 | | } |
26 | | ~Exception() CYBOZU_NOEXCEPT {} |
27 | | const char *what() const CYBOZU_NOEXCEPT { return "cybozu:Exception"; } |
28 | | template<class T> |
29 | | Exception& operator<<(const T&) |
30 | | { |
31 | | return *this; |
32 | | } |
33 | | }; |
34 | | |
35 | | } // cybozu |
36 | | |
37 | | #else |
38 | | |
39 | | #include <string> |
40 | | #include <algorithm> |
41 | | #include <sstream> |
42 | | #include <errno.h> |
43 | | #include <stdio.h> |
44 | | #ifdef _WIN32 |
45 | | #ifndef WIN32_LEAN_AND_MEAN |
46 | | #define WIN32_LEAN_AND_MEAN |
47 | | #endif |
48 | | #include <windows.h> |
49 | | #else |
50 | | #include <string.h> // for strerror_r |
51 | | #endif |
52 | | #include <cybozu/inttype.hpp> |
53 | | #ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE |
54 | | #include <cybozu/stacktrace.hpp> |
55 | | #endif |
56 | | |
57 | | namespace cybozu { |
58 | | |
59 | | const bool DontThrow = true; |
60 | | |
61 | | namespace exception { |
62 | | |
63 | | /* get max 16 characters to avoid buffer overrun */ |
64 | | inline std::string makeString(const char *str, size_t size) |
65 | 0 | { |
66 | 0 | return std::string(str, std::min<size_t>(size, 16)); |
67 | 0 | } |
68 | | |
69 | | #ifdef _WIN32 |
70 | | inline std::string wstr2str(const std::wstring& wstr) |
71 | | { |
72 | | std::string str; |
73 | | for (size_t i = 0; i < wstr.size(); i++) { |
74 | | uint16_t c = wstr[i]; |
75 | | if (c < 0x80) { |
76 | | str += char(c); |
77 | | } else { |
78 | | char buf[16]; |
79 | | CYBOZU_SNPRINTF(buf, sizeof(buf), "\\u%04x", c); |
80 | | str += buf; |
81 | | } |
82 | | } |
83 | | return str; |
84 | | } |
85 | | #endif |
86 | | |
87 | | } // cybozu::exception |
88 | | |
89 | | /** |
90 | | convert errno to string |
91 | | @param err [in] errno |
92 | | @note for both windows and linux |
93 | | */ |
94 | | inline std::string ConvertErrorNoToString(int err) |
95 | 0 | { |
96 | 0 | char errBuf[256]; |
97 | 0 | std::string ret; |
98 | 0 | #ifdef _WIN32 |
99 | 0 | if (strerror_s(errBuf, sizeof(errBuf), err) == 0) { |
100 | 0 | ret = errBuf; |
101 | 0 | } else { |
102 | 0 | ret = "err"; |
103 | 0 | } |
104 | 0 | #elif defined(_GNU_SOURCE) |
105 | 0 | ret = ::strerror_r(err, errBuf, sizeof(errBuf)); |
106 | 0 | #else |
107 | 0 | if (strerror_r(err, errBuf, sizeof(errBuf)) == 0) { |
108 | 0 | ret = errBuf; |
109 | 0 | } else { |
110 | 0 | ret = "err"; |
111 | 0 | } |
112 | 0 | #endif |
113 | 0 | char buf2[64]; |
114 | 0 | CYBOZU_SNPRINTF(buf2, sizeof(buf2), "(%d)", err); |
115 | 0 | ret += buf2; |
116 | 0 | return ret; |
117 | 0 | } |
118 | | |
119 | | class Exception : public std::exception { |
120 | | mutable std::string str_; |
121 | | #ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE |
122 | | mutable std::string stackTrace_; |
123 | | #endif |
124 | | public: |
125 | | explicit Exception(const std::string& name = "", bool enableStackTrace = true) |
126 | | : str_(name) |
127 | 19.5k | { |
128 | | #ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE |
129 | | if (enableStackTrace) stackTrace_ = cybozu::StackTrace().toString(); |
130 | | #else |
131 | 19.5k | cybozu::disable_warning_unused_variable(enableStackTrace); |
132 | 19.5k | #endif |
133 | 19.5k | } |
134 | 57.5k | ~Exception() CYBOZU_NOEXCEPT {} |
135 | 0 | const char *what() const CYBOZU_NOEXCEPT { return toString().c_str(); } |
136 | | const std::string& toString() const CYBOZU_NOEXCEPT |
137 | 0 | { |
138 | | #ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE |
139 | | try { |
140 | | if (!stackTrace_.empty()) { |
141 | | #ifdef CYBOZU_STACKTRACE_ONELINE |
142 | | str_ += "\n<<<STACKTRACE>>> "; |
143 | | str_ += stackTrace_; |
144 | | #else |
145 | | str_ += "\n<<<STACKTRACE\n"; |
146 | | str_ += stackTrace_; |
147 | | str_ += "\n>>>STACKTRACE"; |
148 | | #endif |
149 | | } |
150 | | } catch (...) { |
151 | | } |
152 | | stackTrace_.clear(); |
153 | | #endif |
154 | 0 | return str_; |
155 | 0 | } |
156 | | Exception& operator<<(const char *s) |
157 | 35.2k | { |
158 | 35.2k | str_ += ':'; |
159 | 35.2k | str_ += s; |
160 | 35.2k | return *this; |
161 | 35.2k | } |
162 | | Exception& operator<<(const std::string& s) |
163 | 35.2k | { |
164 | 35.2k | return operator<<(s.c_str()); |
165 | 35.2k | } |
166 | | #ifdef _WIN32 |
167 | | Exception& operator<<(const std::wstring& s) |
168 | | { |
169 | | return operator<<(cybozu::exception::wstr2str(s)); |
170 | | } |
171 | | #endif |
172 | | template<class T> |
173 | | Exception& operator<<(const T& x) |
174 | 35.2k | { |
175 | 35.2k | std::ostringstream os; |
176 | 35.2k | os << x; |
177 | 35.2k | return operator<<(os.str()); |
178 | 35.2k | } cybozu::Exception& cybozu::Exception::operator<< <mcl::FpT<mcl::bn::local::FpTag, 384ul> >(mcl::FpT<mcl::bn::local::FpTag, 384ul> const&) Line | Count | Source | 174 | 13.9k | { | 175 | 13.9k | std::ostringstream os; | 176 | 13.9k | os << x; | 177 | 13.9k | return operator<<(os.str()); | 178 | 13.9k | } |
cybozu::Exception& cybozu::Exception::operator<< <int>(int const&) Line | Count | Source | 174 | 3.86k | { | 175 | 3.86k | std::ostringstream os; | 176 | 3.86k | os << x; | 177 | 3.86k | return operator<<(os.str()); | 178 | 3.86k | } |
cybozu::Exception& cybozu::Exception::operator<< <mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > >(mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&) Line | Count | Source | 174 | 17.4k | { | 175 | 17.4k | std::ostringstream os; | 176 | 17.4k | os << x; | 177 | 17.4k | return operator<<(os.str()); | 178 | 17.4k | } |
Unexecuted instantiation: cybozu::Exception& cybozu::Exception::operator<< <unsigned long>(unsigned long const&) |
179 | | }; |
180 | | |
181 | | class ErrorNo { |
182 | | public: |
183 | | #ifdef _WIN32 |
184 | | typedef unsigned int NativeErrorNo; |
185 | | #else |
186 | | typedef int NativeErrorNo; |
187 | | #endif |
188 | | explicit ErrorNo(NativeErrorNo err) |
189 | | : err_(err) |
190 | 0 | { |
191 | 0 | } |
192 | | ErrorNo() |
193 | | : err_(getLatestNativeErrorNo()) |
194 | 0 | { |
195 | 0 | } |
196 | | NativeErrorNo getLatestNativeErrorNo() const |
197 | 0 | { |
198 | 0 | #ifdef _WIN32 |
199 | 0 | return ::GetLastError(); |
200 | 0 | #else |
201 | 0 | return errno; |
202 | 0 | #endif |
203 | 0 | } |
204 | | /** |
205 | | convert NativeErrNo to string(maybe UTF8) |
206 | | @note Linux : same as ConvertErrorNoToString |
207 | | Windows : for Win32 API(use en-us) |
208 | | */ |
209 | | std::string toString() const |
210 | 0 | { |
211 | 0 | #ifdef _WIN32 |
212 | 0 | const int msgSize = 256; |
213 | 0 | wchar_t msg[msgSize]; |
214 | 0 | int size = FormatMessageW( |
215 | 0 | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, |
216 | 0 | 0, |
217 | 0 | err_, |
218 | 0 | MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), |
219 | 0 | msg, |
220 | 0 | msgSize, |
221 | 0 | NULL |
222 | 0 | ); |
223 | 0 | if (size <= 0) return ""; |
224 | 0 | // remove last "\r\n" |
225 | 0 | if (size > 2 && msg[size - 2] == '\r') { |
226 | 0 | msg[size - 2] = 0; |
227 | 0 | size -= 2; |
228 | 0 | } |
229 | 0 | std::string ret; |
230 | 0 | ret.resize(size); |
231 | 0 | // assume ascii only |
232 | 0 | for (int i = 0; i < size; i++) { |
233 | 0 | ret[i] = (char)msg[i]; |
234 | 0 | } |
235 | 0 | char buf2[64]; |
236 | 0 | CYBOZU_SNPRINTF(buf2, sizeof(buf2), "(%u)", err_); |
237 | 0 | ret += buf2; |
238 | 0 | return ret; |
239 | 0 | #else |
240 | 0 | return ConvertErrorNoToString(err_); |
241 | 0 | #endif |
242 | 0 | } |
243 | | private: |
244 | | NativeErrorNo err_; |
245 | | }; |
246 | | |
247 | | inline std::ostream& operator<<(std::ostream& os, const cybozu::ErrorNo& self) |
248 | 0 | { |
249 | 0 | return os << self.toString(); |
250 | 0 | } |
251 | | |
252 | | } // cybozu |
253 | | #endif |