1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <vector>
17 #include <string>
18
19 #include "print_cups_attribute.h"
20 #include "print_service_converter.h"
21 #include "print_log.h"
22
23 namespace OHOS::Print {
24 template <typename T>
ParseAttributeToValue(ipp_t *response, const std::string &keyword, T &value, bool (*convertAttr)(const char *src, T &dst))25 bool ParseAttributeToValue(ipp_t *response, const std::string &keyword, T &value,
26 bool (*convertAttr)(const char *src, T &dst))
27 {
28 if (convertAttr == nullptr) {
29 PRINT_HILOGW("convertAttr is null");
30 return false;
31 }
32 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_KEYWORD);
33 if (attrPtr == nullptr) {
34 PRINT_HILOGW("attrPtr is null");
35 return false;
36 }
37 const char *attrString = ippGetString(attrPtr, 0, NULL);
38 if (attrString == nullptr) {
39 PRINT_HILOGW("attrString is null");
40 return false;
41 }
42 PRINT_HILOGD("attrString: %{public}s", attrString);
43 if (!convertAttr(attrString, value)) {
44 PRINT_HILOGW("ConvertFunction fail");
45 return false;
46 }
47 return true;
48 }
49
50 template <typename T>
ParseAttributesToList(ipp_t *response, const std::string &keyword, std::vector<T> &list, bool (*convertAttr)(const char *src, T &dst))51 bool ParseAttributesToList(ipp_t *response, const std::string &keyword, std::vector<T> &list,
52 bool (*convertAttr)(const char *src, T &dst))
53 {
54 if (convertAttr == nullptr) {
55 PRINT_HILOGW("convertAttr is null");
56 return false;
57 }
58 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_KEYWORD);
59 if (attrPtr == nullptr) {
60 PRINT_HILOGW("attrPtr is null");
61 return false;
62 }
63 int num = ippGetCount(attrPtr);
64 PRINT_HILOGD("number of values %{public}d", num);
65 for (int i = 0; i < num; i++) {
66 const char *attrString = ippGetString(attrPtr, i, NULL);
67 if (attrString == nullptr) {
68 PRINT_HILOGW("attrString is null");
69 continue;
70 }
71 PRINT_HILOGD("attrString: %{public}s", attrString);
72 T attrValue;
73 if (!convertAttr(attrString, attrValue)) {
74 PRINT_HILOGW("ConvertFunction fail");
75 continue;
76 }
77 AddToUniqueList<T>(list, attrValue);
78 }
79 return true;
80 }
81
ConvertDuplexModeCode(const char *src, DuplexModeCode &dst)82 bool ConvertDuplexModeCode(const char *src, DuplexModeCode &dst)
83 {
84 if (src == nullptr) {
85 return false;
86 }
87 if (strcasestr(src, CUPS_SIDES_ONE_SIDED)) {
88 dst = DUPLEX_MODE_ONE_SIDED;
89 } else if (strcasestr(src, CUPS_SIDES_TWO_SIDED_PORTRAIT)) {
90 dst = DUPLEX_MODE_TWO_SIDED_LONG_EDGE;
91 } else if (strcasestr(src, CUPS_SIDES_TWO_SIDED_LANDSCAPE)) {
92 dst = DUPLEX_MODE_TWO_SIDED_SHORT_EDGE;
93 } else {
94 return false;
95 }
96 return true;
97 }
98
ConvertIppAttributesToJsonString(ipp_t *response, const std::string &keyword)99 std::string ConvertIppAttributesToJsonString(ipp_t *response, const std::string &keyword)
100 {
101 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_KEYWORD);
102 if (attrPtr == nullptr) {
103 return "";
104 }
105 nlohmann::json jsonArray = nlohmann::json::array();
106 for (int i = 0; i < ippGetCount(attrPtr); i++) {
107 const char *attrString = ippGetString(attrPtr, i, NULL);
108 if (attrString == nullptr) {
109 continue;
110 }
111 jsonArray.push_back(attrString);
112 }
113 return jsonArray.dump();
114 }
115
SetCapabilityGroupAttribute(ipp_t *response, PrinterCapability &printerCaps)116 void SetCapabilityGroupAttribute(ipp_t *response, PrinterCapability &printerCaps)
117 {
118 ipp_attribute_t *attrPtr;
119 if ((attrPtr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) {
120 printerCaps.SetPrinterAttrNameAndValue("printer-state",
121 ippEnumString("printer-state", ippGetInteger(attrPtr, 0)));
122 }
123 if ((attrPtr = ippFindAttribute(response, "printer-info", IPP_TAG_TEXTLANG)) != NULL) {
124 printerCaps.SetPrinterAttrNameAndValue("printer-info", ippGetString(attrPtr, 0, NULL));
125 }
126 if ((attrPtr = ippFindAttribute(response, "printer-location", IPP_TAG_TEXT)) != NULL) {
127 printerCaps.SetPrinterAttrNameAndValue("printer-location", ippGetString(attrPtr, 0, NULL));
128 }
129 }
130
ParseDuplexModeAttributes(ipp_t *response, PrinterCapability &printerCaps)131 void ParseDuplexModeAttributes(ipp_t *response, PrinterCapability &printerCaps)
132 {
133 std::string keyword = "sides-supported";
134 std::vector<DuplexModeCode> list;
135 ParseAttributesToList(response, keyword, list, ConvertDuplexModeCode);
136 std::string duplexModeJson = ConvertListToJson<DuplexModeCode>(list, ConvertDuplexModeToJson);
137 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), duplexModeJson.c_str());
138 size_t num = list.size();
139 if (static_cast<int>(num) <= 1) {
140 printerCaps.SetDuplexMode((uint32_t)DUPLEX_MODE_ONE_SIDED);
141 } else {
142 printerCaps.SetDuplexMode((uint32_t)DUPLEX_MODE_TWO_SIDED_LONG_EDGE);
143 }
144 printerCaps.SetSupportedDuplexMode(std::vector<uint32_t>(list.begin(), list.end()));
145
146 keyword = "sides-default";
147 DuplexModeCode code;
148 if (ParseAttributeToValue<DuplexModeCode>(response, keyword, code, ConvertDuplexModeCode)) {
149 uint32_t value = static_cast<uint32_t>(code);
150 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), std::to_string(value).c_str());
151 }
152 }
153
ParseColorModeAttributes(ipp_t *response, PrinterCapability &printerCaps)154 void ParseColorModeAttributes(ipp_t *response, PrinterCapability &printerCaps)
155 {
156 std::string keyword = "print-color-mode-supported";
157 std::vector<ColorModeCode> supportedColorModes;
158 ParseAttributesToList<ColorModeCode>(response, keyword, supportedColorModes, ConvertColorModeCode);
159 std::string colorModeJson = ConvertListToJson<ColorModeCode>(supportedColorModes, ConvertColorModeToJson);
160 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), colorModeJson.c_str());
161
162 keyword = "print-color-mode-default";
163 ColorModeCode code;
164 if (ParseAttributeToValue<ColorModeCode>(response, keyword, code, ConvertColorModeCode)) {
165 uint32_t mode = static_cast<uint32_t>(code);
166 printerCaps.SetPrinterAttrNameAndValue("defaultColorMode", std::to_string(mode).c_str());
167 }
168 for (auto& color : supportedColorModes) {
169 if (color == ColorModeCode::COLOR_MODE_COLOR) {
170 printerCaps.SetColorMode(ColorModeCode::COLOR_MODE_COLOR);
171 break;
172 }
173 }
174 printerCaps.SetSupportedColorMode(std::vector<uint32_t>(supportedColorModes.begin(), supportedColorModes.end()));
175 }
176
ParsePageSizeAttributes(ipp_t *response, PrinterCapability &printerCaps)177 void ParsePageSizeAttributes(ipp_t *response, PrinterCapability &printerCaps)
178 {
179 std::string keyword = "media-supported";
180 std::vector<PrintPageSize> supportedPageSizes;
181 ParseAttributesToList<PrintPageSize>(response, keyword, supportedPageSizes, ConvertPrintPageSize);
182 std::string pageSizeJson = ConvertListToJson<PrintPageSize>(supportedPageSizes, ConvertPageSizeToJson);
183 printerCaps.SetSupportedPageSize(supportedPageSizes);
184 printerCaps.SetPrinterAttrNameAndValue("supportedPageSizeArray", pageSizeJson.c_str());
185
186 std::string defaultPageSizeId;
187 keyword = "media-default";
188 if (ParseAttributeToValue<std::string>(response, keyword, defaultPageSizeId, ConvertPageSizeId)) {
189 printerCaps.SetPrinterAttrNameAndValue("defaultPageSizeId", defaultPageSizeId.c_str());
190 }
191 }
192
ParseQualityAttributes(ipp_t *response, PrinterCapability &printerCaps)193 void ParseQualityAttributes(ipp_t *response, PrinterCapability &printerCaps)
194 {
195 std::string keyword = "print-quality-supported";
196 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_ENUM);
197 if (attrPtr == nullptr) {
198 PRINT_HILOGW("%{public}s missing", keyword.c_str());
199 return;
200 }
201 nlohmann::json supportedQualities = nlohmann::json::array();
202 std::vector<uint32_t> list;
203 for (int i = 0; i < ippGetCount(attrPtr); i++) {
204 nlohmann::json jsonObject;
205 int quality = ippGetInteger(attrPtr, i);
206 if (quality < 0) {
207 PRINT_HILOGE("%{public}s meet error quality", keyword.c_str());
208 continue;
209 }
210 uint32_t value = static_cast<uint32_t>(quality);
211 jsonObject["quality"] = value;
212 supportedQualities.push_back(jsonObject);
213 list.emplace_back(value);
214 }
215 std::string attrString = supportedQualities.dump();
216 PRINT_HILOGD("%{public}s: %{public}s", keyword.c_str(), attrString.c_str());
217 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), attrString.c_str());
218 printerCaps.SetSupportedQuality(list);
219 }
220
ParseCopiesAttributes(ipp_t *response, PrinterCapability &printerCaps)221 void ParseCopiesAttributes(ipp_t *response, PrinterCapability &printerCaps)
222 {
223 ipp_attribute_t *attrPtr = ippFindAttribute(response, "copies-supported", IPP_TAG_RANGE);
224 if (attrPtr != nullptr) {
225 int upper = 0;
226 for (int i = 0; i < ippGetCount(attrPtr); i++) {
227 ippGetRange(attrPtr, i, &upper);
228 }
229 printerCaps.SetPrinterAttrNameAndValue("copies-supported", std::to_string(upper).c_str());
230 }
231 attrPtr = ippFindAttribute(response, "copies-default", IPP_TAG_INTEGER);
232 if (attrPtr != nullptr) {
233 printerCaps.SetPrinterAttrNameAndValue("copies-default", std::to_string(ippGetInteger(attrPtr, 0)).c_str());
234 }
235 }
236
ParseSupportedResolutionAttribute(ipp_t *response, PrinterCapability &printerCaps)237 void ParseSupportedResolutionAttribute(ipp_t *response, PrinterCapability &printerCaps)
238 {
239 std::string keyword = "printer-resolution-supported";
240 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_RESOLUTION);
241 if (attrPtr == nullptr) {
242 PRINT_HILOGW("attrPtr is null");
243 return;
244 }
245 int num = ippGetCount(attrPtr);
246 PRINT_HILOGD("number of values %{public}d", num);
247 nlohmann::json resolutionArray = nlohmann::json::array();
248 std::vector<PrintResolution> list;
249 for (int i = 0; i < num; i++) {
250 ipp_res_t units = IPP_RES_PER_INCH;
251 int xres = 0;
252 int yres = 0;
253 xres = ippGetResolution(attrPtr, i, &yres, &units);
254 if (xres == 0 || yres == 0) {
255 continue;
256 }
257 if (units == IPP_RES_PER_CM) {
258 xres = DpcToDpi(xres);
259 yres = DpcToDpi(yres);
260 } else if (units != IPP_RES_PER_INCH) {
261 PRINT_HILOGW("unknown dpi unit: %{public}d", static_cast<int>(units));
262 continue;
263 }
264 nlohmann::json object;
265 object["horizontalDpi"] = xres;
266 object["verticalDpi"] = yres;
267 PrintResolution printResolution;
268 printResolution.SetHorizontalDpi(xres);
269 printResolution.SetVerticalDpi(yres);
270 list.emplace_back(printResolution);
271 resolutionArray.push_back(object);
272 }
273 printerCaps.SetResolution(list);
274 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), resolutionArray.dump().c_str());
275 }
276
ParseDefaultResolutionAttribute(ipp_t *response, PrinterCapability &printerCaps)277 void ParseDefaultResolutionAttribute(ipp_t *response, PrinterCapability &printerCaps)
278 {
279 std::string keyword = "printer-resolution-default";
280 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_RESOLUTION);
281 if (attrPtr == nullptr) {
282 PRINT_HILOGW("attrPtr is null");
283 return;
284 }
285 int num = ippGetCount(attrPtr);
286 PRINT_HILOGD("number of values %{public}d", num);
287 for (int i = 0; i < num; i++) {
288 ipp_res_t units = IPP_RES_PER_INCH;
289 int xres = 0;
290 int yres = 0;
291 xres = ippGetResolution(attrPtr, i, &yres, &units);
292 if (xres == 0 || yres == 0) {
293 continue;
294 }
295 if (units == IPP_RES_PER_CM) {
296 xres = DpcToDpi(xres);
297 yres = DpcToDpi(yres);
298 } else if (units != IPP_RES_PER_INCH) {
299 PRINT_HILOGW("unknown dpi unit: %{public}d", static_cast<int>(units));
300 continue;
301 }
302 nlohmann::json object;
303 object["horizontalDpi"] = xres;
304 object["verticalDpi"] = yres;
305 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), object.dump().c_str());
306 break;
307 }
308 }
309
ParseMediaColDefaultAttributes(ipp_t *response, PrinterCapability &printerCaps)310 void ParseMediaColDefaultAttributes(ipp_t *response, PrinterCapability &printerCaps)
311 {
312 ipp_attribute_t *defaultMediaPtr = ippFindAttribute(response, "media-col-default", IPP_TAG_BEGIN_COLLECTION);
313 if (defaultMediaPtr == nullptr) {
314 PRINT_HILOGW("media-col-default missing");
315 return;
316 }
317 ipp_t *defaultMediaCol = defaultMediaPtr->values[0].collection;
318 if (defaultMediaCol == nullptr) {
319 PRINT_HILOGW("defaultMediaCol is null");
320 return;
321 }
322 std::vector<std::string> keywordList;
323 keywordList.push_back("media-top-margin");
324 keywordList.push_back("media-bottom-margin");
325 keywordList.push_back("media-left-margin");
326 keywordList.push_back("media-right-margin");
327 for (auto &keyword : keywordList) {
328 ipp_attribute_t *attrPtr = ippFindAttribute(defaultMediaCol, keyword.c_str(), IPP_TAG_INTEGER);
329 if (attrPtr != nullptr) {
330 int value = ippGetInteger(attrPtr, 0);
331 PRINT_HILOGD("%{public}s found: %{public}d", keyword.c_str(), value);
332 std::string defaultKeyword = keyword + "-default";
333 printerCaps.SetPrinterAttrNameAndValue(defaultKeyword.c_str(), std::to_string(value).c_str());
334 }
335 }
336 ipp_attribute_t *attrPtr = ippFindAttribute(defaultMediaCol, "duplex-supported", IPP_TAG_BOOLEAN);
337 if (attrPtr != nullptr) {
338 PRINT_HILOGD("duplex-supported found: %{public}d", ippGetBoolean(attrPtr, 0));
339 }
340 attrPtr = ippFindAttribute(defaultMediaCol, "media-source", IPP_TAG_KEYWORD);
341 if (attrPtr != nullptr) {
342 PRINT_HILOGD("media-source-default found: %{public}s", ippGetString(attrPtr, 0, NULL));
343 printerCaps.SetPrinterAttrNameAndValue("media-source-default", ippGetString(attrPtr, 0, NULL));
344 }
345 attrPtr = ippFindAttribute(defaultMediaCol, "media-type", IPP_TAG_KEYWORD);
346 if (attrPtr != nullptr) {
347 PRINT_HILOGD("media-type-default found: %{public}s", ippGetString(attrPtr, 0, NULL));
348 printerCaps.SetPrinterAttrNameAndValue("media-type-default", ippGetString(attrPtr, 0, NULL));
349 }
350 }
351
ParseMediaMarginAttributes(ipp_t *response, PrinterCapability &printerCaps)352 void ParseMediaMarginAttributes(ipp_t *response, PrinterCapability &printerCaps)
353 {
354 ipp_attribute_t *attrPtr;
355 if ((attrPtr = ippFindAttribute(response, "media-bottom-margin-supported", IPP_TAG_INTEGER)) != NULL) {
356 printerCaps.SetPrinterAttrNameAndValue("media-bottom-margin-supported",
357 std::to_string(ippGetInteger(attrPtr, 0)).c_str());
358 }
359 if ((attrPtr = ippFindAttribute(response, "media-top-margin-supported", IPP_TAG_INTEGER)) != NULL) {
360 printerCaps.SetPrinterAttrNameAndValue("media-top-margin-supported",
361 std::to_string(ippGetInteger(attrPtr, 0)).c_str());
362 }
363 if ((attrPtr = ippFindAttribute(response, "media-left-margin-supported", IPP_TAG_INTEGER)) != NULL) {
364 printerCaps.SetPrinterAttrNameAndValue("media-left-margin-supported",
365 std::to_string(ippGetInteger(attrPtr, 0)).c_str());
366 }
367 if ((attrPtr = ippFindAttribute(response, "media-right-margin-supported", IPP_TAG_INTEGER)) != NULL) {
368 printerCaps.SetPrinterAttrNameAndValue("media-right-margin-supported",
369 std::to_string(ippGetInteger(attrPtr, 0)).c_str());
370 }
371 }
372
ParseOrientationAttributes(ipp_t *response, PrinterCapability &printerCaps)373 void ParseOrientationAttributes(ipp_t *response, PrinterCapability &printerCaps)
374 {
375 std::string keyword = "orientation-requested-default";
376 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_ENUM);
377 if (attrPtr != NULL) {
378 int orientationEnum = ippGetInteger(attrPtr, 0);
379 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), std::to_string(orientationEnum).c_str());
380 PRINT_HILOGD("orientation-default found: %{public}d", orientationEnum);
381 }
382 keyword = "orientation-requested-supported";
383 attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_ENUM);
384 if (attrPtr != NULL) {
385 int num = ippGetCount(attrPtr);
386 if (num > 0) {
387 nlohmann::json supportedOrientationArray = nlohmann::json::array();
388 std::vector<uint32_t> supportedOrientations;
389 supportedOrientations.reserve(num);
390 for (int i = 0; i < ippGetCount(attrPtr); i++) {
391 int orientationEnum = ippGetInteger(attrPtr, i);
392 supportedOrientationArray.push_back(orientationEnum);
393 supportedOrientations.emplace_back(orientationEnum);
394 PRINT_HILOGD("orientation-supported found: %{public}d", orientationEnum);
395 }
396 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), supportedOrientationArray.dump().c_str());
397 printerCaps.SetSupportedOrientation(supportedOrientations);
398 }
399 }
400 }
401
ParseOtherAttributes(ipp_t *response, PrinterCapability &printerCaps)402 void ParseOtherAttributes(ipp_t *response, PrinterCapability &printerCaps)
403 {
404 std::string keyword = "media-source-supported";
405 std::string attrString = ConvertIppAttributesToJsonString(response, keyword);
406 PRINT_HILOGD("%{public}s: %{public}s", keyword.c_str(), attrString.c_str());
407 if (!attrString.empty()) {
408 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), attrString.c_str());
409 }
410
411 keyword = "multiple-document-handling-supported";
412 attrString = ConvertIppAttributesToJsonString(response, keyword);
413 PRINT_HILOGD("%{public}s: %{public}s", keyword.c_str(), attrString.c_str());
414 if (!attrString.empty()) {
415 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), attrString.c_str());
416 }
417 }
418
SetOptionAttribute(ipp_t *response, PrinterCapability &printerCaps)419 void SetOptionAttribute(ipp_t *response, PrinterCapability &printerCaps)
420 {
421 ipp_attribute_t *attrPtr;
422 nlohmann::json options;
423 if ((attrPtr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL) {
424 options["make"] = ippGetString(attrPtr, 0, NULL);
425 }
426 if ((attrPtr = ippFindAttribute(response, "printer-uuid", IPP_TAG_URI)) != NULL) {
427 options["uuid"] = ippGetString(attrPtr, 0, NULL);
428 }
429 if ((attrPtr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL) {
430 options["printerName"] = ippGetString(attrPtr, 0, NULL);
431 }
432 std::string keyword = "media-type-supported";
433 std::string supportTypes;
434 std::vector<std::string> list;
435 attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_ZERO);
436 if (attrPtr == nullptr) {
437 supportTypes = "";
438 } else {
439 nlohmann::json jsonArray = nlohmann::json::array();
440 for (int i = 0; i < ippGetCount(attrPtr); i++) {
441 const char *attrString = ippGetString(attrPtr, i, NULL);
442 if (attrString == nullptr) {
443 continue;
444 }
445 jsonArray.push_back(attrString);
446 list.emplace_back(attrString);
447 }
448 supportTypes = jsonArray.dump();
449 }
450 PRINT_HILOGD("%{public}s: %{public}s", keyword.c_str(), supportTypes.c_str());
451 if (!supportTypes.empty()) {
452 printerCaps.SetSupportedMediaType(list);
453 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), supportTypes.c_str());
454 }
455
456 nlohmann::json cupsOptionsJson = printerCaps.GetPrinterAttrGroupJson();
457 options["cupsOptions"] = cupsOptionsJson;
458
459 std::string optionStr = options.dump();
460 PRINT_HILOGD("SetOption: %{public}s", optionStr.c_str());
461 printerCaps.SetOption(optionStr);
462 }
463
ParsePrinterAttributes(ipp_t *response, PrinterCapability &printerCaps)464 void ParsePrinterAttributes(ipp_t *response, PrinterCapability &printerCaps)
465 {
466 SetCapabilityGroupAttribute(response, printerCaps);
467 ParseColorModeAttributes(response, printerCaps);
468 ParseDuplexModeAttributes(response, printerCaps);
469 ParsePageSizeAttributes(response, printerCaps);
470 ParseQualityAttributes(response, printerCaps);
471 ParseSupportedResolutionAttribute(response, printerCaps);
472 ParseDefaultResolutionAttribute(response, printerCaps);
473 ParseMediaColDefaultAttributes(response, printerCaps);
474 ParseMediaMarginAttributes(response, printerCaps);
475 ParseOrientationAttributes(response, printerCaps);
476 ParseCopiesAttributes(response, printerCaps);
477 ParseOtherAttributes(response, printerCaps);
478 SetOptionAttribute(response, printerCaps);
479 }
480
ParsePrinterStatusAttributes(ipp_t *response, PrinterStatus &status)481 bool ParsePrinterStatusAttributes(ipp_t *response, PrinterStatus &status)
482 {
483 ipp_attribute_t *attrPtr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM);
484 if (attrPtr != NULL) {
485 int enumValue = ippGetInteger(attrPtr, 0) - IPP_PSTATE_IDLE;
486 if (enumValue >= PRINTER_STATUS_IDLE && enumValue <= PRINTER_STATUS_UNAVAILABLE) {
487 status = static_cast<PrinterStatus>(enumValue);
488 return true;
489 }
490 }
491 return false;
492 }
493 } // namespace OHOS::Print