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