Copy fbjni library from react-native

This commit is contained in:
Emil Sjolander
2016-08-31 16:15:15 +01:00
parent b51e832e4e
commit 57725e849a
66 changed files with 8653 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <jni.h>
#include <fb/Countable.h>
#include <fb/RefPtr.h>
#include <fb/visibility.h>
namespace facebook {
namespace jni {
FBEXPORT const RefPtr<Countable>& countableFromJava(JNIEnv* env, jobject obj);
template <typename T> RefPtr<T> extractRefPtr(JNIEnv* env, jobject obj) {
return static_cast<RefPtr<T>>(countableFromJava(env, obj));
}
template <typename T> RefPtr<T> extractPossiblyNullRefPtr(JNIEnv* env, jobject obj) {
return obj ? extractRefPtr<T>(env, obj) : nullptr;
}
FBEXPORT void setCountableForJava(JNIEnv* env, jobject obj, RefPtr<Countable>&& countable);
void CountableOnLoad(JNIEnv* env);
} }

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <memory>
#include <type_traits>
#include <jni.h>
#include <fb/Environment.h>
namespace facebook { namespace jni {
template<typename T>
class GlobalReference {
static_assert(std::is_convertible<T, jobject>::value,
"GlobalReference<T> instantiated with type that is not "
"convertible to jobject");
public:
explicit GlobalReference(T globalReference) :
reference_(globalReference? Environment::current()->NewGlobalRef(globalReference) : nullptr) {
}
~GlobalReference() {
reset();
}
GlobalReference() :
reference_(nullptr) {
}
// enable move constructor and assignment
GlobalReference(GlobalReference&& rhs) :
reference_(std::move(rhs.reference_)) {
rhs.reference_ = nullptr;
}
GlobalReference& operator=(GlobalReference&& rhs) {
if (this != &rhs) {
reset();
reference_ = std::move(rhs.reference_);
rhs.reference_ = nullptr;
}
return *this;
}
GlobalReference(const GlobalReference<T>& rhs) :
reference_{} {
reset(rhs.get());
}
GlobalReference& operator=(const GlobalReference<T>& rhs) {
if (this == &rhs) {
return *this;
}
reset(rhs.get());
return *this;
}
explicit operator bool() const {
return (reference_ != nullptr);
}
T get() const {
return reinterpret_cast<T>(reference_);
}
void reset(T globalReference = nullptr) {
if (reference_) {
Environment::current()->DeleteGlobalRef(reference_);
}
if (globalReference) {
reference_ = Environment::current()->NewGlobalRef(globalReference);
} else {
reference_ = nullptr;
}
}
private:
jobject reference_;
};
}}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <memory>
#include <type_traits>
#include <jni.h>
#include <fb/Environment.h>
namespace facebook {
namespace jni {
template<class T>
struct LocalReferenceDeleter {
static_assert(std::is_convertible<T, jobject>::value,
"LocalReferenceDeleter<T> instantiated with type that is not convertible to jobject");
void operator()(T localReference) {
if (localReference != nullptr) {
Environment::current()->DeleteLocalRef(localReference);
}
}
};
template<class T>
using LocalReference =
std::unique_ptr<typename std::remove_pointer<T>::type, LocalReferenceDeleter<T>>;
} }

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <string>
#include <jni.h>
#include <fb/visibility.h>
namespace facebook {
namespace jni {
namespace detail {
void utf8ToModifiedUTF8(const uint8_t* bytes, size_t len, uint8_t* modified, size_t modifiedLength);
size_t modifiedLength(const std::string& str);
size_t modifiedLength(const uint8_t* str, size_t* length);
std::string modifiedUTF8ToUTF8(const uint8_t* modified, size_t len) noexcept;
std::string utf16toUTF8(const uint16_t* utf16Bytes, size_t len) noexcept;
}
// JNI represents strings encoded with modified version of UTF-8. The difference between UTF-8 and
// Modified UTF-8 is that the latter support only 1-byte, 2-byte, and 3-byte formats. Supplementary
// character (4 bytes in unicode) needs to be represented in the form of surrogate pairs. To create
// a Modified UTF-8 surrogate pair that Dalvik would understand we take 4-byte unicode character,
// encode it with UTF-16 which gives us two 2 byte chars (surrogate pair) and then we encode each
// pair as UTF-8. This result in 2 x 3 byte characters. To convert modified UTF-8 to standard
// UTF-8, this mus tbe reversed.
//
// The second difference is that Modified UTF-8 is encoding NUL byte in 2-byte format.
//
// In order to avoid complex error handling, only a minimum of validity checking is done to avoid
// crashing. If the input is invalid, the output may be invalid as well.
//
// Relevant links:
// - http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html
// - https://docs.oracle.com/javase/6/docs/api/java/io/DataInput.html#modified-utf-8
class FBEXPORT LocalString {
public:
// Assumes UTF8 encoding and make a required convertion to modified UTF-8 when the string
// contains unicode supplementary characters.
explicit LocalString(const std::string& str);
explicit LocalString(const char* str);
jstring string() const {
return m_string;
}
~LocalString();
private:
jstring m_string;
};
// JString to UTF16 extractor using RAII idiom
class JStringUtf16Extractor {
public:
JStringUtf16Extractor(JNIEnv* env, jstring javaString)
: env_(env)
, javaString_(javaString)
, utf16String_(nullptr) {
if (env_ && javaString_) {
utf16String_ = env_->GetStringCritical(javaString_, nullptr);
}
}
~JStringUtf16Extractor() {
if (utf16String_) {
env_->ReleaseStringCritical(javaString_, utf16String_);
}
}
operator const jchar* () const {
return utf16String_;
}
private:
JNIEnv* env_;
jstring javaString_;
const jchar* utf16String_;
};
// The string from JNI is converted to standard UTF-8 if the string contains supplementary
// characters.
FBEXPORT std::string fromJString(JNIEnv* env, jstring str);
} }

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <jni.h>
#include <initializer_list>
#include <fb/assert.h>
namespace facebook {
namespace jni {
static inline void registerNatives(JNIEnv* env, jclass cls, std::initializer_list<JNINativeMethod> methods) {
auto result = env->RegisterNatives(cls, methods.begin(), methods.size());
FBASSERT(result == 0);
}
static inline void registerNatives(JNIEnv* env, const char* cls, std::initializer_list<JNINativeMethod> list) {
registerNatives(env, env->FindClass(cls), list);
}
} }

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <string>
#include <jni.h>
#include <fb/noncopyable.h>
#include <fb/Countable.h>
#include <fb/visibility.h>
namespace facebook {
namespace jni {
class FBEXPORT WeakReference : public Countable {
public:
typedef RefPtr<WeakReference> Ptr;
WeakReference(jobject strongRef);
~WeakReference();
jweak weakRef() {
return m_weakReference;
}
private:
jweak m_weakReference;
};
// This class is intended to take a weak reference and turn it into a strong
// local reference. Consequently, it should only be allocated on the stack.
class FBEXPORT ResolvedWeakReference : public noncopyable {
public:
ResolvedWeakReference(jobject weakRef);
ResolvedWeakReference(const RefPtr<WeakReference>& weakRef);
~ResolvedWeakReference();
operator jobject () {
return m_strongReference;
}
explicit operator bool () {
return m_strongReference != nullptr;
}
private:
jobject m_strongReference;
};
} }

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <jni.h>
#include <fb/visibility.h>
namespace facebook {
/**
* Instructs the JNI environment to throw an exception.
*
* @param pEnv JNI environment
* @param szClassName class name to throw
* @param szFmt sprintf-style format string
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
FBEXPORT jint throwException(JNIEnv* pEnv, const char* szClassName, const char* szFmt, va_list va_args);
/**
* Instructs the JNI environment to throw a NoClassDefFoundError.
*
* @param pEnv JNI environment
* @param szFmt sprintf-style format string
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
FBEXPORT jint throwNoClassDefError(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw a RuntimeException.
*
* @param pEnv JNI environment
* @param szFmt sprintf-style format string
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
FBEXPORT jint throwRuntimeException(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw a IllegalArgumentException.
*
* @param pEnv JNI environment
* @param szFmt sprintf-style format string
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
FBEXPORT jint throwIllegalArgumentException(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw a IllegalStateException.
*
* @param pEnv JNI environment
* @param szFmt sprintf-style format string
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
FBEXPORT jint throwIllegalStateException(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw an IOException.
*
* @param pEnv JNI environment
* @param szFmt sprintf-style format string
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
FBEXPORT jint throwIOException(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw an AssertionError.
*
* @param pEnv JNI environment
* @param szFmt sprintf-style format string
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
FBEXPORT jint throwAssertionError(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw an OutOfMemoryError.
*
* @param pEnv JNI environment
* @param szFmt sprintf-style format string
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
FBEXPORT jint throwOutOfMemoryError(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Finds the specified class. If it's not found, instructs the JNI environment to throw an
* exception.
*
* @param pEnv JNI environment
* @param szClassName the classname to find in JNI format (e.g. "java/lang/String")
* @return the class or NULL if not found (in which case a pending exception will be queued). This
* returns a global reference (JNIEnv::NewGlobalRef).
*/
FBEXPORT jclass findClassOrThrow(JNIEnv *pEnv, const char* szClassName);
/**
* Finds the specified field of the specified class. If it's not found, instructs the JNI
* environment to throw an exception.
*
* @param pEnv JNI environment
* @param clazz the class to lookup the field in
* @param szFieldName the name of the field to find
* @param szSig the signature of the field
* @return the field or NULL if not found (in which case a pending exception will be queued)
*/
FBEXPORT jfieldID getFieldIdOrThrow(JNIEnv* pEnv, jclass clazz, const char* szFieldName, const char* szSig);
/**
* Finds the specified method of the specified class. If it's not found, instructs the JNI
* environment to throw an exception.
*
* @param pEnv JNI environment
* @param clazz the class to lookup the method in
* @param szMethodName the name of the method to find
* @param szSig the signature of the method
* @return the method or NULL if not found (in which case a pending exception will be queued)
*/
FBEXPORT jmethodID getMethodIdOrThrow(
JNIEnv* pEnv,
jclass clazz,
const char* szMethodName,
const char* szSig);
} // namespace facebook