]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testipp.c
Fix unused store - actually use the count we saved.
[thirdparty/cups.git] / cups / testipp.c
CommitLineData
ef416fc2 1/*
7e86f2f6 2 * IPP test program for CUPS.
ef416fc2 3 *
fd96ad89
MS
4 * Copyright © 2007-2018 by Apple Inc.
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 225ssize_t read_cb(_ippdata_t *data, ipp_uchar_t *buffer, size_t bytes);
fd96ad89 226int token_cb(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, const char *token);
83e08001 227ssize_t write_cb(_ippdata_t *data, ipp_uchar_t *buffer, size_t bytes);
ef416fc2 228
229
230/*
231 * 'main()' - Main entry.
232 */
233
234int /* O - Exit status */
235main(int argc, /* I - Number of command-line arguments */
236 char *argv[]) /* I - Command-line arguments */
237{
83e08001
MS
238 _ippdata_t data; /* IPP buffer */
239 ipp_uchar_t buffer[8192]; /* Write buffer data */
54afec33
MS
240 ipp_t *cols[2], /* Collections */
241 *size; /* media-size collection */
ef416fc2 242 ipp_t *request; /* Request */
54afec33
MS
243 ipp_attribute_t *media_col, /* media-col attribute */
244 *media_size, /* media-size attribute */
245 *attr; /* Other attribute */
ef416fc2 246 ipp_state_t state; /* State */
7e86f2f6 247 size_t length; /* Length of data */
54afec33 248 cups_file_t *fp; /* File pointer */
7e86f2f6 249 size_t i; /* Looping var */
ef416fc2 250 int status; /* Status of tests (0 = success, 1 = fail) */
dfc4cea4 251#ifdef DEBUG
a469f8a5 252 const char *name; /* Option name */
dfc4cea4 253#endif /* DEBUG */
ef416fc2 254
255
256 status = 0;
257
258 if (argc == 1)
259 {
260 /*
261 * Test request generation code...
262 */
263
264 printf("Create Sample Request: ");
265
266 request = ippNew();
267 request->request.op.version[0] = 0x01;
268 request->request.op.version[1] = 0x01;
cb7f98ee 269 request->request.op.operation_id = IPP_OP_PRINT_JOB;
ef416fc2 270 request->request.op.request_id = 1;
271
272 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
273 "attributes-charset", NULL, "utf-8");
274 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
275 "attributes-natural-language", NULL, "en");
276 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
277 "printer-uri", NULL, "ipp://localhost/printers/foo");
278
279 cols[0] = ippNew();
54afec33
MS
280 size = ippNew();
281 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21590);
282 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 27940);
283 ippAddCollection(cols[0], IPP_TAG_JOB, "media-size", size);
aaf19ab0 284 ippDelete(size);
54afec33
MS
285 ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL,
286 "blue");
287 ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL,
288 "plain");
ef416fc2 289
290 cols[1] = ippNew();
54afec33
MS
291 size = ippNew();
292 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21000);
293 ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 29700);
294 ippAddCollection(cols[1], IPP_TAG_JOB, "media-size", size);
aaf19ab0 295 ippDelete(size);
54afec33
MS
296 ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL,
297 "plaid");
298 ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL,
299 "glossy");
300
301 ippAddCollections(request, IPP_TAG_JOB, "media-col", 2,
302 (const ipp_t **)cols);
aaf19ab0
MS
303 ippDelete(cols[0]);
304 ippDelete(cols[1]);
ef416fc2 305
306 length = ippLength(request);
307 if (length != sizeof(collection))
308 {
309 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
7e86f2f6 310 (int)length, (int)sizeof(collection));
ef416fc2 311 status = 1;
312 }
313 else
314 puts("PASS");
315
316 /*
317 * Write test #1...
318 */
319
320 printf("Write Sample to Memory: ");
321
83e08001
MS
322 data.wused = 0;
323 data.wsize = sizeof(buffer);
324 data.wbuffer = buffer;
325
326 while ((state = ippWriteIO(&data, (ipp_iocb_t)write_cb, 1, NULL,
cb7f98ee
MS
327 request)) != IPP_STATE_DATA)
328 if (state == IPP_STATE_ERROR)
ef416fc2 329 break;
330
cb7f98ee 331 if (state != IPP_STATE_DATA)
ef416fc2 332 {
83e08001 333 printf("FAIL - %d bytes written.\n", (int)data.wused);
ef416fc2 334 status = 1;
335 }
83e08001 336 else if (data.wused != sizeof(collection))
ef416fc2 337 {
83e08001 338 printf("FAIL - wrote %d bytes, expected %d bytes!\n", (int)data.wused,
ef416fc2 339 (int)sizeof(collection));
83e08001 340 hex_dump("Bytes Written", data.wbuffer, data.wused);
ef416fc2 341 hex_dump("Baseline", collection, sizeof(collection));
342 status = 1;
343 }
83e08001 344 else if (memcmp(data.wbuffer, collection, data.wused))
ef416fc2 345 {
83e08001
MS
346 for (i = 0; i < data.wused; i ++)
347 if (data.wbuffer[i] != collection[i])
54afec33
MS
348 break;
349
7e86f2f6 350 printf("FAIL - output does not match baseline at 0x%04x!\n", (unsigned)i);
83e08001 351 hex_dump("Bytes Written", data.wbuffer, data.wused);
ef416fc2 352 hex_dump("Baseline", collection, sizeof(collection));
353 status = 1;
354 }
355 else
356 puts("PASS");
357
358 ippDelete(request);
359
360 /*
361 * Read the data back in and confirm...
362 */
363
364 printf("Read Sample from Memory: ");
365
83e08001
MS
366 request = ippNew();
367 data.rpos = 0;
ef416fc2 368
83e08001 369 while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL,
cb7f98ee
MS
370 request)) != IPP_STATE_DATA)
371 if (state == IPP_STATE_ERROR)
ef416fc2 372 break;
373
374 length = ippLength(request);
375
cb7f98ee 376 if (state != IPP_STATE_DATA)
ef416fc2 377 {
83e08001 378 printf("FAIL - %d bytes read.\n", (int)data.rpos);
ef416fc2 379 status = 1;
380 }
83e08001 381 else if (data.rpos != data.wused)
ef416fc2 382 {
83e08001
MS
383 printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos,
384 (int)data.wused);
ef416fc2 385 print_attributes(request, 8);
386 status = 1;
387 }
388 else if (length != sizeof(collection))
389 {
390 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
7e86f2f6 391 (int)length, (int)sizeof(collection));
ef416fc2 392 print_attributes(request, 8);
393 status = 1;
394 }
395 else
396 puts("PASS");
397
54afec33
MS
398 fputs("ippFindAttribute(media-col): ", stdout);
399 if ((media_col = ippFindAttribute(request, "media-col",
400 IPP_TAG_BEGIN_COLLECTION)) == NULL)
401 {
402 if ((media_col = ippFindAttribute(request, "media-col",
403 IPP_TAG_ZERO)) == NULL)
404 puts("FAIL (not found)");
405 else
406 printf("FAIL (wrong type - %s)\n", ippTagString(media_col->value_tag));
407
408 status = 1;
409 }
410 else if (media_col->num_values != 2)
411 {
412 printf("FAIL (wrong count - %d)\n", media_col->num_values);
413 status = 1;
414 }
415 else
416 puts("PASS");
417
aaf19ab0 418 if (media_col)
54afec33 419 {
aaf19ab0 420 fputs("ippFindAttribute(media-size 1): ", stdout);
54afec33 421 if ((media_size = ippFindAttribute(media_col->values[0].collection,
aaf19ab0
MS
422 "media-size",
423 IPP_TAG_BEGIN_COLLECTION)) == NULL)
54afec33 424 {
aaf19ab0
MS
425 if ((media_size = ippFindAttribute(media_col->values[0].collection,
426 "media-col",
427 IPP_TAG_ZERO)) == NULL)
428 puts("FAIL (not found)");
54afec33 429 else
aaf19ab0
MS
430 printf("FAIL (wrong type - %s)\n",
431 ippTagString(media_size->value_tag));
54afec33
MS
432
433 status = 1;
434 }
aaf19ab0 435 else
54afec33
MS
436 {
437 if ((attr = ippFindAttribute(media_size->values[0].collection,
aaf19ab0
MS
438 "x-dimension", IPP_TAG_INTEGER)) == NULL)
439 {
440 if ((attr = ippFindAttribute(media_size->values[0].collection,
441 "x-dimension", IPP_TAG_ZERO)) == NULL)
442 puts("FAIL (missing x-dimension)");
443 else
444 printf("FAIL (wrong type for x-dimension - %s)\n",
445 ippTagString(attr->value_tag));
446
447 status = 1;
448 }
449 else if (attr->values[0].integer != 21590)
450 {
451 printf("FAIL (wrong value for x-dimension - %d)\n",
452 attr->values[0].integer);
453 status = 1;
454 }
455 else if ((attr = ippFindAttribute(media_size->values[0].collection,
456 "y-dimension",
457 IPP_TAG_INTEGER)) == NULL)
458 {
459 if ((attr = ippFindAttribute(media_size->values[0].collection,
460 "y-dimension", IPP_TAG_ZERO)) == NULL)
461 puts("FAIL (missing y-dimension)");
462 else
463 printf("FAIL (wrong type for y-dimension - %s)\n",
464 ippTagString(attr->value_tag));
465
466 status = 1;
467 }
468 else if (attr->values[0].integer != 27940)
469 {
470 printf("FAIL (wrong value for y-dimension - %d)\n",
471 attr->values[0].integer);
472 status = 1;
473 }
54afec33 474 else
aaf19ab0 475 puts("PASS");
54afec33 476 }
54afec33 477
aaf19ab0 478 fputs("ippFindAttribute(media-size 2): ", stdout);
54afec33 479 if ((media_size = ippFindAttribute(media_col->values[1].collection,
aaf19ab0
MS
480 "media-size",
481 IPP_TAG_BEGIN_COLLECTION)) == NULL)
54afec33 482 {
aaf19ab0
MS
483 if ((media_size = ippFindAttribute(media_col->values[1].collection,
484 "media-col",
485 IPP_TAG_ZERO)) == NULL)
486 puts("FAIL (not found)");
54afec33 487 else
aaf19ab0
MS
488 printf("FAIL (wrong type - %s)\n",
489 ippTagString(media_size->value_tag));
54afec33
MS
490
491 status = 1;
492 }
aaf19ab0 493 else
54afec33
MS
494 {
495 if ((attr = ippFindAttribute(media_size->values[0].collection,
aaf19ab0
MS
496 "x-dimension",
497 IPP_TAG_INTEGER)) == NULL)
498 {
499 if ((attr = ippFindAttribute(media_size->values[0].collection,
500 "x-dimension", IPP_TAG_ZERO)) == NULL)
501 puts("FAIL (missing x-dimension)");
502 else
503 printf("FAIL (wrong type for x-dimension - %s)\n",
504 ippTagString(attr->value_tag));
505
506 status = 1;
507 }
508 else if (attr->values[0].integer != 21000)
509 {
510 printf("FAIL (wrong value for x-dimension - %d)\n",
511 attr->values[0].integer);
512 status = 1;
513 }
514 else if ((attr = ippFindAttribute(media_size->values[0].collection,
515 "y-dimension",
516 IPP_TAG_INTEGER)) == NULL)
517 {
518 if ((attr = ippFindAttribute(media_size->values[0].collection,
519 "y-dimension", IPP_TAG_ZERO)) == NULL)
520 puts("FAIL (missing y-dimension)");
521 else
522 printf("FAIL (wrong type for y-dimension - %s)\n",
523 ippTagString(attr->value_tag));
524
525 status = 1;
526 }
527 else if (attr->values[0].integer != 29700)
528 {
529 printf("FAIL (wrong value for y-dimension - %d)\n",
530 attr->values[0].integer);
531 status = 1;
532 }
54afec33 533 else
aaf19ab0 534 puts("PASS");
54afec33 535 }
54afec33
MS
536 }
537
f2a31e21
MS
538 /*
539 * Test hierarchical find...
540 */
541
542 fputs("ippFindAttribute(media-col/media-size/x-dimension): ", stdout);
543 if ((attr = ippFindAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
544 {
545 if (ippGetInteger(attr, 0) != 21590)
546 {
547 printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0));
548 status = 1;
549 }
550 else
551 puts("PASS");
552 }
553 else
554 {
555 puts("FAIL (not found)");
556 status = 1;
557 }
558
559 fputs("ippFindNextAttribute(media-col/media-size/x-dimension): ", stdout);
560 if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
561 {
562 if (ippGetInteger(attr, 0) != 21000)
563 {
564 printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0));
565 status = 1;
566 }
567 else
568 puts("PASS");
569 }
570 else
571 {
572 puts("FAIL (not found)");
573 status = 1;
574 }
575
576 fputs("ippFindNextAttribute(media-col/media-size/x-dimension) again: ", stdout);
577 if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
578 {
579 printf("FAIL (got %d, expected nothing)\n", ippGetInteger(attr, 0));
580 status = 1;
581 }
582 else
583 puts("PASS");
584
ef416fc2 585 ippDelete(request);
586
83e08001
MS
587 /*
588 * Read the mixed data and confirm we converted everything to rangeOfInteger
589 * values...
590 */
591
592 printf("Read Mixed integer/rangeOfInteger from Memory: ");
593
594 request = ippNew();
595 data.rpos = 0;
596 data.wused = sizeof(mixed);
597 data.wsize = sizeof(mixed);
598 data.wbuffer = mixed;
599
600 while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL,
cb7f98ee
MS
601 request)) != IPP_STATE_DATA)
602 if (state == IPP_STATE_ERROR)
83e08001
MS
603 break;
604
605 length = ippLength(request);
606
cb7f98ee 607 if (state != IPP_STATE_DATA)
83e08001
MS
608 {
609 printf("FAIL - %d bytes read.\n", (int)data.rpos);
610 status = 1;
611 }
612 else if (data.rpos != sizeof(mixed))
613 {
614 printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos,
615 (int)sizeof(mixed));
616 print_attributes(request, 8);
617 status = 1;
618 }
619 else if (length != (sizeof(mixed) + 4))
620 {
621 printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
7e86f2f6 622 (int)length, (int)sizeof(mixed) + 4);
83e08001
MS
623 print_attributes(request, 8);
624 status = 1;
625 }
626 else
627 puts("PASS");
628
629 fputs("ippFindAttribute(notify-lease-duration-supported): ", stdout);
630 if ((attr = ippFindAttribute(request, "notify-lease-duration-supported",
631 IPP_TAG_ZERO)) == NULL)
632 {
633 puts("FAIL (not found)");
634 status = 1;
635 }
636 else if (attr->value_tag != IPP_TAG_RANGE)
637 {
638 printf("FAIL (wrong type - %s)\n", ippTagString(attr->value_tag));
639 status = 1;
640 }
641 else if (attr->num_values != 2)
642 {
643 printf("FAIL (wrong count - %d)\n", attr->num_values);
644 status = 1;
645 }
646 else if (attr->values[0].range.lower != 1 ||
647 attr->values[0].range.upper != 1 ||
648 attr->values[1].range.lower != 16 ||
649 attr->values[1].range.upper != 32)
650 {
651 printf("FAIL (wrong values - %d,%d and %d,%d)\n",
652 attr->values[0].range.lower,
653 attr->values[0].range.upper,
654 attr->values[1].range.lower,
655 attr->values[1].range.upper);
656 status = 1;
657 }
658 else
659 puts("PASS");
660
661 ippDelete(request);
662
a469f8a5
MS
663#ifdef DEBUG
664 /*
665 * Test that private option array is sorted...
666 */
667
668 fputs("_ippCheckOptions: ", stdout);
669 if ((name = _ippCheckOptions()) == NULL)
670 puts("PASS");
671 else
672 {
673 printf("FAIL (\"%s\" out of order)\n", name);
674 status = 1;
675 }
676#endif /* DEBUG */
677
8ca02f3c 678 /*
679 * Test _ippFindOption() private API...
680 */
681
a469f8a5 682 fputs("_ippFindOption(\"printer-type\"): ", stdout);
8ca02f3c 683 if (_ippFindOption("printer-type"))
684 puts("PASS");
685 else
686 {
687 puts("FAIL");
688 status = 1;
689 }
690
ef416fc2 691 /*
692 * Summarize...
693 */
694
695 putchar('\n');
696
697 if (status)
698 puts("Core IPP tests failed.");
699 else
700 puts("Core IPP tests passed.");
701 }
702 else
703 {
704 /*
705 * Read IPP files...
706 */
707
7e86f2f6 708 for (i = 1; i < (size_t)argc; i ++)
ef416fc2 709 {
fd96ad89 710 if (strlen(argv[i]) > 5 && !strcmp(argv[i] + strlen(argv[i]) - 5, ".test"))
ef416fc2 711 {
fd96ad89
MS
712 /*
713 * Read an ASCII IPP message...
714 */
ef416fc2 715
fd96ad89 716 _ipp_vars_t v; /* IPP variables */
ef416fc2 717
fd96ad89
MS
718 _ippVarsInit(&v);
719 request = _ippFileParse(&v, argv[i], token_cb, NULL, NULL);
720 _ippVarsDeinit(&v);
ef416fc2 721 }
722 else
fd96ad89
MS
723 {
724 /*
725 * Read a raw (binary) IPP message...
726 */
727
728 if ((fp = cupsFileOpen(argv[i], "r")) == NULL)
729 {
730 printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno));
731 status = 1;
732 continue;
733 }
734
735 request = ippNew();
736 while ((state = ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL,
737 request)) == IPP_STATE_ATTRIBUTE);
738
739 if (state != IPP_STATE_DATA)
740 {
741 printf("Error reading IPP message from \"%s\".\n", argv[i]);
742 status = 1;
743
744 ippDelete(request);
745 request = NULL;
746 }
747
748 cupsFileClose(fp);
749 }
750
751 if (request)
ef416fc2 752 {
753 printf("\n%s:\n", argv[i]);
754 print_attributes(request, 4);
fd96ad89 755 ippDelete(request);
ef416fc2 756 }
ef416fc2 757 }
758 }
759
760 return (status);
761}
762
763
764/*
765 * 'hex_dump()' - Produce a hex dump of a buffer.
766 */
767
768void
769hex_dump(const char *title, /* I - Title */
770 ipp_uchar_t *buffer, /* I - Buffer to dump */
7e86f2f6 771 size_t bytes) /* I - Number of bytes */
ef416fc2 772{
7e86f2f6
MS
773 size_t i, j; /* Looping vars */
774 int ch; /* Current ASCII char */
ef416fc2 775
776
777 /*
778 * Show lines of 16 bytes at a time...
779 */
780
781 printf(" %s:\n", title);
782
783 for (i = 0; i < bytes; i += 16)
784 {
785 /*
786 * Show the offset...
787 */
788
7e86f2f6 789 printf(" %04x ", (unsigned)i);
ef416fc2 790
791 /*
792 * Then up to 16 bytes in hex...
793 */
794
795 for (j = 0; j < 16; j ++)
796 if ((i + j) < bytes)
797 printf(" %02x", buffer[i + j]);
798 else
799 printf(" ");
800
801 /*
802 * Then the ASCII representation of the bytes...
803 */
804
805 putchar(' ');
806 putchar(' ');
807
808 for (j = 0; j < 16 && (i + j) < bytes; j ++)
809 {
810 ch = buffer[i + j] & 127;
811
812 if (ch < ' ' || ch == 127)
813 putchar('.');
814 else
815 putchar(ch);
816 }
817
818 putchar('\n');
819 }
820}
821
822
823/*
824 * 'print_attributes()' - Print the attributes in a request...
825 */
826
827void
828print_attributes(ipp_t *ipp, /* I - IPP request */
829 int indent) /* I - Indentation */
830{
ef416fc2 831 ipp_tag_t group; /* Current group */
832 ipp_attribute_t *attr; /* Current attribute */
d2123aee 833 char buffer[2048]; /* Value string */
ef416fc2 834
835
836 for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next)
837 {
d2354e63 838 if (!attr->name && indent == 4)
ef416fc2 839 {
840 group = IPP_TAG_ZERO;
841 putchar('\n');
842 continue;
843 }
844
845 if (group != attr->group_tag)
846 {
847 group = attr->group_tag;
848
d2123aee 849 printf("\n%*s%s:\n\n", indent - 4, "", ippTagString(group));
ef416fc2 850 }
851
d2123aee 852 ippAttributeString(attr, buffer, sizeof(buffer));
ef416fc2 853
d2123aee 854 printf("%*s%s (%s%s): %s\n", indent, "", attr->name ? attr->name : "(null)", attr->num_values > 1 ? "1setOf " : "", ippTagString(attr->value_tag), buffer);
ef416fc2 855 }
856}
857
858
859/*
860 * 'read_cb()' - Read data from a buffer.
861 */
862
a4d04587 863ssize_t /* O - Number of bytes read */
83e08001 864read_cb(_ippdata_t *data, /* I - Data */
ef416fc2 865 ipp_uchar_t *buffer, /* O - Buffer to read */
a4d04587 866 size_t bytes) /* I - Number of bytes to read */
ef416fc2 867{
83e08001 868 size_t count; /* Number of bytes */
ef416fc2 869
870
871 /*
872 * Copy bytes from the data buffer to the read buffer...
873 */
874
83e08001
MS
875 if ((count = data->wsize - data->rpos) > bytes)
876 count = bytes;
877
878 memcpy(buffer, data->wbuffer + data->rpos, count);
879 data->rpos += count;
ef416fc2 880
881 /*
882 * Return the number of bytes read...
883 */
884
7e86f2f6 885 return ((ssize_t)count);
ef416fc2 886}
887
888
fd96ad89
MS
889/*
890 * 'token_cb()' - Token callback for ASCII IPP data file parser.
891 */
892
893int /* O - 1 on success, 0 on failure */
894token_cb(_ipp_file_t *f, /* I - IPP file data */
895 _ipp_vars_t *v, /* I - IPP variables */
896 void *user_data, /* I - User data pointer */
897 const char *token) /* I - Token string */
898{
899 (void)v;
900 (void)user_data;
901
902 if (!token)
903 {
904 f->attrs = ippNew();
905 f->group_tag = IPP_TAG_PRINTER;
906 }
907 else
908 {
909 fprintf(stderr, "Unknown directive \"%s\" on line %d of \"%s\".\n", token, f->linenum, f->filename);
910 return (0);
911 }
912
913 return (1);
914}
915
916
ef416fc2 917/*
918 * 'write_cb()' - Write data into a buffer.
919 */
920
a4d04587 921ssize_t /* O - Number of bytes written */
83e08001 922write_cb(_ippdata_t *data, /* I - Data */
ef416fc2 923 ipp_uchar_t *buffer, /* I - Buffer to write */
a4d04587 924 size_t bytes) /* I - Number of bytes to write */
ef416fc2 925{
83e08001 926 size_t count; /* Number of bytes */
ef416fc2 927
928
929 /*
930 * Loop until all bytes are written...
931 */
932
83e08001
MS
933 if ((count = data->wsize - data->wused) > bytes)
934 count = bytes;
935
936 memcpy(data->wbuffer + data->wused, buffer, count);
937 data->wused += count;
ef416fc2 938
939 /*
940 * Return the number of bytes written...
941 */
942
7e86f2f6 943 return ((ssize_t)count);
ef416fc2 944}