2 * IPP test program for CUPS.
4 * Copyright © 2007-2019 by Apple Inc.
5 * Copyright © 1997-2005 by Easy Software Products.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
12 * Include necessary headers...
16 #include "string-private.h"
17 #include "ipp-private.h"
30 typedef struct _ippdata_t
32 size_t rpos
, /* Read position */
33 wused
, /* Bytes used */
34 wsize
; /* Max size of buffer */
35 ipp_uchar_t
*wbuffer
; /* Buffer */
43 static ipp_uchar_t collection
[] = /* Collection buffer */
45 0x01, 0x01, /* IPP version */
46 0x00, 0x02, /* Print-Job operation */
47 0x00, 0x00, 0x00, 0x01,
53 0x00, 0x12, /* Name length + name */
54 'a','t','t','r','i','b','u','t','e','s','-',
55 'c','h','a','r','s','e','t',
56 0x00, 0x05, /* Value length + value */
60 0x00, 0x1b, /* Name length + name */
61 'a','t','t','r','i','b','u','t','e','s','-',
62 'n','a','t','u','r','a','l','-','l','a','n',
64 0x00, 0x02, /* Value length + value */
68 0x00, 0x0b, /* Name length + name */
69 'p','r','i','n','t','e','r','-','u','r','i',
70 0x00, 0x1c, /* Value length + value */
71 'i','p','p',':','/','/','l','o','c','a','l',
72 'h','o','s','t','/','p','r','i','n','t','e',
73 'r','s','/','f','o','o',
75 IPP_TAG_JOB
, /* job group tag */
77 IPP_TAG_BEGIN_COLLECTION
,
78 /* begCollection tag */
79 0x00, 0x09, /* Name length + name */
80 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l',
81 0x00, 0x00, /* No value */
82 IPP_TAG_MEMBERNAME
, /* memberAttrName tag */
83 0x00, 0x00, /* No name */
84 0x00, 0x0a, /* Value length + value */
85 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e',
86 IPP_TAG_BEGIN_COLLECTION
,
87 /* begCollection tag */
88 0x00, 0x00, /* Name length + name */
89 0x00, 0x00, /* No value */
91 /* memberAttrName tag */
92 0x00, 0x00, /* No name */
93 0x00, 0x0b, /* Value length + value */
94 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n',
95 IPP_TAG_INTEGER
, /* integer tag */
96 0x00, 0x00, /* No name */
97 0x00, 0x04, /* Value length + value */
98 0x00, 0x00, 0x54, 0x56,
100 /* memberAttrName tag */
101 0x00, 0x00, /* No name */
102 0x00, 0x0b, /* Value length + value */
103 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n',
104 IPP_TAG_INTEGER
, /* integer tag */
105 0x00, 0x00, /* No name */
106 0x00, 0x04, /* Value length + value */
107 0x00, 0x00, 0x6d, 0x24,
108 IPP_TAG_END_COLLECTION
,
109 /* endCollection tag */
110 0x00, 0x00, /* No name */
111 0x00, 0x00, /* No value */
112 IPP_TAG_MEMBERNAME
, /* memberAttrName tag */
113 0x00, 0x00, /* No name */
114 0x00, 0x0b, /* Value length + value */
115 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 'o', 'r',
116 IPP_TAG_KEYWORD
, /* keyword tag */
117 0x00, 0x00, /* No name */
118 0x00, 0x04, /* Value length + value */
121 IPP_TAG_MEMBERNAME
, /* memberAttrName tag */
122 0x00, 0x00, /* No name */
123 0x00, 0x0a, /* Value length + value */
124 'm', 'e', 'd', 'i', 'a', '-', 't', 'y', 'p', 'e',
125 IPP_TAG_KEYWORD
, /* keyword tag */
126 0x00, 0x00, /* No name */
127 0x00, 0x05, /* Value length + value */
128 'p', 'l', 'a', 'i', 'n',
129 IPP_TAG_END_COLLECTION
,
130 /* endCollection tag */
131 0x00, 0x00, /* No name */
132 0x00, 0x00, /* No value */
134 IPP_TAG_BEGIN_COLLECTION
,
135 /* begCollection tag */
136 0x00, 0x00, /* No name */
137 0x00, 0x00, /* No value */
138 IPP_TAG_MEMBERNAME
, /* memberAttrName tag */
139 0x00, 0x00, /* No name */
140 0x00, 0x0a, /* Value length + value */
141 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e',
142 IPP_TAG_BEGIN_COLLECTION
,
143 /* begCollection tag */
144 0x00, 0x00, /* Name length + name */
145 0x00, 0x00, /* No value */
147 /* memberAttrName tag */
148 0x00, 0x00, /* No name */
149 0x00, 0x0b, /* Value length + value */
150 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n',
151 IPP_TAG_INTEGER
, /* integer tag */
152 0x00, 0x00, /* No name */
153 0x00, 0x04, /* Value length + value */
154 0x00, 0x00, 0x52, 0x08,
156 /* memberAttrName tag */
157 0x00, 0x00, /* No name */
158 0x00, 0x0b, /* Value length + value */
159 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n',
160 IPP_TAG_INTEGER
, /* integer tag */
161 0x00, 0x00, /* No name */
162 0x00, 0x04, /* Value length + value */
163 0x00, 0x00, 0x74, 0x04,
164 IPP_TAG_END_COLLECTION
,
165 /* endCollection tag */
166 0x00, 0x00, /* No name */
167 0x00, 0x00, /* No value */
168 IPP_TAG_MEMBERNAME
, /* memberAttrName tag */
169 0x00, 0x00, /* No name */
170 0x00, 0x0b, /* Value length + value */
171 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 'o', 'r',
172 IPP_TAG_KEYWORD
, /* keyword tag */
173 0x00, 0x00, /* No name */
174 0x00, 0x05, /* Value length + value */
175 'p', 'l', 'a', 'i', 'd',
177 IPP_TAG_MEMBERNAME
, /* memberAttrName tag */
178 0x00, 0x00, /* No name */
179 0x00, 0x0a, /* Value length + value */
180 'm', 'e', 'd', 'i', 'a', '-', 't', 'y', 'p', 'e',
181 IPP_TAG_KEYWORD
, /* keyword tag */
182 0x00, 0x00, /* No name */
183 0x00, 0x06, /* Value length + value */
184 'g', 'l', 'o', 's', 's', 'y',
185 IPP_TAG_END_COLLECTION
,
186 /* endCollection tag */
187 0x00, 0x00, /* No name */
188 0x00, 0x00, /* No value */
190 IPP_TAG_END
/* end tag */
192 static ipp_uchar_t bad_collection
[] = /* Collection buffer (bad encoding) */
194 0x01, 0x01, /* IPP version */
195 0x00, 0x02, /* Print-Job operation */
196 0x00, 0x00, 0x00, 0x01,
202 0x00, 0x12, /* Name length + name */
203 'a','t','t','r','i','b','u','t','e','s','-',
204 'c','h','a','r','s','e','t',
205 0x00, 0x05, /* Value length + value */
209 0x00, 0x1b, /* Name length + name */
210 'a','t','t','r','i','b','u','t','e','s','-',
211 'n','a','t','u','r','a','l','-','l','a','n',
213 0x00, 0x02, /* Value length + value */
217 0x00, 0x0b, /* Name length + name */
218 'p','r','i','n','t','e','r','-','u','r','i',
219 0x00, 0x1c, /* Value length + value */
220 'i','p','p',':','/','/','l','o','c','a','l',
221 'h','o','s','t','/','p','r','i','n','t','e',
222 'r','s','/','f','o','o',
224 IPP_TAG_JOB
, /* job group tag */
226 IPP_TAG_BEGIN_COLLECTION
,
227 /* begCollection tag */
228 0x00, 0x09, /* Name length + name */
229 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l',
230 0x00, 0x00, /* No value */
231 IPP_TAG_BEGIN_COLLECTION
,
232 /* begCollection tag */
233 0x00, 0x0a, /* Name length + name */
234 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e',
235 0x00, 0x00, /* No value */
236 IPP_TAG_INTEGER
, /* integer tag */
237 0x00, 0x0b, /* Name length + name */
238 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n',
239 0x00, 0x04, /* Value length + value */
240 0x00, 0x00, 0x54, 0x56,
241 IPP_TAG_INTEGER
, /* integer tag */
242 0x00, 0x0b, /* Name length + name */
243 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n',
244 0x00, 0x04, /* Value length + value */
245 0x00, 0x00, 0x6d, 0x24,
246 IPP_TAG_END_COLLECTION
,
247 /* endCollection tag */
248 0x00, 0x00, /* No name */
249 0x00, 0x00, /* No value */
250 IPP_TAG_END_COLLECTION
,
251 /* endCollection tag */
252 0x00, 0x00, /* No name */
253 0x00, 0x00, /* No value */
255 IPP_TAG_END
/* end tag */
258 static ipp_uchar_t mixed
[] = /* Mixed value buffer */
260 0x01, 0x01, /* IPP version */
261 0x00, 0x02, /* Print-Job operation */
262 0x00, 0x00, 0x00, 0x01,
267 IPP_TAG_INTEGER
, /* integer tag */
268 0x00, 0x1f, /* Name length + name */
269 'n', 'o', 't', 'i', 'f', 'y', '-', 'l', 'e', 'a', 's', 'e',
270 '-', 'd', 'u', 'r', 'a', 't', 'i', 'o', 'n', '-', 's', 'u',
271 'p', 'p', 'o', 'r', 't', 'e', 'd',
272 0x00, 0x04, /* Value length + value */
273 0x00, 0x00, 0x00, 0x01,
275 IPP_TAG_RANGE
, /* rangeOfInteger tag */
276 0x00, 0x00, /* No name */
277 0x00, 0x08, /* Value length + value */
278 0x00, 0x00, 0x00, 0x10,
279 0x00, 0x00, 0x00, 0x20,
281 IPP_TAG_END
/* end tag */
289 void hex_dump(const char *title
, ipp_uchar_t
*buffer
, size_t bytes
);
290 void print_attributes(ipp_t
*ipp
, int indent
);
291 ssize_t
read_cb(_ippdata_t
*data
, ipp_uchar_t
*buffer
, size_t bytes
);
292 ssize_t
read_hex(cups_file_t
*fp
, ipp_uchar_t
*buffer
, size_t bytes
);
293 int token_cb(_ipp_file_t
*f
, _ipp_vars_t
*v
, void *user_data
, const char *token
);
294 ssize_t
write_cb(_ippdata_t
*data
, ipp_uchar_t
*buffer
, size_t bytes
);
298 * 'main()' - Main entry.
301 int /* O - Exit status */
302 main(int argc
, /* I - Number of command-line arguments */
303 char *argv
[]) /* I - Command-line arguments */
305 _ippdata_t data
; /* IPP buffer */
306 ipp_uchar_t buffer
[8192]; /* Write buffer data */
307 ipp_t
*cols
[2], /* Collections */
308 *size
; /* media-size collection */
309 ipp_t
*request
; /* Request */
310 ipp_attribute_t
*media_col
, /* media-col attribute */
311 *media_size
, /* media-size attribute */
312 *attr
; /* Other attribute */
313 ipp_state_t state
; /* State */
314 size_t length
; /* Length of data */
315 cups_file_t
*fp
; /* File pointer */
316 size_t i
; /* Looping var */
317 int status
; /* Status of tests (0 = success, 1 = fail) */
319 const char *name
; /* Option name */
328 * Test request generation code...
331 printf("Create Sample Request: ");
334 request
->request
.op
.version
[0] = 0x01;
335 request
->request
.op
.version
[1] = 0x01;
336 request
->request
.op
.operation_id
= IPP_OP_PRINT_JOB
;
337 request
->request
.op
.request_id
= 1;
339 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_CHARSET
,
340 "attributes-charset", NULL
, "utf-8");
341 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_LANGUAGE
,
342 "attributes-natural-language", NULL
, "en");
343 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
,
344 "printer-uri", NULL
, "ipp://localhost/printers/foo");
348 ippAddInteger(size
, IPP_TAG_ZERO
, IPP_TAG_INTEGER
, "x-dimension", 21590);
349 ippAddInteger(size
, IPP_TAG_ZERO
, IPP_TAG_INTEGER
, "y-dimension", 27940);
350 ippAddCollection(cols
[0], IPP_TAG_JOB
, "media-size", size
);
352 ippAddString(cols
[0], IPP_TAG_JOB
, IPP_TAG_KEYWORD
, "media-color", NULL
,
354 ippAddString(cols
[0], IPP_TAG_JOB
, IPP_TAG_KEYWORD
, "media-type", NULL
,
359 ippAddInteger(size
, IPP_TAG_ZERO
, IPP_TAG_INTEGER
, "x-dimension", 21000);
360 ippAddInteger(size
, IPP_TAG_ZERO
, IPP_TAG_INTEGER
, "y-dimension", 29700);
361 ippAddCollection(cols
[1], IPP_TAG_JOB
, "media-size", size
);
363 ippAddString(cols
[1], IPP_TAG_JOB
, IPP_TAG_KEYWORD
, "media-color", NULL
,
365 ippAddString(cols
[1], IPP_TAG_JOB
, IPP_TAG_KEYWORD
, "media-type", NULL
,
368 ippAddCollections(request
, IPP_TAG_JOB
, "media-col", 2,
369 (const ipp_t
**)cols
);
373 length
= ippLength(request
);
374 if (length
!= sizeof(collection
))
376 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
377 (int)length
, (int)sizeof(collection
));
387 printf("Write Sample to Memory: ");
390 data
.wsize
= sizeof(buffer
);
391 data
.wbuffer
= buffer
;
393 while ((state
= ippWriteIO(&data
, (ipp_iocb_t
)write_cb
, 1, NULL
,
394 request
)) != IPP_STATE_DATA
)
395 if (state
== IPP_STATE_ERROR
)
398 if (state
!= IPP_STATE_DATA
)
400 printf("FAIL - %d bytes written.\n", (int)data
.wused
);
403 else if (data
.wused
!= sizeof(collection
))
405 printf("FAIL - wrote %d bytes, expected %d bytes!\n", (int)data
.wused
,
406 (int)sizeof(collection
));
407 hex_dump("Bytes Written", data
.wbuffer
, data
.wused
);
408 hex_dump("Baseline", collection
, sizeof(collection
));
411 else if (memcmp(data
.wbuffer
, collection
, data
.wused
))
413 for (i
= 0; i
< data
.wused
; i
++)
414 if (data
.wbuffer
[i
] != collection
[i
])
417 printf("FAIL - output does not match baseline at 0x%04x!\n", (unsigned)i
);
418 hex_dump("Bytes Written", data
.wbuffer
, data
.wused
);
419 hex_dump("Baseline", collection
, sizeof(collection
));
428 * Read the data back in and confirm...
431 printf("Read Sample from Memory: ");
436 while ((state
= ippReadIO(&data
, (ipp_iocb_t
)read_cb
, 1, NULL
,
437 request
)) != IPP_STATE_DATA
)
438 if (state
== IPP_STATE_ERROR
)
441 length
= ippLength(request
);
443 if (state
!= IPP_STATE_DATA
)
445 printf("FAIL - %d bytes read.\n", (int)data
.rpos
);
448 else if (data
.rpos
!= data
.wused
)
450 printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data
.rpos
,
452 print_attributes(request
, 8);
455 else if (length
!= sizeof(collection
))
457 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
458 (int)length
, (int)sizeof(collection
));
459 print_attributes(request
, 8);
465 fputs("ippFindAttribute(media-col): ", stdout
);
466 if ((media_col
= ippFindAttribute(request
, "media-col",
467 IPP_TAG_BEGIN_COLLECTION
)) == NULL
)
469 if ((media_col
= ippFindAttribute(request
, "media-col",
470 IPP_TAG_ZERO
)) == NULL
)
471 puts("FAIL (not found)");
473 printf("FAIL (wrong type - %s)\n", ippTagString(media_col
->value_tag
));
477 else if (media_col
->num_values
!= 2)
479 printf("FAIL (wrong count - %d)\n", media_col
->num_values
);
487 fputs("ippFindAttribute(media-size 1): ", stdout
);
488 if ((media_size
= ippFindAttribute(media_col
->values
[0].collection
,
490 IPP_TAG_BEGIN_COLLECTION
)) == NULL
)
492 if ((media_size
= ippFindAttribute(media_col
->values
[0].collection
,
494 IPP_TAG_ZERO
)) == NULL
)
495 puts("FAIL (not found)");
497 printf("FAIL (wrong type - %s)\n",
498 ippTagString(media_size
->value_tag
));
504 if ((attr
= ippFindAttribute(media_size
->values
[0].collection
,
505 "x-dimension", IPP_TAG_INTEGER
)) == NULL
)
507 if ((attr
= ippFindAttribute(media_size
->values
[0].collection
,
508 "x-dimension", IPP_TAG_ZERO
)) == NULL
)
509 puts("FAIL (missing x-dimension)");
511 printf("FAIL (wrong type for x-dimension - %s)\n",
512 ippTagString(attr
->value_tag
));
516 else if (attr
->values
[0].integer
!= 21590)
518 printf("FAIL (wrong value for x-dimension - %d)\n",
519 attr
->values
[0].integer
);
522 else if ((attr
= ippFindAttribute(media_size
->values
[0].collection
,
524 IPP_TAG_INTEGER
)) == NULL
)
526 if ((attr
= ippFindAttribute(media_size
->values
[0].collection
,
527 "y-dimension", IPP_TAG_ZERO
)) == NULL
)
528 puts("FAIL (missing y-dimension)");
530 printf("FAIL (wrong type for y-dimension - %s)\n",
531 ippTagString(attr
->value_tag
));
535 else if (attr
->values
[0].integer
!= 27940)
537 printf("FAIL (wrong value for y-dimension - %d)\n",
538 attr
->values
[0].integer
);
545 fputs("ippFindAttribute(media-size 2): ", stdout
);
546 if ((media_size
= ippFindAttribute(media_col
->values
[1].collection
,
548 IPP_TAG_BEGIN_COLLECTION
)) == NULL
)
550 if ((media_size
= ippFindAttribute(media_col
->values
[1].collection
,
552 IPP_TAG_ZERO
)) == NULL
)
553 puts("FAIL (not found)");
555 printf("FAIL (wrong type - %s)\n",
556 ippTagString(media_size
->value_tag
));
562 if ((attr
= ippFindAttribute(media_size
->values
[0].collection
,
564 IPP_TAG_INTEGER
)) == NULL
)
566 if ((attr
= ippFindAttribute(media_size
->values
[0].collection
,
567 "x-dimension", IPP_TAG_ZERO
)) == NULL
)
568 puts("FAIL (missing x-dimension)");
570 printf("FAIL (wrong type for x-dimension - %s)\n",
571 ippTagString(attr
->value_tag
));
575 else if (attr
->values
[0].integer
!= 21000)
577 printf("FAIL (wrong value for x-dimension - %d)\n",
578 attr
->values
[0].integer
);
581 else if ((attr
= ippFindAttribute(media_size
->values
[0].collection
,
583 IPP_TAG_INTEGER
)) == NULL
)
585 if ((attr
= ippFindAttribute(media_size
->values
[0].collection
,
586 "y-dimension", IPP_TAG_ZERO
)) == NULL
)
587 puts("FAIL (missing y-dimension)");
589 printf("FAIL (wrong type for y-dimension - %s)\n",
590 ippTagString(attr
->value_tag
));
594 else if (attr
->values
[0].integer
!= 29700)
596 printf("FAIL (wrong value for y-dimension - %d)\n",
597 attr
->values
[0].integer
);
606 * Test hierarchical find...
609 fputs("ippFindAttribute(media-col/media-size/x-dimension): ", stdout
);
610 if ((attr
= ippFindAttribute(request
, "media-col/media-size/x-dimension", IPP_TAG_INTEGER
)) != NULL
)
612 if (ippGetInteger(attr
, 0) != 21590)
614 printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr
, 0));
622 puts("FAIL (not found)");
626 fputs("ippFindNextAttribute(media-col/media-size/x-dimension): ", stdout
);
627 if ((attr
= ippFindNextAttribute(request
, "media-col/media-size/x-dimension", IPP_TAG_INTEGER
)) != NULL
)
629 if (ippGetInteger(attr
, 0) != 21000)
631 printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr
, 0));
639 puts("FAIL (not found)");
643 fputs("ippFindNextAttribute(media-col/media-size/x-dimension) again: ", stdout
);
644 if ((attr
= ippFindNextAttribute(request
, "media-col/media-size/x-dimension", IPP_TAG_INTEGER
)) != NULL
)
646 printf("FAIL (got %d, expected nothing)\n", ippGetInteger(attr
, 0));
655 * Read the bad collection data and confirm we get an error...
658 fputs("Read Bad Collection from Memory: ", stdout
);
662 data
.wused
= sizeof(bad_collection
);
663 data
.wsize
= sizeof(bad_collection
);
664 data
.wbuffer
= bad_collection
;
666 while ((state
= ippReadIO(&data
, (ipp_iocb_t
)read_cb
, 1, NULL
, request
)) != IPP_STATE_DATA
)
667 if (state
== IPP_STATE_ERROR
)
670 if (state
!= IPP_STATE_ERROR
)
671 puts("FAIL (read successful)");
676 * Read the mixed data and confirm we converted everything to rangeOfInteger
680 fputs("Read Mixed integer/rangeOfInteger from Memory: ", stdout
);
684 data
.wused
= sizeof(mixed
);
685 data
.wsize
= sizeof(mixed
);
686 data
.wbuffer
= mixed
;
688 while ((state
= ippReadIO(&data
, (ipp_iocb_t
)read_cb
, 1, NULL
,
689 request
)) != IPP_STATE_DATA
)
690 if (state
== IPP_STATE_ERROR
)
693 length
= ippLength(request
);
695 if (state
!= IPP_STATE_DATA
)
697 printf("FAIL - %d bytes read.\n", (int)data
.rpos
);
700 else if (data
.rpos
!= sizeof(mixed
))
702 printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data
.rpos
,
704 print_attributes(request
, 8);
707 else if (length
!= (sizeof(mixed
) + 4))
709 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
710 (int)length
, (int)sizeof(mixed
) + 4);
711 print_attributes(request
, 8);
717 fputs("ippFindAttribute(notify-lease-duration-supported): ", stdout
);
718 if ((attr
= ippFindAttribute(request
, "notify-lease-duration-supported",
719 IPP_TAG_ZERO
)) == NULL
)
721 puts("FAIL (not found)");
724 else if (attr
->value_tag
!= IPP_TAG_RANGE
)
726 printf("FAIL (wrong type - %s)\n", ippTagString(attr
->value_tag
));
729 else if (attr
->num_values
!= 2)
731 printf("FAIL (wrong count - %d)\n", attr
->num_values
);
734 else if (attr
->values
[0].range
.lower
!= 1 ||
735 attr
->values
[0].range
.upper
!= 1 ||
736 attr
->values
[1].range
.lower
!= 16 ||
737 attr
->values
[1].range
.upper
!= 32)
739 printf("FAIL (wrong values - %d,%d and %d,%d)\n",
740 attr
->values
[0].range
.lower
,
741 attr
->values
[0].range
.upper
,
742 attr
->values
[1].range
.lower
,
743 attr
->values
[1].range
.upper
);
753 * Test that private option array is sorted...
756 fputs("_ippCheckOptions: ", stdout
);
757 if ((name
= _ippCheckOptions()) == NULL
)
761 printf("FAIL (\"%s\" out of order)\n", name
);
767 * Test _ippFindOption() private API...
770 fputs("_ippFindOption(\"printer-type\"): ", stdout
);
771 if (_ippFindOption("printer-type"))
786 puts("Core IPP tests failed.");
788 puts("Core IPP tests passed.");
796 for (i
= 1; i
< (size_t)argc
; i
++)
798 if (strlen(argv
[i
]) > 5 && !strcmp(argv
[i
] + strlen(argv
[i
]) - 5, ".test"))
801 * Read an ASCII IPP message...
804 _ipp_vars_t v
; /* IPP variables */
806 _ippVarsInit(&v
, NULL
, NULL
, token_cb
);
807 request
= _ippFileParse(&v
, argv
[i
], NULL
);
810 else if (strlen(argv
[i
]) > 4 && !strcmp(argv
[i
] + strlen(argv
[i
]) - 4, ".hex"))
813 * Read a hex-encoded IPP message...
816 if ((fp
= cupsFileOpen(argv
[i
], "r")) == NULL
)
818 printf("Unable to open \"%s\" - %s\n", argv
[i
], strerror(errno
));
824 while ((state
= ippReadIO(fp
, (ipp_iocb_t
)read_hex
, 1, NULL
, request
)) == IPP_STATE_ATTRIBUTE
);
826 if (state
!= IPP_STATE_DATA
)
828 printf("Error reading IPP message from \"%s\": %s\n", argv
[i
], cupsLastErrorString());
840 * Read a raw (binary) IPP message...
843 if ((fp
= cupsFileOpen(argv
[i
], "r")) == NULL
)
845 printf("Unable to open \"%s\" - %s\n", argv
[i
], strerror(errno
));
851 while ((state
= ippReadIO(fp
, (ipp_iocb_t
)cupsFileRead
, 1, NULL
,
852 request
)) == IPP_STATE_ATTRIBUTE
);
854 if (state
!= IPP_STATE_DATA
)
856 printf("Error reading IPP message from \"%s\": %s\n", argv
[i
], cupsLastErrorString());
868 printf("\n%s:\n", argv
[i
]);
869 print_attributes(request
, 4);
880 * 'hex_dump()' - Produce a hex dump of a buffer.
884 hex_dump(const char *title
, /* I - Title */
885 ipp_uchar_t
*buffer
, /* I - Buffer to dump */
886 size_t bytes
) /* I - Number of bytes */
888 size_t i
, j
; /* Looping vars */
889 int ch
; /* Current ASCII char */
893 * Show lines of 16 bytes at a time...
896 printf(" %s:\n", title
);
898 for (i
= 0; i
< bytes
; i
+= 16)
904 printf(" %04x ", (unsigned)i
);
907 * Then up to 16 bytes in hex...
910 for (j
= 0; j
< 16; j
++)
912 printf(" %02x", buffer
[i
+ j
]);
917 * Then the ASCII representation of the bytes...
923 for (j
= 0; j
< 16 && (i
+ j
) < bytes
; j
++)
925 ch
= buffer
[i
+ j
] & 127;
927 if (ch
< ' ' || ch
== 127)
939 * 'print_attributes()' - Print the attributes in a request...
943 print_attributes(ipp_t
*ipp
, /* I - IPP request */
944 int indent
) /* I - Indentation */
946 ipp_tag_t group
; /* Current group */
947 ipp_attribute_t
*attr
; /* Current attribute */
948 char buffer
[2048]; /* Value string */
951 for (group
= IPP_TAG_ZERO
, attr
= ipp
->attrs
; attr
; attr
= attr
->next
)
953 if (!attr
->name
&& indent
== 4)
955 group
= IPP_TAG_ZERO
;
960 if (group
!= attr
->group_tag
)
962 group
= attr
->group_tag
;
964 printf("\n%*s%s:\n\n", indent
- 4, "", ippTagString(group
));
967 ippAttributeString(attr
, buffer
, sizeof(buffer
));
969 printf("%*s%s (%s%s): %s\n", indent
, "", attr
->name
? attr
->name
: "(null)", attr
->num_values
> 1 ? "1setOf " : "", ippTagString(attr
->value_tag
), buffer
);
975 * 'read_cb()' - Read data from a buffer.
978 ssize_t
/* O - Number of bytes read */
979 read_cb(_ippdata_t
*data
, /* I - Data */
980 ipp_uchar_t
*buffer
, /* O - Buffer to read */
981 size_t bytes
) /* I - Number of bytes to read */
983 size_t count
; /* Number of bytes */
987 * Copy bytes from the data buffer to the read buffer...
990 if ((count
= data
->wsize
- data
->rpos
) > bytes
)
993 memcpy(buffer
, data
->wbuffer
+ data
->rpos
, count
);
997 * Return the number of bytes read...
1000 return ((ssize_t
)count
);
1005 * 'read_hex()' - Read a hex dump of an IPP request.
1008 ssize_t
/* O - Number of bytes read */
1009 read_hex(cups_file_t
*fp
, /* I - File to read from */
1010 ipp_uchar_t
*buffer
, /* I - Buffer to read */
1011 size_t bytes
) /* I - Number of bytes to read */
1013 size_t total
= 0; /* Total bytes read */
1014 static char hex
[256] = ""; /* Line from file */
1015 static char *hexptr
= NULL
; /* Pointer in line */
1018 while (total
< bytes
)
1020 if (!hexptr
|| (isspace(hexptr
[0] & 255) && isspace(hexptr
[1] & 255)))
1022 if (!cupsFileGets(fp
, hex
, sizeof(hex
)))
1026 while (isxdigit(*hexptr
& 255))
1028 while (isspace(*hexptr
& 255))
1031 if (!isxdigit(*hexptr
& 255))
1038 *buffer
++ = (ipp_uchar_t
)strtol(hexptr
, &hexptr
, 16);
1042 return (total
== 0 ? -1 : (ssize_t
)total
);
1047 * 'token_cb()' - Token callback for ASCII IPP data file parser.
1050 int /* O - 1 on success, 0 on failure */
1051 token_cb(_ipp_file_t
*f
, /* I - IPP file data */
1052 _ipp_vars_t
*v
, /* I - IPP variables */
1053 void *user_data
, /* I - User data pointer */
1054 const char *token
) /* I - Token string */
1061 f
->attrs
= ippNew();
1062 f
->group_tag
= IPP_TAG_PRINTER
;
1066 fprintf(stderr
, "Unknown directive \"%s\" on line %d of \"%s\".\n", token
, f
->linenum
, f
->filename
);
1075 * 'write_cb()' - Write data into a buffer.
1078 ssize_t
/* O - Number of bytes written */
1079 write_cb(_ippdata_t
*data
, /* I - Data */
1080 ipp_uchar_t
*buffer
, /* I - Buffer to write */
1081 size_t bytes
) /* I - Number of bytes to write */
1083 size_t count
; /* Number of bytes */
1087 * Loop until all bytes are written...
1090 if ((count
= data
->wsize
- data
->wused
) > bytes
)
1093 memcpy(data
->wbuffer
+ data
->wused
, buffer
, count
);
1094 data
->wused
+= count
;
1097 * Return the number of bytes written...
1100 return ((ssize_t
)count
);