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