1/*
2 * Copyright (c) 2021 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 "demo_javascript_class.h"
17
18static napi_value DemoJavascriptClassConstructor(napi_env env, napi_callback_info info);
19static napi_value DemoJavascriptClassAdd(napi_env env, napi_callback_info info);
20static napi_value DemoJavascriptClassSub(napi_env env, napi_callback_info info);
21static napi_value DemoJavascriptClassMul(napi_env env, napi_callback_info info);
22static napi_value DemoJavascriptClassDiv(napi_env env, napi_callback_info info);
23
24enum TestEnum {
25    ONE = 0,
26    TWO,
27    THREE,
28    FOUR
29};
30
31/*
32 * Class Init
33 */
34void DemoJavascriptClassInit(napi_env env, napi_value exports)
35{
36    napi_value one = nullptr;
37    napi_value two = nullptr;
38    napi_value three = nullptr;
39    napi_value four = nullptr;
40
41    napi_create_int32(env, TestEnum::ONE, &one);
42    napi_create_int32(env, TestEnum::TWO, &two);
43    napi_create_int32(env, TestEnum::THREE, &three);
44    napi_create_int32(env, TestEnum::FOUR, &four);
45
46    napi_property_descriptor descriptors[] = {
47        DECLARE_NAPI_FUNCTION("add", DemoJavascriptClassAdd),
48        DECLARE_NAPI_FUNCTION("sub", DemoJavascriptClassSub),
49        DECLARE_NAPI_FUNCTION("mul", DemoJavascriptClassMul),
50        DECLARE_NAPI_FUNCTION("div", DemoJavascriptClassDiv),
51        DECLARE_NAPI_STATIC_PROPERTY("ONE", one),
52        DECLARE_NAPI_STATIC_PROPERTY("TWO", two),
53        DECLARE_NAPI_STATIC_PROPERTY("THREE", three),
54        DECLARE_NAPI_STATIC_PROPERTY("FOUR", four),
55    };
56
57    napi_value result = nullptr;
58    napi_define_class(env, "DemoClass", NAPI_AUTO_LENGTH, DemoJavascriptClassConstructor, nullptr,
59                      sizeof(descriptors) / sizeof(*descriptors), descriptors, &result);
60
61    napi_set_named_property(env, exports, "DemoClass", result);
62}
63
64/*
65 * Constructor
66 */
67static napi_value DemoJavascriptClassConstructor(napi_env env, napi_callback_info info)
68{
69    napi_value thisArg = nullptr;
70    void* data = nullptr;
71
72    napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, &data);
73
74    napi_value global = nullptr;
75    napi_get_global(env, &global);
76
77    return thisArg;
78}
79
80/*
81 * Add Method
82 */
83static napi_value DemoJavascriptClassAdd(napi_env env, napi_callback_info info)
84{
85    size_t requireArgc = 2;
86    size_t argc = 2;
87    napi_value argv[2] = { 0 };
88    napi_value thisArg = nullptr;
89    void* data = nullptr;
90    napi_get_cb_info(env, info, &argc, argv, &thisArg, &data);
91
92    napi_value result = nullptr;
93
94    NAPI_ASSERT(env, argc >= requireArgc, "requires 2 parameters of number type");
95
96    napi_valuetype valueType = napi_undefined;
97    double param1 = 0;
98    double param2 = 0;
99
100    napi_typeof(env, argv[0], &valueType);
101    if (valueType != napi_valuetype::napi_number) {
102        napi_throw_type_error(env, nullptr, "type mismatch for parameter 1");
103        return nullptr;
104    }
105
106    napi_typeof(env, argv[1], &valueType);
107    if (valueType != napi_valuetype::napi_number) {
108        napi_throw_type_error(env, nullptr, "type mismatch for parameter 2");
109        return nullptr;
110    }
111
112    napi_get_value_double(env, argv[0], &param1);
113    napi_get_value_double(env, argv[1], &param2);
114
115    napi_create_double(env, param1 + param2, &result);
116
117    return result;
118}
119
120/*
121 * Sub Method
122 */
123static napi_value DemoJavascriptClassSub(napi_env env, napi_callback_info info)
124{
125    size_t requireArgc = 2;
126    size_t argc = 2;
127    napi_value argv[2] = { 0 };
128    napi_value thisArg = nullptr;
129    void* data = nullptr;
130    napi_get_cb_info(env, info, &argc, argv, &thisArg, &data);
131
132    napi_value result = nullptr;
133
134    NAPI_ASSERT(env, argc >= requireArgc, "requires 2 parameters of number type");
135
136    napi_valuetype valueType = napi_undefined;
137    double param1 = 0;
138    double param2 = 0;
139
140    napi_typeof(env, argv[0], &valueType);
141    if (valueType != napi_valuetype::napi_number) {
142        napi_throw_type_error(env, nullptr, "type mismatch for parameter 1");
143        return nullptr;
144    }
145
146    napi_typeof(env, argv[1], &valueType);
147    if (valueType != napi_valuetype::napi_number) {
148        napi_throw_type_error(env, nullptr, "type mismatch for parameter 2");
149        return nullptr;
150    }
151
152    napi_get_value_double(env, argv[0], &param1);
153    napi_get_value_double(env, argv[1], &param2);
154
155    napi_create_double(env, param1 - param2, &result);
156
157    return result;
158}
159
160/*
161 * Mul Method
162 */
163static napi_value DemoJavascriptClassMul(napi_env env, napi_callback_info info)
164{
165    size_t requireArgc = 2;
166    size_t argc = 2;
167    napi_value argv[2] = { 0 };
168    napi_value thisArg = nullptr;
169    void* data = nullptr;
170    napi_get_cb_info(env, info, &argc, argv, &thisArg, &data);
171
172    napi_value result = nullptr;
173
174    NAPI_ASSERT(env, argc >= requireArgc, "requires 2 parameters of number type");
175
176    napi_valuetype valueType = napi_undefined;
177    double param1 = 0;
178    double param2 = 0;
179
180    napi_typeof(env, argv[0], &valueType);
181    if (valueType != napi_valuetype::napi_number) {
182        napi_throw_type_error(env, nullptr, "type mismatch for parameter 1");
183        return nullptr;
184    }
185
186    napi_typeof(env, argv[1], &valueType);
187    if (valueType != napi_valuetype::napi_number) {
188        napi_throw_type_error(env, nullptr, "type mismatch for parameter 2");
189        return nullptr;
190    }
191
192    napi_get_value_double(env, argv[0], &param1);
193    napi_get_value_double(env, argv[1], &param2);
194
195    napi_create_double(env, param1 * param2, &result);
196
197    return result;
198}
199
200/*
201 * Div Method
202 */
203static napi_value DemoJavascriptClassDiv(napi_env env, napi_callback_info info)
204{
205    size_t requireArgc = 2;
206    size_t argc = 2;
207    napi_value argv[2] = { 0 };
208    napi_value thisArg = nullptr;
209    void* data = nullptr;
210    napi_get_cb_info(env, info, &argc, argv, &thisArg, &data);
211
212    napi_value result = nullptr;
213
214    NAPI_ASSERT(env, argc >= requireArgc, "requires 2 parameters of number type");
215
216    napi_valuetype valueType = napi_undefined;
217    double param1 = 0;
218    double param2 = 0;
219
220    napi_typeof(env, argv[0], &valueType);
221    if (valueType != napi_valuetype::napi_number) {
222        napi_throw_type_error(env, nullptr, "type mismatch for parameter 1");
223        return nullptr;
224    }
225
226    napi_typeof(env, argv[1], &valueType);
227    if (valueType != napi_valuetype::napi_number) {
228        napi_throw_type_error(env, nullptr, "type mismatch for parameter 2");
229        return nullptr;
230    }
231
232    napi_get_value_double(env, argv[0], &param1);
233    napi_get_value_double(env, argv[1], &param2);
234
235    NAPI_ASSERT(env, param2 == 0, "parameter 2 cannot be zero");
236
237    napi_create_double(env, param1 / param2, &result);
238
239    return result;
240}
241