2727#include < assert.h>
2828#include < jni.h>
2929
30+ #include < cstring>
31+ #include < string>
32+
33+ extern jclass g_jbyte_buffer_clazz;
34+ extern jmethodID g_jbyte_buffer_array_mid;
35+ extern jmethodID g_jbyte_buffer_allocate_mid;
36+
37+ const std::string &GetByteArrayInternalWithLength (const char *key, size_t key_len);
38+ char *GetByteArrayInternalForWriteWithLength (const char *key, size_t key_len, size_t len);
39+
40+ inline jbyteArray StringToJavaByteArray (JNIEnv *env, const std::string& str) {
41+ const jsize jlen = static_cast <jsize>(str.size ());
42+ jbyteArray jbytes = env->NewByteArray (jlen);
43+ if (jbytes == nullptr ) {
44+ // exception thrown: OutOfMemoryError
45+ return nullptr ;
46+ }
47+
48+ env->SetByteArrayRegion (jbytes, 0 , jlen,
49+ const_cast <jbyte*>(reinterpret_cast <const jbyte*>(str.c_str ())));
50+ if (env->ExceptionCheck ()) {
51+ // exception thrown: ArrayIndexOutOfBoundsException
52+ env->DeleteLocalRef (jbytes);
53+ return nullptr ;
54+ }
55+
56+ return jbytes;
57+ }
58+
59+ inline void SetByteBufferData (JNIEnv* env, const jmethodID jarray_mid, const jobject& jbuf,
60+ const char * content, const size_t content_len) {
61+ jbyteArray jarray = static_cast <jbyteArray>(env->CallObjectMethod (jbuf, jarray_mid));
62+ if (env->ExceptionCheck ()) {
63+ // exception occurred
64+ env->DeleteLocalRef (jbuf);
65+ return ;
66+ }
67+
68+ jboolean is_copy = JNI_FALSE ;
69+ jbyte* ja = reinterpret_cast <jbyte*>(
70+ env->GetPrimitiveArrayCritical (jarray, &is_copy));
71+ if (ja == nullptr ) {
72+ // exception occurred
73+ env->DeleteLocalRef (jarray);
74+ env->DeleteLocalRef (jbuf);
75+ return ;
76+ }
77+
78+ memcpy (ja, const_cast <char *>(content), content_len);
79+
80+ env->ReleasePrimitiveArrayCritical (jarray, ja, is_copy ? 0 : JNI_ABORT );
81+
82+ env->DeleteLocalRef (jarray);
83+ }
84+
85+ inline jobject NewByteBuffer (JNIEnv* env, const size_t capacity, const char * content) {
86+
87+ const jobject jbuf = env->CallStaticObjectMethod (
88+ g_jbyte_buffer_clazz, g_jbyte_buffer_allocate_mid, static_cast <jint>(capacity));
89+ if (env->ExceptionCheck ()) {
90+ // exception occurred
91+ return nullptr ;
92+ }
93+
94+ // Set buffer data
95+ if (content != nullptr ) {
96+ SetByteBufferData (env, g_jbyte_buffer_array_mid, jbuf, content, capacity);
97+ }
98+
99+ return jbuf;
100+ }
101+
102+ inline jobject NewDirectByteBuffer (JNIEnv* env, const size_t capacity, const char * content) {
103+ bool allocated = false ;
104+ if (content == nullptr ) {
105+ content = new char [capacity];
106+ allocated = true ;
107+ }
108+ jobject jbuf = env->NewDirectByteBuffer (const_cast <char *>(content), static_cast <jlong>(capacity));
109+ if (jbuf == nullptr ) {
110+ // exception occurred
111+ if (allocated) {
112+ delete[] static_cast <const char *>(content);
113+ }
114+ return nullptr ;
115+ }
116+ return jbuf;
117+ }
118+
30119namespace jnibench {
31120
32121// Native class template
@@ -81,4 +170,4 @@ class FooByCallInvokeFinalJni : public FooJniClass<jnibench::Foo*, FooByCallInvo
81170 }
82171};
83172
84- } // end namespace jnibench
173+ } // end namespace jnibench
0 commit comments