• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <vector>
17 
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