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 <securec.h>
17 #include "vendor_helper.h"
18 #include "print_service_converter.h"
19 #include "print_log.h"
20 
21 namespace {
22 const std::string VENDOR_MANAGER_PREFIX = "fwk.";
23 const std::string GLOBAL_ID_DELIMITER = ":";
24 const uint32_t ORIENTATION_OFFSET = 3;
25 const int NUMBER_BASE = 10;
26 const size_t MAX_STRING_COUNT = 1000;
27 }
28 
29 namespace OHOS::Print {
30 
CopyString(const std::string &source)31 char *CopyString(const std::string &source)
32 {
33     auto len = source.length();
34     char *dest = new (std::nothrow) char[len + 1];
35     if (dest == nullptr) {
36         PRINT_HILOGW("allocate failed");
37         return nullptr;
38     }
39     if (strcpy_s(dest, len + 1, source.c_str()) != 0) {
40         PRINT_HILOGW("CopyString strcpy_s failed");
41     }
42     dest[len] = '\0';
43     return dest;
44 }
45 
46 template <typename T1, typename T2>
ConvertArrayToList(const T1 *array, uint32_t count, std::vector<T2> &list, bool (*convertType)(const T1 &, T2 &))47 bool ConvertArrayToList(const T1 *array, uint32_t count, std::vector<T2> &list, bool (*convertType)(const T1 &, T2 &))
48 {
49     if (convertType == nullptr) {
50         PRINT_HILOGW("convertType is null");
51         return false;
52     }
53     if (count == 0) {
54         return true;
55     }
56     if (array == nullptr) {
57         PRINT_HILOGW("array is null");
58         return false;
59     }
60     for (uint32_t i = 0; i < count; ++i) {
61         T2 data;
62         if (convertType(array[i], data)) {
63             list.push_back(data);
64         }
65     }
66     return true;
67 }
68 
69 template <typename T>
ConvertArrayToJson(const T *array, uint32_t count, bool (*convertToJson)(const T &, nlohmann::json &))70 std::string ConvertArrayToJson(const T *array, uint32_t count, bool (*convertToJson)(const T &, nlohmann::json &))
71 {
72     if (array == nullptr || convertToJson == nullptr) {
73         PRINT_HILOGW("invalid params");
74         return "";
75     }
76     std::vector<T> list;
77     for (uint32_t i = 0; i < count; ++i) {
78         AddToUniqueList<T>(list, array[i]);
79     }
80     return ConvertListToJson<T>(list, convertToJson);
81 }
82 
ConvertJsonToStringList(const std::string &jsonString, std::vector<std::string> &list)83 bool ConvertJsonToStringList(const std::string &jsonString, std::vector<std::string> &list)
84 {
85     if (!nlohmann::json::accept(jsonString)) {
86         PRINT_HILOGW("invalid jsonString");
87         return false;
88     }
89     nlohmann::json jsonObject = nlohmann::json::parse(jsonString, nullptr, false);
90     if (jsonObject.is_discarded()) {
91         PRINT_HILOGW("jsonString discarded");
92         return false;
93     }
94     if (!jsonObject.is_array()) {
95         PRINT_HILOGW("jsonObject is not array");
96         return false;
97     }
98     for (auto &element : jsonObject.items()) {
99         nlohmann::json object = element.value();
100         if (object.is_string()) {
101             list.push_back(object.get<std::string>());
102         }
103     }
104     return true;
105 }
106 
ConvertStringToLong(const char *src, long &dst)107 bool ConvertStringToLong(const char *src, long &dst)
108 {
109     if (src == nullptr) {
110         return false;
111     }
112     errno = 0;
113     char *endPtr = nullptr;
114     dst = strtol(src, &endPtr, NUMBER_BASE);
115     if (errno == ERANGE || endPtr == src) {
116         PRINT_HILOGW("ConvertStringToLong fail: %{public}s", src);
117         return false;
118     }
119     return true;
120 }
121 
ConvertColorMode(const Print_ColorMode &code, uint32_t &dst)122 bool ConvertColorMode(const Print_ColorMode &code, uint32_t &dst)
123 {
124     dst = static_cast<uint32_t>(code);
125     if (dst > static_cast<uint32_t>(COLOR_MODE_AUTO)) {
126         return false;
127     }
128     return true;
129 }
ConvertColorModeToJson(const Print_ColorMode &code, nlohmann::json &jsonObject)130 bool ConvertColorModeToJson(const Print_ColorMode &code, nlohmann::json &jsonObject)
131 {
132     jsonObject["color"] = std::to_string(static_cast<int>(code));
133     return true;
134 }
135 
ConvertDuplexMode(const Print_DuplexMode &code, uint32_t &dst)136 bool ConvertDuplexMode(const Print_DuplexMode &code, uint32_t &dst)
137 {
138     dst = static_cast<uint32_t>(code);
139     if (dst > static_cast<uint32_t>(DUPLEX_MODE_TWO_SIDED_SHORT_EDGE)) {
140         return false;
141     }
142     return true;
143 }
ConvertDuplexModeToJson(const Print_DuplexMode &code, nlohmann::json &jsonObject)144 bool ConvertDuplexModeToJson(const Print_DuplexMode &code, nlohmann::json &jsonObject)
145 {
146     jsonObject["duplex"] = std::to_string(static_cast<int>(code));
147     return true;
148 }
149 
ConvertQuality(const Print_Quality &code, uint32_t &dst)150 bool ConvertQuality(const Print_Quality &code, uint32_t &dst)
151 {
152     dst = static_cast<uint32_t>(code);
153     if (dst < static_cast<uint32_t>(PRINT_QUALITY_DRAFT) || dst > static_cast<uint32_t>(PRINT_QUALITY_HIGH)) {
154         return false;
155     }
156     return true;
157 }
ConvertQualityToJson(const Print_Quality &code, nlohmann::json &jsonObject)158 bool ConvertQualityToJson(const Print_Quality &code, nlohmann::json &jsonObject)
159 {
160     jsonObject["quality"] = std::to_string(static_cast<int>(code));
161     return true;
162 }
163 
ConvertStringToPrinterState(const std::string &stateData, Print_PrinterState &state)164 bool ConvertStringToPrinterState(const std::string &stateData, Print_PrinterState &state)
165 {
166     long result = 0;
167     if (!ConvertStringToLong(stateData.c_str(), result)) {
168         if (!nlohmann::json::accept(stateData)) {
169             PRINT_HILOGW("invalid stateData");
170             return false;
171         }
172         nlohmann::json jsonObject = nlohmann::json::parse(stateData, nullptr, false);
173         if (jsonObject.is_discarded()) {
174             PRINT_HILOGW("stateData discarded");
175             return false;
176         }
177         if (!jsonObject.contains("state") || !jsonObject["state"].is_string()) {
178             PRINT_HILOGW("can not find state");
179             return false;
180         }
181         std::string stateValue = jsonObject["state"].get<std::string>();
182         if (!ConvertStringToLong(stateValue.c_str(), result)) {
183             return false;
184         }
185     }
186     if (result < 0 || result > PRINTER_UNAVAILABLE + 1) {
187         PRINT_HILOGW("invalid state");
188         return false;
189     }
190     if (result == PRINTER_UNAVAILABLE + 1) {
191         state = PRINTER_UNAVAILABLE;
192     } else if (result == 1) {
193         state = PRINTER_BUSY;
194     } else {
195         state = PRINTER_IDLE;
196     }
197     return true;
198 }
199 
LogDiscoveryItem(const Print_DiscoveryItem *discoveryItem)200 void LogDiscoveryItem(const Print_DiscoveryItem *discoveryItem)
201 {
202     if (discoveryItem == nullptr) {
203         PRINT_HILOGW("discoveryItem is null");
204         return;
205     }
206     if (discoveryItem->printerId != nullptr) {
207         PRINT_HILOGD("printerId: %{public}s", discoveryItem->printerId);
208     } else {
209         PRINT_HILOGW("printerId is null");
210     }
211     if (discoveryItem->printerName != nullptr) {
212         PRINT_HILOGD("printerName: %{public}s", discoveryItem->printerName);
213     } else {
214         PRINT_HILOGW("printerName is null");
215     }
216     if (discoveryItem->description != nullptr) {
217         PRINT_HILOGD("description: %{public}s", discoveryItem->description);
218     }
219     if (discoveryItem->location != nullptr) {
220         PRINT_HILOGD("location: %{public}s", discoveryItem->location);
221     }
222     if (discoveryItem->makeAndModel != nullptr) {
223         PRINT_HILOGD("makeAndModel: %{public}s", discoveryItem->makeAndModel);
224     } else {
225         PRINT_HILOGW("makeAndModel is null");
226     }
227     if (discoveryItem->printerUri != nullptr) {
228         PRINT_HILOGD("printerUri: %{public}s", discoveryItem->printerUri);
229     } else {
230         PRINT_HILOGW("printerUri is null");
231     }
232     if (discoveryItem->printerUuid != nullptr) {
233         PRINT_HILOGD("printerUuid: %{public}s", discoveryItem->printerUuid);
234     }
235 }
236 
LogPageCapability(const Print_PrinterCapability *capability)237 void LogPageCapability(const Print_PrinterCapability *capability)
238 {
239     if (capability == nullptr) {
240         PRINT_HILOGW("capability is null");
241         return;
242     }
243     if (capability->supportedPageSizes != nullptr && capability->supportedPageSizesCount > 0) {
244         for (uint32_t i = 0; i < capability->supportedPageSizesCount; ++i) {
245             if (capability->supportedPageSizes[i].id != nullptr) {
246                 PRINT_HILOGD("page id = %{public}s", capability->supportedPageSizes[i].id);
247             }
248             if (capability->supportedPageSizes[i].name != nullptr) {
249                 PRINT_HILOGD("page name = %{public}s", capability->supportedPageSizes[i].name);
250             }
251             PRINT_HILOGD("page size = %{public}u x %{public}u", capability->supportedPageSizes[i].width,
252                          capability->supportedPageSizes[i].height);
253         }
254     }
255     if (capability->supportedMediaTypes != nullptr) {
256         PRINT_HILOGD("media types = %{public}s", capability->supportedMediaTypes);
257     }
258     if (capability->supportedPaperSources != nullptr) {
259         PRINT_HILOGD("Paper Sources = %{public}s", capability->supportedPaperSources);
260     }
261 }
262 
LogOtherCapability(const Print_PrinterCapability *capability)263 void LogOtherCapability(const Print_PrinterCapability *capability)
264 {
265     if (capability == nullptr) {
266         PRINT_HILOGW("capability is null");
267         return;
268     }
269     if (capability->supportedColorModes != nullptr && capability->supportedColorModesCount > 0) {
270         for (uint32_t i = 0; i < capability->supportedColorModesCount; ++i) {
271             PRINT_HILOGD("color mode = %{public}u", static_cast<uint32_t>(capability->supportedColorModes[i]));
272         }
273     }
274     if (capability->supportedDuplexModes != nullptr && capability->supportedDuplexModesCount > 0) {
275         for (uint32_t i = 0; i < capability->supportedDuplexModesCount; ++i) {
276             PRINT_HILOGD("duplex mode = %{public}u", static_cast<uint32_t>(capability->supportedDuplexModes[i]));
277         }
278     }
279     if (capability->supportedQualities != nullptr && capability->supportedQualitiesCount > 0) {
280         for (uint32_t i = 0; i < capability->supportedQualitiesCount; ++i) {
281             PRINT_HILOGD("quality mode = %{public}u", static_cast<uint32_t>(capability->supportedQualities[i]));
282         }
283     }
284     PRINT_HILOGD("copy count = %{public}u", capability->supportedCopies);
285     if (capability->supportedResolutions != nullptr && capability->supportedResolutionsCount > 0) {
286         for (uint32_t i = 0; i < capability->supportedResolutionsCount; ++i) {
287             PRINT_HILOGD("dpi = %{public}u x %{public}u", capability->supportedResolutions[i].horizontalDpi,
288                          capability->supportedResolutions[i].verticalDpi);
289         }
290     }
291     if (capability->supportedOrientations != nullptr && capability->supportedOrientationsCount > 0) {
292         for (uint32_t i = 0; i < capability->supportedOrientationsCount; ++i) {
293             PRINT_HILOGD("Orientation = %{public}u", static_cast<uint32_t>(capability->supportedOrientations[i]));
294         }
295     }
296     if (capability->advancedCapability != nullptr) {
297         PRINT_HILOGD("advancedCapability = %{public}s", capability->advancedCapability);
298     }
299 }
300 
LogDefaultValue(const Print_DefaultValue *defaultValue)301 void LogDefaultValue(const Print_DefaultValue *defaultValue)
302 {
303     if (defaultValue == nullptr) {
304         PRINT_HILOGW("defaultValue is null");
305         return;
306     }
307     PRINT_HILOGD("default color mode = %{public}u", static_cast<uint32_t>(defaultValue->defaultColorMode));
308     PRINT_HILOGD("default duplex mode = %{public}u", static_cast<uint32_t>(defaultValue->defaultDuplexMode));
309     if (defaultValue->defaultMediaType != nullptr) {
310         PRINT_HILOGD("defaultMediaType = %{public}s", defaultValue->defaultMediaType);
311     }
312     if (defaultValue->defaultPageSizeId != nullptr) {
313         PRINT_HILOGD("defaultPageSizeId = %{public}s", defaultValue->defaultPageSizeId);
314     }
315     PRINT_HILOGD("defaultMargin = [%{public}u, %{public}u, %{public}u, %{public}u]",
316                  defaultValue->defaultMargin.leftMargin, defaultValue->defaultMargin.topMargin,
317                  defaultValue->defaultMargin.rightMargin, defaultValue->defaultMargin.bottomMargin);
318     if (defaultValue->defaultPaperSource != nullptr) {
319         PRINT_HILOGD("defaultPaperSource = %{public}s", defaultValue->defaultPaperSource);
320     }
321     PRINT_HILOGD("defaultPrintQuality = %{public}u", static_cast<uint32_t>(defaultValue->defaultPrintQuality));
322     PRINT_HILOGD("defaultCopies = %{public}u", defaultValue->defaultCopies);
323     PRINT_HILOGD("defaultResolution = %{public}u x %{public}u", defaultValue->defaultResolution.horizontalDpi,
324                  defaultValue->defaultResolution.verticalDpi);
325     PRINT_HILOGD("defaultOrientation = %{public}u", static_cast<uint32_t>(defaultValue->defaultOrientation));
326     if (defaultValue->otherDefaultValues != nullptr) {
327         PRINT_HILOGD("otherDefaultValues = %{public}s", defaultValue->otherDefaultValues);
328     }
329 }
330 
LogProperties(const Print_PropertyList *propertyList)331 void LogProperties(const Print_PropertyList *propertyList)
332 {
333     if (propertyList == nullptr) {
334         PRINT_HILOGW("propertyList is null");
335         return;
336     }
337     if (propertyList->count == 0 || propertyList->list == nullptr) {
338         PRINT_HILOGW("propertyList empty");
339         return;
340     }
341     for (uint32_t i = 0; i < propertyList->count; ++i) {
342         if (propertyList->list[i].key == nullptr) {
343             PRINT_HILOGW("propertyList item empty: %{public}u", i);
344             continue;
345         }
346         PRINT_HILOGD("LogProperties key: %{public}s", propertyList->list[i].key);
347         if (propertyList->list[i].value == nullptr) {
348             PRINT_HILOGW("propertyList value empty: %{public}u", i);
349             continue;
350         }
351         PRINT_HILOGD("LogProperties value: %{public}s", propertyList->list[i].value);
352     }
353 }
354 
FindPropertyFromPropertyList(const Print_PropertyList *propertyList, const std::string &keyName)355 std::string FindPropertyFromPropertyList(const Print_PropertyList *propertyList, const std::string &keyName)
356 {
357     if (propertyList == nullptr) {
358         PRINT_HILOGW("propertyList is null");
359         return "";
360     }
361     if (propertyList->count == 0 || propertyList->list == nullptr) {
362         PRINT_HILOGW("propertyList empty");
363         return "";
364     }
365     for (uint32_t i = 0; i < propertyList->count; ++i) {
366         if (propertyList->list[i].key == nullptr) {
367             PRINT_HILOGW("propertyList key empty: %{public}u", i);
368             continue;
369         }
370         PRINT_HILOGD("FindPropertyFromPropertyList key: %{public}s", propertyList->list[i].key);
371         if (strcmp(keyName.c_str(), propertyList->list[i].key) != 0) {
372             continue;
373         }
374         if (propertyList->list[i].value == nullptr) {
375             PRINT_HILOGW("propertyList value empty, key: %{public}s", keyName.c_str());
376             break;
377         }
378         PRINT_HILOGD("FindPropertyFromPropertyList value: %{public}s", propertyList->list[i].value);
379         return std::string(propertyList->list[i].value);
380     }
381     return "";
382 }
UpdatePrinterInfoWithDiscovery(PrinterInfo &info, const Print_DiscoveryItem *discoveryItem)383 bool UpdatePrinterInfoWithDiscovery(PrinterInfo &info, const Print_DiscoveryItem *discoveryItem)
384 {
385     if (discoveryItem == nullptr) {
386         PRINT_HILOGW("discoveryItem is null");
387         return false;
388     }
389     if (discoveryItem->printerId == nullptr || discoveryItem->printerName == nullptr) {
390         PRINT_HILOGW("invalid discoveryItem");
391         return false;
392     }
393     info.SetPrinterId(std::string(discoveryItem->printerId));
394     std::string name(discoveryItem->printerName);
395     name += " UNI";
396     info.SetPrinterName(name);
397     if (discoveryItem->description != nullptr) {
398         info.SetDescription(std::string(discoveryItem->description));
399     }
400     if (discoveryItem->printerUri != nullptr) {
401         info.SetUri(std::string(discoveryItem->printerUri));
402     }
403     if (discoveryItem->makeAndModel != nullptr) {
404         info.SetPrinterMake(std::string(discoveryItem->makeAndModel));
405     }
406     if (discoveryItem->printerUri != nullptr && discoveryItem->makeAndModel != nullptr) {
407         PRINT_HILOGD("printerUri: %{public}s", discoveryItem->printerUri);
408         nlohmann::json option;
409         option["printerName"] = name;
410         option["printerUri"] = std::string(discoveryItem->printerUri);
411         option["make"] = std::string(discoveryItem->makeAndModel);
412         info.SetOption(option.dump());
413     }
414     return true;
415 }
416 
AddUniquePageSize(std::vector<PrintPageSize> &pageSizeList, const PrintPageSize &printPageSize)417 void AddUniquePageSize(std::vector<PrintPageSize> &pageSizeList, const PrintPageSize &printPageSize)
418 {
419     for (auto const &item : pageSizeList) {
420         if (item.GetId() == printPageSize.GetId()) {
421             return;
422         }
423     }
424     pageSizeList.push_back(printPageSize);
425 }
426 
UpdateDefaultPageSizeId(PrinterCapability &printerCap, const std::string &defaultPageId, const std::string &pageId, const Print_PageSize &page)427 bool UpdateDefaultPageSizeId(PrinterCapability &printerCap, const std::string &defaultPageId, const std::string &pageId,
428                              const Print_PageSize &page)
429 {
430     if (page.id != nullptr && defaultPageId == std::string(page.id)) {
431         printerCap.SetPrinterAttrNameAndValue("defaultPageSizeId", pageId.c_str());
432         return true;
433     }
434     return false;
435 }
436 
UpdatePageSizeCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)437 bool UpdatePageSizeCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
438                               const Print_DefaultValue *defaultValue)
439 {
440     if (capability == nullptr || capability->supportedPageSizes == nullptr) {
441         PRINT_HILOGW("supportedPageSizes is null");
442         return false;
443     }
444     std::string defaultPageId;
445     if (defaultValue != nullptr && defaultValue->defaultPageSizeId != nullptr) {
446         defaultPageId = defaultValue->defaultPageSizeId;
447     }
448     std::vector<PrintPageSize> pageSizeList;
449     for (uint32_t i = 0; i < capability->supportedPageSizesCount; ++i) {
450         PrintPageSize printPageSize;
451         if (capability->supportedPageSizes[i].name != nullptr) {
452             std::string pageSizeName(capability->supportedPageSizes[i].name);
453             PAGE_SIZE_ID id = PrintPageSize::MatchPageSize(pageSizeName);
454             if (!id.empty() && PrintPageSize::FindPageSizeById(id, printPageSize)) {
455                 AddUniquePageSize(pageSizeList, printPageSize);
456                 UpdateDefaultPageSizeId(printerCap, defaultPageId, id, capability->supportedPageSizes[i]);
457                 PRINT_HILOGD("page size matched = %{public}s", id.c_str());
458                 continue;
459             }
460         }
461         if (capability->supportedPageSizes[i].id != nullptr) {
462             PAGE_SIZE_ID id = std::string(capability->supportedPageSizes[i].id);
463             if (!id.empty() && PrintPageSize::FindPageSizeById(id, printPageSize)) {
464                 AddUniquePageSize(pageSizeList, printPageSize);
465                 UpdateDefaultPageSizeId(printerCap, defaultPageId, id, capability->supportedPageSizes[i]);
466                 PRINT_HILOGD("page size matched = %{public}s", id.c_str());
467                 continue;
468             }
469         }
470         PRINT_HILOGD("page size = %{public}u x %{public}u", capability->supportedPageSizes[i].width,
471                      capability->supportedPageSizes[i].height);
472     }
473     printerCap.SetSupportedPageSize(pageSizeList);
474     std::string pageSizeJson = ConvertListToJson<PrintPageSize>(pageSizeList, ConvertPageSizeToJson);
475     printerCap.SetPrinterAttrNameAndValue("supportedPageSizeArray", pageSizeJson.c_str());
476     return true;
477 }
478 
UpdateQualityCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)479 bool UpdateQualityCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
480 {
481     if (capability == nullptr || capability->supportedQualities == nullptr) {
482         PRINT_HILOGW("supportedQualities is null");
483         return false;
484     }
485     std::vector<uint32_t> supportedQualityList;
486     if (ConvertArrayToList<Print_Quality, uint32_t>(capability->supportedQualities,
487         capability->supportedQualitiesCount, supportedQualityList, ConvertQuality)) {
488         printerCap.SetSupportedQuality(supportedQualityList);
489     }
490     std::string supportedQualities = ConvertArrayToJson<Print_Quality>(
491         capability->supportedQualities, capability->supportedQualitiesCount, ConvertQualityToJson);
492     PRINT_HILOGD("quality: %{public}s", supportedQualities.c_str());
493     if (!supportedQualities.empty()) {
494         printerCap.SetPrinterAttrNameAndValue("print-quality-supported", supportedQualities.c_str());
495     }
496     return true;
497 }
498 
UpdateColorCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)499 bool UpdateColorCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
500 {
501     if (capability == nullptr || capability->supportedColorModes == nullptr) {
502         PRINT_HILOGW("supportedColorModes is null");
503         return false;
504     }
505     std::vector<uint32_t> supportedColorModes;
506     if (ConvertArrayToList<Print_ColorMode, uint32_t>(capability->supportedColorModes,
507         capability->supportedColorModesCount, supportedColorModes, ConvertColorMode)) {
508         printerCap.SetSupportedColorMode(supportedColorModes);
509     }
510     std::string colorModeJson = ConvertArrayToJson<Print_ColorMode>(
511         capability->supportedColorModes, capability->supportedColorModesCount, ConvertColorModeToJson);
512     if (!colorModeJson.empty()) {
513         printerCap.SetPrinterAttrNameAndValue("print-color-mode-supported", colorModeJson.c_str());
514     }
515     for (uint32_t i = 0; i < capability->supportedColorModesCount; ++i) {
516         if (capability->supportedColorModes[i] == Print_ColorMode::COLOR_MODE_COLOR) {
517             printerCap.SetColorMode(ColorModeCode::COLOR_MODE_COLOR);
518             break;
519         }
520     }
521     return true;
522 }
523 
UpdateDuplexCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)524 bool UpdateDuplexCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
525 {
526     if (capability == nullptr || capability->supportedDuplexModes == nullptr) {
527         PRINT_HILOGW("supportedDuplexModes is null");
528         return false;
529     }
530     std::vector<uint32_t> supportedDuplexModes;
531     if (ConvertArrayToList<Print_DuplexMode, uint32_t>(capability->supportedDuplexModes,
532         capability->supportedDuplexModesCount, supportedDuplexModes, ConvertDuplexMode)) {
533         printerCap.SetSupportedDuplexMode(supportedDuplexModes);
534     }
535     std::string duplexModeJson = ConvertArrayToJson<Print_DuplexMode>(
536         capability->supportedDuplexModes, capability->supportedDuplexModesCount, ConvertDuplexModeToJson);
537     if (!duplexModeJson.empty()) {
538         printerCap.SetPrinterAttrNameAndValue("sides-supported", duplexModeJson.c_str());
539     }
540     if (capability->supportedDuplexModesCount > 1) {
541         printerCap.SetDuplexMode(static_cast<uint32_t>(Print_DuplexMode::DUPLEX_MODE_TWO_SIDED_LONG_EDGE));
542     }
543     return true;
544 }
UpdateResolutionCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)545 bool UpdateResolutionCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
546 {
547     if (capability == nullptr || capability->supportedResolutions == nullptr) {
548         PRINT_HILOGW("supportedResolutions is null");
549         return false;
550     }
551     std::vector<PrintResolution> resolutionList;
552     nlohmann::json resolutionArray = nlohmann::json::array();
553     for (uint32_t i = 0; i < capability->supportedResolutionsCount; ++i) {
554         PrintResolution printResolution;
555         uint32_t xRes = capability->supportedResolutions[i].horizontalDpi;
556         uint32_t yRes = capability->supportedResolutions[i].verticalDpi;
557         printResolution.SetHorizontalDpi(xRes);
558         printResolution.SetVerticalDpi(yRes);
559         PRINT_HILOGD("resolution = %{public}u x %{public}u", xRes, yRes);
560         resolutionList.push_back(printResolution);
561         nlohmann::json object;
562         object["horizontalDpi"] = xRes;
563         object["verticalDpi"] = yRes;
564         resolutionArray.push_back(object);
565     }
566     printerCap.SetResolution(resolutionList);
567     printerCap.SetPrinterAttrNameAndValue("printer-resolution-supported", resolutionArray.dump().c_str());
568     return true;
569 }
570 
UpdateResolutionDefaultValue(PrinterCapability &printerCap, const Print_DefaultValue *defaultValue)571 bool UpdateResolutionDefaultValue(PrinterCapability &printerCap, const Print_DefaultValue *defaultValue)
572 {
573     if (defaultValue == nullptr) {
574         PRINT_HILOGW("defaultValue is null");
575         return false;
576     }
577     nlohmann::json object;
578     object["horizontalDpi"] = defaultValue->defaultResolution.horizontalDpi;
579     object["verticalDpi"] = defaultValue->defaultResolution.verticalDpi;
580     printerCap.SetPrinterAttrNameAndValue("printer-resolution-default", object.dump().c_str());
581     return true;
582 }
583 
UpdateCopiesCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)584 bool UpdateCopiesCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
585                             const Print_DefaultValue *defaultValue)
586 {
587     if (capability == nullptr || defaultValue == nullptr) {
588         PRINT_HILOGW("capability or defaultValue is null");
589         return false;
590     }
591     printerCap.SetPrinterAttrNameAndValue("copies-supported", std::to_string(capability->supportedCopies).c_str());
592     printerCap.SetPrinterAttrNameAndValue("copies-default", std::to_string(defaultValue->defaultCopies).c_str());
593     return true;
594 }
595 
UpdateOrientationCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)596 bool UpdateOrientationCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
597                                  const Print_DefaultValue *defaultValue)
598 {
599     if (capability == nullptr || defaultValue == nullptr) {
600         PRINT_HILOGW("capability or defaultValue is null");
601         return false;
602     }
603     printerCap.SetPrinterAttrNameAndValue("orientation-requested-default",
604                                           std::to_string(defaultValue->defaultOrientation).c_str());
605     if (capability->supportedOrientations != nullptr) {
606         nlohmann::json supportedOrientationArray = nlohmann::json::array();
607         std::vector<uint32_t> supportedOrientations;
608         for (uint32_t i = 0; i < capability->supportedOrientationsCount; ++i) {
609             int orientationEnum = static_cast<int>(capability->supportedOrientations[i]) + ORIENTATION_OFFSET;
610             supportedOrientationArray.push_back(orientationEnum);
611             supportedOrientations.push_back(static_cast<uint32_t>(orientationEnum));
612         }
613         printerCap.SetSupportedOrientation(supportedOrientations);
614         printerCap.SetPrinterAttrNameAndValue("orientation-requested-supported",
615                                               supportedOrientationArray.dump().c_str());
616     }
617     return true;
618 }
619 
UpdateMediaCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)620 bool UpdateMediaCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
621                            const Print_DefaultValue *defaultValue)
622 {
623     if (capability == nullptr || defaultValue == nullptr) {
624         PRINT_HILOGW("capability or defaultValue is null");
625         return false;
626     }
627     if (capability->supportedMediaTypes != nullptr) {
628         printerCap.SetPrinterAttrNameAndValue("media-type-supported", capability->supportedMediaTypes);
629         std::string mdiaTypeJson(capability->supportedMediaTypes);
630         std::vector<std::string> mediaTypeList;
631         if (ConvertJsonToStringList(mdiaTypeJson, mediaTypeList)) {
632             printerCap.SetSupportedMediaType(mediaTypeList);
633         } else {
634             PRINT_HILOGW("invalid media types");
635         }
636     }
637     if (defaultValue->defaultMediaType != nullptr) {
638         printerCap.SetPrinterAttrNameAndValue("media-type-default", defaultValue->defaultMediaType);
639     }
640     if (capability->supportedPaperSources != nullptr) {
641         printerCap.SetPrinterAttrNameAndValue("media-source-supported", capability->supportedPaperSources);
642     }
643     if (defaultValue->defaultPaperSource != nullptr) {
644         printerCap.SetPrinterAttrNameAndValue("media-source-default", defaultValue->defaultPaperSource);
645     }
646     return true;
647 }
UpdateMarginCapability(PrinterCapability &printerCap, const Print_DefaultValue *defaultValue)648 bool UpdateMarginCapability(PrinterCapability &printerCap, const Print_DefaultValue *defaultValue)
649 {
650     if (defaultValue == nullptr) {
651         PRINT_HILOGW("defaultValue is null");
652         return false;
653     }
654     PrintMargin printMargin;
655     printMargin.SetLeft(defaultValue->defaultMargin.leftMargin);
656     printMargin.SetTop(defaultValue->defaultMargin.topMargin);
657     printMargin.SetRight(defaultValue->defaultMargin.rightMargin);
658     printMargin.SetBottom(defaultValue->defaultMargin.bottomMargin);
659     PRINT_HILOGD("margin left = %{public}u, top =  %{public}u, right = %{public}u, bottom =  %{public}u",
660                  defaultValue->defaultMargin.leftMargin, defaultValue->defaultMargin.topMargin,
661                  defaultValue->defaultMargin.rightMargin, defaultValue->defaultMargin.bottomMargin);
662     printerCap.SetMinMargin(printMargin);
663     return true;
664 }
UpdatePrinterCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)665 bool UpdatePrinterCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
666                              const Print_DefaultValue *defaultValue)
667 {
668     if (capability == nullptr || defaultValue == nullptr) {
669         PRINT_HILOGW("capability or defaultValue is null");
670         return false;
671     }
672     if (!UpdatePageSizeCapability(printerCap, capability, defaultValue)) {
673         return false;
674     }
675     UpdateColorCapability(printerCap, capability);
676     uint32_t defaultColorMode = static_cast<uint32_t>(defaultValue->defaultColorMode);
677     printerCap.SetPrinterAttrNameAndValue("defaultColorMode", std::to_string(defaultColorMode).c_str());
678     UpdateDuplexCapability(printerCap, capability);
679     uint32_t defaultDuplexMode = static_cast<uint32_t>(defaultValue->defaultDuplexMode);
680     printerCap.SetPrinterAttrNameAndValue("sides-default", std::to_string(defaultDuplexMode).c_str());
681     UpdateQualityCapability(printerCap, capability);
682     UpdateResolutionCapability(printerCap, capability);
683     UpdateResolutionDefaultValue(printerCap, defaultValue);
684     UpdateCopiesCapability(printerCap, capability, defaultValue);
685     UpdateOrientationCapability(printerCap, capability, defaultValue);
686     UpdateMediaCapability(printerCap, capability, defaultValue);
687     UpdateMarginCapability(printerCap, defaultValue);
688     return true;
689 }
690 
UpdatePrinterInfoWithCapability(PrinterInfo &info, const Print_DiscoveryItem *discoveryItem, const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)691 bool UpdatePrinterInfoWithCapability(PrinterInfo &info, const Print_DiscoveryItem *discoveryItem,
692                                      const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)
693 {
694     PrinterCapability printerCap;
695     if (!UpdatePrinterCapability(printerCap, capability, defaultValue)) {
696         PRINT_HILOGW("update capability fail");
697         return false;
698     }
699     nlohmann::json options;
700     if (discoveryItem != nullptr) {
701         if (discoveryItem->makeAndModel != nullptr) {
702             options["make"] = std::string(discoveryItem->makeAndModel);
703         }
704         if (discoveryItem->printerName != nullptr) {
705             options["printerName"] = info.GetPrinterName();
706         }
707         if (discoveryItem->printerUuid != nullptr) {
708             options["printer-uuid"] = std::string(discoveryItem->printerUuid);
709         }
710     }
711     nlohmann::json cupsOptionsJson = printerCap.GetPrinterAttrGroupJson();
712     options["cupsOptions"] = cupsOptionsJson;
713     std::string optionStr = options.dump();
714     PRINT_HILOGD("SetOption: %{public}s", optionStr.c_str());
715     printerCap.SetOption(optionStr);
716     info.SetCapability(printerCap);
717     info.Dump();
718     return true;
719 }
720 
ConvertVendorCapabilityToPrinterInfo(const Print_DiscoveryItem *printer, const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)721 std::shared_ptr<PrinterInfo> ConvertVendorCapabilityToPrinterInfo(const Print_DiscoveryItem *printer,
722                                                                   const Print_PrinterCapability *capability,
723                                                                   const Print_DefaultValue *defaultValue)
724 {
725     if (printer == nullptr || printer->printerId == nullptr) {
726         PRINT_HILOGW("printer null");
727         return nullptr;
728     }
729     std::shared_ptr<PrinterInfo> info = std::make_shared<PrinterInfo>();
730     if (info == nullptr) {
731         return nullptr;
732     }
733     if (!UpdatePrinterInfoWithDiscovery(*info, printer)) {
734         PRINT_HILOGW("update printer info fail");
735         return nullptr;
736     }
737     UpdatePrinterInfoWithCapability(*info, printer, capability, defaultValue);
738     return info;
739 }
740 
ConvertStringVectorToStringList(const std::vector<std::string> &stringVector, Print_StringList &stringList)741 bool ConvertStringVectorToStringList(const std::vector<std::string> &stringVector, Print_StringList &stringList)
742 {
743     size_t count = stringVector.size();
744     if (count == 0 || count > MAX_STRING_COUNT) {
745         return false;
746     }
747     stringList.count = 0;
748     stringList.list = new (std::nothrow) char *[count];
749     if (stringList.list == nullptr) {
750         PRINT_HILOGW("stringList list allocate fail");
751         return false;
752     }
753     if (memset_s(stringList.list, count * sizeof(char *), 0, count * sizeof(char *)) != 0) {
754         PRINT_HILOGW("memset_s fail");
755         delete[] stringList.list;
756         stringList.list = nullptr;
757         return false;
758     }
759     for (auto const &key : stringVector) {
760         stringList.list[stringList.count] = CopyString(key);
761         stringList.count++;
762     }
763     return true;
764 }
765 
ReleaseStringList(Print_StringList &stringList)766 void ReleaseStringList(Print_StringList &stringList)
767 {
768     if (stringList.list != nullptr) {
769         for (uint32_t i = 0; i < stringList.count; i++) {
770             if (stringList.list[i] != nullptr) {
771                 delete[] stringList.list[i];
772                 stringList.list[i] = nullptr;
773             }
774         }
775         delete[] stringList.list;
776         stringList.list = nullptr;
777     }
778     stringList.count = 0;
779 }
780 }
781