1 /*
2  * Copyright (c) 2022 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 #include <cstring>
16 
17 #include "ace_log.h"
18 #include "locale_util.h"
19 #include "key_parser.h"
20 #include "keys.h"
21 #include "image.h"
22 #include "image_module.h"
23 namespace OHOS {
24 namespace ACELite {
25 constexpr jerry_object_native_info_t ImageModule::gcCallback;
26 const char * const ImageModule::attrOnload = "onload";
27 const char * const ImageModule::attrOnError = "onerror";
28 const char * const ImageModule::attrSrc = "src";
29 const char * const ImageModule::attrWidth = "width";
30 const char * const ImageModule::attrHeight = "height";
31 const char * const ImageModule::className = "Image";
32 
Init(jerry_value_t intlHandle)33 void ImageModule::Init(jerry_value_t intlHandle)
34 {
35     (void)intlHandle;
36     jerry_value_t gObj = jerry_get_global_object();
37     JerrySetFuncProperty(gObj, className, CreateImage);
38 }
RegisterAttributeFunc(jerry_value_t canvas2dContext,const char * attributeName,jerry_external_handler_t setterHandler,jerry_external_handler_t getterHandler)39 void ImageModule::RegisterAttributeFunc(jerry_value_t canvas2dContext,
40                                         const char *attributeName,
41                                         jerry_external_handler_t setterHandler,
42                                         jerry_external_handler_t getterHandler)
43 {
44     // register canvas js attribute setter property via the jerry_define_own_property method
45     jerry_value_t propName = jerry_create_string(reinterpret_cast<const jerry_char_t *>(attributeName));
46     jerry_property_descriptor_t desc;
47     jerry_init_property_descriptor_fields(&desc);
48     desc.is_set_defined = true;
49     desc.setter = jerry_create_external_function(setterHandler);
50     desc.is_get_defined = true;
51     desc.getter = jerry_create_external_function(getterHandler);
52     jerry_value_t returnValue = jerry_define_own_property(canvas2dContext, propName, &desc);
53     jerry_free_property_descriptor_fields(&desc);
54     ReleaseJerryValue(propName, returnValue, VA_ARG_END_FLAG);
55 }
CreateImage(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)56 jerry_value_t ImageModule::CreateImage(const jerry_value_t func,
57                                        const jerry_value_t context,
58                                        const jerry_value_t args[],
59                                        const jerry_length_t argsNum)
60 {
61     if (!jerry_value_is_constructor(func)) {
62         return jerry_create_error(JERRY_ERROR_EVAL,
63                                   reinterpret_cast<const jerry_char_t *>("use new to create Image"));
64     }
65     ImageModule *imageModule = new ImageModule();
66     if (imageModule == nullptr) {
67         return jerry_create_error(JERRY_ERROR_EVAL,
68                                   reinterpret_cast<const jerry_char_t *>("memory is not enough"));
69     }
70 
71     imageModule->width_ = -1;
72     imageModule->height_ = -1;
73     if (argsNum >= 1) {
74         if (jerry_value_is_number(args[0])) {
75             imageModule->width_ = jerry_value_to_number(args[0]);
76         } else if (jerry_value_is_string(args[0])) {
77             char* val = MallocStringOf(args[0]);
78             if (val == nullptr) {
79                 return jerry_create_error(JERRY_ERROR_EVAL,
80                                           reinterpret_cast<const jerry_char_t *>("val is nullptr"));
81             }
82             imageModule->width_ = atoi(val);
83             ACE_FREE(val);
84         }
85     }
86     if (argsNum >= static_cast<uint32_t>(ArgsCount::NUM_2)) {
87         if (jerry_value_is_number(args[1])) {
88             imageModule->height_ = jerry_value_to_number(args[1]);
89         } else if (jerry_value_is_string(args[1])) {
90             char* val = MallocStringOf(args[1]);
91             if (val == nullptr) {
92                 return jerry_create_error(JERRY_ERROR_EVAL,
93                                           reinterpret_cast<const jerry_char_t *>("val is nullptr"));
94             }
95             imageModule->height_ = atoi(val);
96             ACE_FREE(val);
97         }
98     }
99 
100     jerry_set_object_native_pointer(context, imageModule, &gcCallback);
101     RegisterAttributeFunc(context, attrWidth, OnLoadSetter, OnLoadGetter);
102     RegisterAttributeFunc(context, attrOnError, OnErrorSetter, OnErrorGetter);
103     RegisterAttributeFunc(context, attrSrc, OnSrcSetter, OnSrcGetter);
104     RegisterAttributeFunc(context, attrWidth, OnWidthSetter, OnWidthGetter);
105     RegisterAttributeFunc(context, attrHeight, OnHeightSetter, OnHeightGetter);
106     return UNDEFINED;
107 }
108 
OnLoadSetter(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)109 jerry_value_t ImageModule::OnLoadSetter(const jerry_value_t func,
110                                         const jerry_value_t context,
111                                         const jerry_value_t args[],
112                                         const jerry_length_t argsNum)
113 {
114     (void)func;
115     ImageModule* imageModel = nullptr;
116     jerry_get_object_native_pointer(context, (void**)&imageModel, &gcCallback);
117     if (imageModel == nullptr) {
118         return jerry_create_error(JERRY_ERROR_EVAL,
119                                   reinterpret_cast<const jerry_char_t *>("get imageModel fail"));
120     }
121     if (argsNum == 1 && jerry_value_is_function(args[0])) {
122         jerry_release_value(imageModel->onLoadFunc_);
123         imageModel->onLoadFunc_ = args[0];
124     } else {
125         return jerry_create_error(JERRY_ERROR_EVAL,
126                                   reinterpret_cast<const jerry_char_t *>("set imageModel onload arg fail"));
127     }
128     return UNDEFINED;
129 }
130 
OnLoadGetter(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)131 jerry_value_t ImageModule::OnLoadGetter(const jerry_value_t func,
132                                         const jerry_value_t context,
133                                         const jerry_value_t args[],
134                                         const jerry_length_t argsNum)
135 {
136     (void)func;
137     (void)args;
138     (void)argsNum;
139     ImageModule* imageModel = nullptr;
140     jerry_get_object_native_pointer(context, (void**)&imageModel, &gcCallback);
141     if (imageModel == nullptr) {
142         return jerry_create_error(JERRY_ERROR_EVAL,
143                                   reinterpret_cast<const jerry_char_t *>("get imageModel fail"));
144     }
145     return imageModel->onLoadFunc_;
146 }
147 
OnErrorSetter(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)148 jerry_value_t ImageModule::OnErrorSetter(const jerry_value_t func,
149                                          const jerry_value_t context,
150                                          const jerry_value_t args[],
151                                          const jerry_length_t argsNum)
152 {
153     (void)func;
154     ImageModule* imageModel = nullptr;
155     jerry_get_object_native_pointer(context, (void**)&imageModel, &gcCallback);
156     if (imageModel == nullptr) {
157         return jerry_create_error(JERRY_ERROR_EVAL,
158                                   reinterpret_cast<const jerry_char_t *>("get imageModel fail"));
159     }
160     if (argsNum >= 1 && jerry_value_is_function(args[0])) {
161         jerry_release_value(imageModel->onErrorFunc_);
162         imageModel->onErrorFunc_ = args[0];
163     } else {
164         return jerry_create_error(JERRY_ERROR_EVAL,
165                                   reinterpret_cast<const jerry_char_t *>("set imageModel onload arg fail"));
166     }
167     return UNDEFINED;
168 }
169 
OnErrorGetter(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)170 jerry_value_t ImageModule::OnErrorGetter(const jerry_value_t func,
171                                          const jerry_value_t context,
172                                          const jerry_value_t args[],
173                                          const jerry_length_t argsNum)
174 {
175     (void)func;
176     (void)args;
177     (void)argsNum;
178     ImageModule* imageModel = nullptr;
179     jerry_get_object_native_pointer(context, (void**)&imageModel, &gcCallback);
180     if (imageModel == nullptr) {
181         return jerry_create_error(JERRY_ERROR_EVAL,
182                                   reinterpret_cast<const jerry_char_t *>("get imageModel fail"));
183     }
184     return imageModel->onErrorFunc_;
185 }
186 
OnSrcSetter(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)187 jerry_value_t ImageModule::OnSrcSetter(const jerry_value_t func,
188                                        const jerry_value_t context,
189                                        const jerry_value_t args[],
190                                        const jerry_length_t argsNum)
191 {
192     (void)func;
193     ImageModule* imageModel = nullptr;
194     jerry_get_object_native_pointer(context, (void**)&imageModel, &gcCallback);
195     if (imageModel == nullptr) {
196         return jerry_create_error(JERRY_ERROR_EVAL,
197                                   reinterpret_cast<const jerry_char_t *>("get imageModel fail"));
198     }
199     if (argsNum >= 1) {
200         ACE_FREE(imageModel->src_);
201         imageModel->src_ = MallocStringOf(args[0]);
202     }
203     if (imageModel->src_ == nullptr || strlen(imageModel->src_) == 0) {
204         OnCallBack(context, imageModel, false, "src is null");
205         return UNDEFINED;
206     }
207     jerry_release_value(imageModel->jerrySrc_);
208     imageModel->jerrySrc_ = jerry_create_string(reinterpret_cast<const jerry_char_t *>(imageModel->src_));
209     Image image;
210     bool isLoad = image.PreParse(imageModel->src_);
211     if (!isLoad) {
212         OnCallBack(context, imageModel, false, "unknown image");
213         return UNDEFINED;
214     }
215     OnCallBack(context, imageModel, true, "load sucess");
216     return UNDEFINED;
217 }
218 
OnSrcGetter(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)219 jerry_value_t ImageModule::OnSrcGetter(const jerry_value_t func,
220                                        const jerry_value_t context,
221                                        const jerry_value_t args[],
222                                        const jerry_length_t argsNum)
223 {
224     (void)func;
225     (void)args;
226     (void)argsNum;
227     ImageModule* imageModel = nullptr;
228     jerry_get_object_native_pointer(context, (void**)&imageModel, &gcCallback);
229     if (imageModel == nullptr) {
230         return jerry_create_error(JERRY_ERROR_EVAL,
231                                   reinterpret_cast<const jerry_char_t *>("get imageModel fail"));
232     }
233     if (jerry_value_is_string(imageModel->jerrySrc_)) {
234         return imageModel->jerrySrc_;
235     }
236     return UNDEFINED;
237 }
238 
OnHeightSetter(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)239 jerry_value_t ImageModule::OnHeightSetter(const jerry_value_t func,
240                                           const jerry_value_t context,
241                                           const jerry_value_t args[],
242                                           const jerry_length_t argsNum)
243 {
244     (void)func;
245     ImageModule* imageModel = nullptr;
246     jerry_get_object_native_pointer(context, (void**)&imageModel, &gcCallback);
247     if (imageModel == nullptr) {
248         return jerry_create_error(JERRY_ERROR_EVAL,
249                                   reinterpret_cast<const jerry_char_t *>("get imageModel fail"));
250     }
251     if (argsNum < 1) {
252         return jerry_create_error(JERRY_ERROR_EVAL,
253                                   reinterpret_cast<const jerry_char_t *>("set height fail"));
254     }
255     imageModel->height_ = IntegerOf(args[0]);
256     return UNDEFINED;
257 }
258 
OnHeightGetter(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)259 jerry_value_t ImageModule::OnHeightGetter(const jerry_value_t func,
260                                           const jerry_value_t context,
261                                           const jerry_value_t args[],
262                                           const jerry_length_t argsNum)
263 {
264     (void)func;
265     (void)args;
266     (void)argsNum;
267     ImageModule* imageModel = nullptr;
268     jerry_get_object_native_pointer(context, (void**)&imageModel, &gcCallback);
269     if (imageModel == nullptr) {
270         return jerry_create_error(JERRY_ERROR_EVAL,
271                                   reinterpret_cast<const jerry_char_t *>("get imageModel fail"));
272     }
273     return imageModel->height_;
274 }
275 
OnWidthSetter(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)276 jerry_value_t ImageModule::OnWidthSetter(const jerry_value_t func,
277                                          const jerry_value_t context,
278                                          const jerry_value_t args[],
279                                          const jerry_length_t argsNum)
280 {
281     (void)func;
282     ImageModule* imageModel = nullptr;
283     jerry_get_object_native_pointer(context, (void**)&imageModel, &gcCallback);
284     if (imageModel == nullptr) {
285         return jerry_create_error(JERRY_ERROR_EVAL,
286                                   reinterpret_cast<const jerry_char_t *>("get imageModel fail"));
287     }
288     if (argsNum < 1) {
289         return jerry_create_error(JERRY_ERROR_EVAL,
290                                   reinterpret_cast<const jerry_char_t *>("set width fail"));
291     }
292     imageModel->width_ = IntegerOf(args[0]);
293     return UNDEFINED;
294 }
295 
OnWidthGetter(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)296 jerry_value_t ImageModule::OnWidthGetter(const jerry_value_t func,
297                                          const jerry_value_t context,
298                                          const jerry_value_t args[],
299                                          const jerry_length_t argsNum)
300 {
301     (void)func;
302     (void)args;
303     (void)argsNum;
304     ImageModule* imageModel = nullptr;
305     jerry_get_object_native_pointer(context, (void**)&imageModel, &gcCallback);
306     if (imageModel == nullptr) {
307         return jerry_create_error(JERRY_ERROR_EVAL,
308                                   reinterpret_cast<const jerry_char_t *>("get imageModel fail"));
309     }
310     return imageModel->width_;
311 }
312 
OnCallBack(const jerry_value_t context,const ImageModule * imageModule,bool isSucess,const char * msg)313 void ImageModule::OnCallBack(const jerry_value_t context,
314                              const ImageModule *imageModule,
315                              bool isSucess,
316                              const char* msg)
317 {
318     jerry_value_t  targetFunction;
319     if (imageModule == nullptr) {
320         return;
321     }
322     if (isSucess) {
323         targetFunction = imageModule->onLoadFunc_;
324     } else {
325         targetFunction = imageModule->onErrorFunc_;
326     }
327     if (!jerry_value_is_function(targetFunction)) {
328         return;
329     }
330     const int16_t argcount = 1;
331     jerry_value_t arg = jerry_create_string(reinterpret_cast<const jerry_char_t *>(msg));
332     jerry_value_t args[argcount] = {arg};
333     jerry_value_t ret_val = jerry_call_function (targetFunction, context, args, argcount);
334     if (jerry_value_is_error (ret_val)) {
335         HILOG_ERROR(HILOG_MODULE_ACE, "call back failed!");
336     }
337     jerry_release_value(arg);
338     jerry_release_value (ret_val);
339 }
340 }
341 }
342 
343