Skip to content

Commit efcac4f

Browse files
committed
Add support for indirect ByteBuffer
1 parent 0382d33 commit efcac4f

File tree

3 files changed

+75
-22
lines changed

3 files changed

+75
-22
lines changed

test-app/app/src/main/assets/app/tests/byte-buffer-test.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
describe("Tests mapped ByteBuffer conversion", function () {
2-
it("should convert ByteBuffer to ArrayBuffer", function () {
2+
it("should convert ByteBuffer to ArrayBuffer [Direct ByteBuffer]", function () {
33
var bb = java.nio.ByteBuffer.allocateDirect(12);
44
var ab = ArrayBuffer.from(bb);
55
var int8arr = new Int8Array(ab);
@@ -8,7 +8,16 @@ describe("Tests mapped ByteBuffer conversion", function () {
88
expect(int32arr.length).toBe(3);
99
});
1010

11-
it("should share the same memory of all typed arrays", function () {
11+
it("should convert ByteBuffer to ArrayBuffer [Indirect ByteBuffer]", function () {
12+
var bb = java.nio.ByteBuffer.allocate(12);
13+
var ab = ArrayBuffer.from(bb);
14+
var int8arr = new Int8Array(ab);
15+
expect(int8arr.length).toBe(12);
16+
var int32arr = new Int32Array(ab);
17+
expect(int32arr.length).toBe(3);
18+
});
19+
20+
it("should share the same memory of all typed arrays [Direct ByteBuffer]", function () {
1221
var bb = java.nio.ByteBuffer.allocateDirect(12);
1322
var ab = ArrayBuffer.from(bb);
1423
var int8arr = new Int8Array(ab);
@@ -23,13 +32,35 @@ describe("Tests mapped ByteBuffer conversion", function () {
2332
expect(value).toBe(0x44332211);
2433
});
2534

26-
it("should keep original ByteBuffer after conversion", function () {
35+
it("should share the same memory of all typed arrays [Indirect ByteBuffer]", function () {
36+
var bb = java.nio.ByteBuffer.allocate(12);
37+
var ab = ArrayBuffer.from(bb);
38+
var int8arr = new Int8Array(ab);
39+
expect(int8arr.length).toBe(12);
40+
var int32arr = new Int32Array(ab);
41+
expect(int32arr.length).toBe(3);
42+
int8arr[0] = 0x11;
43+
int8arr[1] = 0x22;
44+
int8arr[2] = 0x33;
45+
int8arr[3] = 0x44;
46+
var value = int32arr[0];
47+
expect(value).toBe(0x44332211);
48+
});
49+
50+
it("should keep original ByteBuffer after conversion [Direct ByteBuffer]", function () {
2751
var bb = java.nio.ByteBuffer.allocateDirect(12);
2852
var ab = ArrayBuffer.from(bb);
2953
var same = bb === ab.nativeObject;
3054
expect(same).toBe(true);
3155
});
3256

57+
it("should keep original ByteBuffer after conversion [Indirect ByteBuffer]", function () {
58+
var bb = java.nio.ByteBuffer.allocate(12);
59+
var ab = ArrayBuffer.from(bb);
60+
var same = bb === ab.nativeObject;
61+
expect(same).toBe(true);
62+
});
63+
3364
it("should throw exception when ArrayBuffer.from is called with wrong number of arguments", function () {
3465
var exceptionCaught = false;
3566
try {

test-app/runtime/src/main/cpp/ArrayBufferHelper.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ using namespace v8;
88
using namespace tns;
99

1010
ArrayBufferHelper::ArrayBufferHelper()
11-
: m_objectManager(nullptr), m_ByteBufferClass(nullptr), m_isDirectMethodID(nullptr) {
11+
: m_objectManager(nullptr), m_ByteBufferClass(nullptr), m_isDirectMethodID(nullptr),
12+
m_remainingMethodID(nullptr), m_getMethodID(nullptr) {
1213
}
1314

1415
void ArrayBufferHelper::CreateConvertFunctions(Isolate* isolate, const Local<Object>& global, ObjectManager* objectManager) {
@@ -82,14 +83,34 @@ void ArrayBufferHelper::CreateFromCallbackImpl(const FunctionCallbackInfo<Value>
8283

8384
auto isDirectBuffer = ret == JNI_TRUE;
8485

85-
if (!isDirectBuffer) {
86-
throw NativeScriptException("Direct ByteBuffer expected)");
87-
}
86+
Local<ArrayBuffer> arrayBuffer;
87+
88+
if (isDirectBuffer) {
89+
auto data = env.GetDirectBufferAddress(obj);
90+
auto size = env.GetDirectBufferCapacity(obj);
91+
92+
arrayBuffer = ArrayBuffer::New(isolate, data, size);
93+
} else {
94+
if (m_remainingMethodID == nullptr) {
95+
m_remainingMethodID = env.GetMethodID(m_ByteBufferClass, "remaining", "()I");
96+
assert(m_remainingMethodID != nullptr);
97+
}
98+
99+
int bufferRemainingSize = env.CallIntMethod(obj, m_remainingMethodID);
88100

89-
auto data = env.GetDirectBufferAddress(obj);
90-
auto size = env.GetDirectBufferCapacity(obj);
101+
if (m_getMethodID == nullptr) {
102+
m_getMethodID = env.GetMethodID(m_ByteBufferClass, "get", "([BII)Ljava/nio/ByteBuffer;");
103+
assert(m_getMethodID != nullptr);
104+
}
105+
106+
jbyteArray byteArray = env.NewByteArray(bufferRemainingSize);
107+
env.CallObjectMethod(obj, m_getMethodID, byteArray, 0, bufferRemainingSize);
108+
109+
auto buffer = env.GetByteArrayElements(byteArray, 0);
110+
arrayBuffer = ArrayBuffer::New(isolate, bufferRemainingSize);
111+
memcpy(arrayBuffer->GetContents().Data(), buffer, bufferRemainingSize);
112+
}
91113

92-
auto arrayBuffer = ArrayBuffer::New(isolate, data, size);
93114
auto ctx = isolate->GetCurrentContext();
94115
arrayBuffer->Set(ctx, ArgConverter::ConvertToV8String(isolate, "nativeObject"), argObj);
95116

test-app/runtime/src/main/cpp/ArrayBufferHelper.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,25 @@
55
#include "ObjectManager.h"
66

77
namespace tns {
8-
class ArrayBufferHelper {
9-
public:
10-
ArrayBufferHelper();
8+
class ArrayBufferHelper {
9+
public:
10+
ArrayBufferHelper();
1111

12-
void CreateConvertFunctions(v8::Isolate* isolate, const v8::Local<v8::Object>& global, ObjectManager* objectManager);
12+
void CreateConvertFunctions(v8::Isolate* isolate, const v8::Local<v8::Object>& global, ObjectManager* objectManager);
1313

14-
private:
14+
private:
1515

16-
static void CreateFromCallbackStatic(const v8::FunctionCallbackInfo<v8::Value>& info);
16+
static void CreateFromCallbackStatic(const v8::FunctionCallbackInfo<v8::Value>& info);
1717

18-
void CreateFromCallbackImpl(const v8::FunctionCallbackInfo<v8::Value>& info);
18+
void CreateFromCallbackImpl(const v8::FunctionCallbackInfo<v8::Value>& info);
1919

20-
ObjectManager* m_objectManager;
20+
ObjectManager* m_objectManager;
2121

22-
jclass m_ByteBufferClass;
23-
24-
jmethodID m_isDirectMethodID;
25-
};
22+
jclass m_ByteBufferClass;
23+
jmethodID m_isDirectMethodID;
24+
jmethodID m_remainingMethodID;
25+
jmethodID m_getMethodID;
26+
};
2627
}
2728

2829

0 commit comments

Comments
 (0)