local_ref<jstring> make_jstring(const char* utf8) { if (!utf8) { return {}; } const auto env = internal::getEnv(); size_t len; size_t modlen = detail::modifiedLength(reinterpret_cast<const uint8_t*>(utf8), &len); jstring result; if (modlen == len) { // The only difference between utf8 and modifiedUTF8 is in encoding 4-byte UTF8 chars // and '\0' that is encoded on 2 bytes. // // Since modifiedUTF8-encoded string can be no shorter than it's UTF8 conterpart we // know that if those two strings are of the same length we don't need to do any // conversion -> no 4-byte chars nor '\0'. result = env->NewStringUTF(utf8); } else { auto modified = std::vector<char>(modlen + 1); // allocate extra byte for \0 detail::utf8ToModifiedUTF8( reinterpret_cast<const uint8_t*>(utf8), len, reinterpret_cast<uint8_t*>(modified.data()), modified.size()); result = env->NewStringUTF(modified.data()); } FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); return adopt_local(result); }
local_ref<JByteBuffer> JByteBuffer::wrapBytes(uint8_t* data, size_t size) { // env->NewDirectByteBuffer requires that size is positive. Android's // dalvik returns an invalid result and Android's art aborts if size == 0. // Workaround this by using a slow path through Java in that case. if (!size) { return createEmpty(); } auto res = adopt_local(static_cast<javaobject>(Environment::current()->NewDirectByteBuffer(data, size))); FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); if (!res) { throw std::runtime_error("Direct byte buffers are unsupported."); } return res; }
local_ref<jclass> findClassLocal(const char* name) { const auto env = internal::getEnv(); auto cls = env->FindClass(name); FACEBOOK_JNI_THROW_EXCEPTION_IF(!cls); return adopt_local(cls); }