]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testipp.c
Fix clang-reported issues (<rdar://problem/15936066>)
[thirdparty/cups.git] / cups / testipp.c
CommitLineData
ef416fc2 1/*
f2d18633 2 * "$Id$"
ef416fc2 3 *
71e16022 4 * IPP test program for CUPS.
ef416fc2 5 *
cb7f98ee 6 * Copyright 2007-2013 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) */
dfc4cea4 266#ifdef DEBUG
a469f8a5 267 const char *name; /* Option name */
dfc4cea4 268#endif /* DEBUG */
ef416fc2 269
270
271 status = 0;
272
273 if (argc == 1)
274 {
275 /*
276 * Test request generation code...
277 */
278
279 printf("Create Sample Request: ");
280
281 request = ippNew();
282 request->request.op.version[0] = 0x01;
283 request->request.op.version[1] = 0x01;
cb7f98ee 284 request->request.op.operation_id = IPP_OP_PRINT_JOB;
ef416fc2 285 request->request.op.request_id = 1;
286
287 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
288 "attributes-charset", NULL, "utf-8");
289 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
290 "attributes-natural-language", NULL, "en");
291 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
292 "printer-uri", NULL, "ipp://localhost/printers/foo");
293
294 cols[0] = ippNew();
54afec33
MS
295 size = ippNew();
296 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21590);
297 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 27940);
298 ippAddCollection(cols[0], IPP_TAG_JOB, "media-size", size);
aaf19ab0 299 ippDelete(size);
54afec33
MS
300 ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL,
301 "blue");
302 ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL,
303 "plain");
ef416fc2 304
305 cols[1] = ippNew();
54afec33
MS
306 size = ippNew();
307 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21000);
308 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 29700);
309 ippAddCollection(cols[1], IPP_TAG_JOB, "media-size", size);
aaf19ab0 310 ippDelete(size);
54afec33
MS
311 ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL,
312 "plaid");
313 ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL,
314 "glossy");
315
316 ippAddCollections(request, IPP_TAG_JOB, "media-col", 2,
317 (const ipp_t **)cols);
aaf19ab0
MS
318 ippDelete(cols[0]);
319 ippDelete(cols[1]);
ef416fc2 320
321 length = ippLength(request);
322 if (length != sizeof(collection))
323 {
324 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
325 length, (int)sizeof(collection));
326 status = 1;
327 }
328 else
329 puts("PASS");
330
331 /*
332 * Write test #1...
333 */
334
335 printf("Write Sample to Memory: ");
336
83e08001
MS
337 data.wused = 0;
338 data.wsize = sizeof(buffer);
339 data.wbuffer = buffer;
340
341 while ((state = ippWriteIO(&data, (ipp_iocb_t)write_cb, 1, NULL,
cb7f98ee
MS
342 request)) != IPP_STATE_DATA)
343 if (state == IPP_STATE_ERROR)
ef416fc2 344 break;
345
cb7f98ee 346 if (state != IPP_STATE_DATA)
ef416fc2 347 {
83e08001 348 printf("FAIL - %d bytes written.\n", (int)data.wused);
ef416fc2 349 status = 1;
350 }
83e08001 351 else if (data.wused != sizeof(collection))
ef416fc2 352 {
83e08001 353 printf("FAIL - wrote %d bytes, expected %d bytes!\n", (int)data.wused,
ef416fc2 354 (int)sizeof(collection));
83e08001 355 hex_dump("Bytes Written", data.wbuffer, data.wused);
ef416fc2 356 hex_dump("Baseline", collection, sizeof(collection));
357 status = 1;
358 }
83e08001 359 else if (memcmp(data.wbuffer, collection, data.wused))
ef416fc2 360 {
83e08001
MS
361 for (i = 0; i < data.wused; i ++)
362 if (data.wbuffer[i] != collection[i])
54afec33
MS
363 break;
364
365 printf("FAIL - output does not match baseline at 0x%04x!\n", i);
83e08001 366 hex_dump("Bytes Written", data.wbuffer, data.wused);
ef416fc2 367 hex_dump("Baseline", collection, sizeof(collection));
368 status = 1;
369 }
370 else
371 puts("PASS");
372
373 ippDelete(request);
374
375 /*
376 * Read the data back in and confirm...
377 */
378
379 printf("Read Sample from Memory: ");
380
83e08001
MS
381 request = ippNew();
382 data.rpos = 0;
ef416fc2 383
83e08001 384 while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL,
cb7f98ee
MS
385 request)) != IPP_STATE_DATA)
386 if (state == IPP_STATE_ERROR)
ef416fc2 387 break;
388
389 length = ippLength(request);
390
cb7f98ee 391 if (state != IPP_STATE_DATA)
ef416fc2 392 {
83e08001 393 printf("FAIL - %d bytes read.\n", (int)data.rpos);
ef416fc2 394 status = 1;
395 }
83e08001 396 else if (data.rpos != data.wused)
ef416fc2 397 {
83e08001
MS
398 printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos,
399 (int)data.wused);
ef416fc2 400 print_attributes(request, 8);
401 status = 1;
402 }
403 else if (length != sizeof(collection))
404 {
405 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
406 length, (int)sizeof(collection));
407 print_attributes(request, 8);
408 status = 1;
409 }
410 else
411 puts("PASS");
412
54afec33
MS
413 fputs("ippFindAttribute(media-col): ", stdout);
414 if ((media_col = ippFindAttribute(request, "media-col",
415 IPP_TAG_BEGIN_COLLECTION)) == NULL)
416 {
417 if ((media_col = ippFindAttribute(request, "media-col",
418 IPP_TAG_ZERO)) == NULL)
419 puts("FAIL (not found)");
420 else
421 printf("FAIL (wrong type - %s)\n", ippTagString(media_col->value_tag));
422
423 status = 1;
424 }
425 else if (media_col->num_values != 2)
426 {
427 printf("FAIL (wrong count - %d)\n", media_col->num_values);
428 status = 1;
429 }
430 else
431 puts("PASS");
432
aaf19ab0 433 if (media_col)
54afec33 434 {
aaf19ab0 435 fputs("ippFindAttribute(media-size 1): ", stdout);
54afec33 436 if ((media_size = ippFindAttribute(media_col->values[0].collection,
aaf19ab0
MS
437 "media-size",
438 IPP_TAG_BEGIN_COLLECTION)) == NULL)
54afec33 439 {
aaf19ab0
MS
440 if ((media_size = ippFindAttribute(media_col->values[0].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", IPP_TAG_INTEGER)) == NULL)
454 {
455 if ((attr = ippFindAttribute(media_size->values[0].collection,
456 "x-dimension", IPP_TAG_ZERO)) == NULL)
457 puts("FAIL (missing x-dimension)");
458 else
459 printf("FAIL (wrong type for x-dimension - %s)\n",
460 ippTagString(attr->value_tag));
461
462 status = 1;
463 }
464 else if (attr->values[0].integer != 21590)
465 {
466 printf("FAIL (wrong value for x-dimension - %d)\n",
467 attr->values[0].integer);
468 status = 1;
469 }
470 else if ((attr = ippFindAttribute(media_size->values[0].collection,
471 "y-dimension",
472 IPP_TAG_INTEGER)) == NULL)
473 {
474 if ((attr = ippFindAttribute(media_size->values[0].collection,
475 "y-dimension", IPP_TAG_ZERO)) == NULL)
476 puts("FAIL (missing y-dimension)");
477 else
478 printf("FAIL (wrong type for y-dimension - %s)\n",
479 ippTagString(attr->value_tag));
480
481 status = 1;
482 }
483 else if (attr->values[0].integer != 27940)
484 {
485 printf("FAIL (wrong value for y-dimension - %d)\n",
486 attr->values[0].integer);
487 status = 1;
488 }
54afec33 489 else
aaf19ab0 490 puts("PASS");
54afec33 491 }
54afec33 492
aaf19ab0 493 fputs("ippFindAttribute(media-size 2): ", stdout);
54afec33 494 if ((media_size = ippFindAttribute(media_col->values[1].collection,
aaf19ab0
MS
495 "media-size",
496 IPP_TAG_BEGIN_COLLECTION)) == NULL)
54afec33 497 {
aaf19ab0
MS
498 if ((media_size = ippFindAttribute(media_col->values[1].collection,
499 "media-col",
500 IPP_TAG_ZERO)) == NULL)
501 puts("FAIL (not found)");
54afec33 502 else
aaf19ab0
MS
503 printf("FAIL (wrong type - %s)\n",
504 ippTagString(media_size->value_tag));
54afec33
MS
505
506 status = 1;
507 }
aaf19ab0 508 else
54afec33
MS
509 {
510 if ((attr = ippFindAttribute(media_size->values[0].collection,
aaf19ab0
MS
511 "x-dimension",
512 IPP_TAG_INTEGER)) == NULL)
513 {
514 if ((attr = ippFindAttribute(media_size->values[0].collection,
515 "x-dimension", IPP_TAG_ZERO)) == NULL)
516 puts("FAIL (missing x-dimension)");
517 else
518 printf("FAIL (wrong type for x-dimension - %s)\n",
519 ippTagString(attr->value_tag));
520
521 status = 1;
522 }
523 else if (attr->values[0].integer != 21000)
524 {
525 printf("FAIL (wrong value for x-dimension - %d)\n",
526 attr->values[0].integer);
527 status = 1;
528 }
529 else if ((attr = ippFindAttribute(media_size->values[0].collection,
530 "y-dimension",
531 IPP_TAG_INTEGER)) == NULL)
532 {
533 if ((attr = ippFindAttribute(media_size->values[0].collection,
534 "y-dimension", IPP_TAG_ZERO)) == NULL)
535 puts("FAIL (missing y-dimension)");
536 else
537 printf("FAIL (wrong type for y-dimension - %s)\n",
538 ippTagString(attr->value_tag));
539
540 status = 1;
541 }
542 else if (attr->values[0].integer != 29700)
543 {
544 printf("FAIL (wrong value for y-dimension - %d)\n",
545 attr->values[0].integer);
546 status = 1;
547 }
54afec33 548 else
aaf19ab0 549 puts("PASS");
54afec33 550 }
54afec33
MS
551 }
552
ef416fc2 553 ippDelete(request);
554
83e08001
MS
555 /*
556 * Read the mixed data and confirm we converted everything to rangeOfInteger
557 * values...
558 */
559
560 printf("Read Mixed integer/rangeOfInteger from Memory: ");
561
562 request = ippNew();
563 data.rpos = 0;
564 data.wused = sizeof(mixed);
565 data.wsize = sizeof(mixed);
566 data.wbuffer = mixed;
567
568 while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL,
cb7f98ee
MS
569 request)) != IPP_STATE_DATA)
570 if (state == IPP_STATE_ERROR)
83e08001
MS
571 break;
572
573 length = ippLength(request);
574
cb7f98ee 575 if (state != IPP_STATE_DATA)
83e08001
MS
576 {
577 printf("FAIL - %d bytes read.\n", (int)data.rpos);
578 status = 1;
579 }
580 else if (data.rpos != sizeof(mixed))
581 {
582 printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos,
583 (int)sizeof(mixed));
584 print_attributes(request, 8);
585 status = 1;
586 }
587 else if (length != (sizeof(mixed) + 4))
588 {
589 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
590 length, (int)sizeof(mixed) + 4);
591 print_attributes(request, 8);
592 status = 1;
593 }
594 else
595 puts("PASS");
596
597 fputs("ippFindAttribute(notify-lease-duration-supported): ", stdout);
598 if ((attr = ippFindAttribute(request, "notify-lease-duration-supported",
599 IPP_TAG_ZERO)) == NULL)
600 {
601 puts("FAIL (not found)");
602 status = 1;
603 }
604 else if (attr->value_tag != IPP_TAG_RANGE)
605 {
606 printf("FAIL (wrong type - %s)\n", ippTagString(attr->value_tag));
607 status = 1;
608 }
609 else if (attr->num_values != 2)
610 {
611 printf("FAIL (wrong count - %d)\n", attr->num_values);
612 status = 1;
613 }
614 else if (attr->values[0].range.lower != 1 ||
615 attr->values[0].range.upper != 1 ||
616 attr->values[1].range.lower != 16 ||
617 attr->values[1].range.upper != 32)
618 {
619 printf("FAIL (wrong values - %d,%d and %d,%d)\n",
620 attr->values[0].range.lower,
621 attr->values[0].range.upper,
622 attr->values[1].range.lower,
623 attr->values[1].range.upper);
624 status = 1;
625 }
626 else
627 puts("PASS");
628
629 ippDelete(request);
630
a469f8a5
MS
631#ifdef DEBUG
632 /*
633 * Test that private option array is sorted...
634 */
635
636 fputs("_ippCheckOptions: ", stdout);
637 if ((name = _ippCheckOptions()) == NULL)
638 puts("PASS");
639 else
640 {
641 printf("FAIL (\"%s\" out of order)\n", name);
642 status = 1;
643 }
644#endif /* DEBUG */
645
8ca02f3c 646 /*
647 * Test _ippFindOption() private API...
648 */
649
a469f8a5 650 fputs("_ippFindOption(\"printer-type\"): ", stdout);
8ca02f3c 651 if (_ippFindOption("printer-type"))
652 puts("PASS");
653 else
654 {
655 puts("FAIL");
656 status = 1;
657 }
658
ef416fc2 659 /*
660 * Summarize...
661 */
662
663 putchar('\n');
664
665 if (status)
666 puts("Core IPP tests failed.");
667 else
668 puts("Core IPP tests passed.");
669 }
670 else
671 {
672 /*
673 * Read IPP files...
674 */
675
676 for (i = 1; i < argc; i ++)
677 {
54afec33 678 if ((fp = cupsFileOpen(argv[i], "r")) == NULL)
ef416fc2 679 {
680 printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno));
681 status = 1;
682 continue;
683 }
684
685 request = ippNew();
54afec33 686 while ((state = ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL,
cb7f98ee 687 request)) == IPP_STATE_ATTRIBUTE);
ef416fc2 688
cb7f98ee 689 if (state != IPP_STATE_DATA)
ef416fc2 690 {
691 printf("Error reading IPP message from \"%s\"!\n", argv[i]);
692 status = 1;
693 }
694 else
695 {
696 printf("\n%s:\n", argv[i]);
697 print_attributes(request, 4);
698 }
699
700 ippDelete(request);
54afec33 701 cupsFileClose(fp);
ef416fc2 702 }
703 }
704
705 return (status);
706}
707
708
709/*
710 * 'hex_dump()' - Produce a hex dump of a buffer.
711 */
712
713void
714hex_dump(const char *title, /* I - Title */
715 ipp_uchar_t *buffer, /* I - Buffer to dump */
716 int bytes) /* I - Number of bytes */
717{
718 int i, j; /* Looping vars */
719 int ch; /* Current ASCII char */
720
721
722 /*
723 * Show lines of 16 bytes at a time...
724 */
725
726 printf(" %s:\n", title);
727
728 for (i = 0; i < bytes; i += 16)
729 {
730 /*
731 * Show the offset...
732 */
733
734 printf(" %04x ", i);
735
736 /*
737 * Then up to 16 bytes in hex...
738 */
739
740 for (j = 0; j < 16; j ++)
741 if ((i + j) < bytes)
742 printf(" %02x", buffer[i + j]);
743 else
744 printf(" ");
745
746 /*
747 * Then the ASCII representation of the bytes...
748 */
749
750 putchar(' ');
751 putchar(' ');
752
753 for (j = 0; j < 16 && (i + j) < bytes; j ++)
754 {
755 ch = buffer[i + j] & 127;
756
757 if (ch < ' ' || ch == 127)
758 putchar('.');
759 else
760 putchar(ch);
761 }
762
763 putchar('\n');
764 }
765}
766
767
768/*
769 * 'print_attributes()' - Print the attributes in a request...
770 */
771
772void
773print_attributes(ipp_t *ipp, /* I - IPP request */
774 int indent) /* I - Indentation */
775{
776 int i; /* Looping var */
777 ipp_tag_t group; /* Current group */
778 ipp_attribute_t *attr; /* Current attribute */
a2326b5b 779 _ipp_value_t *val; /* Current value */
ef416fc2 780 static const char * const tags[] = /* Value/group tag strings */
781 {
782 "reserved-00",
783 "operation-attributes-tag",
784 "job-attributes-tag",
785 "end-of-attributes-tag",
786 "printer-attributes-tag",
787 "unsupported-attributes-tag",
788 "subscription-attributes-tag",
789 "event-attributes-tag",
790 "reserved-08",
791 "reserved-09",
792 "reserved-0A",
793 "reserved-0B",
794 "reserved-0C",
795 "reserved-0D",
796 "reserved-0E",
797 "reserved-0F",
798 "unsupported",
799 "default",
800 "unknown",
801 "no-value",
802 "reserved-14",
803 "not-settable",
804 "delete-attr",
805 "admin-define",
806 "reserved-18",
807 "reserved-19",
808 "reserved-1A",
809 "reserved-1B",
810 "reserved-1C",
811 "reserved-1D",
812 "reserved-1E",
813 "reserved-1F",
814 "reserved-20",
815 "integer",
816 "boolean",
817 "enum",
818 "reserved-24",
819 "reserved-25",
820 "reserved-26",
821 "reserved-27",
822 "reserved-28",
823 "reserved-29",
824 "reserved-2a",
825 "reserved-2b",
826 "reserved-2c",
827 "reserved-2d",
828 "reserved-2e",
829 "reserved-2f",
830 "octetString",
831 "dateTime",
832 "resolution",
833 "rangeOfInteger",
834 "begCollection",
835 "textWithLanguage",
836 "nameWithLanguage",
837 "endCollection",
838 "reserved-38",
839 "reserved-39",
840 "reserved-3a",
841 "reserved-3b",
842 "reserved-3c",
843 "reserved-3d",
844 "reserved-3e",
845 "reserved-3f",
846 "reserved-40",
847 "textWithoutLanguage",
848 "nameWithoutLanguage",
849 "reserved-43",
850 "keyword",
851 "uri",
852 "uriScheme",
853 "charset",
854 "naturalLanguage",
855 "mimeMediaType",
856 "memberName"
857 };
858
859
860 for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next)
861 {
d2354e63 862 if (!attr->name && indent == 4)
ef416fc2 863 {
864 group = IPP_TAG_ZERO;
865 putchar('\n');
866 continue;
867 }
868
869 if (group != attr->group_tag)
870 {
871 group = attr->group_tag;
872
d2354e63 873 printf("\n%*s%s:\n\n", indent - 4, "", tags[group]);
ef416fc2 874 }
875
d2354e63 876 printf("%*s%s (", indent, "", attr->name ? attr->name : "(null)");
ef416fc2 877 if (attr->num_values > 1)
878 printf("1setOf ");
879 printf("%s):", tags[attr->value_tag]);
880
881 switch (attr->value_tag)
882 {
883 case IPP_TAG_ENUM :
884 case IPP_TAG_INTEGER :
885 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
886 printf(" %d", val->integer);
887 putchar('\n');
888 break;
889
890 case IPP_TAG_BOOLEAN :
891 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
892 printf(" %s", val->boolean ? "true" : "false");
893 putchar('\n');
894 break;
895
896 case IPP_TAG_RANGE :
897 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
898 printf(" %d-%d", val->range.lower, val->range.upper);
899 putchar('\n');
900 break;
901
902 case IPP_TAG_DATE :
903 {
904 time_t vtime; /* Date/Time value */
905 struct tm *vdate; /* Date info */
906 char vstring[256]; /* Formatted time */
907
908 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
909 {
910 vtime = ippDateToTime(val->date);
911 vdate = localtime(&vtime);
912 strftime(vstring, sizeof(vstring), "%c", vdate);
913 printf(" (%s)", vstring);
914 }
915 }
916 putchar('\n');
917 break;
918
919 case IPP_TAG_RESOLUTION :
920 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
921 printf(" %dx%d%s", val->resolution.xres, val->resolution.yres,
3e7fe0ca 922 val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
ef416fc2 923 putchar('\n');
924 break;
925
926 case IPP_TAG_STRING :
927 case IPP_TAG_TEXTLANG :
928 case IPP_TAG_NAMELANG :
929 case IPP_TAG_TEXT :
930 case IPP_TAG_NAME :
931 case IPP_TAG_KEYWORD :
932 case IPP_TAG_URI :
933 case IPP_TAG_URISCHEME :
934 case IPP_TAG_CHARSET :
935 case IPP_TAG_LANGUAGE :
936 case IPP_TAG_MIMETYPE :
937 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
938 printf(" \"%s\"", val->string.text);
939 putchar('\n');
940 break;
941
942 case IPP_TAG_BEGIN_COLLECTION :
943 putchar('\n');
944
945 for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
946 {
947 if (i)
948 putchar('\n');
949 print_attributes(val->collection, indent + 4);
950 }
951 break;
952
953 default :
954 printf("UNKNOWN (%d values)\n", attr->num_values);
955 break;
956 }
957 }
958}
959
960
961/*
962 * 'read_cb()' - Read data from a buffer.
963 */
964
a4d04587 965ssize_t /* O - Number of bytes read */
83e08001 966read_cb(_ippdata_t *data, /* I - Data */
ef416fc2 967 ipp_uchar_t *buffer, /* O - Buffer to read */
a4d04587 968 size_t bytes) /* I - Number of bytes to read */
ef416fc2 969{
83e08001 970 size_t count; /* Number of bytes */
ef416fc2 971
972
973 /*
974 * Copy bytes from the data buffer to the read buffer...
975 */
976
83e08001
MS
977 if ((count = data->wsize - data->rpos) > bytes)
978 count = bytes;
979
980 memcpy(buffer, data->wbuffer + data->rpos, count);
981 data->rpos += count;
ef416fc2 982
983 /*
984 * Return the number of bytes read...
985 */
986
83e08001 987 return (count);
ef416fc2 988}
989
990
991/*
992 * 'write_cb()' - Write data into a buffer.
993 */
994
a4d04587 995ssize_t /* O - Number of bytes written */
83e08001 996write_cb(_ippdata_t *data, /* I - Data */
ef416fc2 997 ipp_uchar_t *buffer, /* I - Buffer to write */
a4d04587 998 size_t bytes) /* I - Number of bytes to write */
ef416fc2 999{
83e08001 1000 size_t count; /* Number of bytes */
ef416fc2 1001
1002
1003 /*
1004 * Loop until all bytes are written...
1005 */
1006
83e08001
MS
1007 if ((count = data->wsize - data->wused) > bytes)
1008 count = bytes;
1009
1010 memcpy(data->wbuffer + data->wused, buffer, count);
1011 data->wused += count;
ef416fc2 1012
1013 /*
1014 * Return the number of bytes written...
1015 */
1016
83e08001 1017 return (count);
ef416fc2 1018}
1019
1020
1021/*
f2d18633 1022 * End of "$Id$".
ef416fc2 1023 */