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