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