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, nullptr);
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, nullptr);
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, nullptr);
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)) != nullptr) {
120 printerCaps.SetPrinterAttrNameAndValue("printer-state",
121 ippEnumString("printer-state", ippGetInteger(attrPtr, 0)));
122 }
123 if ((attrPtr = ippFindAttribute(response, "printer-info", IPP_TAG_TEXTLANG)) != nullptr) {
124 printerCaps.SetPrinterAttrNameAndValue("printer-info", ippGetString(attrPtr, 0, nullptr));
125 }
126 if ((attrPtr = ippFindAttribute(response, "printer-location", IPP_TAG_TEXT)) != nullptr) {
127 printerCaps.SetPrinterAttrNameAndValue("printer-location", ippGetString(attrPtr, 0, nullptr));
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 printerCaps.SetSupportedPageSize(supportedPageSizes);
183
184 std::string defaultPageSizeId;
185 keyword = "media-default";
186 if (ParseAttributeToValue<std::string>(response, keyword, defaultPageSizeId, ConvertPageSizeId)) {
187 printerCaps.SetPrinterAttrNameAndValue("defaultPageSizeId", defaultPageSizeId.c_str());
188 }
189 }
190
ParseQualityAttributes(ipp_t * response,PrinterCapability & printerCaps)191 void ParseQualityAttributes(ipp_t *response, PrinterCapability &printerCaps)
192 {
193 std::string keyword = "print-quality-supported";
194 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_ENUM);
195 if (attrPtr == nullptr) {
196 PRINT_HILOGW("%{public}s missing", keyword.c_str());
197 return;
198 }
199 nlohmann::json supportedQualities = nlohmann::json::array();
200 std::vector<uint32_t> list;
201 for (int i = 0; i < ippGetCount(attrPtr); i++) {
202 nlohmann::json jsonObject;
203 int quality = ippGetInteger(attrPtr, i);
204 if (quality < 0) {
205 PRINT_HILOGE("%{public}s meet error quality", keyword.c_str());
206 continue;
207 }
208 uint32_t value = static_cast<uint32_t>(quality);
209 jsonObject["quality"] = value;
210 supportedQualities.push_back(jsonObject);
211 list.emplace_back(value);
212 }
213 std::string attrString = supportedQualities.dump();
214 PRINT_HILOGD("%{public}s: %{public}s", keyword.c_str(), attrString.c_str());
215 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), attrString.c_str());
216 printerCaps.SetSupportedQuality(list);
217 }
218
ParseCopiesAttributes(ipp_t * response,PrinterCapability & printerCaps)219 void ParseCopiesAttributes(ipp_t *response, PrinterCapability &printerCaps)
220 {
221 ipp_attribute_t *attrPtr = ippFindAttribute(response, "copies-supported", IPP_TAG_RANGE);
222 if (attrPtr != nullptr) {
223 int upper = 0;
224 for (int i = 0; i < ippGetCount(attrPtr); i++) {
225 ippGetRange(attrPtr, i, &upper);
226 }
227 printerCaps.SetPrinterAttrNameAndValue("copies-supported", std::to_string(upper).c_str());
228 }
229 attrPtr = ippFindAttribute(response, "copies-default", IPP_TAG_INTEGER);
230 if (attrPtr != nullptr) {
231 printerCaps.SetPrinterAttrNameAndValue("copies-default", std::to_string(ippGetInteger(attrPtr, 0)).c_str());
232 }
233 }
234
ParseSupportedResolutionAttribute(ipp_t * response,PrinterCapability & printerCaps)235 void ParseSupportedResolutionAttribute(ipp_t *response, PrinterCapability &printerCaps)
236 {
237 std::string keyword = "printer-resolution-supported";
238 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_RESOLUTION);
239 if (attrPtr == nullptr) {
240 PRINT_HILOGW("attrPtr is null");
241 return;
242 }
243 int num = ippGetCount(attrPtr);
244 PRINT_HILOGD("number of values %{public}d", num);
245 nlohmann::json resolutionArray = nlohmann::json::array();
246 std::vector<PrintResolution> list;
247 for (int i = 0; i < num; i++) {
248 ipp_res_t units = IPP_RES_PER_INCH;
249 int xres = 0;
250 int yres = 0;
251 xres = ippGetResolution(attrPtr, i, &yres, &units);
252 if (xres == 0 || yres == 0) {
253 continue;
254 }
255 if (units == IPP_RES_PER_CM) {
256 xres = DpcToDpi(xres);
257 yres = DpcToDpi(yres);
258 } else if (units != IPP_RES_PER_INCH) {
259 PRINT_HILOGW("unknown dpi unit: %{public}d", static_cast<int>(units));
260 continue;
261 }
262 nlohmann::json object;
263 object["horizontalDpi"] = xres;
264 object["verticalDpi"] = yres;
265 PrintResolution printResolution;
266 printResolution.SetHorizontalDpi(xres);
267 printResolution.SetVerticalDpi(yres);
268 list.emplace_back(printResolution);
269 resolutionArray.push_back(object);
270 }
271 printerCaps.SetResolution(list);
272 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), resolutionArray.dump().c_str());
273 }
274
ParseDefaultResolutionAttribute(ipp_t * response,PrinterCapability & printerCaps)275 void ParseDefaultResolutionAttribute(ipp_t *response, PrinterCapability &printerCaps)
276 {
277 std::string keyword = "printer-resolution-default";
278 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_RESOLUTION);
279 if (attrPtr == nullptr) {
280 PRINT_HILOGW("attrPtr is null");
281 return;
282 }
283 int num = ippGetCount(attrPtr);
284 PRINT_HILOGD("number of values %{public}d", num);
285 for (int i = 0; i < num; i++) {
286 ipp_res_t units = IPP_RES_PER_INCH;
287 int xres = 0;
288 int yres = 0;
289 xres = ippGetResolution(attrPtr, i, &yres, &units);
290 if (xres == 0 || yres == 0) {
291 continue;
292 }
293 if (units == IPP_RES_PER_CM) {
294 xres = DpcToDpi(xres);
295 yres = DpcToDpi(yres);
296 } else if (units != IPP_RES_PER_INCH) {
297 PRINT_HILOGW("unknown dpi unit: %{public}d", static_cast<int>(units));
298 continue;
299 }
300 nlohmann::json object;
301 object["horizontalDpi"] = xres;
302 object["verticalDpi"] = yres;
303 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), object.dump().c_str());
304 break;
305 }
306 }
307
ParseMediaColDefaultAttributes(ipp_t * response,PrinterCapability & printerCaps)308 void ParseMediaColDefaultAttributes(ipp_t *response, PrinterCapability &printerCaps)
309 {
310 ipp_attribute_t *defaultMediaPtr = ippFindAttribute(response, "media-col-default", IPP_TAG_BEGIN_COLLECTION);
311 if (defaultMediaPtr == nullptr) {
312 PRINT_HILOGW("media-col-default missing");
313 return;
314 }
315 ipp_t *defaultMediaCol = defaultMediaPtr->values[0].collection;
316 if (defaultMediaCol == nullptr) {
317 PRINT_HILOGW("defaultMediaCol is null");
318 return;
319 }
320 std::vector<std::string> keywordList;
321 keywordList.push_back("media-top-margin");
322 keywordList.push_back("media-bottom-margin");
323 keywordList.push_back("media-left-margin");
324 keywordList.push_back("media-right-margin");
325 for (auto &keyword : keywordList) {
326 ipp_attribute_t *attrPtr = ippFindAttribute(defaultMediaCol, keyword.c_str(), IPP_TAG_INTEGER);
327 if (attrPtr != nullptr) {
328 int value = ippGetInteger(attrPtr, 0);
329 PRINT_HILOGD("%{public}s found: %{public}d", keyword.c_str(), value);
330 std::string defaultKeyword = keyword + "-default";
331 printerCaps.SetPrinterAttrNameAndValue(defaultKeyword.c_str(), std::to_string(value).c_str());
332 }
333 }
334 ipp_attribute_t *attrPtr = ippFindAttribute(defaultMediaCol, "duplex-supported", IPP_TAG_BOOLEAN);
335 if (attrPtr != nullptr) {
336 PRINT_HILOGD("duplex-supported found: %{public}d", ippGetBoolean(attrPtr, 0));
337 }
338 attrPtr = ippFindAttribute(defaultMediaCol, "media-source", IPP_TAG_KEYWORD);
339 if (attrPtr != nullptr) {
340 PRINT_HILOGD("media-source-default found: %{public}s", ippGetString(attrPtr, 0, nullptr));
341 printerCaps.SetPrinterAttrNameAndValue("media-source-default", ippGetString(attrPtr, 0, nullptr));
342 }
343 attrPtr = ippFindAttribute(defaultMediaCol, "media-type", IPP_TAG_KEYWORD);
344 if (attrPtr != nullptr) {
345 PRINT_HILOGD("media-type-default found: %{public}s", ippGetString(attrPtr, 0, nullptr));
346 printerCaps.SetPrinterAttrNameAndValue("media-type-default", ippGetString(attrPtr, 0, nullptr));
347 }
348 }
349
ParseMediaMarginAttributes(ipp_t * response,PrinterCapability & printerCaps)350 void ParseMediaMarginAttributes(ipp_t *response, PrinterCapability &printerCaps)
351 {
352 ipp_attribute_t *attrPtr;
353 if ((attrPtr = ippFindAttribute(response, "media-bottom-margin-supported", IPP_TAG_INTEGER)) != nullptr) {
354 printerCaps.SetPrinterAttrNameAndValue("media-bottom-margin-supported",
355 std::to_string(ippGetInteger(attrPtr, 0)).c_str());
356 }
357 if ((attrPtr = ippFindAttribute(response, "media-top-margin-supported", IPP_TAG_INTEGER)) != nullptr) {
358 printerCaps.SetPrinterAttrNameAndValue("media-top-margin-supported",
359 std::to_string(ippGetInteger(attrPtr, 0)).c_str());
360 }
361 if ((attrPtr = ippFindAttribute(response, "media-left-margin-supported", IPP_TAG_INTEGER)) != nullptr) {
362 printerCaps.SetPrinterAttrNameAndValue("media-left-margin-supported",
363 std::to_string(ippGetInteger(attrPtr, 0)).c_str());
364 }
365 if ((attrPtr = ippFindAttribute(response, "media-right-margin-supported", IPP_TAG_INTEGER)) != nullptr) {
366 printerCaps.SetPrinterAttrNameAndValue("media-right-margin-supported",
367 std::to_string(ippGetInteger(attrPtr, 0)).c_str());
368 }
369 }
370
ParseOrientationAttributes(ipp_t * response,PrinterCapability & printerCaps)371 void ParseOrientationAttributes(ipp_t *response, PrinterCapability &printerCaps)
372 {
373 std::string keyword = "orientation-requested-default";
374 ipp_attribute_t *attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_ENUM);
375 if (attrPtr != nullptr) {
376 int orientationEnum = ippGetInteger(attrPtr, 0);
377 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), std::to_string(orientationEnum).c_str());
378 PRINT_HILOGD("orientation-default found: %{public}d", orientationEnum);
379 }
380 keyword = "orientation-requested-supported";
381 attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_ENUM);
382 if (attrPtr != nullptr) {
383 int num = ippGetCount(attrPtr);
384 if (num > 0) {
385 nlohmann::json supportedOrientationArray = nlohmann::json::array();
386 std::vector<uint32_t> supportedOrientations;
387 supportedOrientations.reserve(num);
388 for (int i = 0; i < ippGetCount(attrPtr); i++) {
389 int orientationEnum = ippGetInteger(attrPtr, i);
390 supportedOrientationArray.push_back(orientationEnum);
391 supportedOrientations.emplace_back(orientationEnum);
392 PRINT_HILOGD("orientation-supported found: %{public}d", orientationEnum);
393 }
394 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), supportedOrientationArray.dump().c_str());
395 printerCaps.SetSupportedOrientation(supportedOrientations);
396 }
397 }
398 }
399
ParseOtherAttributes(ipp_t * response,PrinterCapability & printerCaps)400 void ParseOtherAttributes(ipp_t *response, PrinterCapability &printerCaps)
401 {
402 std::string keyword = "media-source-supported";
403 std::string attrString = ConvertIppAttributesToJsonString(response, keyword);
404 PRINT_HILOGD("%{public}s: %{public}s", keyword.c_str(), attrString.c_str());
405 if (!attrString.empty()) {
406 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), attrString.c_str());
407 }
408
409 keyword = "multiple-document-handling-supported";
410 attrString = ConvertIppAttributesToJsonString(response, keyword);
411 PRINT_HILOGD("%{public}s: %{public}s", keyword.c_str(), attrString.c_str());
412 if (!attrString.empty()) {
413 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), attrString.c_str());
414 }
415 }
416
SetOptionAttribute(ipp_t * response,PrinterCapability & printerCaps)417 void SetOptionAttribute(ipp_t *response, PrinterCapability &printerCaps)
418 {
419 ipp_attribute_t *attrPtr;
420 nlohmann::json options;
421 if ((attrPtr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != nullptr) {
422 options["make"] = ippGetString(attrPtr, 0, nullptr);
423 }
424 if ((attrPtr = ippFindAttribute(response, "printer-uuid", IPP_TAG_URI)) != nullptr) {
425 options["uuid"] = ippGetString(attrPtr, 0, nullptr);
426 }
427 if ((attrPtr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != nullptr) {
428 options["printerName"] = ippGetString(attrPtr, 0, nullptr);
429 }
430 std::string keyword = "media-type-supported";
431 std::string supportTypes;
432 std::vector<std::string> list;
433 attrPtr = ippFindAttribute(response, keyword.c_str(), IPP_TAG_ZERO);
434 if (attrPtr == nullptr) {
435 supportTypes = "";
436 } else {
437 nlohmann::json jsonArray = nlohmann::json::array();
438 for (int i = 0; i < ippGetCount(attrPtr); i++) {
439 const char *attrString = ippGetString(attrPtr, i, nullptr);
440 if (attrString == nullptr) {
441 continue;
442 }
443 jsonArray.push_back(attrString);
444 list.emplace_back(attrString);
445 }
446 supportTypes = jsonArray.dump();
447 }
448 PRINT_HILOGD("%{public}s: %{public}s", keyword.c_str(), supportTypes.c_str());
449 if (!supportTypes.empty()) {
450 printerCaps.SetSupportedMediaType(list);
451 printerCaps.SetPrinterAttrNameAndValue(keyword.c_str(), supportTypes.c_str());
452 }
453
454 nlohmann::json cupsOptionsJson = printerCaps.GetPrinterAttrGroupJson();
455 options["cupsOptions"] = cupsOptionsJson;
456
457 std::string optionStr = options.dump();
458 PRINT_HILOGD("SetOption: %{public}s", optionStr.c_str());
459 printerCaps.SetOption(optionStr);
460 }
461
ParsePrinterAttributes(ipp_t * response,PrinterCapability & printerCaps)462 void ParsePrinterAttributes(ipp_t *response, PrinterCapability &printerCaps)
463 {
464 SetCapabilityGroupAttribute(response, printerCaps);
465 ParseColorModeAttributes(response, printerCaps);
466 ParseDuplexModeAttributes(response, printerCaps);
467 ParsePageSizeAttributes(response, printerCaps);
468 ParseQualityAttributes(response, printerCaps);
469 ParseSupportedResolutionAttribute(response, printerCaps);
470 ParseDefaultResolutionAttribute(response, printerCaps);
471 ParseMediaColDefaultAttributes(response, printerCaps);
472 ParseMediaMarginAttributes(response, printerCaps);
473 ParseOrientationAttributes(response, printerCaps);
474 ParseCopiesAttributes(response, printerCaps);
475 ParseOtherAttributes(response, printerCaps);
476 SetOptionAttribute(response, printerCaps);
477 }
478
ParsePrinterStatusAttributes(ipp_t * response,PrinterStatus & status)479 bool ParsePrinterStatusAttributes(ipp_t *response, PrinterStatus &status)
480 {
481 ipp_attribute_t *attrPtr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM);
482 if (attrPtr != nullptr) {
483 int enumValue = ippGetInteger(attrPtr, 0) - IPP_PSTATE_IDLE;
484 if (enumValue >= PRINTER_STATUS_IDLE && enumValue <= PRINTER_STATUS_UNAVAILABLE) {
485 status = static_cast<PrinterStatus>(enumValue);
486 return true;
487 }
488 }
489 return false;
490 }
491 } // namespace OHOS::Print