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