]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testipp.c
The `ipptool` program did not compare URI scheme or hostname components
[thirdparty/cups.git] / cups / testipp.c
CommitLineData
ef416fc2 1/*
7e86f2f6 2 * IPP test program for CUPS.
ef416fc2 3 *
7e86f2f6
MS
4 * Copyright 2007-2014 by Apple Inc.
5 * Copyright 1997-2005 by Easy Software Products.
ef416fc2 6 *
7e86f2f6
MS
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
10 * which should have been included with this file. If this file is
57b7b66b 11 * missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 12 *
7e86f2f6 13 * This file is subject to the Apple OS-Developed Software exception.
ef416fc2 14 */
15
16/*
17 * Include necessary headers...
18 */
19
6d2f911b 20#include "file.h"
71e16022 21#include "string-private.h"
8ca02f3c 22#include "ipp-private.h"
ef416fc2 23#ifdef WIN32
24# include <io.h>
25#else
26# include <unistd.h>
27# include <fcntl.h>
28#endif /* WIN32 */
29
30
83e08001
MS
31/*
32 * Local types...
33 */
34
35typedef struct _ippdata_t
36{
37 size_t rpos, /* Read position */
38 wused, /* Bytes used */
39 wsize; /* Max size of buffer */
40 ipp_uchar_t *wbuffer; /* Buffer */
41} _ippdata_t;
42
43
ef416fc2 44/*
45 * Local globals...
46 */
47
7e86f2f6 48static ipp_uchar_t collection[] = /* Collection buffer */
ef416fc2 49 {
83e08001
MS
50 0x01, 0x01, /* IPP version */
51 0x00, 0x02, /* Print-Job operation */
52 0x00, 0x00, 0x00, 0x01,
53 /* Request ID */
ef416fc2 54
55 IPP_TAG_OPERATION,
56
57 IPP_TAG_CHARSET,
83e08001 58 0x00, 0x12, /* Name length + name */
ef416fc2 59 'a','t','t','r','i','b','u','t','e','s','-',
60 'c','h','a','r','s','e','t',
83e08001 61 0x00, 0x05, /* Value length + value */
ef416fc2 62 'u','t','f','-','8',
63
64 IPP_TAG_LANGUAGE,
83e08001 65 0x00, 0x1b, /* Name length + name */
ef416fc2 66 'a','t','t','r','i','b','u','t','e','s','-',
67 'n','a','t','u','r','a','l','-','l','a','n',
68 'g','u','a','g','e',
83e08001 69 0x00, 0x02, /* Value length + value */
ef416fc2 70 'e','n',
71
72 IPP_TAG_URI,
83e08001 73 0x00, 0x0b, /* Name length + name */
ef416fc2 74 'p','r','i','n','t','e','r','-','u','r','i',
75 0x00, 0x1c, /* Value length + value */
76 'i','p','p',':','/','/','l','o','c','a','l',
77 'h','o','s','t','/','p','r','i','n','t','e',
78 'r','s','/','f','o','o',
79
83e08001 80 IPP_TAG_JOB, /* job group tag */
ef416fc2 81
83e08001
MS
82 IPP_TAG_BEGIN_COLLECTION,
83 /* begCollection tag */
84 0x00, 0x09, /* Name length + name */
ef416fc2 85 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l',
83e08001
MS
86 0x00, 0x00, /* No value */
87 IPP_TAG_MEMBERNAME, /* memberAttrName tag */
88 0x00, 0x00, /* No name */
89 0x00, 0x0a, /* Value length + value */
54afec33 90 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e',
83e08001
MS
91 IPP_TAG_BEGIN_COLLECTION,
92 /* begCollection tag */
93 0x00, 0x00, /* Name length + name */
94 0x00, 0x00, /* No value */
95 IPP_TAG_MEMBERNAME,
96 /* memberAttrName tag */
97 0x00, 0x00, /* No name */
98 0x00, 0x0b, /* Value length + value */
54afec33 99 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n',
83e08001
MS
100 IPP_TAG_INTEGER, /* integer tag */
101 0x00, 0x00, /* No name */
102 0x00, 0x04, /* Value length + value */
54afec33 103 0x00, 0x00, 0x54, 0x56,
83e08001
MS
104 IPP_TAG_MEMBERNAME,
105 /* memberAttrName tag */
106 0x00, 0x00, /* No name */
107 0x00, 0x0b, /* Value length + value */
54afec33 108 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n',
83e08001
MS
109 IPP_TAG_INTEGER, /* integer tag */
110 0x00, 0x00, /* No name */
111 0x00, 0x04, /* Value length + value */
54afec33 112 0x00, 0x00, 0x6d, 0x24,
83e08001
MS
113 IPP_TAG_END_COLLECTION,
114 /* endCollection tag */
115 0x00, 0x00, /* No name */
116 0x00, 0x00, /* No value */
117 IPP_TAG_MEMBERNAME, /* memberAttrName tag */
118 0x00, 0x00, /* No name */
119 0x00, 0x0b, /* Value length + value */
ef416fc2 120 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 'o', 'r',
83e08001
MS
121 IPP_TAG_KEYWORD, /* keyword tag */
122 0x00, 0x00, /* No name */
123 0x00, 0x04, /* Value length + value */
ef416fc2 124 'b', 'l', 'u', 'e',
125
83e08001
MS
126 IPP_TAG_MEMBERNAME, /* memberAttrName tag */
127 0x00, 0x00, /* No name */
128 0x00, 0x0a, /* Value length + value */
ef416fc2 129 'm', 'e', 'd', 'i', 'a', '-', 't', 'y', 'p', 'e',
83e08001
MS
130 IPP_TAG_KEYWORD, /* keyword tag */
131 0x00, 0x00, /* No name */
132 0x00, 0x05, /* Value length + value */
ef416fc2 133 'p', 'l', 'a', 'i', 'n',
83e08001
MS
134 IPP_TAG_END_COLLECTION,
135 /* endCollection tag */
136 0x00, 0x00, /* No name */
137 0x00, 0x00, /* No value */
138
139 IPP_TAG_BEGIN_COLLECTION,
140 /* begCollection tag */
141 0x00, 0x00, /* No name */
142 0x00, 0x00, /* No value */
143 IPP_TAG_MEMBERNAME, /* memberAttrName tag */
144 0x00, 0x00, /* No name */
145 0x00, 0x0a, /* Value length + value */
54afec33 146 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e',
83e08001
MS
147 IPP_TAG_BEGIN_COLLECTION,
148 /* begCollection tag */
149 0x00, 0x00, /* Name length + name */
150 0x00, 0x00, /* No value */
151 IPP_TAG_MEMBERNAME,
152 /* memberAttrName tag */
153 0x00, 0x00, /* No name */
154 0x00, 0x0b, /* Value length + value */
54afec33 155 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n',
83e08001
MS
156 IPP_TAG_INTEGER, /* integer tag */
157 0x00, 0x00, /* No name */
158 0x00, 0x04, /* Value length + value */
54afec33 159 0x00, 0x00, 0x52, 0x08,
83e08001
MS
160 IPP_TAG_MEMBERNAME,
161 /* memberAttrName tag */
162 0x00, 0x00, /* No name */
163 0x00, 0x0b, /* Value length + value */
54afec33 164 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n',
83e08001
MS
165 IPP_TAG_INTEGER, /* integer tag */
166 0x00, 0x00, /* No name */
167 0x00, 0x04, /* Value length + value */
54afec33 168 0x00, 0x00, 0x74, 0x04,
83e08001
MS
169 IPP_TAG_END_COLLECTION,
170 /* endCollection tag */
171 0x00, 0x00, /* No name */
172 0x00, 0x00, /* No value */
173 IPP_TAG_MEMBERNAME, /* memberAttrName tag */
174 0x00, 0x00, /* No name */
175 0x00, 0x0b, /* Value length + value */
ef416fc2 176 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 'o', 'r',
83e08001
MS
177 IPP_TAG_KEYWORD, /* keyword tag */
178 0x00, 0x00, /* No name */
179 0x00, 0x05, /* Value length + value */
ef416fc2 180 'p', 'l', 'a', 'i', 'd',
181
83e08001
MS
182 IPP_TAG_MEMBERNAME, /* memberAttrName tag */
183 0x00, 0x00, /* No name */
184 0x00, 0x0a, /* Value length + value */
ef416fc2 185 'm', 'e', 'd', 'i', 'a', '-', 't', 'y', 'p', 'e',
83e08001
MS
186 IPP_TAG_KEYWORD, /* keyword tag */
187 0x00, 0x00, /* No name */
188 0x00, 0x06, /* Value length + value */
ef416fc2 189 'g', 'l', 'o', 's', 's', 'y',
83e08001
MS
190 IPP_TAG_END_COLLECTION,
191 /* endCollection tag */
192 0x00, 0x00, /* No name */
193 0x00, 0x00, /* No value */
ef416fc2 194
83e08001
MS
195 IPP_TAG_END /* end tag */
196 };
197
7e86f2f6 198static ipp_uchar_t mixed[] = /* Mixed value buffer */
83e08001
MS
199 {
200 0x01, 0x01, /* IPP version */
201 0x00, 0x02, /* Print-Job operation */
202 0x00, 0x00, 0x00, 0x01,
203 /* Request ID */
204
205 IPP_TAG_OPERATION,
206
207 IPP_TAG_INTEGER, /* integer tag */
208 0x00, 0x1f, /* Name length + name */
209 'n', 'o', 't', 'i', 'f', 'y', '-', 'l', 'e', 'a', 's', 'e',
210 '-', 'd', 'u', 'r', 'a', 't', 'i', 'o', 'n', '-', 's', 'u',
211 'p', 'p', 'o', 'r', 't', 'e', 'd',
212 0x00, 0x04, /* Value length + value */
213 0x00, 0x00, 0x00, 0x01,
214
215 IPP_TAG_RANGE, /* rangeOfInteger tag */
216 0x00, 0x00, /* No name */
217 0x00, 0x08, /* Value length + value */
218 0x00, 0x00, 0x00, 0x10,
219 0x00, 0x00, 0x00, 0x20,
220
221 IPP_TAG_END /* end tag */
ef416fc2 222 };
223
224
225/*
226 * Local functions...
227 */
228
7e86f2f6 229void hex_dump(const char *title, ipp_uchar_t *buffer, size_t bytes);
ef416fc2 230void print_attributes(ipp_t *ipp, int indent);
83e08001
MS
231ssize_t read_cb(_ippdata_t *data, ipp_uchar_t *buffer, size_t bytes);
232ssize_t write_cb(_ippdata_t *data, ipp_uchar_t *buffer, size_t bytes);
ef416fc2 233
234
235/*
236 * 'main()' - Main entry.
237 */
238
239int /* O - Exit status */
240main(int argc, /* I - Number of command-line arguments */
241 char *argv[]) /* I - Command-line arguments */
242{
83e08001
MS
243 _ippdata_t data; /* IPP buffer */
244 ipp_uchar_t buffer[8192]; /* Write buffer data */
54afec33
MS
245 ipp_t *cols[2], /* Collections */
246 *size; /* media-size collection */
ef416fc2 247 ipp_t *request; /* Request */
54afec33
MS
248 ipp_attribute_t *media_col, /* media-col attribute */
249 *media_size, /* media-size attribute */
250 *attr; /* Other attribute */
ef416fc2 251 ipp_state_t state; /* State */
7e86f2f6 252 size_t length; /* Length of data */
54afec33 253 cups_file_t *fp; /* File pointer */
7e86f2f6 254 size_t i; /* Looping var */
ef416fc2 255 int status; /* Status of tests (0 = success, 1 = fail) */
dfc4cea4 256#ifdef DEBUG
a469f8a5 257 const char *name; /* Option name */
dfc4cea4 258#endif /* DEBUG */
ef416fc2 259
260
261 status = 0;
262
263 if (argc == 1)
264 {
265 /*
266 * Test request generation code...
267 */
268
269 printf("Create Sample Request: ");
270
271 request = ippNew();
272 request->request.op.version[0] = 0x01;
273 request->request.op.version[1] = 0x01;
cb7f98ee 274 request->request.op.operation_id = IPP_OP_PRINT_JOB;
ef416fc2 275 request->request.op.request_id = 1;
276
277 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
278 "attributes-charset", NULL, "utf-8");
279 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
280 "attributes-natural-language", NULL, "en");
281 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
282 "printer-uri", NULL, "ipp://localhost/printers/foo");
283
284 cols[0] = ippNew();
54afec33
MS
285 size = ippNew();
286 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21590);
287 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 27940);
288 ippAddCollection(cols[0], IPP_TAG_JOB, "media-size", size);
aaf19ab0 289 ippDelete(size);
54afec33
MS
290 ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL,
291 "blue");
292 ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL,
293 "plain");
ef416fc2 294
295 cols[1] = ippNew();
54afec33
MS
296 size = ippNew();
297 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21000);
298 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 29700);
299 ippAddCollection(cols[1], IPP_TAG_JOB, "media-size", size);
aaf19ab0 300 ippDelete(size);
54afec33
MS
301 ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL,
302 "plaid");
303 ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL,
304 "glossy");
305
306 ippAddCollections(request, IPP_TAG_JOB, "media-col", 2,
307 (const ipp_t **)cols);
aaf19ab0
MS
308 ippDelete(cols[0]);
309 ippDelete(cols[1]);
ef416fc2 310
311 length = ippLength(request);
312 if (length != sizeof(collection))
313 {
314 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
7e86f2f6 315 (int)length, (int)sizeof(collection));
ef416fc2 316 status = 1;
317 }
318 else
319 puts("PASS");
320
321 /*
322 * Write test #1...
323 */
324
325 printf("Write Sample to Memory: ");
326
83e08001
MS
327 data.wused = 0;
328 data.wsize = sizeof(buffer);
329 data.wbuffer = buffer;
330
331 while ((state = ippWriteIO(&data, (ipp_iocb_t)write_cb, 1, NULL,
cb7f98ee
MS
332 request)) != IPP_STATE_DATA)
333 if (state == IPP_STATE_ERROR)
ef416fc2 334 break;
335
cb7f98ee 336 if (state != IPP_STATE_DATA)
ef416fc2 337 {
83e08001 338 printf("FAIL - %d bytes written.\n", (int)data.wused);
ef416fc2 339 status = 1;
340 }
83e08001 341 else if (data.wused != sizeof(collection))
ef416fc2 342 {
83e08001 343 printf("FAIL - wrote %d bytes, expected %d bytes!\n", (int)data.wused,
ef416fc2 344 (int)sizeof(collection));
83e08001 345 hex_dump("Bytes Written", data.wbuffer, data.wused);
ef416fc2 346 hex_dump("Baseline", collection, sizeof(collection));
347 status = 1;
348 }
83e08001 349 else if (memcmp(data.wbuffer, collection, data.wused))
ef416fc2 350 {
83e08001
MS
351 for (i = 0; i < data.wused; i ++)
352 if (data.wbuffer[i] != collection[i])
54afec33
MS
353 break;
354
7e86f2f6 355 printf("FAIL - output does not match baseline at 0x%04x!\n", (unsigned)i);
83e08001 356 hex_dump("Bytes Written", data.wbuffer, data.wused);
ef416fc2 357 hex_dump("Baseline", collection, sizeof(collection));
358 status = 1;
359 }
360 else
361 puts("PASS");
362
363 ippDelete(request);
364
365 /*
366 * Read the data back in and confirm...
367 */
368
369 printf("Read Sample from Memory: ");
370
83e08001
MS
371 request = ippNew();
372 data.rpos = 0;
ef416fc2 373
83e08001 374 while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL,
cb7f98ee
MS
375 request)) != IPP_STATE_DATA)
376 if (state == IPP_STATE_ERROR)
ef416fc2 377 break;
378
379 length = ippLength(request);
380
cb7f98ee 381 if (state != IPP_STATE_DATA)
ef416fc2 382 {
83e08001 383 printf("FAIL - %d bytes read.\n", (int)data.rpos);
ef416fc2 384 status = 1;
385 }
83e08001 386 else if (data.rpos != data.wused)
ef416fc2 387 {
83e08001
MS
388 printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos,
389 (int)data.wused);
ef416fc2 390 print_attributes(request, 8);
391 status = 1;
392 }
393 else if (length != sizeof(collection))
394 {
395 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
7e86f2f6 396 (int)length, (int)sizeof(collection));
ef416fc2 397 print_attributes(request, 8);
398 status = 1;
399 }
400 else
401 puts("PASS");
402
54afec33
MS
403 fputs("ippFindAttribute(media-col): ", stdout);
404 if ((media_col = ippFindAttribute(request, "media-col",
405 IPP_TAG_BEGIN_COLLECTION)) == NULL)
406 {
407 if ((media_col = ippFindAttribute(request, "media-col",
408 IPP_TAG_ZERO)) == NULL)
409 puts("FAIL (not found)");
410 else
411 printf("FAIL (wrong type - %s)\n", ippTagString(media_col->value_tag));
412
413 status = 1;
414 }
415 else if (media_col->num_values != 2)
416 {
417 printf("FAIL (wrong count - %d)\n", media_col->num_values);
418 status = 1;
419 }
420 else
421 puts("PASS");
422
aaf19ab0 423 if (media_col)
54afec33 424 {
aaf19ab0 425 fputs("ippFindAttribute(media-size 1): ", stdout);
54afec33 426 if ((media_size = ippFindAttribute(media_col->values[0].collection,
aaf19ab0
MS
427 "media-size",
428 IPP_TAG_BEGIN_COLLECTION)) == NULL)
54afec33 429 {
aaf19ab0
MS
430 if ((media_size = ippFindAttribute(media_col->values[0].collection,
431 "media-col",
432 IPP_TAG_ZERO)) == NULL)
433 puts("FAIL (not found)");
54afec33 434 else
aaf19ab0
MS
435 printf("FAIL (wrong type - %s)\n",
436 ippTagString(media_size->value_tag));
54afec33
MS
437
438 status = 1;
439 }
aaf19ab0 440 else
54afec33
MS
441 {
442 if ((attr = ippFindAttribute(media_size->values[0].collection,
aaf19ab0
MS
443 "x-dimension", IPP_TAG_INTEGER)) == NULL)
444 {
445 if ((attr = ippFindAttribute(media_size->values[0].collection,
446 "x-dimension", IPP_TAG_ZERO)) == NULL)
447 puts("FAIL (missing x-dimension)");
448 else
449 printf("FAIL (wrong type for x-dimension - %s)\n",
450 ippTagString(attr->value_tag));
451
452 status = 1;
453 }
454 else if (attr->values[0].integer != 21590)
455 {
456 printf("FAIL (wrong value for x-dimension - %d)\n",
457 attr->values[0].integer);
458 status = 1;
459 }
460 else if ((attr = ippFindAttribute(media_size->values[0].collection,
461 "y-dimension",
462 IPP_TAG_INTEGER)) == NULL)
463 {
464 if ((attr = ippFindAttribute(media_size->values[0].collection,
465 "y-dimension", IPP_TAG_ZERO)) == NULL)
466 puts("FAIL (missing y-dimension)");
467 else
468 printf("FAIL (wrong type for y-dimension - %s)\n",
469 ippTagString(attr->value_tag));
470
471 status = 1;
472 }
473 else if (attr->values[0].integer != 27940)
474 {
475 printf("FAIL (wrong value for y-dimension - %d)\n",
476 attr->values[0].integer);
477 status = 1;
478 }
54afec33 479 else
aaf19ab0 480 puts("PASS");
54afec33 481 }
54afec33 482
aaf19ab0 483 fputs("ippFindAttribute(media-size 2): ", stdout);
54afec33 484 if ((media_size = ippFindAttribute(media_col->values[1].collection,
aaf19ab0
MS
485 "media-size",
486 IPP_TAG_BEGIN_COLLECTION)) == NULL)
54afec33 487 {
aaf19ab0
MS
488 if ((media_size = ippFindAttribute(media_col->values[1].collection,
489 "media-col",
490 IPP_TAG_ZERO)) == NULL)
491 puts("FAIL (not found)");
54afec33 492 else
aaf19ab0
MS
493 printf("FAIL (wrong type - %s)\n",
494 ippTagString(media_size->value_tag));
54afec33
MS
495
496 status = 1;
497 }
aaf19ab0 498 else
54afec33
MS
499 {
500 if ((attr = ippFindAttribute(media_size->values[0].collection,
aaf19ab0
MS
501 "x-dimension",
502 IPP_TAG_INTEGER)) == NULL)
503 {
504 if ((attr = ippFindAttribute(media_size->values[0].collection,
505 "x-dimension", IPP_TAG_ZERO)) == NULL)
506 puts("FAIL (missing x-dimension)");
507 else
508 printf("FAIL (wrong type for x-dimension - %s)\n",
509 ippTagString(attr->value_tag));
510
511 status = 1;
512 }
513 else if (attr->values[0].integer != 21000)
514 {
515 printf("FAIL (wrong value for x-dimension - %d)\n",
516 attr->values[0].integer);
517 status = 1;
518 }
519 else if ((attr = ippFindAttribute(media_size->values[0].collection,
520 "y-dimension",
521 IPP_TAG_INTEGER)) == NULL)
522 {
523 if ((attr = ippFindAttribute(media_size->values[0].collection,
524 "y-dimension", IPP_TAG_ZERO)) == NULL)
525 puts("FAIL (missing y-dimension)");
526 else
527 printf("FAIL (wrong type for y-dimension - %s)\n",
528 ippTagString(attr->value_tag));
529
530 status = 1;
531 }
532 else if (attr->values[0].integer != 29700)
533 {
534 printf("FAIL (wrong value for y-dimension - %d)\n",
535 attr->values[0].integer);
536 status = 1;
537 }
54afec33 538 else
aaf19ab0 539 puts("PASS");
54afec33 540 }
54afec33
MS
541 }
542
f2a31e21
MS
543 /*
544 * Test hierarchical find...
545 */
546
547 fputs("ippFindAttribute(media-col/media-size/x-dimension): ", stdout);
548 if ((attr = ippFindAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
549 {
550 if (ippGetInteger(attr, 0) != 21590)
551 {
552 printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0));
553 status = 1;
554 }
555 else
556 puts("PASS");
557 }
558 else
559 {
560 puts("FAIL (not found)");
561 status = 1;
562 }
563
564 fputs("ippFindNextAttribute(media-col/media-size/x-dimension): ", stdout);
565 if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
566 {
567 if (ippGetInteger(attr, 0) != 21000)
568 {
569 printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0));
570 status = 1;
571 }
572 else
573 puts("PASS");
574 }
575 else
576 {
577 puts("FAIL (not found)");
578 status = 1;
579 }
580
581 fputs("ippFindNextAttribute(media-col/media-size/x-dimension) again: ", stdout);
582 if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
583 {
584 printf("FAIL (got %d, expected nothing)\n", ippGetInteger(attr, 0));
585 status = 1;
586 }
587 else
588 puts("PASS");
589
ef416fc2 590 ippDelete(request);
591
83e08001
MS
592 /*
593 * Read the mixed data and confirm we converted everything to rangeOfInteger
594 * values...
595 */
596
597 printf("Read Mixed integer/rangeOfInteger from Memory: ");
598
599 request = ippNew();
600 data.rpos = 0;
601 data.wused = sizeof(mixed);
602 data.wsize = sizeof(mixed);
603 data.wbuffer = mixed;
604
605 while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL,
cb7f98ee
MS
606 request)) != IPP_STATE_DATA)
607 if (state == IPP_STATE_ERROR)
83e08001
MS
608 break;
609
610 length = ippLength(request);
611
cb7f98ee 612 if (state != IPP_STATE_DATA)
83e08001
MS
613 {
614 printf("FAIL - %d bytes read.\n", (int)data.rpos);
615 status = 1;
616 }
617 else if (data.rpos != sizeof(mixed))
618 {
619 printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos,
620 (int)sizeof(mixed));
621 print_attributes(request, 8);
622 status = 1;
623 }
624 else if (length != (sizeof(mixed) + 4))
625 {
626 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
7e86f2f6 627 (int)length, (int)sizeof(mixed) + 4);
83e08001
MS
628 print_attributes(request, 8);
629 status = 1;
630 }
631 else
632 puts("PASS");
633
634 fputs("ippFindAttribute(notify-lease-duration-supported): ", stdout);
635 if ((attr = ippFindAttribute(request, "notify-lease-duration-supported",
636 IPP_TAG_ZERO)) == NULL)
637 {
638 puts("FAIL (not found)");
639 status = 1;
640 }
641 else if (attr->value_tag != IPP_TAG_RANGE)
642 {
643 printf("FAIL (wrong type - %s)\n", ippTagString(attr->value_tag));
644 status = 1;
645 }
646 else if (attr->num_values != 2)
647 {
648 printf("FAIL (wrong count - %d)\n", attr->num_values);
649 status = 1;
650 }
651 else if (attr->values[0].range.lower != 1 ||
652 attr->values[0].range.upper != 1 ||
653 attr->values[1].range.lower != 16 ||
654 attr->values[1].range.upper != 32)
655 {
656 printf("FAIL (wrong values - %d,%d and %d,%d)\n",
657 attr->values[0].range.lower,
658 attr->values[0].range.upper,
659 attr->values[1].range.lower,
660 attr->values[1].range.upper);
661 status = 1;
662 }
663 else
664 puts("PASS");
665
666 ippDelete(request);
667
a469f8a5
MS
668#ifdef DEBUG
669 /*
670 * Test that private option array is sorted...
671 */
672
673 fputs("_ippCheckOptions: ", stdout);
674 if ((name = _ippCheckOptions()) == NULL)
675 puts("PASS");
676 else
677 {
678 printf("FAIL (\"%s\" out of order)\n", name);
679 status = 1;
680 }
681#endif /* DEBUG */
682
8ca02f3c 683 /*
684 * Test _ippFindOption() private API...
685 */
686
a469f8a5 687 fputs("_ippFindOption(\"printer-type\"): ", stdout);
8ca02f3c 688 if (_ippFindOption("printer-type"))
689 puts("PASS");
690 else
691 {
692 puts("FAIL");
693 status = 1;
694 }
695
ef416fc2 696 /*
697 * Summarize...
698 */
699
700 putchar('\n');
701
702 if (status)
703 puts("Core IPP tests failed.");
704 else
705 puts("Core IPP tests passed.");
706 }
707 else
708 {
709 /*
710 * Read IPP files...
711 */
712
7e86f2f6 713 for (i = 1; i < (size_t)argc; i ++)
ef416fc2 714 {
54afec33 715 if ((fp = cupsFileOpen(argv[i], "r")) == NULL)
ef416fc2 716 {
717 printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno));
718 status = 1;
719 continue;
720 }
721
722 request = ippNew();
54afec33 723 while ((state = ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL,
cb7f98ee 724 request)) == IPP_STATE_ATTRIBUTE);
ef416fc2 725
cb7f98ee 726 if (state != IPP_STATE_DATA)
ef416fc2 727 {
728 printf("Error reading IPP message from \"%s\"!\n", argv[i]);
729 status = 1;
730 }
731 else
732 {
733 printf("\n%s:\n", argv[i]);
734 print_attributes(request, 4);
735 }
736
737 ippDelete(request);
54afec33 738 cupsFileClose(fp);
ef416fc2 739 }
740 }
741
742 return (status);
743}
744
745
746/*
747 * 'hex_dump()' - Produce a hex dump of a buffer.
748 */
749
750void
751hex_dump(const char *title, /* I - Title */
752 ipp_uchar_t *buffer, /* I - Buffer to dump */
7e86f2f6 753 size_t bytes) /* I - Number of bytes */
ef416fc2 754{
7e86f2f6
MS
755 size_t i, j; /* Looping vars */
756 int ch; /* Current ASCII char */
ef416fc2 757
758
759 /*
760 * Show lines of 16 bytes at a time...
761 */
762
763 printf(" %s:\n", title);
764
765 for (i = 0; i < bytes; i += 16)
766 {
767 /*
768 * Show the offset...
769 */
770
7e86f2f6 771 printf(" %04x ", (unsigned)i);
ef416fc2 772
773 /*
774 * Then up to 16 bytes in hex...
775 */
776
777 for (j = 0; j < 16; j ++)
778 if ((i + j) < bytes)
779 printf(" %02x", buffer[i + j]);
780 else
781 printf(" ");
782
783 /*
784 * Then the ASCII representation of the bytes...
785 */
786
787 putchar(' ');
788 putchar(' ');
789
790 for (j = 0; j < 16 && (i + j) < bytes; j ++)
791 {
792 ch = buffer[i + j] & 127;
793
794 if (ch < ' ' || ch == 127)
795 putchar('.');
796 else
797 putchar(ch);
798 }
799
800 putchar('\n');
801 }
802}
803
804
805/*
806 * 'print_attributes()' - Print the attributes in a request...
807 */
808
809void
810print_attributes(ipp_t *ipp, /* I - IPP request */
811 int indent) /* I - Indentation */
812{
813 int i; /* Looping var */
814 ipp_tag_t group; /* Current group */
815 ipp_attribute_t *attr; /* Current attribute */
a2326b5b 816 _ipp_value_t *val; /* Current value */
ef416fc2 817 static const char * const tags[] = /* Value/group tag strings */
818 {
819 "reserved-00",
820 "operation-attributes-tag",
821 "job-attributes-tag",
822 "end-of-attributes-tag",
823 "printer-attributes-tag",
824 "unsupported-attributes-tag",
825 "subscription-attributes-tag",
826 "event-attributes-tag",
827 "reserved-08",
828 "reserved-09",
829 "reserved-0A",
830 "reserved-0B",
831 "reserved-0C",
832 "reserved-0D",
833 "reserved-0E",
834 "reserved-0F",
835 "unsupported",
836 "default",
837 "unknown",
838 "no-value",
839 "reserved-14",
840 "not-settable",
841 "delete-attr",
842 "admin-define",
843 "reserved-18",
844 "reserved-19",
845 "reserved-1A",
846 "reserved-1B",
847 "reserved-1C",
848 "reserved-1D",
849 "reserved-1E",
850 "reserved-1F",
851 "reserved-20",
852 "integer",
853 "boolean",
854 "enum",
855 "reserved-24",
856 "reserved-25",
857 "reserved-26",
858 "reserved-27",
859 "reserved-28",
860 "reserved-29",
861 "reserved-2a",
862 "reserved-2b",
863 "reserved-2c",
864 "reserved-2d",
865 "reserved-2e",
866 "reserved-2f",
867 "octetString",
868 "dateTime",
869 "resolution",
870 "rangeOfInteger",
871 "begCollection",
872 "textWithLanguage",
873 "nameWithLanguage",
874 "endCollection",
875 "reserved-38",
876 "reserved-39",
877 "reserved-3a",
878 "reserved-3b",
879 "reserved-3c",
880 "reserved-3d",
881 "reserved-3e",
882 "reserved-3f",
883 "reserved-40",
884 "textWithoutLanguage",
885 "nameWithoutLanguage",
886 "reserved-43",
887 "keyword",
888 "uri",
889 "uriScheme",
890 "charset",
891 "naturalLanguage",
892 "mimeMediaType",
893 "memberName"
894 };
895
896
897 for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next)
898 {
d2354e63 899 if (!attr->name && indent == 4)
ef416fc2 900 {
901 group = IPP_TAG_ZERO;
902 putchar('\n');
903 continue;
904 }
905
906 if (group != attr->group_tag)
907 {
908 group = attr->group_tag;
909
d2354e63 910 printf("\n%*s%s:\n\n", indent - 4, "", tags[group]);
ef416fc2 911 }
912
d2354e63 913 printf("%*s%s (", indent, "", attr->name ? attr->name : "(null)");
ef416fc2 914 if (attr->num_values > 1)
915 printf("1setOf ");
916 printf("%s):", tags[attr->value_tag]);
917
918 switch (attr->value_tag)
919 {
920 case IPP_TAG_ENUM :
921 case IPP_TAG_INTEGER :
922 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
923 printf(" %d", val->integer);
924 putchar('\n');
925 break;
926
927 case IPP_TAG_BOOLEAN :
928 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
929 printf(" %s", val->boolean ? "true" : "false");
930 putchar('\n');
931 break;
932
933 case IPP_TAG_RANGE :
934 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
935 printf(" %d-%d", val->range.lower, val->range.upper);
936 putchar('\n');
937 break;
938
939 case IPP_TAG_DATE :
940 {
ef416fc2 941 char vstring[256]; /* Formatted time */
942
943 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
554aa7b7 944 printf(" (%s)", _cupsStrDate(vstring, sizeof(vstring), ippDateToTime(val->date)));
ef416fc2 945 }
946 putchar('\n');
947 break;
948
949 case IPP_TAG_RESOLUTION :
950 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
951 printf(" %dx%d%s", val->resolution.xres, val->resolution.yres,
3e7fe0ca 952 val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
ef416fc2 953 putchar('\n');
954 break;
955
956 case IPP_TAG_STRING :
957 case IPP_TAG_TEXTLANG :
958 case IPP_TAG_NAMELANG :
959 case IPP_TAG_TEXT :
960 case IPP_TAG_NAME :
961 case IPP_TAG_KEYWORD :
962 case IPP_TAG_URI :
963 case IPP_TAG_URISCHEME :
964 case IPP_TAG_CHARSET :
965 case IPP_TAG_LANGUAGE :
966 case IPP_TAG_MIMETYPE :
967 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
968 printf(" \"%s\"", val->string.text);
969 putchar('\n');
970 break;
971
972 case IPP_TAG_BEGIN_COLLECTION :
973 putchar('\n');
974
975 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
976 {
977 if (i)
978 putchar('\n');
979 print_attributes(val->collection, indent + 4);
980 }
981 break;
982
983 default :
984 printf("UNKNOWN (%d values)\n", attr->num_values);
985 break;
986 }
987 }
988}
989
990
991/*
992 * 'read_cb()' - Read data from a buffer.
993 */
994
a4d04587 995ssize_t /* O - Number of bytes read */
83e08001 996read_cb(_ippdata_t *data, /* I - Data */
ef416fc2 997 ipp_uchar_t *buffer, /* O - Buffer to read */
a4d04587 998 size_t bytes) /* I - Number of bytes to read */
ef416fc2 999{
83e08001 1000 size_t count; /* Number of bytes */
ef416fc2 1001
1002
1003 /*
1004 * Copy bytes from the data buffer to the read buffer...
1005 */
1006
83e08001
MS
1007 if ((count = data->wsize - data->rpos) > bytes)
1008 count = bytes;
1009
1010 memcpy(buffer, data->wbuffer + data->rpos, count);
1011 data->rpos += count;
ef416fc2 1012
1013 /*
1014 * Return the number of bytes read...
1015 */
1016
7e86f2f6 1017 return ((ssize_t)count);
ef416fc2 1018}
1019
1020
1021/*
1022 * 'write_cb()' - Write data into a buffer.
1023 */
1024
a4d04587 1025ssize_t /* O - Number of bytes written */
83e08001 1026write_cb(_ippdata_t *data, /* I - Data */
ef416fc2 1027 ipp_uchar_t *buffer, /* I - Buffer to write */
a4d04587 1028 size_t bytes) /* I - Number of bytes to write */
ef416fc2 1029{
83e08001 1030 size_t count; /* Number of bytes */
ef416fc2 1031
1032
1033 /*
1034 * Loop until all bytes are written...
1035 */
1036
83e08001
MS
1037 if ((count = data->wsize - data->wused) > bytes)
1038 count = bytes;
1039
1040 memcpy(data->wbuffer + data->wused, buffer, count);
1041 data->wused += count;
ef416fc2 1042
1043 /*
1044 * Return the number of bytes written...
1045 */
1046
7e86f2f6 1047 return ((ssize_t)count);
ef416fc2 1048}