github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/cybozu/exception.hpp (about) 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 #include <winsock2.h> 46 #include <windows.h> 47 #else 48 #include <string.h> // for strerror_r 49 #endif 50 #include <cybozu/inttype.hpp> 51 #ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE 52 #include <cybozu/stacktrace.hpp> 53 #endif 54 55 namespace cybozu { 56 57 const bool DontThrow = true; 58 59 namespace exception { 60 61 /* get max 16 characters to avoid buffer overrun */ 62 inline std::string makeString(const char *str, size_t size) 63 { 64 return std::string(str, std::min<size_t>(size, 16)); 65 } 66 67 #ifdef _WIN32 68 inline std::string wstr2str(const std::wstring& wstr) 69 { 70 std::string str; 71 for (size_t i = 0; i < wstr.size(); i++) { 72 uint16_t c = wstr[i]; 73 if (c < 0x80) { 74 str += char(c); 75 } else { 76 char buf[16]; 77 CYBOZU_SNPRINTF(buf, sizeof(buf), "\\u%04x", c); 78 str += buf; 79 } 80 } 81 return str; 82 } 83 #endif 84 85 } // cybozu::exception 86 87 /** 88 convert errno to string 89 @param err [in] errno 90 @note for both windows and linux 91 */ 92 inline std::string ConvertErrorNoToString(int err) 93 { 94 char errBuf[256]; 95 std::string ret; 96 #ifdef _WIN32 97 if (strerror_s(errBuf, sizeof(errBuf), err) == 0) { 98 ret = errBuf; 99 } else { 100 ret = "err"; 101 } 102 #elif defined(_GNU_SOURCE) 103 ret = ::strerror_r(err, errBuf, sizeof(errBuf)); 104 #else 105 if (strerror_r(err, errBuf, sizeof(errBuf)) == 0) { 106 ret = errBuf; 107 } else { 108 ret = "err"; 109 } 110 #endif 111 char buf2[64]; 112 CYBOZU_SNPRINTF(buf2, sizeof(buf2), "(%d)", err); 113 ret += buf2; 114 return ret; 115 } 116 117 class Exception : public std::exception { 118 mutable std::string str_; 119 #ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE 120 mutable std::string stackTrace_; 121 #endif 122 public: 123 explicit Exception(const std::string& name = "", bool enableStackTrace = true) 124 : str_(name) 125 { 126 #ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE 127 if (enableStackTrace) stackTrace_ = cybozu::StackTrace().toString(); 128 #else 129 cybozu::disable_warning_unused_variable(enableStackTrace); 130 #endif 131 } 132 ~Exception() CYBOZU_NOEXCEPT {} 133 const char *what() const CYBOZU_NOEXCEPT { return toString().c_str(); } 134 const std::string& toString() const CYBOZU_NOEXCEPT 135 { 136 #ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE 137 try { 138 if (!stackTrace_.empty()) { 139 #ifdef CYBOZU_STACKTRACE_ONELINE 140 str_ += "\n<<<STACKTRACE>>> "; 141 str_ += stackTrace_; 142 #else 143 str_ += "\n<<<STACKTRACE\n"; 144 str_ += stackTrace_; 145 str_ += "\n>>>STACKTRACE"; 146 #endif 147 } 148 } catch (...) { 149 } 150 stackTrace_.clear(); 151 #endif 152 return str_; 153 } 154 Exception& operator<<(const char *s) 155 { 156 str_ += ':'; 157 str_ += s; 158 return *this; 159 } 160 Exception& operator<<(const std::string& s) 161 { 162 return operator<<(s.c_str()); 163 } 164 #ifdef _WIN32 165 Exception& operator<<(const std::wstring& s) 166 { 167 return operator<<(cybozu::exception::wstr2str(s)); 168 } 169 #endif 170 template<class T> 171 Exception& operator<<(const T& x) 172 { 173 std::ostringstream os; 174 os << x; 175 return operator<<(os.str()); 176 } 177 }; 178 179 class ErrorNo { 180 public: 181 #ifdef _WIN32 182 typedef unsigned int NativeErrorNo; 183 #else 184 typedef int NativeErrorNo; 185 #endif 186 explicit ErrorNo(NativeErrorNo err) 187 : err_(err) 188 { 189 } 190 ErrorNo() 191 : err_(getLatestNativeErrorNo()) 192 { 193 } 194 NativeErrorNo getLatestNativeErrorNo() const 195 { 196 #ifdef _WIN32 197 return ::GetLastError(); 198 #else 199 return errno; 200 #endif 201 } 202 /** 203 convert NativeErrNo to string(maybe UTF8) 204 @param err [in] errno 205 @note Linux : same as ConvertErrorNoToString 206 Windows : for Win32 API(use en-us) 207 */ 208 std::string toString() const 209 { 210 #ifdef _WIN32 211 const int msgSize = 256; 212 wchar_t msg[msgSize]; 213 int size = FormatMessageW( 214 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 215 0, 216 err_, 217 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 218 msg, 219 msgSize, 220 NULL 221 ); 222 if (size <= 0) return ""; 223 // remove last "\r\n" 224 if (size > 2 && msg[size - 2] == '\r') { 225 msg[size - 2] = 0; 226 size -= 2; 227 } 228 std::string ret; 229 ret.resize(size); 230 // assume ascii only 231 for (int i = 0; i < size; i++) { 232 ret[i] = (char)msg[i]; 233 } 234 char buf2[64]; 235 CYBOZU_SNPRINTF(buf2, sizeof(buf2), "(%u)", err_); 236 ret += buf2; 237 return ret; 238 #else 239 return ConvertErrorNoToString(err_); 240 #endif 241 } 242 private: 243 NativeErrorNo err_; 244 }; 245 246 inline std::ostream& operator<<(std::ostream& os, const cybozu::ErrorNo& self) 247 { 248 return os << self.toString(); 249 } 250 251 } // cybozu 252 #endif