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- Lifecycle and memory management: When using Node-API to process **ArrayBuffer** objects, note that the lifecycle of the created **arrayBufferPtr** is managed by the engine and cannot be deleted by users. Otherwise, a double free error may occur. 11 12## Available APIs 13 14The following table lists the APIs used to manipulate data of the **ArrayBuffer** type. 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 29Use **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 78### napi_get_arraybuffer_info 79 80Use **napi_get_arraybuffer_info** to obtain the underlying data buffer and length of an **ArrayBuffer** object. 81 82CPP code: 83 84```cpp 85#include "napi/native_api.h" 86 87static napi_value GetArraybufferInfo(napi_env env, napi_callback_info info) 88{ 89 size_t argc = 1; 90 napi_value args[1] = {nullptr}; 91 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 92 // Check whether the parameter is an ArrayBuffer object. 93 bool isArraybuffer = false; 94 napi_is_arraybuffer(env, args[0], &isArraybuffer); 95 if (!isArraybuffer) { 96 napi_throw_type_error(env, nullptr, "Argument must be an ArrayBuffer"); 97 return nullptr; 98 } 99 100 void *data = nullptr; 101 size_t byteLength = 0; 102 // Obtain the underlying data buffer and length of the ArrayBuffer object. 103 napi_status status = napi_get_arraybuffer_info(env, args[0], &data, &byteLength); 104 if (status != napi_ok) { 105 napi_throw_error(env, nullptr, "Failed to get ArrayBuffer info"); 106 return nullptr; 107 } 108 // Create a result object. 109 napi_value result = nullptr; 110 napi_create_object(env, &result); 111 // Set the byte length property of the data buffer. 112 napi_value byteLengthValue = nullptr; 113 napi_create_uint32(env, byteLength, &byteLengthValue); 114 napi_set_named_property(env, result, "byteLength", byteLengthValue); 115 napi_value bufferData; 116 napi_create_arraybuffer(env, byteLength, &data, &bufferData); 117 napi_set_named_property(env, result, "buffer", bufferData); 118 return result; 119} 120``` 121 122API declaration: 123 124```ts 125// index.d.ts 126export class ArrayBufferInfo { 127 byteLength: number; 128 buffer: Object; 129} 130export const getArraybufferInfo: (data: ArrayBuffer) => ArrayBufferInfo | void; 131``` 132 133ArkTS code: 134 135```ts 136import hilog from '@ohos.hilog' 137import testNapi from 'libentry.so' 138 139const buffer = new ArrayBuffer(10); 140hilog.info(0x0000, 'testTag', 'Test Node-API get_arraybuffer_info:%{public}s ', JSON.stringify(testNapi.getArraybufferInfo(buffer))); 141``` 142 143### napi_detach_arraybuffer 144 145Use **napi_detach_arraybuffer** to detach the underlying data from an **ArrayBuffer** object. 146 147### napi_is_detached_arraybuffer 148 149Use **napi_is_detached_arraybuffer** to check whether an **ArrayBuffer** object has been detached. 150 151CPP code: 152 153```cpp 154#include "napi/native_api.h" 155 156static napi_value DetachedArraybuffer(napi_env env, napi_callback_info info) 157{ 158 // Call napi_detach_arraybuffer to detach the underlying data from an ArrayBuffer object. 159 size_t argc = 1; 160 napi_value args[1] = {nullptr}; 161 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 162 napi_value arrayBuffer = args[0]; 163 napi_detach_arraybuffer(env, arrayBuffer); 164 // Pass out the detached ArrayBuffer object. 165 return arrayBuffer; 166} 167 168static napi_value IsDetachedArraybuffer(napi_env env, napi_callback_info info) 169{ 170 // Call napi_is_detached_arraybuffer to check whether the specified ArrayBuffer object has been detached. 171 size_t argc = 1; 172 napi_value args[1] = {nullptr}; 173 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 174 napi_value arrayBuffer = args[0]; 175 bool result = false; 176 napi_is_detached_arraybuffer(env, arrayBuffer, &result); 177 // Call napi_get_boolean to convert the return value to napi_value, and pass out the napi_value for printing. 178 napi_value returnValue; 179 napi_get_boolean(env, result, &returnValue); 180 return returnValue; 181} 182``` 183 184API declaration: 185 186```ts 187// index.d.ts 188export const detachedArraybuffer: (buffer:ArrayBuffer) => ArrayBuffer; 189export const isDetachedArraybuffer: (arrarBeffer: ArrayBuffer) => boolean; 190``` 191 192ArkTS code: 193 194```ts 195import hilog from '@ohos.hilog' 196import testNapi from 'libentry.so' 197try { 198 const bufferArray = new ArrayBuffer(8); 199 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_detached_arraybuffer one: %{public}s', testNapi.isDetachedArraybuffer(bufferArray)); 200 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_detached_arraybuffer two: %{public}s ', testNapi.isDetachedArraybuffer(testNapi.detachedArraybuffer(bufferArray))); 201} catch (error) { 202 hilog.error(0x0000, 'testTag', 'Test Node-API napi_is_detached_arraybuffer error: %{public}s', error.message); 203} 204``` 205 206### napi_create_arraybuffer 207 208Use **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. 209 210CPP code: 211 212```cpp 213#include "napi/native_api.h" 214 215static napi_value CreateArraybuffer(napi_env env, napi_callback_info info) 216{ 217 size_t argc = 1; 218 napi_value argv[1] = {nullptr}; 219 napi_value result = nullptr; 220 // Parse the input parameters. 221 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 222 int32_t value; 223 size_t length; 224 // Convert the parameter passed from ArkTS to the size_t type and use it as the parameter of napi_create_arraybuffer. 225 napi_get_value_int32(env, argv[0], &value); 226 length = size_t(value); 227 void *data; 228 // Create an ArrayBuffer object. 229 napi_create_arraybuffer(env, length, &data, &result); 230 // Return the ArrayBuffer object. 231 return result; 232} 233``` 234 235API declaration: 236 237```ts 238// index.d.ts 239export const createArraybuffer: (size: number) => ArrayBuffer; 240``` 241 242ArkTS code: 243 244```ts 245import hilog from '@ohos.hilog' 246import testNapi from 'libentry.so' 247 248hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_arraybuffer:%{public}s', testNapi.createArraybuffer(10).toString()); 249``` 250 251To 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"**. 252 253```text 254// CMakeLists.txt 255add_definitions( "-DLOG_DOMAIN=0xd0d0" ) 256add_definitions( "-DLOG_TAG=\"testTag\"" ) 257target_link_libraries(entry PUBLIC libhilog_ndk.z.so) 258``` 259