1# Working with ArrayBuffer Using JSVM-API
2
3## Introduction
4
5**ArrayBuffer** in JavaScript (JS) 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 JS.
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 **ArrayBuffer** with JSVM-API, pay special attention to lifecycle and memory management.
11
12## Available APIs
13
14| API                        | Description                                  |
15| ---------------------------- | ------------------------------------------ |
16| OH_JSVM_GetArraybufferInfo    | Obtains the underlying data buffer of an **ArrayBuffer** and its length.|
17| OH_JSVM_IsArraybuffer        | Checks whether a JS object is an **ArrayBuffer** object.       |
18| OH_JSVM_DetachArraybuffer    | Calls the **Detach()** operation of an **ArrayBuffer** object.           |
19| OH_JSVM_IsDetachedArraybuffer | Checks whether an **ArrayBuffer** object has been detached.       |
20| OH_JSVM_CreateArraybuffer      | Creates an **ArrayBuffer** object of the specified size.  |
21
22## Example
23
24If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ code involved in **ArrayBuffer** development.
25
26### OH_JSVM_GetArraybufferInfo
27
28Use **OH_JSVM_GetArraybufferInfo** to obtain the underlying data buffer of an **ArrayBuffer** object and its length.
29
30CPP code:
31
32```cpp
33// hello.cpp
34#include "napi/native_api.h"
35#include "ark_runtime/jsvm.h"
36#include <hilog/log.h>
37// Define OH_JSVM_GetArraybufferInfo.
38static JSVM_Value GetArraybufferInfo(JSVM_Env env, JSVM_CallbackInfo info)
39{
40    size_t argc = 1;
41    JSVM_Value args[1] = {nullptr};
42    // Parse the input parameters.
43    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
44    // Check whether the parameter is an ArrayBuffer object.
45    bool isArrayBuffer = false;
46    OH_JSVM_IsArraybuffer(env, args[0], &isArrayBuffer);
47    if (!isArrayBuffer) {
48        OH_LOG_ERROR(LOG_APP, "JSVM GetArraybufferInfo isArrayBuffer:false");
49    }
50    void *data;
51    size_t byteLength;
52    // Obtain the underlying data buffer and length of the ArrayBuffer object.
53    JSVM_Status status = OH_JSVM_GetArraybufferInfo(env, args[0], &data, &byteLength);
54    if (status != JSVM_OK) {
55        OH_LOG_ERROR(LOG_APP, "JSVM GetArraybufferInfo: failed");
56    } else {
57        OH_LOG_INFO(LOG_APP, "JSVM GetArraybufferInfo: success");
58    }
59    return args[0];
60}
61// Register the GetArraybufferInfo callback.
62static JSVM_CallbackStruct param[] = {
63    {.data = nullptr, .callback = GetArraybufferInfo},
64};
65static JSVM_CallbackStruct *method = param;
66// Set a property descriptor named getArraybufferInfo and associate it with a callback. This allows the GetArraybufferInfo callback to be called from JS.
67static JSVM_PropertyDescriptor descriptor[] = {
68    {"getArraybufferInfo", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
69};
70// Call the C++ code from JS.
71const char *srcCallNative = R"JS(
72getArraybufferInfo(new ArrayBuffer(10));
73)JS";
74```
75
76### OH_JSVM_IsArraybuffer
77
78Use **OH_JSVM_IsArraybuffer** to check whether a JS object is an **ArrayBuffer** object.
79
80CPP code:
81
82```cpp
83// hello.cpp
84#include "napi/native_api.h"
85#include "ark_runtime/jsvm.h"
86#include <hilog/log.h>
87// Define OH_JSVM_IsArraybuffer.
88static JSVM_Value IsArrayBuffer(JSVM_Env env, JSVM_CallbackInfo info)
89{
90    size_t argc = 1;
91    JSVM_Value args[1] = {nullptr};
92    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
93    // Call OH_JSVM_IsArraybuffer to check whether the input parameter is an ArrayBuffer object.
94    bool isArrayBuffer = false;
95    JSVM_Status status = OH_JSVM_IsArraybuffer(env, args[0], &isArrayBuffer);
96    if (status != JSVM_OK) {
97        OH_LOG_ERROR(LOG_APP, "JSVM IsArrayBuffer: failed");
98    } else {
99        OH_LOG_INFO(LOG_APP, "JSVM IsArrayBuffer: success");
100        OH_LOG_INFO(LOG_APP, "JSVM IsArrayBuffer: %{public}d", isArrayBuffer);
101    }
102    JSVM_Value boolean = nullptr;
103    OH_JSVM_GetBoolean(env, isArrayBuffer, &boolean);
104    return boolean;
105}
106// Register the IsArrayBuffer callback.
107static JSVM_CallbackStruct param[] = {
108    {.data = nullptr, .callback = IsArrayBuffer},
109};
110static JSVM_CallbackStruct *method = param;
111// Set a property descriptor named isArrayBuffer and associate it with a callback. This allows the IsArrayBuffer callback to be called from JS.
112static JSVM_PropertyDescriptor descriptor[] = {
113    {"isArrayBuffer", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
114};
115// Call the C++ code from JS.
116const char *srcCallNative = R"JS(
117isArrayBuffer(new ArrayBuffer(8));
118)JS";
119```
120
121### OH_JSVM_DetachArraybuffer
122
123Use **OH_JSVM_DetachArraybuffer** to call the **Detach()** operation of an **ArrayBuffer** object.
124
125### OH_JSVM_IsDetachedArraybuffer
126
127Use **OH_JSVM_IsDetachedArraybuffer** to check whether an **ArrayBuffer** object has been detached.
128
129CPP code:
130
131```cpp
132// hello.cpp
133#include "napi/native_api.h"
134#include "ark_runtime/jsvm.h"
135#include <hilog/log.h>
136// Define OH_JSVM_DetachArraybuffer and OH_JSVM_IsDetachedArraybuffer.
137static JSVM_Value DetachArraybuffer(JSVM_Env env, JSVM_CallbackInfo info)
138{
139    size_t argc = 1;
140    JSVM_Value args[1] = {nullptr};
141    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
142    JSVM_Value arraybuffer = args[0];
143    JSVM_Status status = OH_JSVM_DetachArraybuffer(env, arraybuffer);
144    if (status != JSVM_OK) {
145        OH_LOG_ERROR(LOG_APP, "JSVM DetachArraybuffer: failed");
146    } else {
147        OH_LOG_INFO(LOG_APP, "JSVM DetachArraybuffer: success");
148    }
149    return arraybuffer;
150}
151static JSVM_Value IsDetachedArraybuffer(JSVM_Env env, JSVM_CallbackInfo info)
152{
153    size_t argc = 1;
154    JSVM_Value args[1] = {nullptr};
155    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
156    JSVM_Value arraybuffer = args[0];
157    OH_JSVM_DetachArraybuffer(env, arraybuffer);
158    bool result = false;
159    JSVM_Status status = OH_JSVM_IsDetachedArraybuffer(env, arraybuffer, &result);
160    if (status != JSVM_OK) {
161        OH_LOG_ERROR(LOG_APP, "JSVM IsDetachedArraybuffer: failed");
162    } else {
163        OH_LOG_INFO(LOG_APP, "JSVM IsDetachedArraybuffer: success");
164        OH_LOG_INFO(LOG_APP, "JSVM IsArrayBuffer: %{public}d", result);
165    }
166    JSVM_Value isDetached = nullptr;
167    OH_JSVM_GetBoolean(env, result, &isDetached);
168    return isDetached;
169}
170// Register the DetachArraybuffer and IsDetachedArraybuffer callbacks.
171static JSVM_CallbackStruct param[] = {
172    {.data = nullptr, .callback = DetachArraybuffer},
173    {.data = nullptr, .callback = IsDetachedArraybuffer},
174};
175static JSVM_CallbackStruct *method = param;
176// Set property descriptors named DetachArraybuffer and IsDetachedArraybuffer, and associate them with a callback each. This allows the DetachArraybuffer and IsDetachedArraybuffer callbacks to be called from JS.
177static JSVM_PropertyDescriptor descriptor[] = {
178    {"detachArraybuffer", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
179    {"isDetachedArraybuffer", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
180};
181// Call the C++ code from JS.
182const char *srcCallNative = R"JS(
183let arrayBuffer = new ArrayBuffer(10);
184detachArraybuffer(arrayBuffer);
185isDetachedArraybuffer(arrayBuffer);
186)JS";
187```
188
189### OH_JSVM_CreateArraybuffer
190
191Use **OH_JSVM_CreateArraybuffer** to create an **ArrayBuffer** object of the specified size.
192
193CPP code:
194
195```cpp
196// hello.cpp
197#include "napi/native_api.h"
198#include "ark_runtime/jsvm.h"
199#include <hilog/log.h>
200// Define OH_JSVM_CreateArraybuffer.
201static JSVM_Value CreateArraybuffer(JSVM_Env env, JSVM_CallbackInfo info)
202{
203    size_t argc = 1;
204    JSVM_Value argv[1] = {nullptr};
205    JSVM_Value result = nullptr;
206    // Parse the input parameters.
207    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
208    int32_t value;
209    size_t length;
210    OH_JSVM_GetValueInt32(env, argv[0], &value);
211    length = size_t(value);
212    void *data;
213    // Create an ArrayBuffer object.
214    JSVM_Status status = OH_JSVM_CreateArraybuffer(env, length, &data, &result);
215    if (status != JSVM_OK) {
216        OH_LOG_ERROR(LOG_APP, "JSVM CreateArraybuffer: failed");
217    } else {
218        OH_LOG_INFO(LOG_APP, "JSVM CreateArraybuffer: success");
219        OH_LOG_INFO(LOG_APP, "JSVM ArrayBuffer length: %{public}d", length);
220    }
221    // Return the created ArrayBuffer.
222    return result;
223}
224// Register the CreateArraybuffer callback.
225static JSVM_CallbackStruct param[] = {
226    {.data = nullptr, .callback = CreateArraybuffer},
227};
228static JSVM_CallbackStruct *method = param;
229// Set a property descriptor named createArraybuffer and associate it with a callback. This allows the CreateArraybuffer callback to be called from JS.
230static JSVM_PropertyDescriptor descriptor[] = {
231    {"createArraybuffer", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
232};
233// Call the C++ code from JS.
234const char *srcCallNative = R"JS(
235createArraybuffer(8);
236)JS";
237```
238