From bd95643499b77d6ebedcac05a0c15a2697e05420 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Tue, 7 Jan 2025 16:20:06 +0100 Subject: [PATCH] feat: Add `copyIfNeeded` flag --- .../ios/core/ArrayBufferHolder.swift | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/react-native-nitro-modules/ios/core/ArrayBufferHolder.swift b/packages/react-native-nitro-modules/ios/core/ArrayBufferHolder.swift index 5e72cb5d5..aee85d626 100644 --- a/packages/react-native-nitro-modules/ios/core/ArrayBufferHolder.swift +++ b/packages/react-native-nitro-modules/ios/core/ArrayBufferHolder.swift @@ -126,16 +126,26 @@ public extension ArrayBufferHolder { public extension ArrayBufferHolder { /** * Wrap this `ArrayBufferHolder` in a `Data` instance, without performing a copy. + * - `copyIfNeeded`: If this `ArrayBuffer` is **non-owning**, the foreign + * data may needs to be copied to be safely used outside of the scope of the caller function. + * This flag controls that. */ - func toData() -> Data { - // 1. Get the std::shared_ptr - var sharedPointer = self.getArrayBuffer() - // 2. Create a Data object WRAPPING our pointer - return Data(bytesNoCopy: self.data, count: self.size, deallocator: .custom({ buffer, size in - // 3. Capture the std::shared_ptr in the deallocator lambda so it stays alive. - // As soon as this lambda gets called, the `sharedPointer` gets deleted causing the - // underlying `ArrayBuffer` to be freed. - sharedPointer.reset() - })) + func toData(copyIfNeeded: Bool) -> Data { + let shouldCopy = copyIfNeeded && !self.isOwner + if shouldCopy { + // COPY DATA + return Data.init(bytes: self.data, count: self.size) + } else { + // WRAP DATA + // 1. Get the std::shared_ptr + var sharedPointer = self.getArrayBuffer() + // 2. Create a Data object WRAPPING our pointer + return Data(bytesNoCopy: self.data, count: self.size, deallocator: .custom({ buffer, size in + // 3. Capture the std::shared_ptr in the deallocator lambda so it stays alive. + // As soon as this lambda gets called, the `sharedPointer` gets deleted causing the + // underlying `ArrayBuffer` to be freed. + sharedPointer.reset() + })) + } } }