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 
16 #include "print_range_helper.h"
17 #include "napi_print_utils.h"
18 #include "print_constant.h"
19 #include "print_log.h"
20 
21 namespace OHOS::Print {
22 static constexpr const char *PARAM_RANGE_STARTPAGE = "startPage";
23 static constexpr const char *PARAM_RANGE_ENDPAGE = "endPage";
24 static constexpr const char *PARAM_RANGE_PAGES = "pages";
25 
MakeJsObject(napi_env env,const PrintRange & range)26 napi_value PrintRangeHelper::MakeJsObject(napi_env env, const PrintRange &range)
27 {
28     napi_value jsObj = nullptr;
29     PRINT_CALL(env, napi_create_object(env, &jsObj));
30     if (range.HasStartPage()) {
31         NapiPrintUtils::SetUint32Property(env, jsObj, PARAM_RANGE_STARTPAGE, range.GetStartPage());
32     }
33     if (range.HasEndPage()) {
34         NapiPrintUtils::SetUint32Property(env, jsObj, PARAM_RANGE_ENDPAGE, range.GetEndPage());
35     }
36 
37     if (range.HasPages()) {
38         std::vector<uint32_t> pages;
39         range.GetPages(pages);
40         if (range.GetStartPage() == 0 && range.GetEndPage() == 0 && pages.size() > 0) {
41             napi_value arrPages = nullptr;
42             PRINT_CALL(env, napi_create_array(env, &arrPages));
43             uint32_t arrPagesLength = pages.size();
44             for (uint32_t i = 0; i < arrPagesLength; i++) {
45                 napi_value value;
46                 PRINT_CALL(env, napi_create_uint32(env, pages[i], &value));
47                 PRINT_CALL(env, napi_set_element(env, arrPages, i, value));
48             }
49             PRINT_CALL(env, napi_set_named_property(env, jsObj, PARAM_RANGE_PAGES, arrPages));
50         }
51     }
52     return jsObj;
53 }
54 
BuildFromJs(napi_env env,napi_value jsValue)55 std::shared_ptr<PrintRange> PrintRangeHelper::BuildFromJs(napi_env env, napi_value jsValue)
56 {
57     auto nativeObj = std::make_shared<PrintRange>();
58 
59     if (!ValidateProperty(env, jsValue)) {
60         PRINT_HILOGE("Invalid property of print range");
61         return nullptr;
62     }
63 
64     auto jsStartPage = NapiPrintUtils::GetNamedProperty(env, jsValue, PARAM_RANGE_STARTPAGE);
65     if (jsStartPage != nullptr) {
66         nativeObj->SetStartPage(NapiPrintUtils::GetUint32FromValue(env, jsStartPage));
67     }
68 
69     auto jsEndPage = NapiPrintUtils::GetNamedProperty(env, jsValue, PARAM_RANGE_ENDPAGE);
70     if (jsEndPage != nullptr) {
71         nativeObj->SetEndPage(NapiPrintUtils::GetUint32FromValue(env, jsEndPage));
72     }
73 
74     if (nativeObj->GetEndPage() != 0 && nativeObj->GetEndPage() < nativeObj->GetStartPage()) {
75         PRINT_HILOGE("Start and end page conflict");
76         return nullptr;
77     }
78 
79     napi_value jsPages = NapiPrintUtils::GetNamedProperty(env, jsValue, PARAM_RANGE_PAGES);
80     if (jsPages != nullptr) {
81         std::vector<uint32_t> pages;
82         bool isArray = false;
83         PRINT_CALL(env, napi_is_array(env, jsPages, &isArray));
84         if (!isArray) {
85             PRINT_HILOGE("Invalid pages of page range");
86             return nullptr;
87         }
88         uint32_t arrayLength = 0;
89         PRINT_CALL(env, napi_get_array_length(env, jsPages, &arrayLength));
90         for (uint32_t index = 0; index < arrayLength; index++) {
91             napi_value jsPage;
92             uint32_t pageNo;
93             PRINT_CALL(env, napi_get_element(env, jsPages, index, &jsPage));
94             PRINT_CALL(env, napi_get_value_uint32(env, jsPage, &pageNo));
95             pages.emplace_back(pageNo);
96         }
97         nativeObj->SetPages(pages);
98     }
99 
100     PRINT_HILOGI("Build Page Range succeed");
101     return nativeObj;
102 }
103 
ValidateProperty(napi_env env,napi_value object)104 bool PrintRangeHelper::ValidateProperty(napi_env env, napi_value object)
105 {
106     std::map<std::string, PrintParamStatus> propertyList = {
107         {PARAM_RANGE_STARTPAGE, PRINT_PARAM_OPT},
108         {PARAM_RANGE_ENDPAGE, PRINT_PARAM_OPT},
109         {PARAM_RANGE_PAGES, PRINT_PARAM_OPT},
110     };
111 
112     auto names = NapiPrintUtils::GetPropertyNames(env, object);
113     for (auto name : names) {
114         if (propertyList.find(name) == propertyList.end()) {
115             PRINT_HILOGE("Invalid property: %{public}s", name.c_str());
116             return false;
117         }
118         propertyList[name] = PRINT_PARAM_SET;
119     }
120     bool hasStartPage = propertyList[PARAM_RANGE_STARTPAGE] == PRINT_PARAM_SET;
121     bool hasEndPage = propertyList[PARAM_RANGE_ENDPAGE] == PRINT_PARAM_SET;
122     bool hasPages = propertyList[PARAM_RANGE_PAGES] == PRINT_PARAM_SET;
123     if ((hasStartPage || hasEndPage) && hasPages) {
124         return false;
125     }
126     return true;
127 }
128 } // namespace OHOS::Print
129