• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-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 #include "pasteboard_common.h"
16 
17 #include "napi_common_want.h"
18 #include "paste_data_record.h"
19 #include "pasteboard_hilog.h"
20 #include "pasteboard_js_err.h"
21 #include "pixel_map_napi.h"
22 
23 namespace OHOS {
24 namespace MiscServicesNapi {
25 using namespace OHOS::MiscServices;
26 const size_t ARGC_TYPE_SET2 = 2;
27 constexpr size_t STR_TAIL_LENGTH = 1;
28 constexpr int32_t MIMETYPE_MAX_SIZE = 1024;
29 
GetCallbackErrorValue(napi_env env,int32_t errorCode)30 napi_value GetCallbackErrorValue(napi_env env, int32_t errorCode)
31 {
32     napi_value result = nullptr;
33     napi_value eCode = nullptr;
34     NAPI_CALL(env, napi_create_int32(env, errorCode, &eCode));
35     NAPI_CALL(env, napi_create_object(env, &result));
36     NAPI_CALL(env, napi_set_named_property(env, result, "code", eCode));
37     return result;
38 }
39 
SetCallback(const napi_env & env,const napi_ref & callbackIn,const napi_value * results)40 void SetCallback(const napi_env &env, const napi_ref &callbackIn, const napi_value *results)
41 {
42     if (results == nullptr) {
43         return;
44     }
45     napi_value callback = nullptr;
46     napi_value resultout = nullptr;
47     napi_get_reference_value(env, callbackIn, &callback);
48     napi_call_function(env, nullptr, callback, ARGC_TYPE_SET2, results, &resultout);
49 }
50 
NapiGetNull(napi_env env)51 napi_value NapiGetNull(napi_env env)
52 {
53     napi_value result = nullptr;
54     napi_get_null(env, &result);
55     return result;
56 }
57 
CreateNapiNumber(napi_env env,int32_t num)58 napi_value CreateNapiNumber(napi_env env, int32_t num)
59 {
60     napi_value value = nullptr;
61     napi_create_int32(env, num, &value);
62     return value;
63 }
64 
CreateNapiString(napi_env env,std::string str)65 napi_value CreateNapiString(napi_env env, std::string str)
66 {
67     napi_value value = nullptr;
68     napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &value);
69     return value;
70 }
71 
72 /* napi_value <-> std::string */
GetValue(napi_env env,napi_value in,std::string & out)73 bool GetValue(napi_env env, napi_value in, std::string &out)
74 {
75     napi_valuetype type = napi_undefined;
76     NAPI_CALL_BASE(env, napi_typeof(env, in, &type), false);
77     NAPI_ASSERT_BASE(env, type == napi_string, "Wrong argument type. String expected.", false);
78 
79     size_t len = 0;
80     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, in, nullptr, 0, &len), false);
81     if (len < 0) {
82         return false;
83     }
84 
85     size_t length = 0;
86     out.resize(len + STR_TAIL_LENGTH, 0);
87     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, in, out.data(), len + STR_TAIL_LENGTH, &length), false);
88     out.resize(len);
89 
90     return true;
91 }
92 
93 /* napi_value <-> std::set<Pattern> */
GetValue(napi_env env,napi_value in,std::set<MiscServices::Pattern> & out)94 bool GetValue(napi_env env, napi_value in, std::set<MiscServices::Pattern> &out)
95 {
96     bool isArray = false;
97     NAPI_CALL_BASE(env, napi_is_array(env, in, &isArray), false);
98     if (!isArray) {
99         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "Wrong argument type. pattern/uint32 array expected.");
100         return false;
101     }
102 
103     uint32_t len = 0;
104     napi_status status = napi_get_array_length(env, in, &len);
105     if (status != napi_ok || len == 0) {
106         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "napi_get_array_length status = %{public}d, len = %{public}d",
107             status, len);
108         return false;
109     }
110 
111     for (uint32_t i = 0; i < len; i++) {
112         napi_value element;
113         napi_status status = napi_get_element(env, in, i, &element);
114         if (status != napi_ok) {
115             PASTEBOARD_HILOGE(
116                 PASTEBOARD_MODULE_JS_NAPI, "napi_get_element%{public}d err status = %{public}d", i, status);
117             return false;
118         }
119         uint32_t pattern;
120         status = napi_get_value_uint32(env, element, &pattern);
121         if (status != napi_ok) {
122             PASTEBOARD_HILOGE(
123                 PASTEBOARD_MODULE_JS_NAPI, "napi_get_value_uint32 err status = %{public}d", status);
124             return false;
125         }
126         if (pattern >= static_cast<uint32_t>(Pattern::PatternCount)) {
127             PASTEBOARD_HILOGE(
128                 PASTEBOARD_MODULE_JS_NAPI, "Unsurportted pattern value: %{public}d", pattern);
129             return false;
130         }
131         out.insert(static_cast<Pattern>(pattern));
132     }
133     return true;
134 }
135 
136 /* napi_value <-> std::set<Pattern> */
SetValue(napi_env env,std::set<Pattern> & in,napi_value & result)137 napi_status SetValue(napi_env env, std::set<Pattern> &in, napi_value &result)
138 {
139     napi_status status = napi_create_array_with_length(env, in.size(), &result);
140     if (status != napi_ok) {
141         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "napi_create_array_with_length error status = %{public}d", status);
142         return status;
143     }
144     int i = 0;
145     for (auto &pattern : in) {
146         napi_value element;
147         status = napi_create_uint32(env, static_cast<uint32_t>(pattern), &element);
148         if (status != napi_ok) {
149             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "napi_create_uint32 error status = %{public}d", status);
150             return status;
151         }
152         status = napi_set_element(env, result, i, element);
153         if (status != napi_ok) {
154             PASTEBOARD_HILOGE(
155                 PASTEBOARD_MODULE_JS_NAPI, "napi_set_element %{public}d err status = %{public}d", i, status);
156             return status;
157         }
158         ++i;
159     }
160     return status;
161 }
162 
CheckArgsType(napi_env env,napi_value in,napi_valuetype expectedType,const char * message)163 bool CheckArgsType(napi_env env, napi_value in, napi_valuetype expectedType, const char *message)
164 {
165     napi_valuetype type = napi_undefined;
166     NAPI_CALL_BASE(env, napi_typeof(env, in, &type), false);
167     int32_t errCode = static_cast<int32_t>(JSErrorCode::INVALID_PARAMETERS);
168     if (type != expectedType) {
169         napi_throw_error(env, std::to_string(errCode).c_str(), message);
170         return false;
171     }
172     return true;
173 }
174 
CheckExpression(napi_env env,bool flag,MiscServices::JSErrorCode errCode,const char * message)175 bool CheckExpression(napi_env env, bool flag, MiscServices::JSErrorCode errCode, const char *message)
176 {
177     if (!flag) {
178         NAPI_CALL_BASE(
179             env, napi_throw_error(env, std::to_string(static_cast<int32_t>(errCode)).c_str(), message), false);
180         return false;
181     }
182     return true;
183 }
184 
185 // Check Parameters of CreateData, CreateRecord and AddRecord
CheckArgs(napi_env env,napi_value * argv,size_t argc,std::string & mimeType)186 bool CheckArgs(napi_env env, napi_value *argv, size_t argc, std::string &mimeType)
187 {
188     // 2: CreateRecord, CreateRecord and AddRecord has 2 args.
189     if (!CheckExpression(env, argc >= ARGC_TYPE_SET2, JSErrorCode::INVALID_PARAMETERS,
190         "Parameter error. The number of arguments cannot be less than two.") ||
191         !CheckArgsType(env, argv[0], napi_string, "Parameter error. The type of mimeType must be string.")) {
192         return false;
193     }
194 
195     bool ret = GetValue(env, argv[0], mimeType);
196     if (!ret) {
197         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "GetValue failed");
198         return false;
199     }
200     if (!CheckExpression(
201         env, mimeType != "", JSErrorCode::INVALID_PARAMETERS, "Parameter error. mimeType cannot be empty.") ||
202         !CheckExpression(env, mimeType.size() <= MIMETYPE_MAX_SIZE, JSErrorCode::INVALID_PARAMETERS,
203         "Parameter error. The length of mimeType cannot be greater than 1024 bytes.")) {
204         return false;
205     }
206 
207     if (mimeType == MIMETYPE_TEXT_URI || mimeType == MIMETYPE_TEXT_PLAIN || mimeType == MIMETYPE_TEXT_HTML) {
208         if (!CheckArgsType(env, argv[1], napi_string, "Parameter error. The type of mimeType must be string.")) {
209             return false;
210         }
211     } else if (mimeType == MIMETYPE_PIXELMAP) {
212         if (!CheckExpression(env, Media::PixelMapNapi::GetPixelMap(env, argv[1]) != nullptr,
213             JSErrorCode::INVALID_PARAMETERS, "Parameter error. Actual mimeType is not mimetype_pixelmap.")) {
214             return false;
215         }
216     } else if (mimeType == MIMETYPE_TEXT_WANT) {
217         AAFwk::Want want;
218         ret = OHOS::AppExecFwk::UnwrapWant(env, argv[1], want);
219         if (!CheckExpression(env, ret, JSErrorCode::INVALID_PARAMETERS,
220             "Parameter error. Actual mimeType is not mimetype_text_want.")) {
221             return false;
222         }
223     } else {
224         bool isArrayBuffer = false;
225         NAPI_CALL_BASE(env, napi_is_arraybuffer(env, argv[1], &isArrayBuffer), false);
226         if (!CheckExpression(env, isArrayBuffer, JSErrorCode::INVALID_PARAMETERS,
227             "Parameter error. The mimeType is not an arraybuffer.")) {
228             return false;
229         }
230     }
231     return true;
232 }
233 } // namespace MiscServicesNapi
234 } // namespace OHOS