Skip to content

Commit 49315c7

Browse files
committed
Use length-aware accessors
1 parent 9ff7f94 commit 49315c7

6 files changed

Lines changed: 169 additions & 173 deletions

File tree

src/main/c++/bytearray/GetByteArray.cpp

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -58,23 +58,33 @@ static const auto DB_READ_MOCK = std::unordered_map<std::string, std::string>{
5858
{"testKeyWithReturnValueSize0131072Bytes", STR_128_KB},
5959
{"testKeyWithReturnValueSize0262144Bytes", STR_256_KB}};
6060

61-
const std::string &GetByteArrayInternal(const char *key)
62-
{
63-
std::string str(key, 38);
64-
65-
//std::cerr << std::endl << "Getting " << str << std::endl << std::endl;
66-
return DB_READ_MOCK.at(str);
67-
}
68-
69-
struct WriteKey
70-
{
71-
std::string key;
72-
size_t length;
73-
74-
WriteKey(const std::string &key, size_t length) : key(key, 38), length(length)
75-
{
76-
}
77-
};
61+
static const std::string &GetByteArrayInternal(const char *key)
62+
{
63+
std::string str(key, 38);
64+
65+
//std::cerr << std::endl << "Getting " << str << std::endl << std::endl;
66+
return DB_READ_MOCK.at(str);
67+
}
68+
69+
const std::string &GetByteArrayInternalWithLength(const char *key, size_t key_len)
70+
{
71+
std::string str(key, key_len);
72+
return DB_READ_MOCK.at(str);
73+
}
74+
75+
struct WriteKey
76+
{
77+
std::string key;
78+
size_t length;
79+
80+
WriteKey(const std::string &key, size_t length) : key(key), length(length)
81+
{
82+
}
83+
84+
WriteKey(const char *key_ptr, size_t key_len, size_t length) : key(key_ptr, key_len), length(length)
85+
{
86+
}
87+
};
7888

7989
bool operator==(const WriteKey &lhs, const WriteKey &rhs)
8090
{
@@ -98,17 +108,29 @@ namespace std
98108

99109
static auto DB_WRITE_MOCK = std::unordered_map<WriteKey, char *>();
100110

101-
char *GetByteArrayInternalForWrite(const char *key, size_t size)
102-
{
103-
auto writeKey = WriteKey(key, size);
104-
auto it = DB_WRITE_MOCK.find(writeKey);
111+
static char *GetByteArrayInternalForWrite(const char *key, size_t size)
112+
{
113+
auto writeKey = WriteKey(key, 38, size);
114+
auto it = DB_WRITE_MOCK.find(writeKey);
105115
if (it == DB_WRITE_MOCK.end())
106116
{
107117
DB_WRITE_MOCK[writeKey] = new char[size];
108118
it = DB_WRITE_MOCK.find(writeKey);
109-
}
110-
return it->second;
111-
}
119+
}
120+
return it->second;
121+
}
122+
123+
char *GetByteArrayInternalForWriteWithLength(const char *key, size_t key_len, size_t size)
124+
{
125+
auto writeKey = WriteKey(key, key_len, size);
126+
auto it = DB_WRITE_MOCK.find(writeKey);
127+
if (it == DB_WRITE_MOCK.end())
128+
{
129+
DB_WRITE_MOCK[writeKey] = new char[size];
130+
it = DB_WRITE_MOCK.find(writeKey);
131+
}
132+
return it->second;
133+
}
112134

113135
jclass g_jbyte_buffer_clazz;
114136
jmethodID g_jbyte_buffer_array_mid;

src/main/c++/bytearray/Portal.h

Lines changed: 0 additions & 112 deletions
This file was deleted.

src/main/c++/call/Portal.h

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,95 @@
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+
30119
namespace 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

Comments
 (0)