react-native-nitro-modules 0.31.1 → 0.31.2
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 +47 -2
- package/cpp/core/ArrayBuffer.cpp +5 -0
- package/cpp/core/ArrayBuffer.hpp +4 -0
- package/cpp/core/Promise.cpp +127 -1
- package/cpp/core/Promise.hpp +16 -121
- package/cpp/utils/FastVectorCopy.hpp +1 -0
- package/cpp/utils/NitroDefines.hpp +1 -1
- package/cpp/utils/ObjectUtils.cpp +5 -2
- package/ios/core/ArrayBuffer.swift +19 -15
- package/package.json +1 -1
|
@@ -90,11 +90,47 @@ class ArrayBuffer {
|
|
|
90
90
|
return boxed as HardwareBuffer
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Copies the underlying data into a `ByteArray`.
|
|
95
|
+
* If this `ArrayBuffer` is backed by a GPU-HardwareBuffer,
|
|
96
|
+
* this performs a GPU-download.
|
|
97
|
+
*/
|
|
98
|
+
fun toByteArray(): ByteArray {
|
|
99
|
+
val buffer = this.getBuffer(false)
|
|
100
|
+
if (buffer.hasArray()) {
|
|
101
|
+
// It's a CPU-backed array - we can return this directly if the size matches
|
|
102
|
+
val array = buffer.array()
|
|
103
|
+
if (array.size == this.size) {
|
|
104
|
+
// The ByteBuffer is 1:1 mapped to a byte array - return as is!
|
|
105
|
+
return array
|
|
106
|
+
}
|
|
107
|
+
// we had a CPU-backed array, but it's size differs from our ArrayBuffer size.
|
|
108
|
+
// This might be because the ArrayBuffer has a smaller view of the data, so we need
|
|
109
|
+
// to resort back to a good ol' copy.
|
|
110
|
+
}
|
|
111
|
+
// It's not a 1:1 mapped array (e.g. HardwareBuffer) - we need to copy to the CPU
|
|
112
|
+
val copy = ByteBuffer.allocate(buffer.capacity())
|
|
113
|
+
copy.put(buffer)
|
|
114
|
+
return copy.array()
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Returns an **owning** version of this `ArrayBuffer`.
|
|
119
|
+
* If this `ArrayBuffer` already is **owning**, it is returned as-is.
|
|
120
|
+
* If this `ArrayBuffer` is **non-owning**, it is _copied_.
|
|
121
|
+
*/
|
|
122
|
+
fun asOwning(): ArrayBuffer {
|
|
123
|
+
if (!isOwner) {
|
|
124
|
+
return ArrayBuffer.copy(this)
|
|
125
|
+
}
|
|
126
|
+
return this
|
|
127
|
+
}
|
|
128
|
+
|
|
93
129
|
/**
|
|
94
130
|
* Create a new **owning-** `ArrayBuffer` that holds the given `ByteBuffer`.
|
|
95
131
|
* The `ByteBuffer` needs to remain valid for as long as the `ArrayBuffer` is alive.
|
|
96
132
|
*/
|
|
97
|
-
constructor(byteBuffer: ByteBuffer) {
|
|
133
|
+
internal constructor(byteBuffer: ByteBuffer) {
|
|
98
134
|
if (!byteBuffer.isDirect) {
|
|
99
135
|
throw Error(
|
|
100
136
|
"ArrayBuffers can only be created from direct ByteBuffers, " +
|
|
@@ -109,7 +145,7 @@ class ArrayBuffer {
|
|
|
109
145
|
* The `HardwareBuffer` needs to remain valid for as long as the `ArrayBuffer` is alive.
|
|
110
146
|
*/
|
|
111
147
|
@RequiresApi(Build.VERSION_CODES.O)
|
|
112
|
-
constructor(hardwareBuffer: HardwareBuffer) {
|
|
148
|
+
internal constructor(hardwareBuffer: HardwareBuffer) {
|
|
113
149
|
if (hardwareBuffer.isClosed) {
|
|
114
150
|
throw Error("Cannot create ArrayBuffer from an already-closed HardwareBuffer!")
|
|
115
151
|
}
|
|
@@ -187,6 +223,15 @@ class ArrayBuffer {
|
|
|
187
223
|
return ArrayBuffer(newBuffer)
|
|
188
224
|
}
|
|
189
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Copy the given `ByteArray` into a new **owning** `ArrayBuffer`.
|
|
228
|
+
*/
|
|
229
|
+
fun copy(byteArray: ByteArray): ArrayBuffer {
|
|
230
|
+
val byteBuffer = ByteBuffer.allocateDirect(byteArray.size)
|
|
231
|
+
byteBuffer.put(byteArray)
|
|
232
|
+
return ArrayBuffer.wrap(byteBuffer)
|
|
233
|
+
}
|
|
234
|
+
|
|
190
235
|
/**
|
|
191
236
|
* Copy the given `HardwareBuffer` into a new **owning** `ArrayBuffer`.
|
|
192
237
|
*/
|
package/cpp/core/ArrayBuffer.cpp
CHANGED
|
@@ -32,6 +32,11 @@ std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(const std::vector<uint8_t>& data)
|
|
|
32
32
|
return ArrayBuffer::copy(data.data(), data.size());
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
std::shared_ptr<ArrayBuffer> ArrayBuffer::move(std::vector<uint8_t>&& data) {
|
|
36
|
+
auto* vector = new std::vector<uint8_t>(std::move(data));
|
|
37
|
+
return ArrayBuffer::wrap(vector->data(), vector->size(), [=]() { delete vector; });
|
|
38
|
+
}
|
|
39
|
+
|
|
35
40
|
std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(const std::shared_ptr<ArrayBuffer>& buffer) {
|
|
36
41
|
return ArrayBuffer::copy(buffer->data(), buffer->size());
|
|
37
42
|
}
|
package/cpp/core/ArrayBuffer.hpp
CHANGED
|
@@ -64,6 +64,10 @@ public:
|
|
|
64
64
|
* Create a new `NativeArrayBuffer` that copies the given `std::vector`.
|
|
65
65
|
*/
|
|
66
66
|
static std::shared_ptr<ArrayBuffer> copy(const std::vector<uint8_t>& data);
|
|
67
|
+
/**
|
|
68
|
+
* Create a new `NativeArrayBuffer` that moves the given `std::vector`.
|
|
69
|
+
*/
|
|
70
|
+
static std::shared_ptr<ArrayBuffer> move(std::vector<uint8_t>&& data);
|
|
67
71
|
/**
|
|
68
72
|
* Create a new `NativeArrayBuffer` that copies the given `std::shared_ptr<ArrayBuffer>`.
|
|
69
73
|
*/
|
package/cpp/core/Promise.cpp
CHANGED
|
@@ -7,4 +7,130 @@
|
|
|
7
7
|
|
|
8
8
|
#include "Promise.hpp"
|
|
9
9
|
|
|
10
|
-
namespace margelo::nitro {
|
|
10
|
+
namespace margelo::nitro {
|
|
11
|
+
|
|
12
|
+
Promise<void>::~Promise() {
|
|
13
|
+
if (isPending()) [[unlikely]] {
|
|
14
|
+
std::runtime_error error("Timeouted: Promise<void> was destroyed!");
|
|
15
|
+
reject(std::make_exception_ptr(error));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
std::shared_ptr<Promise<void>> Promise<void>::create() {
|
|
20
|
+
return std::shared_ptr<Promise<void>>(new Promise());
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
std::shared_ptr<Promise<void>> Promise<void>::async(std::function<void()>&& run) {
|
|
24
|
+
auto promise = create();
|
|
25
|
+
ThreadPool::shared().run([run = std::move(run), promise]() {
|
|
26
|
+
try {
|
|
27
|
+
// Run the code, then resolve.
|
|
28
|
+
run();
|
|
29
|
+
promise->resolve();
|
|
30
|
+
} catch (...) {
|
|
31
|
+
// It threw an error.
|
|
32
|
+
promise->reject(std::current_exception());
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return promise;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
std::shared_ptr<Promise<void>> Promise<void>::awaitFuture(std::future<void>&& future) {
|
|
39
|
+
auto sharedFuture = std::make_shared<std::future<void>>(std::move(future));
|
|
40
|
+
return async([sharedFuture = std::move(sharedFuture)]() { sharedFuture->get(); });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
std::shared_ptr<Promise<void>> Promise<void>::resolved() {
|
|
44
|
+
auto promise = create();
|
|
45
|
+
promise->resolve();
|
|
46
|
+
return promise;
|
|
47
|
+
}
|
|
48
|
+
std::shared_ptr<Promise<void>> Promise<void>::rejected(const std::exception_ptr& error) {
|
|
49
|
+
auto promise = create();
|
|
50
|
+
promise->reject(error);
|
|
51
|
+
return promise;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void Promise<void>::resolve() {
|
|
55
|
+
std::unique_lock lock(_mutex);
|
|
56
|
+
#ifdef NITRO_DEBUG
|
|
57
|
+
assertPromiseState(*this, PromiseTask::WANTS_TO_RESOLVE);
|
|
58
|
+
#endif
|
|
59
|
+
_isResolved = true;
|
|
60
|
+
for (const auto& onResolved : _onResolvedListeners) {
|
|
61
|
+
onResolved();
|
|
62
|
+
}
|
|
63
|
+
didFinish();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void Promise<void>::reject(const std::exception_ptr& exception) {
|
|
67
|
+
if (exception == nullptr) [[unlikely]] {
|
|
68
|
+
throw std::runtime_error("Cannot reject Promise<void> with a null exception_ptr!");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
std::unique_lock lock(_mutex);
|
|
72
|
+
#ifdef NITRO_DEBUG
|
|
73
|
+
assertPromiseState(*this, PromiseTask::WANTS_TO_REJECT);
|
|
74
|
+
#endif
|
|
75
|
+
_error = exception;
|
|
76
|
+
for (const auto& onRejected : _onRejectedListeners) {
|
|
77
|
+
onRejected(exception);
|
|
78
|
+
}
|
|
79
|
+
didFinish();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
void Promise<void>::addOnResolvedListener(OnResolvedFunc&& onResolved) {
|
|
83
|
+
std::unique_lock lock(_mutex);
|
|
84
|
+
if (_isResolved) {
|
|
85
|
+
onResolved();
|
|
86
|
+
} else {
|
|
87
|
+
_onResolvedListeners.push_back(std::move(onResolved));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
void Promise<void>::addOnResolvedListener(const OnResolvedFunc& onResolved) {
|
|
91
|
+
std::unique_lock lock(_mutex);
|
|
92
|
+
if (_isResolved) {
|
|
93
|
+
onResolved();
|
|
94
|
+
} else {
|
|
95
|
+
_onResolvedListeners.push_back(onResolved);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
void Promise<void>::addOnRejectedListener(OnRejectedFunc&& onRejected) {
|
|
99
|
+
std::unique_lock lock(_mutex);
|
|
100
|
+
if (_error) {
|
|
101
|
+
onRejected(_error);
|
|
102
|
+
} else {
|
|
103
|
+
// Promise is not yet rejected, put the listener in our queue.
|
|
104
|
+
_onRejectedListeners.push_back(std::move(onRejected));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
void Promise<void>::addOnRejectedListener(const OnRejectedFunc& onRejected) {
|
|
108
|
+
std::unique_lock lock(_mutex);
|
|
109
|
+
if (_error) {
|
|
110
|
+
onRejected(_error);
|
|
111
|
+
} else {
|
|
112
|
+
// Promise is not yet rejected, put the listener in our queue.
|
|
113
|
+
_onRejectedListeners.push_back(onRejected);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
std::future<void> Promise<void>::await() {
|
|
118
|
+
auto promise = std::make_shared<std::promise<void>>();
|
|
119
|
+
addOnResolvedListener([promise]() { promise->set_value(); });
|
|
120
|
+
addOnRejectedListener([promise](const std::exception_ptr& error) { promise->set_exception(error); });
|
|
121
|
+
return promise->get_future();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const std::exception_ptr& Promise<void>::getError() {
|
|
125
|
+
if (!isRejected()) {
|
|
126
|
+
throw std::runtime_error("Cannot get error when Promise<void> is not yet rejected!");
|
|
127
|
+
}
|
|
128
|
+
return _error;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
void Promise<void>::didFinish() noexcept {
|
|
132
|
+
_onResolvedListeners.clear();
|
|
133
|
+
_onRejectedListeners.clear();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
} // namespace margelo::nitro
|
package/cpp/core/Promise.hpp
CHANGED
|
@@ -270,153 +270,48 @@ public:
|
|
|
270
270
|
|
|
271
271
|
public:
|
|
272
272
|
Promise(const Promise&) = delete;
|
|
273
|
+
Promise(Promise&&) = delete;
|
|
274
|
+
~Promise();
|
|
273
275
|
|
|
274
276
|
private:
|
|
275
277
|
Promise() = default;
|
|
276
278
|
|
|
277
279
|
public:
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
280
|
+
static std::shared_ptr<Promise> create();
|
|
281
|
+
static std::shared_ptr<Promise> async(std::function<void()>&& run);
|
|
282
|
+
static std::shared_ptr<Promise> awaitFuture(std::future<void>&& future);
|
|
283
|
+
static std::shared_ptr<Promise> resolved();
|
|
284
|
+
static std::shared_ptr<Promise> rejected(const std::exception_ptr& error);
|
|
284
285
|
|
|
285
286
|
public:
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
static std::shared_ptr<Promise> async(std::function<void()>&& run) {
|
|
291
|
-
auto promise = create();
|
|
292
|
-
ThreadPool::shared().run([run = std::move(run), promise]() {
|
|
293
|
-
try {
|
|
294
|
-
// Run the code, then resolve.
|
|
295
|
-
run();
|
|
296
|
-
promise->resolve();
|
|
297
|
-
} catch (...) {
|
|
298
|
-
// It threw an error.
|
|
299
|
-
promise->reject(std::current_exception());
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
return promise;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
static std::shared_ptr<Promise> awaitFuture(std::future<void>&& future) {
|
|
306
|
-
auto sharedFuture = std::make_shared<std::future<void>>(std::move(future));
|
|
307
|
-
return async([sharedFuture = std::move(sharedFuture)]() { sharedFuture->get(); });
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
static std::shared_ptr<Promise> resolved() {
|
|
311
|
-
auto promise = create();
|
|
312
|
-
promise->resolve();
|
|
313
|
-
return promise;
|
|
314
|
-
}
|
|
315
|
-
static std::shared_ptr<Promise> rejected(const std::exception_ptr& error) {
|
|
316
|
-
auto promise = create();
|
|
317
|
-
promise->reject(error);
|
|
318
|
-
return promise;
|
|
319
|
-
}
|
|
287
|
+
void resolve();
|
|
288
|
+
void reject(const std::exception_ptr& exception);
|
|
320
289
|
|
|
321
290
|
public:
|
|
322
|
-
void
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
#endif
|
|
327
|
-
_isResolved = true;
|
|
328
|
-
for (const auto& onResolved : _onResolvedListeners) {
|
|
329
|
-
onResolved();
|
|
330
|
-
}
|
|
331
|
-
didFinish();
|
|
332
|
-
}
|
|
333
|
-
void reject(const std::exception_ptr& exception) {
|
|
334
|
-
if (exception == nullptr) [[unlikely]] {
|
|
335
|
-
throw std::runtime_error("Cannot reject Promise<void> with a null exception_ptr!");
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
std::unique_lock lock(_mutex);
|
|
339
|
-
#ifdef NITRO_DEBUG
|
|
340
|
-
assertPromiseState(*this, PromiseTask::WANTS_TO_REJECT);
|
|
341
|
-
#endif
|
|
342
|
-
_error = exception;
|
|
343
|
-
for (const auto& onRejected : _onRejectedListeners) {
|
|
344
|
-
onRejected(exception);
|
|
345
|
-
}
|
|
346
|
-
didFinish();
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
public:
|
|
350
|
-
void addOnResolvedListener(OnResolvedFunc&& onResolved) {
|
|
351
|
-
std::unique_lock lock(_mutex);
|
|
352
|
-
if (_isResolved) {
|
|
353
|
-
onResolved();
|
|
354
|
-
} else {
|
|
355
|
-
_onResolvedListeners.push_back(std::move(onResolved));
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
void addOnResolvedListener(const OnResolvedFunc& onResolved) {
|
|
359
|
-
std::unique_lock lock(_mutex);
|
|
360
|
-
if (_isResolved) {
|
|
361
|
-
onResolved();
|
|
362
|
-
} else {
|
|
363
|
-
_onResolvedListeners.push_back(onResolved);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
void addOnRejectedListener(OnRejectedFunc&& onRejected) {
|
|
367
|
-
std::unique_lock lock(_mutex);
|
|
368
|
-
if (_error) {
|
|
369
|
-
onRejected(_error);
|
|
370
|
-
} else {
|
|
371
|
-
// Promise is not yet rejected, put the listener in our queue.
|
|
372
|
-
_onRejectedListeners.push_back(std::move(onRejected));
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
void addOnRejectedListener(const OnRejectedFunc& onRejected) {
|
|
376
|
-
std::unique_lock lock(_mutex);
|
|
377
|
-
if (_error) {
|
|
378
|
-
onRejected(_error);
|
|
379
|
-
} else {
|
|
380
|
-
// Promise is not yet rejected, put the listener in our queue.
|
|
381
|
-
_onRejectedListeners.push_back(onRejected);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
291
|
+
void addOnResolvedListener(OnResolvedFunc&& onResolved);
|
|
292
|
+
void addOnResolvedListener(const OnResolvedFunc& onResolved);
|
|
293
|
+
void addOnRejectedListener(OnRejectedFunc&& onRejected);
|
|
294
|
+
void addOnRejectedListener(const OnRejectedFunc& onRejected);
|
|
384
295
|
|
|
385
296
|
public:
|
|
386
|
-
std::future<void> await()
|
|
387
|
-
auto promise = std::make_shared<std::promise<void>>();
|
|
388
|
-
addOnResolvedListener([promise]() { promise->set_value(); });
|
|
389
|
-
addOnRejectedListener([promise](const std::exception_ptr& error) { promise->set_exception(error); });
|
|
390
|
-
return promise->get_future();
|
|
391
|
-
}
|
|
297
|
+
std::future<void> await();
|
|
392
298
|
|
|
393
299
|
public:
|
|
394
|
-
|
|
395
|
-
if (!isRejected()) {
|
|
396
|
-
throw std::runtime_error("Cannot get error when Promise<void> is not yet rejected!");
|
|
397
|
-
}
|
|
398
|
-
return _error;
|
|
399
|
-
}
|
|
300
|
+
const std::exception_ptr& getError();
|
|
400
301
|
|
|
401
302
|
public:
|
|
402
|
-
[[nodiscard]]
|
|
403
303
|
inline bool isResolved() const noexcept {
|
|
404
304
|
return _isResolved;
|
|
405
305
|
}
|
|
406
|
-
[[nodiscard]]
|
|
407
306
|
inline bool isRejected() const noexcept {
|
|
408
307
|
return _error != nullptr;
|
|
409
308
|
}
|
|
410
|
-
[[nodiscard]]
|
|
411
309
|
inline bool isPending() const noexcept {
|
|
412
310
|
return !isResolved() && !isRejected();
|
|
413
311
|
}
|
|
414
312
|
|
|
415
313
|
private:
|
|
416
|
-
void didFinish() noexcept
|
|
417
|
-
_onResolvedListeners.clear();
|
|
418
|
-
_onRejectedListeners.clear();
|
|
419
|
-
}
|
|
314
|
+
void didFinish() noexcept;
|
|
420
315
|
|
|
421
316
|
private:
|
|
422
317
|
std::mutex _mutex;
|
|
@@ -21,6 +21,7 @@ namespace margelo::nitro {
|
|
|
21
21
|
* the data will be bulk-memcopied.
|
|
22
22
|
*/
|
|
23
23
|
template <typename T>
|
|
24
|
+
[[deprecated("FastVectorCopy is not safe for Swift - upgrade Nitro!")]]
|
|
24
25
|
std::vector<T> FastVectorCopy(const T* CONTIGUOUS_MEMORY NON_NULL data, size_t size) {
|
|
25
26
|
assert(data != nullptr && "FastVectoryCopy: data cannot be null!");
|
|
26
27
|
|
|
@@ -145,9 +145,12 @@ BorrowingReference<jsi::Function> ObjectUtils::getGlobalFunction(jsi::Runtime& r
|
|
|
145
145
|
std::string stringKey = key;
|
|
146
146
|
auto iterator = functionCache.find(stringKey);
|
|
147
147
|
if (iterator != functionCache.end()) {
|
|
148
|
-
// We found it!
|
|
148
|
+
// We found it! Let's check if the reference is still valid...
|
|
149
149
|
BorrowingReference<jsi::Function> function = iterator->second;
|
|
150
|
-
|
|
150
|
+
if (function != nullptr) [[likely]] {
|
|
151
|
+
// It's still alive - let's use it from cache!
|
|
152
|
+
return function;
|
|
153
|
+
}
|
|
151
154
|
}
|
|
152
155
|
}
|
|
153
156
|
// We haven't found the function with the given key in cache - so let's get it:
|
|
@@ -10,7 +10,7 @@ import Foundation
|
|
|
10
10
|
/// Holds instances of `std::shared_ptr<ArrayBuffer>`, which can be passed
|
|
11
11
|
/// between native and JS **without copy**.
|
|
12
12
|
///
|
|
13
|
-
/// See `data`, `size` and `
|
|
13
|
+
/// See `data`, `size` and `isOwner`.
|
|
14
14
|
public typealias ArrayBuffer = margelo.nitro.ArrayBufferHolder
|
|
15
15
|
|
|
16
16
|
@available(*, deprecated, renamed: "ArrayBuffer")
|
|
@@ -77,10 +77,10 @@ extension ArrayBuffer {
|
|
|
77
77
|
|
|
78
78
|
extension ArrayBuffer {
|
|
79
79
|
/**
|
|
80
|
-
* Copy the given `
|
|
80
|
+
* Copy the given `UnsafePointer<UInt8>` into a new **owning** `ArrayBuffer`.
|
|
81
81
|
*/
|
|
82
82
|
public static func copy(
|
|
83
|
-
of other:
|
|
83
|
+
of other: UnsafePointer<UInt8>,
|
|
84
84
|
size: Int
|
|
85
85
|
) -> ArrayBuffer {
|
|
86
86
|
// 1. Create new `UnsafeMutablePointer<UInt8>`
|
|
@@ -94,18 +94,6 @@ extension ArrayBuffer {
|
|
|
94
94
|
return ArrayBuffer.wrap(copy, size, deleteFunc)
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
/**
|
|
98
|
-
* Copy the given `UnsafeMutableRawPointer` into a new **owning** `ArrayBuffer`.
|
|
99
|
-
*/
|
|
100
|
-
public static func copy(
|
|
101
|
-
of other: UnsafeMutableRawPointer,
|
|
102
|
-
size: Int
|
|
103
|
-
) -> ArrayBuffer {
|
|
104
|
-
return ArrayBuffer.copy(
|
|
105
|
-
of: other.assumingMemoryBound(to: UInt8.self),
|
|
106
|
-
size: size)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
97
|
/**
|
|
110
98
|
* Copy the given `ArrayBuffer` into a new **owning** `ArrayBuffer`.
|
|
111
99
|
*/
|
|
@@ -161,3 +149,19 @@ extension ArrayBuffer {
|
|
|
161
149
|
}
|
|
162
150
|
}
|
|
163
151
|
}
|
|
152
|
+
|
|
153
|
+
// pragma MARK: Helper
|
|
154
|
+
|
|
155
|
+
extension ArrayBuffer {
|
|
156
|
+
/**
|
|
157
|
+
* Returns an **owning** version of this `ArrayBuffer`.
|
|
158
|
+
* If this `ArrayBuffer` already is **owning**, it is returned as-is.
|
|
159
|
+
* If this `ArrayBuffer` is **non-owning**, it is _copied_.
|
|
160
|
+
*/
|
|
161
|
+
public func asOwning() -> ArrayBuffer {
|
|
162
|
+
if !isOwner {
|
|
163
|
+
return ArrayBuffer.copy(of: self)
|
|
164
|
+
}
|
|
165
|
+
return self
|
|
166
|
+
}
|
|
167
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-modules",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.2",
|
|
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",
|