// ErrorHandling.cpp //#include #if defined(_WIN32) || defined(_WIN64) #define WIN32_LEAN_AND_MEAN #include #endif #include #include #include #include #include "ErrorHandling.hpp" #define MAX_MESSAGE_LENGTH 1024 namespace CipresJNI { static const char *s_class_names[ ] = { "java/lang/RuntimeException", "java/lang/IllegalArgumentException", "java/lang/OutOfMemoryError" }; // ThrowError void ThrowError(JNIEnv *env, unsigned int name, const char *message) throw() { assert(env); assert(name <= sizeof(s_class_names) / sizeof(char *)); assert(message); jclass exception = env->FindClass(s_class_names[name]); if(exception != NULL) env->ThrowNew(exception, message); } // ThrowSystemError void ThrowSystemError(JNIEnv *env, int code) throw() { assert(env); try { boost::shared_array message; #if defined(_WIN32) || defined(_WIN64) int wide_length; 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, 0)) != 0) { int multi_byte_length = ::WideCharToMultiByte(CP_UTF8, 0, wide_message.get(), wide_length, NULL, 0, NULL, NULL); if(multi_byte_length == 0) return; message.reset(new char[multi_byte_length]); ::WideCharToMultiByte(CP_UTF8, 0, wide_message.get(), wide_length, message.get(), multi_byte_length, NULL, NULL); } else { message.reset(new char[14]); std::memcpy(message.get(), "Unknown error", 14); } #elif defined(linux) || defined(__linux) || (defined(__APPLE__) && defined(__MACH__)) message.reset(new char[MAX_MESSAGE_LENGTH]); ::strerror_r(code, message.get(), MAX_MESSAGE_LENGTH); #endif ThrowError(env, JAVA_CLASS_RUNTIME_EXCEPT, message.get()); } catch(const std::bad_alloc &) { ThrowOutOfMemError(env); } catch(...) { } } } // namespace CipresJNI