react-native-nitro-modules 0.20.1 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/margelo/nitro/core/ArrayBuffer.kt +29 -8
- package/android/src/main/java/com/margelo/nitro/core/HybridObject.kt +1 -1
- package/cpp/core/ArrayBuffer.cpp +16 -1
- package/cpp/core/ArrayBuffer.hpp +20 -1
- package/cpp/utils/NitroDefines.hpp +1 -1
- package/ios/core/ArrayBufferHolder.hpp +3 -3
- package/ios/core/ArrayBufferHolder.swift +97 -9
- package/ios/core/PromiseHolder.hpp +1 -1
- package/package.json +1 -2
|
@@ -107,19 +107,40 @@ class ArrayBuffer {
|
|
|
107
107
|
/**
|
|
108
108
|
* Copy the given `ArrayBuffer` into a new **owning** `ArrayBuffer`.
|
|
109
109
|
*/
|
|
110
|
-
fun
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
fun copy(other: ArrayBuffer): ArrayBuffer {
|
|
111
|
+
val byteBuffer = other.getBuffer(false)
|
|
112
|
+
return copy(byteBuffer)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Copy the given `ByteBuffer` into a new **owning** `ArrayBuffer`.
|
|
117
|
+
*/
|
|
118
|
+
fun copy(byteBuffer: ByteBuffer): ArrayBuffer {
|
|
119
|
+
// 1. Find out size
|
|
120
|
+
byteBuffer.rewind()
|
|
121
|
+
val size = byteBuffer.remaining()
|
|
122
|
+
// 2. Create a new buffer with the same size as the other
|
|
123
|
+
val newBuffer = ByteBuffer.allocateDirect(size)
|
|
116
124
|
// 3. Copy over the source buffer into the new buffer
|
|
117
|
-
newBuffer.put(
|
|
125
|
+
newBuffer.put(byteBuffer)
|
|
118
126
|
// 4. Rewind both buffers again to index 0
|
|
119
127
|
newBuffer.rewind()
|
|
120
|
-
|
|
128
|
+
byteBuffer.rewind()
|
|
121
129
|
// 5. Create a new `ArrayBuffer`
|
|
122
130
|
return ArrayBuffer(newBuffer)
|
|
123
131
|
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Wrap the given `ByteBuffer` in a new **owning** `ArrayBuffer`.
|
|
135
|
+
*/
|
|
136
|
+
fun wrap(byteBuffer: ByteBuffer): ArrayBuffer {
|
|
137
|
+
byteBuffer.rewind()
|
|
138
|
+
return ArrayBuffer(byteBuffer)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@Deprecated("Use copy(...) instead", level = DeprecationLevel.WARNING)
|
|
142
|
+
fun copyOf(other: ArrayBuffer): ArrayBuffer {
|
|
143
|
+
return copy(other)
|
|
144
|
+
}
|
|
124
145
|
}
|
|
125
146
|
}
|
package/cpp/core/ArrayBuffer.cpp
CHANGED
|
@@ -17,10 +17,25 @@ using namespace facebook;
|
|
|
17
17
|
|
|
18
18
|
// 1. ArrayBuffer
|
|
19
19
|
|
|
20
|
-
std::shared_ptr<ArrayBuffer> ArrayBuffer::
|
|
20
|
+
std::shared_ptr<ArrayBuffer> ArrayBuffer::wrap(uint8_t* data, size_t size, DeleteFn&& deleteFunc) {
|
|
21
21
|
return std::make_shared<NativeArrayBuffer>(data, size, std::move(deleteFunc));
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(uint8_t* data, size_t size) {
|
|
25
|
+
uint8_t* copy = new uint8_t[size];
|
|
26
|
+
std::memcpy(copy, data, size);
|
|
27
|
+
return ArrayBuffer::wrap(copy, size, [=]() { delete[] copy; });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(std::vector<uint8_t>& data) {
|
|
31
|
+
return ArrayBuffer::copy(data.data(), data.size());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
std::shared_ptr<ArrayBuffer> ArrayBuffer::allocate(size_t size) {
|
|
35
|
+
uint8_t* data = new uint8_t[size];
|
|
36
|
+
return ArrayBuffer::wrap(data, size, [=]() { delete[] data; });
|
|
37
|
+
}
|
|
38
|
+
|
|
24
39
|
// 2. NativeArrayBuffer
|
|
25
40
|
|
|
26
41
|
NativeArrayBuffer::NativeArrayBuffer(uint8_t* data, size_t size, DeleteFn&& deleteFunc)
|
package/cpp/core/ArrayBuffer.hpp
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#include "OwningReference.hpp"
|
|
11
11
|
#include <jsi/jsi.h>
|
|
12
12
|
#include <thread>
|
|
13
|
+
#include <vector>
|
|
13
14
|
|
|
14
15
|
namespace margelo::nitro {
|
|
15
16
|
|
|
@@ -52,7 +53,25 @@ public:
|
|
|
52
53
|
* Create a new `NativeArrayBuffer` that wraps the given data (without copy) of the given size,
|
|
53
54
|
* and calls `deleteFunc` in which `data` should be deleted.
|
|
54
55
|
*/
|
|
55
|
-
static std::shared_ptr<ArrayBuffer>
|
|
56
|
+
static std::shared_ptr<ArrayBuffer> wrap(uint8_t* data, size_t size, DeleteFn&& deleteFunc);
|
|
57
|
+
/**
|
|
58
|
+
* Create a new `NativeArrayBuffer` that copies the given data of the given size
|
|
59
|
+
* into a newly allocated buffer.
|
|
60
|
+
*/
|
|
61
|
+
static std::shared_ptr<ArrayBuffer> copy(uint8_t* data, size_t size);
|
|
62
|
+
/**
|
|
63
|
+
* Create a new `NativeArrayBuffer` that copies the given `std::vector`.
|
|
64
|
+
*/
|
|
65
|
+
static std::shared_ptr<ArrayBuffer> copy(std::vector<uint8_t>& data);
|
|
66
|
+
/**
|
|
67
|
+
* Create a new `NativeArrayBuffer` that allocates a new buffer of the given size.
|
|
68
|
+
*/
|
|
69
|
+
static std::shared_ptr<ArrayBuffer> allocate(size_t size);
|
|
70
|
+
|
|
71
|
+
[[deprecated("Use wrapBuffer(...) instead.")]]
|
|
72
|
+
static std::shared_ptr<ArrayBuffer> makeBuffer(uint8_t* data, size_t size, DeleteFn&& deleteFunc) {
|
|
73
|
+
return ArrayBuffer::wrap(data, size, std::move(deleteFunc));
|
|
74
|
+
}
|
|
56
75
|
};
|
|
57
76
|
|
|
58
77
|
/**
|
|
@@ -35,9 +35,9 @@ public:
|
|
|
35
35
|
* Once the `ArrayBuffer` is no longer in use, the given `deleteFunc` will be called with the given `deleteFuncContext`
|
|
36
36
|
* as an argument. The caller is responsible for deleting `data` once this is called.
|
|
37
37
|
*/
|
|
38
|
-
static ArrayBufferHolder
|
|
38
|
+
static ArrayBufferHolder wrap(uint8_t* _Nonnull data, size_t size, SwiftClosure destroy) {
|
|
39
39
|
std::function<void()> deleteFunc = destroy.getFunction();
|
|
40
|
-
auto arrayBuffer = ArrayBuffer::
|
|
40
|
+
auto arrayBuffer = ArrayBuffer::wrap(data, size, std::move(deleteFunc));
|
|
41
41
|
return ArrayBufferHolder(arrayBuffer);
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -45,7 +45,7 @@ public:
|
|
|
45
45
|
/**
|
|
46
46
|
* Gets the raw bytes the underlying `ArrayBuffer` points to.
|
|
47
47
|
*/
|
|
48
|
-
|
|
48
|
+
uint8_t* _Nonnull getData() const SWIFT_COMPUTED_PROPERTY {
|
|
49
49
|
return _arrayBuffer->data();
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
@@ -15,6 +15,8 @@ import Foundation
|
|
|
15
15
|
*/
|
|
16
16
|
public typealias ArrayBufferHolder = margelo.nitro.ArrayBufferHolder
|
|
17
17
|
|
|
18
|
+
// pragma MARK: Wrap
|
|
19
|
+
|
|
18
20
|
public extension ArrayBufferHolder {
|
|
19
21
|
/**
|
|
20
22
|
* Create a new `ArrayBufferHolder` that wraps the given `data` of the given `size`
|
|
@@ -28,9 +30,27 @@ public extension ArrayBufferHolder {
|
|
|
28
30
|
// Convert escaping Swift closure to a `void*`
|
|
29
31
|
let swiftClosure = SwiftClosure(wrappingClosure: delete)
|
|
30
32
|
// Create ArrayBufferHolder with our wrapped Swift closure to make it callable as a C-function pointer
|
|
31
|
-
return ArrayBufferHolder.
|
|
33
|
+
return ArrayBufferHolder.wrap(data, size, swiftClosure)
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Create a new `ArrayBufferHolder` that wraps the given `data` of the given `size`
|
|
38
|
+
* without performing a copy.
|
|
39
|
+
* When the `ArrayBuffer` is no longer used, `onDelete` will be called, in which
|
|
40
|
+
* you as a caller are responsible for deleting `data`.
|
|
41
|
+
*/
|
|
42
|
+
static func wrap(dataWithoutCopy data: UnsafeMutableRawPointer,
|
|
43
|
+
size: Int,
|
|
44
|
+
onDelete delete: @escaping () -> Void) -> ArrayBufferHolder {
|
|
45
|
+
return ArrayBufferHolder.wrap(dataWithoutCopy: data.assumingMemoryBound(to: UInt8.self),
|
|
46
|
+
size: size,
|
|
47
|
+
onDelete: delete)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// pragma MARK: Allocate
|
|
52
|
+
|
|
53
|
+
public extension ArrayBufferHolder {
|
|
34
54
|
/**
|
|
35
55
|
* Allocate a new buffer of the given `size`.
|
|
36
56
|
* If `initializeToZero` is `true`, all bytes are set to `0`, otherwise they are left untouched.
|
|
@@ -40,24 +60,92 @@ public extension ArrayBufferHolder {
|
|
|
40
60
|
if initializeToZero {
|
|
41
61
|
data.initialize(repeating: 0, count: size)
|
|
42
62
|
}
|
|
43
|
-
|
|
44
63
|
let deleteFunc = SwiftClosure {
|
|
45
64
|
data.deallocate()
|
|
46
65
|
}
|
|
47
|
-
return ArrayBufferHolder.
|
|
66
|
+
return ArrayBufferHolder.wrap(data, size, deleteFunc)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// pragma MARK: Copy
|
|
71
|
+
|
|
72
|
+
public extension ArrayBufferHolder {
|
|
73
|
+
/**
|
|
74
|
+
* Copy the given `UnsafeMutablePointer<UInt8>` into a new **owning** `ArrayBufferHolder`.
|
|
75
|
+
*/
|
|
76
|
+
static func copy(of other: UnsafeMutablePointer<UInt8>,
|
|
77
|
+
size: Int) -> ArrayBufferHolder {
|
|
78
|
+
// 1. Create new `UnsafeMutablePointer<UInt8>`
|
|
79
|
+
let copy = UnsafeMutablePointer<UInt8>.allocate(capacity: size)
|
|
80
|
+
// 2. Copy over data
|
|
81
|
+
copy.initialize(from: other, count: size)
|
|
82
|
+
// 3. Create memory safe destroyer
|
|
83
|
+
let deleteFunc = SwiftClosure {
|
|
84
|
+
copy.deallocate()
|
|
85
|
+
}
|
|
86
|
+
return ArrayBufferHolder.wrap(copy, size, deleteFunc)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Copy the given `UnsafeMutableRawPointer` into a new **owning** `ArrayBufferHolder`.
|
|
91
|
+
*/
|
|
92
|
+
static func copy(of other: UnsafeMutableRawPointer,
|
|
93
|
+
size: Int) -> ArrayBufferHolder {
|
|
94
|
+
return ArrayBufferHolder.copy(of: other.assumingMemoryBound(to: UInt8.self),
|
|
95
|
+
size: size)
|
|
48
96
|
}
|
|
49
97
|
|
|
50
98
|
/**
|
|
51
99
|
* Copy the given `ArrayBufferHolder` into a new **owning** `ArrayBufferHolder`.
|
|
52
100
|
*/
|
|
53
101
|
static func copy(of other: ArrayBufferHolder) -> ArrayBufferHolder {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
data.initialize(from: pointer, count: other.size)
|
|
102
|
+
return ArrayBufferHolder.copy(of: other.data, size: other.size)
|
|
103
|
+
}
|
|
57
104
|
|
|
58
|
-
|
|
59
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Copy the given `Data` into a new **owning** `ArrayBufferHolder`.
|
|
107
|
+
*/
|
|
108
|
+
static func copy(data: Data) throws -> ArrayBufferHolder {
|
|
109
|
+
// 1. Create new `ArrayBuffer` of same size
|
|
110
|
+
let size = data.count
|
|
111
|
+
let arrayBuffer = ArrayBufferHolder.allocate(size: size)
|
|
112
|
+
// 2. Copy all bytes from `Data` into our new `ArrayBuffer`
|
|
113
|
+
try data.withUnsafeBytes { rawPointer in
|
|
114
|
+
guard let baseAddress = rawPointer.baseAddress else {
|
|
115
|
+
throw RuntimeError.error(withMessage: "Cannot get baseAddress of Data!")
|
|
116
|
+
}
|
|
117
|
+
memcpy(arrayBuffer.data, baseAddress, size)
|
|
118
|
+
}
|
|
119
|
+
return arrayBuffer
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
// pragma MARK: Data
|
|
125
|
+
|
|
126
|
+
public extension ArrayBufferHolder {
|
|
127
|
+
/**
|
|
128
|
+
* Wrap this `ArrayBufferHolder` in a `Data` instance, without performing a copy.
|
|
129
|
+
* - `copyIfNeeded`: If this `ArrayBuffer` is **non-owning**, the foreign
|
|
130
|
+
* data may needs to be copied to be safely used outside of the scope of the caller function.
|
|
131
|
+
* This flag controls that.
|
|
132
|
+
*/
|
|
133
|
+
func toData(copyIfNeeded: Bool) -> Data {
|
|
134
|
+
let shouldCopy = copyIfNeeded && !self.isOwner
|
|
135
|
+
if shouldCopy {
|
|
136
|
+
// COPY DATA
|
|
137
|
+
return Data.init(bytes: self.data, count: self.size)
|
|
138
|
+
} else {
|
|
139
|
+
// WRAP DATA
|
|
140
|
+
// 1. Get the std::shared_ptr<ArrayBuffer>
|
|
141
|
+
var sharedPointer = self.getArrayBuffer()
|
|
142
|
+
// 2. Create a Data object WRAPPING our pointer
|
|
143
|
+
return Data(bytesNoCopy: self.data, count: self.size, deallocator: .custom({ buffer, size in
|
|
144
|
+
// 3. Capture the std::shared_ptr<ArrayBuffer> in the deallocator lambda so it stays alive.
|
|
145
|
+
// As soon as this lambda gets called, the `sharedPointer` gets deleted causing the
|
|
146
|
+
// underlying `ArrayBuffer` to be freed.
|
|
147
|
+
sharedPointer.reset()
|
|
148
|
+
}))
|
|
60
149
|
}
|
|
61
|
-
return ArrayBufferHolder.makeBuffer(data, other.size, deleteFunc)
|
|
62
150
|
}
|
|
63
151
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-modules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Insanely fast native C++, Swift or Kotlin modules with a statically compiled binding layer to JSI.",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -117,7 +117,6 @@
|
|
|
117
117
|
[
|
|
118
118
|
"typescript",
|
|
119
119
|
{
|
|
120
|
-
"tsc": "../../node_modules/.bin/tsc",
|
|
121
120
|
"project": "tsconfig.build.json"
|
|
122
121
|
}
|
|
123
122
|
]
|