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