1# Working with Buffer Using Node-API 2 3## Introduction 4 5In ArkTS, **Buffer** is a data type used to represent binary data. 6 7## Basic Concepts 8 9Node-API provides APIs for handling binary data with ArkTS via the **Buffer** object. You can use these APIs to create, manipulate, and pass **Buffer** objects to ArkTS when processing and transferring binary data in file I/O and network transmission. 10 11- **Buffer** object: an object used to represent binary data. 12- External buffer: a buffer created in the Node-API module to associate with existing data without copying the data. 13 14## Available APIs 15 16The following table lists the APIs for processing the binary data in the ArkTS layer, such as file I/O and network transmission. 17| API| Description| 18| -------- | -------- | 19| napi_create_buffer | Creates an ArkTS **Buffer** instance of the specified size.| 20| napi_create_buffer_copy | Creates and obtains an ArkTS **Buffer** instance of the specified size and initializes the **Buffer** instance with the given parameters.| 21| napi_create_external_buffer | Creates an ArkTS **Buffer** instance of the specified size, and initializes it with the given data. You can use this API to add extra data to the buffer. | 22| napi_get_buffer_info | Obtains the underlying data of an ArkTS **Buffer** instance and its length.| 23| napi_is_buffer | Checks whether the given ArkTS value is a **Buffer** object.| 24| napi_create_external_arraybuffer | Creates an ArkTS external **ArrayBuffer**. An external **ArrayBuffer** is a special type of **ArrayBuffer** that holds the reference to external data without actually owning the data.| 25 26## Example 27 28If 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 **Buffer** management. 29 30### napi_create_buffer 31 32Use **napi_create_buffer** to create a **Buffer** instance. A **Buffer** object is used to manipulate binary data in C/C++. 33 34CPP code: 35 36```cpp 37#include <string> 38#include "napi/native_api.h" 39 40static napi_value CreateBuffer(napi_env env, napi_callback_info info) 41{ 42 std::string str("CreateBuffer"); 43 void *bufferPtr = nullptr; 44 size_t bufferSize = str.size(); 45 napi_value buffer = nullptr; 46 // Call napi_create_buffer to create an ArkTS Buffer instance with the specified size. 47 napi_create_buffer(env, bufferSize, &bufferPtr, &buffer); 48 // Copy the value of str to the Buffer memory. 49 strcpy((char *)bufferPtr, str.data()); 50 return buffer; 51} 52``` 53 54API declaration: 55 56```ts 57// index.d.ts 58export const createBuffer: () => string; 59``` 60 61ArkTS code: 62 63```ts 64import hilog from '@ohos.hilog' 65import testNapi from 'libentry.so' 66try { 67 hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_buffer: %{public}s', testNapi.createBuffer().toString()); 68} catch (error) { 69 hilog.error(0x0000, 'testTag', 'Test Node-API napi_create_buffer error'); 70} 71``` 72 73### napi_create_buffer_copy 74 75Use **napi_create_buffer_copy** to create a **Buffer** instance of the specified size and initialize it with data copied from the passed-in buffer. This API allows the specified data to be copied to a **Buffer** instance created. 76 77CPP code: 78 79```cpp 80#include <string> 81#include "hilog/log.h" 82#include "napi/native_api.h" 83 84static napi_value CreateBufferCopy(napi_env env, napi_callback_info info) 85{ 86 // Data to copy. 87 std::string str("CreateBufferCopy"); 88 napi_value buffer = nullptr; 89 // Call napi_create_buffer_copy to create a Buffer instance and copy the content of str to the Buffer. 90 void* resultData = nullptr; 91 napi_create_buffer_copy(env, str.size(), str.data(), &resultData, &buffer); 92 OH_LOG_INFO(LOG_APP, "Node-API resultData is : %{public}s.", resultData); 93 return buffer; 94} 95``` 96 97API declaration: 98 99```ts 100// index.d.ts 101export const createBufferCopy: () => string; 102``` 103 104ArkTS code: 105 106```ts 107import hilog from '@ohos.hilog' 108import testNapi from 'libentry.so' 109try { 110 hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_buffer_copy: %{public}s', testNapi.createBufferCopy().toString()); 111} catch (error) { 112 hilog.error(0x0000, 'testTag', 'Test Node-API napi_create_buffer_copy error'); 113} 114``` 115 116### napi_create_external_buffer 117 118Use **napi_create_external_buffer** to create an ArkTS **Buffer** instance that holds a pointer to existing data. This allows the data to be directly accessed and manipulated from ArkTS, improving performance while avoiding additional memory allocation and data copy. 119 120CPP code: 121 122```cpp 123#include <malloc.h> 124#include <string> 125#include "napi/native_api.h" 126 127// Callback used to release memory. 128void FinalizeCallback(napi_env env, void *data, void *hint) 129{ 130 if (data == nullptr) { 131 return; 132 } 133 free(data); 134 data = nullptr; 135} 136 137static napi_value CreateExternalBuffer(napi_env env, napi_callback_info info) 138{ 139 // Create a string. 140 std::string str("CreateExternalBuffer"); 141 // Allocate memory of the string length on the heap. 142 void* data = malloc(str.size()); 143 // Copy the string to the allocated memory. 144 strcpy((char *)(data), (char*)(str.data())); 145 // Use napi_create_external_buffer to create a Buffer instance of the specified size. 146 napi_value buffer = nullptr; 147 napi_create_external_buffer(env, str.size(), data, FinalizeCallback, nullptr, &buffer); 148 return buffer; 149} 150``` 151 152API declaration: 153 154```ts 155// index.d.ts 156export const createExternalBuffer: () => string; 157``` 158 159ArkTS code: 160 161```ts 162import hilog from '@ohos.hilog' 163import testNapi from 'libentry.so' 164try { 165 hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_external_buffer: %{public}s', testNapi.createExternalBuffer() 166 .toString()); 167} catch (error) { 168 hilog.error(0x0000, 'testTag', 'Test Node-API napi_create_external_buffer error'); 169} 170``` 171 172### napi_get_buffer_info 173 174Before performing an operation on the data in a **Buffer** instance in ArkTS, use **napi_get_buffer_info** to obtain the pointer to the data and the data length. This allows the data to be operated without copying data. 175 176CPP code: 177 178```cpp 179#include <string> 180#include "napi/native_api.h" 181 182static napi_value GetBufferInfo(napi_env env, napi_callback_info info) 183{ 184 // Create a string. 185 std::string str("GetBufferInfo"); 186 napi_value buffer = nullptr; 187 void *bufferPtr = nullptr; 188 size_t bufferSize = str.size(); 189 napi_create_buffer(env, bufferSize, &bufferPtr, &buffer); 190 strcpy((char *)bufferPtr, str.data()); 191 192 // Obtain the Buffer information. 193 void *tmpBufferPtr = nullptr; 194 size_t bufferLength = 0; 195 napi_get_buffer_info(env, buffer, &tmpBufferPtr, &bufferLength); 196 197 // Create an ArkTS string to save the Buffer content and return it. 198 napi_value returnValue = nullptr; 199 napi_create_string_utf8(env, (char*)tmpBufferPtr, bufferLength, &returnValue); 200 return returnValue; 201} 202``` 203 204API declaration: 205 206```ts 207// index.d.ts 208export const getBufferInfo: () => string; 209``` 210 211ArkTS code: 212 213```ts 214import hilog from '@ohos.hilog' 215import testNapi from 'libentry.so' 216try { 217 hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_buffer_info: %{public}s', testNapi.getBufferInfo().toString()); 218} catch (error) { 219 hilog.error(0x0000, 'testTag', 'Test Node-API napi_get_buffer_info error'); 220} 221``` 222 223### napi_is_buffer 224 225Use **napi_is_buffer** to check whether an ArkTS value is a **Buffer** object. 226 227CPP code: 228 229```cpp 230#include <string> 231#include "napi/native_api.h" 232 233static napi_value IsBuffer(napi_env env, napi_callback_info info) 234{ 235 // Create a Buffer object. 236 std::string str = "buffer"; 237 napi_value buffer = nullptr; 238 napi_create_buffer(env, strlen(str.data()), (void **)(str.data()), &buffer); 239 240 //Call napi_is_buffer to check whether the created object is a Buffer. 241 bool reslut = false; 242 napi_is_buffer(env, buffer, &reslut); 243 // Return the result. 244 napi_value returnValue = nullptr; 245 napi_get_boolean(env, reslut, &returnValue); 246 return returnValue; 247} 248``` 249 250API declaration: 251 252```ts 253// index.d.ts 254export const isBuffer: () => boolean; 255``` 256 257ArkTS code: 258 259```ts 260import hilog from '@ohos.hilog' 261import testNapi from 'libentry.so' 262try { 263 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_buffer: %{public}s', JSON.stringify(testNapi.isBuffer())); 264} catch (error) { 265 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_buffer error'); 266} 267``` 268 269### napi_create_external_arraybuffer 270 271Use **napi_create_external_arraybuffer** to create an ArkTS **ArrayBuffer** with external data. 272 273CPP code: 274 275```cpp 276#include "napi/native_api.h" 277 278typedef struct { 279 uint8_t *data; 280 size_t length; 281} BufferData; 282 283void FinalizeCallback(napi_env env, void *finalize_data, void *finalize_hint) 284{ 285 // Obtain the finalized data. 286 BufferData *bufferData = static_cast<BufferData *>(finalize_data); 287 288 // Perform the cleanup operation, for example, release memory. 289 delete[] bufferData->data; 290 delete bufferData; 291} 292 293napi_value CreateExternalArraybuffer(napi_env env, napi_callback_info info) 294{ 295 // Create a C++ array with five elements. 296 uint8_t *dataArray = new uint8_t[5]{1, 2, 3, 4, 5}; 297 napi_value externalBuffer = nullptr; 298 BufferData *bufferData = new BufferData{dataArray, 5}; 299 300 // Call napi_create_external_arraybuffer to create an external ArrayBuffer instance and specify the callback to be invoked when the ArrayBuffer object is garbage-collected. 301 napi_status status = 302 napi_create_external_arraybuffer(env, dataArray, 5, FinalizeCallback, bufferData, &externalBuffer); 303 if (status != napi_ok) { 304 // Error handling. 305 napi_throw_error(env, nullptr, "Node-API napi_create_external_arraybuffer fail"); 306 return nullptr; 307 } 308 napi_value outputArray; 309 // Use napi_create_typedarray to create a TypedArray object and pass the external buffer object as a parameter. 310 status = napi_create_typedarray(env, napi_int8_array, 5, externalBuffer, 0, &outputArray); 311 if (status != napi_ok) { 312 // Error handling. 313 napi_throw_error(env, nullptr, "Node-API napi_create_typedarray fail"); 314 return nullptr; 315 } 316 return outputArray; 317} 318``` 319 320API declaration: 321 322```ts 323// index.d.ts 324export const createExternalArraybuffer: () => ArrayBuffer | void; 325``` 326 327ArkTS code: 328 329```ts 330import hilog from '@ohos.hilog' 331import testNapi from 'libentry.so' 332 333hilog.info(0x0000, 'testTag', 'Node-API createExternalArraybuffer: %{public}s', 334 JSON.stringify(testNapi.createExternalArraybuffer())); 335``` 336 337To 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"**. 338 339```text 340// CMakeLists.txt 341add_definitions( "-DLOG_DOMAIN=0xd0d0" ) 342add_definitions( "-DLOG_TAG=\"testTag\"" ) 343target_link_libraries(entry PUBLIC libhilog_ndk.z.so) 344``` 345