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