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