// SystemError.cpp //#include #if defined(_WIN32) || defined(_WIN64) #define WIN32_LEAN_AND_MEAN #include #endif #include #include #include #include "SystemError.hpp" #define MAX_MESSAGE_LENGTH 1024 namespace CipresJNI { // SystemError // constructor SystemError::SystemError(const char *who, const char *message, int code) throw() : std::runtime_error(message), m_error_code(code) { try { #if defined(_WIN32) || defined(_WIN64) int wide_length; boost::shared_array system_message; boost::shared_array wide_message(new wchar_t[MAX_MESSAGE_LENGTH]); if((wide_length = ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), wide_message.get(), MAX_MESSAGE_LENGTH, NULL)) != 0) { int multi_byte_length = ::WideCharToMultiByte(CP_UTF8, 0, wide_message.get(), wide_length, NULL, 0, NULL, NULL); if(multi_byte_length == 0) return; system_message.reset(new char[multi_byte_length]); ::WideCharToMultiByte(CP_UTF8, 0, wide_message.get(), wide_length, system_message.get(), multi_byte_length, NULL, NULL); } else { system_message.reset(new char[14]); std::memcpy(system_message.get(), "Unknown error", 14); } #elif defined(__unix) || defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) boost::shared_array system_message(new char[MAX_MESSAGE_LENGTH]); ::strerror_r(code, system_message.get(), MAX_MESSAGE_LENGTH); #endif if(who != NULL) { m_error_message.append(who); m_error_message.append(": "); if(message != NULL) { m_error_message.append(message); m_error_message.append(": "); } } else if(message != NULL) { m_error_message.append(message); m_error_message.append(": "); } m_error_message.append(system_message.get()); } catch(...) { // we're presumably already handling an error, and it's unlikely that an exception // thrown from within the handler will be caught correctly, so we swallow it and // rely on std::runtime_error to provide a message } } } // namespace CipresJNI