1# Working with ArrayBuffer Using Node-API 2 3## Introduction 4 5**ArrayBuffer** in ArkTS is a type of object that represents a generic, fixed-length buffer of raw binary data. It provides a way to effectively represent and manipulate raw binary data in ArkTS. 6 7## Basic Concepts 8 9- **ArrayBuffer**: An **ArrayBuffer** object represents a generic, fixed-length buffer of raw binary data. The **ArrayBuffer** content cannot be directly operated. Instead, you need to use a **TypedArray** or **DataView** object to interpret the buffer data in specific formats. **ArrayBuffer** is used to process a large amount of binary data, such as files and network data packets. 10 11## Available APIs 12 13The following table lists the APIs used to manipulate data of the **ArrayBuffer** type. 14 15| API| Description| 16| -------- | -------- | 17| napi_is_arraybuffer | Checks whether a value is an **ArrayBuffer** object. Note that this API cannot be used to check whether a value is a **TypedArray** object. To check whether a value is a **TypedArray** object, use **napi_is_typedarray**.| 18| napi_get_arraybuffer_info | Obtains information of an **ArrayBuffer** object, including the pointer to the data and the data length.| 19| napi_detach_arraybuffer | Detaches the underlying data from an **ArrayBuffer** object. After the data is detached, you can operate the data in C/C++.| 20| napi_is_detached_arraybuffer | Checks whether an **ArrayBuffer** object has been detached.| 21| napi_create_arraybuffer | Creates an ArkTS **ArrayBuffer** object with the specified byte length.| 22 23## Example 24 25If you are just starting out with Node-API, see [Node-API Development Process](use-napi-process.md). The following demonstrates only the C++ and ArkTS code related to **ArrayBuffer** management. 26 27### napi_is_arraybuffer 28 29Call **napi_is_arraybuffer** to check whether a JS value is an **ArrayBuffer** object. 30 31CPP code: 32 33```cpp 34#include "napi/native_api.h" 35 36static napi_value IsArrayBuffer(napi_env env, napi_callback_info info) 37{ 38 // Obtain a parameter. 39 size_t argc = 1; 40 napi_value args[1] = {nullptr}; 41 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 42 // Call napi_is_arraybuffer to check whether the input parameter is an **ArrayBuffer** object. 43 bool result = false; 44 napi_status status = napi_is_arraybuffer(env, args[0], &result); 45 if (status != napi_ok) { 46 napi_throw_error(env, nullptr, "Node-API napi_is_arraybuffer fail"); 47 return nullptr; 48 } 49 // Convert the result to napi_value and return it. 50 napi_value returnValue = nullptr; 51 napi_get_boolean(env, result, &returnValue); 52 return returnValue; 53} 54``` 55 56API declaration: 57 58```ts 59// index.d.ts 60export const isArrayBuffer: <T>(arrayBuffer: T) => boolean | void; 61``` 62 63ArkTS code: 64 65```ts 66import hilog from '@ohos.hilog'; 67import testNapi from 'libentry.so'; 68try { 69 let value = new ArrayBuffer(1); 70 let data = "123"; 71 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_arraybuffer: %{public}s', testNapi.isArrayBuffer(value)); 72 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_arraybuffer: %{public}s', testNapi.isArrayBuffer(data)); 73} catch (error) { 74 hilog.error(0x0000, 'testTag', 'Test Node-API napi_is_arraybuffer error: %{public}s', error.message); 75} 76``` 77 78Log output: 79Test Node-API napi_is_arraybuffer: true 80Test Node-API napi_is_arraybuffer: false 81 82### napi_get_arraybuffer_info 83 84Call **napi_get_arraybuffer_info** to obtain the underlying data buffer and length of an **ArrayBuffer** object. 85 86CPP code: 87 88```cpp 89#include "napi/native_api.h" 90 91static napi_value GetArrayBufferInfo(napi_env env, napi_callback_info info) 92{ 93 size_t argc = 1; 94 napi_value args[1] = {nullptr}; 95 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 96 // Check whether the parameter is an ArrayBuffer object. 97 bool isArrayBuffer = false; 98 napi_is_arraybuffer(env, args[0], &isArrayBuffer); 99 if (!isArrayBuffer) { 100 napi_throw_type_error(env, nullptr, "Argument must be an ArrayBuffer"); 101 return nullptr; 102 } 103 104 void *data = nullptr; 105 size_t byteLength = 0; 106 // Obtain the underlying data buffer and length of the ArrayBuffer object. 107 napi_status status = napi_get_arraybuffer_info(env, args[0], &data, &byteLength); 108 if (status != napi_ok) { 109 napi_throw_error(env, nullptr, "Failed to get ArrayBuffer info"); 110 return nullptr; 111 } 112 // Create a result object. 113 napi_value result = nullptr; 114 napi_create_object(env, &result); 115 // Set the byte length property of the data buffer. 116 napi_value byteLengthValue = nullptr; 117 napi_create_uint32(env, byteLength, &byteLengthValue); 118 napi_set_named_property(env, result, "byteLength", byteLengthValue); 119 napi_value bufferData; 120 void *newData = nullptr; 121 napi_create_arraybuffer(env, byteLength, &newData, &bufferData); 122 napi_set_named_property(env, result, "buffer", bufferData); 123 return result; 124} 125``` 126 127API declaration: 128 129```ts 130// index.d.ts 131export class ArrayBufferInfo { 132 byteLength: number; 133 buffer: ArrayBuffer; 134} 135export const getArrayBufferInfo: (data: ArrayBuffer) => ArrayBufferInfo | void; 136``` 137 138ArkTS code: 139 140```ts 141import hilog from '@ohos.hilog'; 142import testNapi from 'libentry.so'; 143 144const buffer = new ArrayBuffer(10); 145hilog.info(0x0000, 'testTag', 'Test Node-API get_arrayBuffer_info:%{public}s ', JSON.stringify(testNapi.getArrayBufferInfo(buffer))); 146``` 147 148Log output: 149Test Node-API get_arrayBuffer_info:{"byteLength":10,"buffer":{}} 150 151### napi_detach_arraybuffer 152 153Call **napi_detach_arraybuffer** to detach the underlying data from an **ArrayBuffer** object. 154 155### napi_is_detached_arraybuffer 156 157Call **napi_is_detached_arraybuffer** to check whether an **ArrayBuffer** object has been detached. 158 159CPP code: 160 161```cpp 162#include "napi/native_api.h" 163 164static napi_value DetachedArrayBuffer(napi_env env, napi_callback_info info) 165{ 166 // Call napi_detach_arraybuffer to detach the underlying data from an ArrayBuffer object. 167 size_t argc = 1; 168 napi_value args[1] = {nullptr}; 169 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 170 napi_value arrayBuffer = args[0]; 171 napi_detach_arraybuffer(env, arrayBuffer); 172 // Pass out the detached ArrayBuffer object. 173 return arrayBuffer; 174} 175 176static napi_value IsDetachedArrayBuffer(napi_env env, napi_callback_info info) 177{ 178 // Call napi_is_detached_arraybuffer to check whether the specified ArrayBuffer object has been detached. 179 size_t argc = 1; 180 napi_value args[1] = {nullptr}; 181 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 182 napi_value arrayBuffer = args[0]; 183 bool result = false; 184 napi_is_detached_arraybuffer(env, arrayBuffer, &result); 185 // Call napi_get_boolean to convert the return value to napi_value, and pass out the napi_value for printing. 186 napi_value returnValue; 187 napi_get_boolean(env, result, &returnValue); 188 return returnValue; 189} 190``` 191 192API declaration: 193 194```ts 195// index.d.ts 196export const detachedArrayBuffer: (buffer:ArrayBuffer) => ArrayBuffer; 197export const isDetachedArrayBuffer: (arrayBuffer: ArrayBuffer) => boolean; 198``` 199 200ArkTS code: 201 202```ts 203import hilog from '@ohos.hilog'; 204import testNapi from 'libentry.so'; 205try { 206 const bufferArray = new ArrayBuffer(8); 207 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_detached_arraybuffer one: %{public}s', testNapi.isDetachedArrayBuffer(bufferArray)); 208 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_detached_arraybuffer two: %{public}s ', testNapi.isDetachedArrayBuffer(testNapi.detachedArrayBuffer(bufferArray))); 209} catch (error) { 210 hilog.error(0x0000, 'testTag', 'Test Node-API napi_is_detached_arraybuffer error: %{public}s', error.message); 211} 212``` 213 214Log output: 215Test Node-API napi_is_detached_arraybuffer one: false 216Test Node-API napi_is_detached_arraybuffer two: true 217 218### napi_create_arraybuffer 219 220Call **napi_create_arraybuffer** to create an ArkTS **ArrayBuffer** object with the specified byte length in C/C++. If the caller wants to directly operate the buffer, return the underlying buffer to the caller. To write data to this buffer from ArkTS, you need to create a **TypedArray** or **DataView** object. 221 222> **NOTE** 223> 224> If **byte_length** of **napi_create_arraybuffer** is **0** or an excessively large value, nullptr will be returned in **data**. Therefore, it is necessary to check whether **data** is empty before using it. 225 226CPP code: 227 228```cpp 229#include "napi/native_api.h" 230 231static napi_value CreateArrayBuffer(napi_env env, napi_callback_info info) 232{ 233 size_t argc = 1; 234 napi_value argv[1] = {nullptr}; 235 napi_value result = nullptr; 236 // Parse the input parameters. 237 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 238 int32_t value; 239 size_t length; 240 // Convert the parameter passed from ArkTS to the size_t type and use it as the parameter of napi_create_arraybuffer. 241 napi_get_value_int32(env, argv[0], &value); 242 length = size_t(value); 243 void *data; 244 // Create an ArrayBuffer object. 245 napi_create_arraybuffer(env, length, &data, &result); 246 if (data != nullptr) { 247 // Check data before using it for subsequent operations. 248 } 249 // Return the ArrayBuffer object. 250 return result; 251} 252``` 253 254API declaration: 255 256```ts 257// index.d.ts 258export const createArrayBuffer: (size: number) => ArrayBuffer; 259``` 260 261ArkTS code: 262 263```ts 264import hilog from '@ohos.hilog'; 265import testNapi from 'libentry.so'; 266 267hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_arraybuffer:%{public}s', testNapi.createArrayBuffer(10).toString()); 268``` 269 270To print logs in the native CPP, add the following information to the **CMakeLists.txt** file and add the header file by using **#include "hilog/log.h"**. 271 272```text 273// CMakeLists.txt 274add_definitions( "-DLOG_DOMAIN=0xd0d0" ) 275add_definitions( "-DLOG_TAG=\"testTag\"" ) 276target_link_libraries(entry PUBLIC libhilog_ndk.z.so) 277``` 278 279Log output: 280Test Node-API napi_create_arraybuffer:[object ArrayBuffer] 281 282## NOTE 283 284- Lifecycle and memory management: When using Node-API to process **ArrayBuffer** objects, note that the lifecycle of the buffer data segment of the **void*** type is managed by the engine and [cannot be deleted by users. Otherwise, a double free error may occur](napi-guidelines.md#avoiding-releasing-the-obtained-buffer-repeatedly). 285