• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ark_native_buffer.h"
17 #include "ark_native_array_buffer.h"
18 #include <memory>
19 #include <securec.h>
20 
21 #include "utils/log.h"
22 
23 using panda::BufferRef;
24 using panda::JSValueRef;
25 // The maximum length for NativaBuffer, default is 2MiB.
26 static constexpr size_t K_MAX_BYTE_LENGTH = 2097152;
27 static constexpr size_t ONE_MIB_BYTE_SIZE = 1048576;
28 
ArkNativeBuffer(ArkNativeEngine * engine,Local<JSValueRef> value)29 ArkNativeBuffer::ArkNativeBuffer(ArkNativeEngine* engine, Local<JSValueRef> value)
30     : ArkNativeObject(engine, value)
31 {
32 }
33 
ArkNativeBuffer(ArkNativeEngine * engine,uint8_t ** value,size_t length)34 ArkNativeBuffer::ArkNativeBuffer(ArkNativeEngine* engine, uint8_t** value, size_t length)
35     : ArkNativeBuffer(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
36 {
37     if (!value) {
38         HILOG_ERROR("value is empty");
39         return;
40     }
41 
42     if (length > K_MAX_BYTE_LENGTH) {
43         HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
44                     static_cast<float>(length) / static_cast<float>(ONE_MIB_BYTE_SIZE),
45                     static_cast<float>(K_MAX_BYTE_LENGTH) / static_cast<float>(ONE_MIB_BYTE_SIZE));
46         *value = nullptr;
47         return;
48     }
49 
50     auto vm = engine->GetEcmaVm();
51     LocalScope scope(vm);
52     value_ = Global<BufferRef>(vm, BufferRef::New(vm, length));
53     Global<BufferRef> obj = value_;
54     *value = reinterpret_cast<uint8_t*>(obj->GetBuffer());
55 }
56 
ArkNativeBuffer(ArkNativeEngine * engine,uint8_t ** value,size_t length,const uint8_t * data)57 ArkNativeBuffer::ArkNativeBuffer(ArkNativeEngine* engine, uint8_t** value, size_t length, const uint8_t* data)
58     : ArkNativeBuffer(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
59 {
60     if (!value) {
61         HILOG_ERROR("value is empty");
62         return;
63     }
64 
65     if (length > K_MAX_BYTE_LENGTH) {
66         HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
67                     static_cast<float>(length) / static_cast<float>(ONE_MIB_BYTE_SIZE),
68                     static_cast<float>(K_MAX_BYTE_LENGTH) / static_cast<float>(ONE_MIB_BYTE_SIZE));
69         *value = nullptr;
70         return;
71     }
72 
73     auto vm = engine->GetEcmaVm();
74     LocalScope scope(vm);
75     value_ = Global<BufferRef>(vm, BufferRef::New(vm, length));
76     Global<BufferRef> obj = value_;
77     *value = reinterpret_cast<uint8_t*>(obj->GetBuffer());
78     if (memcpy_s(*value, length, data, length) != EOK) {
79         HILOG_ERROR("memcpy_s failed");
80     }
81 }
82 
ArkNativeBuffer(ArkNativeEngine * engine,uint8_t * value,size_t length,NativeFinalize cb,void * hint)83 ArkNativeBuffer::ArkNativeBuffer(ArkNativeEngine* engine,
84                                  uint8_t* value,
85                                  size_t length,
86                                  NativeFinalize cb,
87                                  void* hint)
88     : ArkNativeBuffer(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
89 {
90     if (!value) {
91         HILOG_ERROR("value is empty");
92         return;
93     }
94 
95     if (length > K_MAX_BYTE_LENGTH) {
96         HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
97                     static_cast<float>(length) / static_cast<float>(ONE_MIB_BYTE_SIZE),
98                     static_cast<float>(K_MAX_BYTE_LENGTH) / static_cast<float>(ONE_MIB_BYTE_SIZE));
99         value = nullptr;
100         return;
101     }
102 
103     auto vm = engine->GetEcmaVm();
104     LocalScope scope(vm);
105 
106     std::unique_ptr<NativeObjectInfo> cbinfo(NativeObjectInfo::CreateNewInstance());
107     if (!cbinfo) {
108         HILOG_ERROR("cbinfo is nullptr");
109         return;
110     }
111     cbinfo->engine = engine_;
112     cbinfo->callback = cb;
113     cbinfo->hint = hint;
114 
115     Local<BufferRef> object = BufferRef::New(vm, value, length,
116         [](void* data, void* info) {
117             auto externalInfo = reinterpret_cast<NativeObjectInfo*>(info);
118             auto engine = externalInfo->engine;
119             auto callback = externalInfo->callback;
120             auto hint = externalInfo->hint;
121             if (callback != nullptr) {
122                 callback(engine, data, hint);
123             }
124             delete externalInfo;
125         },
126         cbinfo.get());
127 
128     value_ = Global<BufferRef>(vm, object);
129     cbinfo.release();
130 }
131 
~ArkNativeBuffer()132 ArkNativeBuffer::~ArkNativeBuffer() {}
133 
GetInterface(int interfaceId)134 void* ArkNativeBuffer::GetInterface(int interfaceId)
135 {
136     return (NativeBuffer::INTERFACE_ID == interfaceId) ? (NativeBuffer*)this
137                                                        : ArkNativeObject::GetInterface(interfaceId);
138 }
139 
GetBuffer()140 void* ArkNativeBuffer::GetBuffer()
141 {
142     auto vm = engine_->GetEcmaVm();
143     LocalScope scope(vm);
144     Global<BufferRef> v = value_;
145     return v->GetBuffer();
146 }
147 
GetLength()148 size_t ArkNativeBuffer::GetLength()
149 {
150     auto vm = engine_->GetEcmaVm();
151     LocalScope scope(vm);
152     Global<BufferRef> v = value_;
153     return v->ByteLength(vm);
154 }
155 
IsBuffer()156 bool ArkNativeBuffer::IsBuffer()
157 {
158     return true;
159 }
160 
IsArrayBuffer()161 bool ArkNativeBuffer::IsArrayBuffer()
162 {
163     return false;
164 }