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