• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 <vector>
17 #include <nlohmann/json.hpp>
18 
19 #include "print_helper.h"
20 #include "print_constant.h"
21 #include "print_log.h"
22 #include "print_util.h"
23 #include "ability_manager_client.h"
24 #include "print_converter.h"
25 #include "print_manager_client.h"
26 
27 using json = nlohmann::json;
28 
29 namespace OHOS::Print {
30 
31 const std::string DUPLEX_STRING = "duplex";
32 const std::string ORIENTATION_STRING = "orientation";
33 const std::string PAGESIZEID_STRING = "pagesizeId";
34 const std::string QUALITY_STRING = "quality";
35 const std::string DEFAULT_QUALITY_PREFERENCE = "4";
36 
CopyString(const std::string & source)37 char *CopyString(const std::string &source)
38 {
39     auto len = source.length();
40     char *dest = new (std::nothrow) char[len + 1];
41     if (dest == nullptr) {
42         PRINT_HILOGW("allocate failed");
43         return nullptr;
44     }
45     if (strcpy_s(dest, len + 1, source.c_str()) != 0) {
46         PRINT_HILOGW("CopyString strcpy_s failed");
47     }
48     dest[len] = '\0';
49     return dest;
50 }
51 
AddJsonFieldStringToJsonObject(const nlohmann::json & cupsOpt,const std::string & keyword,nlohmann::json & advancedCapJson)52 void AddJsonFieldStringToJsonObject(const nlohmann::json &cupsOpt, const std::string &keyword,
53     nlohmann::json &advancedCapJson)
54 {
55     PRINT_HILOGD("AddJsonFieldStringToJsonObject %{public}s", keyword.c_str());
56     if (!cupsOpt.contains(keyword)) {
57         PRINT_HILOGW("missing keyword");
58         return;
59     }
60     if (!cupsOpt[keyword].is_string()) {
61         PRINT_HILOGW("not string type");
62         return;
63     }
64     std::string optionString = cupsOpt[keyword].get<std::string>();
65     PRINT_HILOGD("AddJsonFieldStringToJsonObject %{public}s", optionString.c_str());
66     advancedCapJson[keyword] = optionString;
67 }
68 
ParseJsonFieldAsArrayOpt(const nlohmann::json & cupsOpt,const std::string & key,Print_PrinterInfo & nativePrinterInfo,void (* arrayOpteration)(const nlohmann::json &,Print_PrinterInfo &))69 void ParseJsonFieldAsArrayOpt(const nlohmann::json &cupsOpt, const std::string &key,
70     Print_PrinterInfo &nativePrinterInfo, void (*arrayOpteration)(const nlohmann::json &, Print_PrinterInfo &))
71 {
72     PRINT_HILOGD("ParseJsonFieldAsArrayOpt: %{public}s", key.c_str());
73     if (arrayOpteration == nullptr) {
74         PRINT_HILOGW("arrayOpteration is null");
75         return;
76     }
77     if (!cupsOpt.contains(key)) {
78         PRINT_HILOGW("key missing");
79         return;
80     }
81     if (!cupsOpt[key].is_string()) {
82         PRINT_HILOGW("not string");
83         return;
84     }
85     std::string arrayJson = cupsOpt[key].get<std::string>();
86     if (!nlohmann::json::accept(arrayJson)) {
87         PRINT_HILOGW("accept fail");
88         return;
89     }
90     nlohmann::json arrayOpt = nlohmann::json::parse(arrayJson);
91     if (!arrayOpt.is_array()) {
92         PRINT_HILOGW("not array");
93         return;
94     }
95     arrayOpteration(arrayOpt, nativePrinterInfo);
96 }
97 
ParseJsonFieldAsInt(const nlohmann::json & cupsOpt,const std::string & key,int & value)98 bool ParseJsonFieldAsInt(const nlohmann::json &cupsOpt, const std::string &key, int &value)
99 {
100     if (!cupsOpt.contains(key)) {
101         PRINT_HILOGW("key missing");
102         return false;
103     }
104     if (cupsOpt[key].is_number()) {
105         value = cupsOpt[key];
106         return true;
107     }
108     if (!cupsOpt[key].is_string()) {
109         PRINT_HILOGW("incorrect type");
110         return false;
111     }
112     std::string jsonString = cupsOpt[key].get<std::string>();
113     if (ConvertStringToInt(jsonString.c_str(), value)) {
114         return true;
115     }
116     return false;
117 }
118 
ConvertJsonArrayToIntList(const nlohmann::json & jsonArray,const std::string & key,std::vector<uint32_t> & list)119 void ConvertJsonArrayToIntList(const nlohmann::json &jsonArray, const std::string &key, std::vector<uint32_t> &list)
120 {
121     PRINT_HILOGD("ConvertJsonArrayToIntList %{public}s, %{public}zu", key.c_str(), jsonArray.size());
122     for (auto &item : jsonArray) {
123         int value = 0;
124         if (!ParseJsonFieldAsInt(item, key, value)) {
125             continue;
126         }
127         list.push_back(static_cast<uint32_t>(value));
128     }
129 }
130 
ReleaseCapabilityPageSizes(Print_PrinterCapability & capability)131 void ReleaseCapabilityPageSizes(Print_PrinterCapability &capability)
132 {
133     if (capability.supportedPageSizes != nullptr) {
134         for (uint32_t i = 0; i < capability.supportedPageSizesCount; i++) {
135             SAFE_DELETE_ARRAY(capability.supportedPageSizes[i].id);
136             SAFE_DELETE_ARRAY(capability.supportedPageSizes[i].name);
137         }
138         SAFE_DELETE_ARRAY(capability.supportedPageSizes);
139     }
140     capability.supportedPageSizesCount = 0;
141 }
142 
ReleaseCapability(Print_PrinterCapability & capability)143 void ReleaseCapability(Print_PrinterCapability &capability)
144 {
145     ReleaseCapabilityPageSizes(capability);
146     SAFE_DELETE_ARRAY(capability.supportedColorModes);
147     capability.supportedColorModesCount = 0;
148     SAFE_DELETE_ARRAY(capability.supportedDuplexModes);
149     capability.supportedDuplexModesCount = 0;
150     SAFE_DELETE_ARRAY(capability.supportedMediaTypes);
151     SAFE_DELETE_ARRAY(capability.supportedQualities);
152     capability.supportedQualitiesCount = 0;
153     SAFE_DELETE_ARRAY(capability.supportedPaperSources);
154     SAFE_DELETE_ARRAY(capability.supportedResolutions);
155     capability.supportedResolutionsCount = 0;
156     SAFE_DELETE_ARRAY(capability.supportedOrientations);
157     capability.supportedOrientationsCount = 0;
158     SAFE_DELETE_ARRAY(capability.advancedCapability);
159 }
160 
ReleaseDefaultValue(Print_DefaultValue & defaultValue)161 void ReleaseDefaultValue(Print_DefaultValue &defaultValue)
162 {
163     SAFE_DELETE_ARRAY(defaultValue.defaultPageSizeId);
164     SAFE_DELETE_ARRAY(defaultValue.defaultMediaType);
165     SAFE_DELETE_ARRAY(defaultValue.defaultPaperSource);
166     SAFE_DELETE_ARRAY(defaultValue.otherDefaultValues);
167 }
168 
ReleasePrinterInfo(Print_PrinterInfo & printerInfo)169 void ReleasePrinterInfo(Print_PrinterInfo &printerInfo)
170 {
171     SAFE_DELETE_ARRAY(printerInfo.printerId);
172     SAFE_DELETE_ARRAY(printerInfo.printerName);
173     SAFE_DELETE_ARRAY(printerInfo.description);
174     SAFE_DELETE_ARRAY(printerInfo.location);
175     SAFE_DELETE_ARRAY(printerInfo.makeAndModel);
176     SAFE_DELETE_ARRAY(printerInfo.printerUri);
177     SAFE_DELETE_ARRAY(printerInfo.detailInfo);
178     ReleaseCapability(printerInfo.capability);
179     ReleaseDefaultValue(printerInfo.defaultValue);
180 }
181 
PageSizeArrayConvert(const nlohmann::json & pageSizeJsonArray,Print_PrinterInfo & nativePrinterInfo)182 void PageSizeArrayConvert(const nlohmann::json &pageSizeJsonArray, Print_PrinterInfo &nativePrinterInfo)
183 {
184     ReleaseCapabilityPageSizes(nativePrinterInfo.capability);
185     PRINT_HILOGI("pageSizeJsonArray size = %{public}zu", pageSizeJsonArray.size());
186     std::vector<Print_PageSize> pageSizeVector;
187     for (auto &item : pageSizeJsonArray) {
188         Print_PageSize pageSize = {0};
189         if (!item.contains("id") || !item.contains("name") || !item.contains("width") || !item.contains("height")) {
190             PRINT_HILOGW("field missing");
191             continue;
192         }
193         if (!item["id"].is_string() || !item["name"].is_string() || !item["width"].is_number() ||
194             !item["height"].is_number()) {
195             PRINT_HILOGW("incorrect type");
196             continue;
197         }
198         pageSize.id = CopyString(item["id"].get<std::string>());
199         pageSize.name = CopyString(item["name"].get<std::string>());
200         pageSize.width = item["width"];
201         pageSize.height = item["height"];
202         pageSizeVector.push_back(pageSize);
203     }
204     nativePrinterInfo.capability.supportedPageSizes = CopyArray<Print_PageSize>(pageSizeVector,
205         nativePrinterInfo.capability.supportedPageSizesCount);
206 }
207 
ParseDefaultPageMargin(const nlohmann::json & cupsOpt,Print_Margin & defaultMargin)208 void ParseDefaultPageMargin(const nlohmann::json &cupsOpt, Print_Margin &defaultMargin)
209 {
210     int leftMargin = 0;
211     int topMargin = 0;
212     int rightMargin = 0;
213     int bottomMargin = 0;
214     if (cupsOpt.contains("media-left-margin-supported") && cupsOpt["media-left-margin-supported"].is_string()) {
215         std::string mediaLeftMargin = cupsOpt["media-left-margin-supported"].get<std::string>();
216         ConvertStringToInt(mediaLeftMargin.c_str(), leftMargin);
217     }
218     if (cupsOpt.contains("media-top-margin-supported") && cupsOpt["media-top-margin-supported"].is_string()) {
219         std::string mediaTopMargin = cupsOpt["media-top-margin-supported"].get<std::string>();
220         ConvertStringToInt(mediaTopMargin.c_str(), topMargin);
221     }
222     if (cupsOpt.contains("media-right-margin-supported") && cupsOpt["media-right-margin-supported"].is_string()) {
223         std::string mediaRightMargin = cupsOpt["media-right-margin-supported"].get<std::string>();
224         ConvertStringToInt(mediaRightMargin.c_str(), rightMargin);
225     }
226     if (cupsOpt.contains("media-bottom-margin-supported") && cupsOpt["media-bottom-margin-supported"].is_string()) {
227         std::string mediaBottomMargin = cupsOpt["media-bottom-margin-supported"].get<std::string>();
228         ConvertStringToInt(mediaBottomMargin.c_str(), bottomMargin);
229     }
230     defaultMargin.leftMargin = static_cast<uint32_t>(leftMargin);
231     defaultMargin.topMargin = static_cast<uint32_t>(topMargin);
232     defaultMargin.rightMargin = static_cast<uint32_t>(rightMargin);
233     defaultMargin.bottomMargin = static_cast<uint32_t>(bottomMargin);
234 }
235 
ParseMediaOpt(const nlohmann::json & cupsOpt,Print_PrinterInfo & nativePrinterInfo)236 void ParseMediaOpt(const nlohmann::json &cupsOpt, Print_PrinterInfo &nativePrinterInfo)
237 {
238     if (cupsOpt.contains("defaultPageSizeId")) {
239         std::string defaultPageSizeId = cupsOpt["defaultPageSizeId"].get<std::string>();
240         PRINT_HILOGD("defaultPageSizeId %{public}s", defaultPageSizeId.c_str());
241         nativePrinterInfo.defaultValue.defaultPageSizeId = CopyString(defaultPageSizeId);
242     }
243     if (cupsOpt.contains("media-type-supported")) {
244         std::string mediaTypeSupported = cupsOpt["media-type-supported"].get<std::string>();
245         PRINT_HILOGD("cupsOptionsStr media-type-supported %{public}s", mediaTypeSupported.c_str());
246         nativePrinterInfo.capability.supportedMediaTypes = CopyString(mediaTypeSupported);
247     }
248     if (cupsOpt.contains("media-type-default")) {
249         std::string mediaTypeDefault = cupsOpt["media-type-default"].get<std::string>();
250         PRINT_HILOGD("cupsOptionsStr media-type-default %{public}s", mediaTypeDefault.c_str());
251         nativePrinterInfo.defaultValue.defaultMediaType = CopyString(mediaTypeDefault);
252     }
253     if (cupsOpt.contains("media-source-default")) {
254         std::string mediaSourceDefault = cupsOpt["media-source-default"].get<std::string>();
255         PRINT_HILOGD("cupsOptionsStr media-source-default %{public}s", mediaSourceDefault.c_str());
256         nativePrinterInfo.defaultValue.defaultPaperSource = CopyString(mediaSourceDefault);
257     }
258     if (cupsOpt.contains("media-source-supported")) {
259         std::string mediaSourceSupported = cupsOpt["media-source-supported"].get<std::string>();
260         PRINT_HILOGD("cupsOptionsStr media-source-supported %{public}s", mediaSourceSupported.c_str());
261         nativePrinterInfo.capability.supportedPaperSources = CopyString(mediaSourceSupported);
262     }
263 }
264 
ParseColorModeArray(const nlohmann::json & arrayObject,Print_PrinterInfo & nativePrinterInfo)265 void ParseColorModeArray(const nlohmann::json &arrayObject, Print_PrinterInfo &nativePrinterInfo)
266 {
267     std::vector<uint32_t> list;
268     std::string key = "color";
269     ConvertJsonArrayToIntList(arrayObject, key, list);
270     nativePrinterInfo.capability.supportedColorModes = CopyArray<uint32_t, Print_ColorMode>(
271         list, nativePrinterInfo.capability.supportedColorModesCount, ConvertColorMode);
272 }
273 
ParseDuplexModeArray(const nlohmann::json & arrayObject,Print_PrinterInfo & nativePrinterInfo)274 void ParseDuplexModeArray(const nlohmann::json &arrayObject, Print_PrinterInfo &nativePrinterInfo)
275 {
276     std::vector<uint32_t> list;
277     std::string key = "duplex";
278     ConvertJsonArrayToIntList(arrayObject, key, list);
279     nativePrinterInfo.capability.supportedDuplexModes = CopyArray<uint32_t, Print_DuplexMode>(
280         list, nativePrinterInfo.capability.supportedDuplexModesCount, ConvertDuplexMode);
281 }
282 
ParseQualityArray(const nlohmann::json & arrayObject,Print_PrinterInfo & nativePrinterInfo)283 void ParseQualityArray(const nlohmann::json &arrayObject, Print_PrinterInfo &nativePrinterInfo)
284 {
285     std::vector<uint32_t> list;
286     std::string key = "quality";
287     ConvertJsonArrayToIntList(arrayObject, key, list);
288     nativePrinterInfo.capability.supportedQualities =
289         CopyArray<uint32_t, Print_Quality>(list, nativePrinterInfo.capability.supportedQualitiesCount, ConvertQuality);
290 }
291 
ParseResolutionObject(const nlohmann::json & jsonObject,Print_Resolution & resolution)292 bool ParseResolutionObject(const nlohmann::json &jsonObject, Print_Resolution &resolution)
293 {
294     if (!jsonObject.contains("horizontalDpi")) {
295         PRINT_HILOGW("horizontalDpi missing");
296         return false;
297     }
298     if (!jsonObject["horizontalDpi"].is_number()) {
299         PRINT_HILOGW("horizontalDpi is not string");
300         return false;
301     }
302     int xDpi = jsonObject["horizontalDpi"];
303     if (!jsonObject.contains("verticalDpi")) {
304         PRINT_HILOGW("verticalDpi missing");
305         return false;
306     }
307     if (!jsonObject["verticalDpi"].is_number()) {
308         PRINT_HILOGW("verticalDpi is not string");
309         return false;
310     }
311     int yDpi = jsonObject["verticalDpi"];
312     resolution.horizontalDpi = static_cast<uint32_t>(xDpi);
313     resolution.verticalDpi = static_cast<uint32_t>(yDpi);
314     return true;
315 }
316 
ParseResolutionArray(const nlohmann::json & arrayObject,Print_PrinterInfo & nativePrinterInfo)317 void ParseResolutionArray(const nlohmann::json &arrayObject, Print_PrinterInfo &nativePrinterInfo)
318 {
319     std::vector<Print_Resolution> list;
320     PRINT_HILOGI("ParseResolutionArray arrayObject size = %{public}zu", arrayObject.size());
321     for (auto &item : arrayObject) {
322         Print_Resolution resolution;
323         if (!ParseResolutionObject(item, resolution)) {
324             PRINT_HILOGW("ParseResolutionObject fail");
325             continue;
326         }
327         list.push_back(resolution);
328     }
329     nativePrinterInfo.capability.supportedResolutions =
330         CopyArray<Print_Resolution>(list, nativePrinterInfo.capability.supportedResolutionsCount);
331 }
332 
ParsePrinterOpt(const nlohmann::json & cupsOpt,Print_PrinterInfo & nativePrinterInfo)333 void ParsePrinterOpt(const nlohmann::json &cupsOpt, Print_PrinterInfo &nativePrinterInfo)
334 {
335     if (cupsOpt.contains("printer-location") && cupsOpt["printer-location"].is_string()) {
336         std::string pLocation = cupsOpt["printer-location"].get<std::string>();
337         PRINT_HILOGD("printer-location: %{public}s", pLocation.c_str());
338         nativePrinterInfo.location = CopyString(pLocation);
339     }
340     std::string keyword = "orientation-requested-supported";
341     if (cupsOpt.contains(keyword) && cupsOpt[keyword].is_string()) {
342         std::string orientationArray = cupsOpt[keyword].get<std::string>();
343         PRINT_HILOGD("supported orientations: %{public}s", orientationArray.c_str());
344         std::vector<uint32_t> orientationVector = PrintUtil::Str2Vec(orientationArray);
345         nativePrinterInfo.capability.supportedOrientations = CopyArray<uint32_t, Print_OrientationMode>(
346             orientationVector, nativePrinterInfo.capability.supportedOrientationsCount, ConvertOrientationMode);
347     }
348     keyword = "orientation-requested-default";
349     if (cupsOpt.contains(keyword) && cupsOpt[keyword].is_string()) {
350         std::string orientationString = cupsOpt[keyword].get<std::string>();
351         PRINT_HILOGD("default orientation: %{public}s", orientationString.c_str());
352         int orientationValue = 0;
353         if (ConvertStringToInt(orientationString.c_str(), orientationValue)) {
354             uint32_t defaultOrientation = static_cast<uint32_t>(orientationValue);
355             ConvertOrientationMode(defaultOrientation, nativePrinterInfo.defaultValue.defaultOrientation);
356         }
357     }
358     keyword = "printer-resolution-supported";
359     ParseJsonFieldAsArrayOpt(cupsOpt, keyword, nativePrinterInfo, ParseResolutionArray);
360     keyword = "printer-resolution-default";
361     if (cupsOpt.contains(keyword) && cupsOpt[keyword].is_string()) {
362         std::string resolutionString = cupsOpt[keyword].get<std::string>();
363         if (json::accept(resolutionString)) {
364             nlohmann::json resolutionJson = json::parse(resolutionString);
365             if (!ParseResolutionObject(resolutionJson, nativePrinterInfo.defaultValue.defaultResolution)) {
366                 PRINT_HILOGW("ParseResolutionObject fail");
367             }
368         }
369     }
370     keyword = "print-color-mode-supported";
371     ParseJsonFieldAsArrayOpt(cupsOpt, keyword, nativePrinterInfo, ParseColorModeArray);
372 }
373 
ParseCupsCopyOpt(const nlohmann::json & cupsOpt,Print_PrinterInfo & nativePrinterInfo)374 void ParseCupsCopyOpt(const nlohmann::json &cupsOpt, Print_PrinterInfo &nativePrinterInfo)
375 {
376     std::string keyword = "sides-supported";
377     ParseJsonFieldAsArrayOpt(cupsOpt, keyword, nativePrinterInfo, ParseDuplexModeArray);
378 
379     keyword = "print-quality-supported";
380     ParseJsonFieldAsArrayOpt(cupsOpt, keyword, nativePrinterInfo, ParseQualityArray);
381     if (cupsOpt.contains("copies-default") && cupsOpt["copies-default"].is_string()) {
382         std::string defaultCopies = cupsOpt["copies-default"].get<std::string>();
383         nativePrinterInfo.defaultValue.defaultCopies = std::stoul(defaultCopies);
384         PRINT_HILOGD("ParseCupsCopyOpt copies-default: %{public}s", defaultCopies.c_str());
385     }
386     if (cupsOpt.contains("copies-supported") && cupsOpt["copies-supported"].is_string()) {
387         std::string copySupport = cupsOpt["copies-supported"].get<std::string>();
388         nativePrinterInfo.capability.supportedCopies = std::stoul(copySupport);
389         PRINT_HILOGD("ParseCupsCopyOpt copies-supported: %{public}s", copySupport.c_str());
390     }
391 }
392 
ParseCupsOptions(const nlohmann::json & cupsOpt,Print_PrinterInfo & nativePrinterInfo)393 void ParseCupsOptions(const nlohmann::json &cupsOpt, Print_PrinterInfo &nativePrinterInfo)
394 {
395     ParsePrinterOpt(cupsOpt, nativePrinterInfo);
396     ParseDefaultPageMargin(cupsOpt, nativePrinterInfo.defaultValue.defaultMargin);
397     ParseCupsCopyOpt(cupsOpt, nativePrinterInfo);
398     ParseMediaOpt(cupsOpt, nativePrinterInfo);
399     std::string keyword = "supportedPageSizeArray";
400     ParseJsonFieldAsArrayOpt(cupsOpt, keyword, nativePrinterInfo, PageSizeArrayConvert);
401     nlohmann::json advancedCapJson;
402     keyword = "multiple-document-handling-supported";
403     AddJsonFieldStringToJsonObject(cupsOpt, keyword, advancedCapJson);
404     nativePrinterInfo.capability.advancedCapability = CopyString(advancedCapJson.dump().c_str());
405 }
406 
ParseInfoOption(const std::string & infoOption,Print_PrinterInfo & nativePrinterInfo)407 int32_t ParseInfoOption(const std::string &infoOption, Print_PrinterInfo &nativePrinterInfo)
408 {
409     if (!json::accept(infoOption)) {
410         PRINT_HILOGW("infoOption can not parse to json object");
411         return E_PRINT_INVALID_PARAMETER;
412     }
413     nlohmann::json infoJson = json::parse(infoOption);
414     if (!infoJson.contains("printerUri") || !infoJson.contains("make")) {
415         PRINT_HILOGW("The infoJson does not have a necessary attribute.");
416         return E_PRINT_INVALID_PARAMETER;
417     }
418     nativePrinterInfo.makeAndModel = CopyString(infoJson["make"].get<std::string>());
419     nativePrinterInfo.printerUri = CopyString(infoJson["printerUri"].get<std::string>());
420     if (!infoJson.contains("cupsOptions")) {
421         PRINT_HILOGW("The infoJson does not have a cupsOptions attribute.");
422         return E_PRINT_NONE;
423     }
424     nlohmann::json cupsOpt = infoJson["cupsOptions"];
425     ParseCupsOptions(cupsOpt, nativePrinterInfo);
426     return E_PRINT_NONE;
427 }
428 
GetSettingItemString(const std::string key,json defaultSetting,json setting)429 std::string GetSettingItemString(const std::string key, json defaultSetting, json setting)
430 {
431     if (setting.contains(key) && setting[key].is_string() && !setting[key].get<std::string>().empty()) {
432         return setting[key].get<std::string>();
433     } else if (defaultSetting.contains(key) && defaultSetting[key].is_string() &&
434                 !defaultSetting[key].get<std::string>().empty()) {
435         return defaultSetting[key].get<std::string>();
436     }
437     if (key == QUALITY_STRING) {
438         return DEFAULT_QUALITY_PREFERENCE;
439     }
440     return "";
441 }
442 
ParsePrinterPreference(const std::string & printerPreference,Print_PrinterInfo & nativePrinterInfo)443 void ParsePrinterPreference(const std::string &printerPreference, Print_PrinterInfo &nativePrinterInfo)
444 {
445     if (!json::accept(printerPreference)) {
446         PRINT_HILOGW("printerPreference can not parse to json object");
447         return;
448     }
449     nlohmann::json preferenceJson = json::parse(printerPreference);
450     if (!preferenceJson.contains("defaultSetting") || !preferenceJson["defaultSetting"].is_object() ||
451         !preferenceJson.contains("setting") || !preferenceJson["setting"].is_object()) {
452         PRINT_HILOGW("The infoJson does not have a necessary attribute.");
453         return;
454     }
455     json defaultSetting = preferenceJson["defaultSetting"];
456     json setting = preferenceJson["setting"];
457 
458     std::string defaultDuplex = GetSettingItemString(DUPLEX_STRING, defaultSetting, setting);
459     if (!defaultDuplex.empty()) {
460         ConvertDuplexMode(std::atoi(defaultDuplex.c_str()), nativePrinterInfo.defaultValue.defaultDuplexMode);
461     }
462 
463     std::string defaultOrientation = GetSettingItemString(ORIENTATION_STRING, defaultSetting, setting);
464     if (!defaultOrientation.empty()) {
465         ConvertOrientationMode(
466             std::atoi(defaultOrientation.c_str()), nativePrinterInfo.defaultValue.defaultOrientation);
467     }
468 
469     nativePrinterInfo.defaultValue.defaultPageSizeId =
470         CopyString(GetSettingItemString(PAGESIZEID_STRING, defaultSetting, setting));
471 
472     std::string defaultQuality = GetSettingItemString(QUALITY_STRING, defaultSetting, setting);
473     if (!defaultQuality.empty()) {
474         ConvertQuality(std::atoi(defaultQuality.c_str()), nativePrinterInfo.defaultValue.defaultPrintQuality);
475     }
476 }
477 
ConvertToNativePrinterInfo(const PrinterInfo & info)478 Print_PrinterInfo *ConvertToNativePrinterInfo(const PrinterInfo &info)
479 {
480     Print_PrinterInfo *nativePrinterInfo = new (std::nothrow) Print_PrinterInfo;
481     if (nativePrinterInfo == nullptr) {
482         PRINT_HILOGW("Print_PrinterInfo allocate fail.");
483         return nullptr;
484     }
485     if (memset_s(nativePrinterInfo, sizeof(Print_PrinterInfo), 0, sizeof(Print_PrinterInfo)) != 0) {
486         PRINT_HILOGW("Print_PrinterInfo memset_s fail.");
487         delete nativePrinterInfo;
488         nativePrinterInfo = nullptr;
489         return nullptr;
490     }
491     nativePrinterInfo->printerId = CopyString(info.GetPrinterId());
492     nativePrinterInfo->printerName = CopyString(info.GetPrinterName());
493     nativePrinterInfo->description = CopyString(info.GetDescription());
494     nativePrinterInfo->detailInfo = nullptr;
495     nativePrinterInfo->printerState = static_cast<Print_PrinterState>(info.GetPrinterStatus());
496     if (info.HasIsDefaultPrinter() && info.GetIsDefaultPrinter() == true) {
497         nativePrinterInfo->isDefaultPrinter = true;
498     }
499     OHOS::Print::PrinterCapability cap;
500     info.GetCapability(cap);
501     if (cap.HasOption() && json::accept(cap.GetOption())) {
502         nlohmann::json capJson = json::parse(cap.GetOption());
503         if (capJson.contains("cupsOptions") && capJson["cupsOptions"].is_object()) {
504             nlohmann::json cupsJson = capJson["cupsOptions"];
505             ParseCupsOptions(cupsJson, *nativePrinterInfo);
506         }
507     }
508     ConvertColorMode(cap.GetColorMode(), nativePrinterInfo->defaultValue.defaultColorMode);
509     ConvertDuplexMode(cap.GetDuplexMode(), nativePrinterInfo->defaultValue.defaultDuplexMode);
510 
511     std::string printerPreference = "";
512     int32_t ret = PrintManagerClient::GetInstance()->GetPrinterPreference(info.GetPrinterId(), printerPreference);
513     if (ret != E_PRINT_NONE) {
514         PRINT_HILOGW("Print_PrinterInfo GetPrinterPreference fail.");
515     } else {
516         ParsePrinterPreference(printerPreference, *nativePrinterInfo);
517     }
518     if (info.HasOption()) {
519         std::string infoOpt = info.GetOption();
520         PRINT_HILOGW("infoOpt json object: %{public}s", infoOpt.c_str());
521         ParseInfoOption(infoOpt, *nativePrinterInfo);
522     }
523     return nativePrinterInfo;
524 }
525 
SetPrintOrientationInPrintJob(const Print_PrintJob & nativePrintJob,PrintJob & printJob)526 void SetPrintOrientationInPrintJob(const Print_PrintJob &nativePrintJob, PrintJob &printJob)
527 {
528     uint32_t ori = static_cast<uint32_t>(nativePrintJob.orientationMode);
529     if (ori == ORIENTATION_MODE_PORTRAIT || ori == ORIENTATION_MODE_REVERSE_PORTRAIT) {
530         printJob.SetIsLandscape(false);
531         printJob.SetIsSequential(true);
532     } else if (ori == ORIENTATION_MODE_LANDSCAPE || ori == ORIENTATION_MODE_REVERSE_LANDSCAPE) {
533         printJob.SetIsLandscape(true);
534         printJob.SetIsSequential(false);
535     }
536 }
537 
SetPrintMarginInPrintJob(const Print_PrintJob & nativePrintJob,PrintJob & printJob)538 void SetPrintMarginInPrintJob(const Print_PrintJob &nativePrintJob, PrintJob &printJob)
539 {
540     PrintMargin margin;
541     if (nativePrintJob.printMargin.topMargin > 0) {
542         margin.SetTop(nativePrintJob.printMargin.topMargin);
543     } else {
544         margin.SetTop(0);
545     }
546     if (nativePrintJob.printMargin.rightMargin > 0) {
547         margin.SetRight(nativePrintJob.printMargin.rightMargin);
548     } else {
549         margin.SetRight(0);
550     }
551     if (nativePrintJob.printMargin.bottomMargin > 0) {
552         margin.SetBottom(nativePrintJob.printMargin.bottomMargin);
553     } else {
554         margin.SetBottom(0);
555     }
556     if (nativePrintJob.printMargin.leftMargin > 0) {
557         margin.SetLeft(nativePrintJob.printMargin.leftMargin);
558     } else {
559         margin.SetLeft(0);
560     }
561     printJob.SetMargin(margin);
562 }
563 
SetPrintPageSizeInPrintJob(const Print_PrintJob & nativePrintJob,PrintJob & printJob)564 bool SetPrintPageSizeInPrintJob(const Print_PrintJob &nativePrintJob, PrintJob &printJob)
565 {
566     PRINT_HILOGI("SetPrintPageSizeInPrintJob in.");
567     if (nativePrintJob.pageSizeId == nullptr) {
568         PRINT_HILOGW("page size is null.");
569         return false;
570     }
571     std::string pageSizeId(nativePrintJob.pageSizeId);
572     PrintPageSize pageSize;
573     if (!PrintPageSize::FindPageSizeById(pageSizeId, pageSize)) {
574         PRINT_HILOGW("cannot find page size: %{public}s.", pageSizeId.c_str());
575         return false;
576     }
577     printJob.SetPageSize(pageSize);
578     PRINT_HILOGI("SetPrintPageSizeInPrintJob out.");
579     return true;
580 }
581 
SetOptionInPrintJob(const Print_PrintJob & nativePrintJob,PrintJob & printJob)582 void SetOptionInPrintJob(const Print_PrintJob &nativePrintJob, PrintJob &printJob)
583 {
584     PRINT_HILOGI("SetOptionInPrintJob in.");
585     nlohmann::json jsonOptions;
586     if (nativePrintJob.jobName != nullptr) {
587         jsonOptions["jobName"] = std::string(nativePrintJob.jobName);
588     }
589     if (nativePrintJob.mediaType != nullptr) {
590         jsonOptions["mediaType"] = std::string(nativePrintJob.mediaType);
591     }
592     jsonOptions["borderless"] = nativePrintJob.borderless ? "true" : "false";
593     jsonOptions["printQuality"] = nativePrintJob.printQuality;
594     jsonOptions["documentFormat"] = GetDocumentFormatString(nativePrintJob.documentFormat);
595     if (nativePrintJob.advancedOptions != nullptr) {
596         jsonOptions["cupsOptions"] = std::string(nativePrintJob.advancedOptions);
597     }
598     std::string option = jsonOptions.dump();
599     PRINT_HILOGD("SetOptionInPrintJob %{public}s", option.c_str());
600     printJob.SetOption(option);
601     PRINT_HILOGI("SetOptionInPrintJob out.");
602 }
603 
ConvertNativeJobToPrintJob(const Print_PrintJob & nativePrintJob,PrintJob & printJob)604 int32_t ConvertNativeJobToPrintJob(const Print_PrintJob &nativePrintJob, PrintJob &printJob)
605 {
606     if (nativePrintJob.fdList == nullptr || nativePrintJob.copyNumber <= 0) {
607         PRINT_HILOGW("ConvertNativeJobToPrintJob invalid param error.");
608         return E_PRINT_INVALID_PARAMETER;
609     }
610     if (!IsValidString(nativePrintJob.printerId)) {
611         PRINT_HILOGW("ConvertNativeJobToPrintJob string empty error.");
612         return E_PRINT_INVALID_PARAMETER;
613     }
614     std::vector<uint32_t> fdList;
615     for (uint32_t i = 0; i < nativePrintJob.fdListCount; i++) {
616         fdList.emplace_back(nativePrintJob.fdList[i]);
617     }
618     printJob.SetFdList(fdList);
619     printJob.SetPrinterId(std::string(nativePrintJob.printerId));
620     printJob.SetCopyNumber(nativePrintJob.copyNumber);
621     printJob.SetDuplexMode(static_cast<uint32_t>(nativePrintJob.duplexMode));
622     printJob.SetColorMode(static_cast<uint32_t>(nativePrintJob.colorMode));
623 
624     SetPrintOrientationInPrintJob(nativePrintJob, printJob);
625     SetPrintMarginInPrintJob(nativePrintJob, printJob);
626     SetPrintPageSizeInPrintJob(nativePrintJob, printJob);
627     SetOptionInPrintJob(nativePrintJob, printJob);
628     return E_PRINT_NONE;
629 }
630 
ConvertStringVectorToPropertyList(const std::vector<std::string> & valueList,Print_PropertyList * propertyList)631 Print_ErrorCode ConvertStringVectorToPropertyList(const std::vector<std::string> &valueList,
632     Print_PropertyList *propertyList)
633 {
634     if (valueList.size() == 0) {
635         PRINT_HILOGW("empty valueList");
636         return PRINT_ERROR_INVALID_PRINTER;
637     }
638     propertyList->list = new (std::nothrow) Print_Property[valueList.size()];
639     if (propertyList->list == nullptr) {
640         PRINT_HILOGW("propertyList->list is null");
641         return PRINT_ERROR_GENERIC_FAILURE;
642     }
643     if (memset_s(propertyList->list, valueList.size() * sizeof(Print_Property), 0,
644         valueList.size() * sizeof(Print_Property)) != 0) {
645         PRINT_HILOGW("memset_s fail");
646         delete[] propertyList->list;
647         propertyList->list = nullptr;
648         return PRINT_ERROR_GENERIC_FAILURE;
649     }
650     uint32_t count = 0;
651     for (size_t i = 0; i < valueList.size(); i++) {
652         std::string keyVal = valueList[i];
653         auto index = keyVal.find('&');
654         if (index == keyVal.npos) {
655             continue;
656         }
657         propertyList->list[count].key = CopyString(keyVal.substr(0, index));
658         propertyList->list[count].value = CopyString(keyVal.substr(index + 1));
659         count++;
660     }
661     propertyList->count = count;
662     return PRINT_ERROR_NONE;
663 }
664 }  // namespace OHOS::Print
665