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