]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/encode.c
Copyright update.
[thirdparty/cups.git] / cups / encode.c
1 /*
2 * "$Id: encode.c,v 1.1.2.10 2003/01/07 18:26:24 mike Exp $"
3 *
4 * Option encoding routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2003 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * This file is subject to the Apple OS-Developed Software exception.
25 *
26 * Contents:
27 *
28 * cupsEncodeOptions() - Encode printer options into IPP attributes.
29 */
30
31 /*
32 * Include necessary headers...
33 */
34
35 #include "cups.h"
36 #include <stdlib.h>
37 #include <ctype.h>
38 #include "string.h"
39 #include "debug.h"
40
41
42 /*
43 * Local list of option names and the value tags they should use...
44 */
45
46 typedef struct
47 {
48 const char *name;
49 ipp_tag_t value_tag;
50 } ipp_option_t;
51
52 static ipp_option_t ipp_options[] =
53 {
54 { "blackplot", IPP_TAG_BOOLEAN },
55 { "brightness", IPP_TAG_INTEGER },
56 { "columns", IPP_TAG_INTEGER },
57 { "copies", IPP_TAG_INTEGER },
58 { "finishings", IPP_TAG_ENUM },
59 { "fitplot", IPP_TAG_BOOLEAN },
60 { "gamma", IPP_TAG_INTEGER },
61 { "hue", IPP_TAG_INTEGER },
62 { "job-k-limit", IPP_TAG_INTEGER },
63 { "job-page-limit", IPP_TAG_INTEGER },
64 { "job-priority", IPP_TAG_INTEGER },
65 { "job-quota-period", IPP_TAG_INTEGER },
66 { "landscape", IPP_TAG_BOOLEAN },
67 { "mirror", IPP_TAG_BOOLEAN },
68 { "natural-scaling", IPP_TAG_INTEGER },
69 { "number-up", IPP_TAG_INTEGER },
70 { "orientation-requested", IPP_TAG_ENUM },
71 { "page-bottom", IPP_TAG_INTEGER },
72 { "page-left", IPP_TAG_INTEGER },
73 { "page-ranges", IPP_TAG_RANGE },
74 { "page-right", IPP_TAG_INTEGER },
75 { "page-top", IPP_TAG_INTEGER },
76 { "penwidth", IPP_TAG_INTEGER },
77 { "ppi", IPP_TAG_INTEGER },
78 { "prettyprint", IPP_TAG_BOOLEAN },
79 { "printer-resolution", IPP_TAG_RESOLUTION },
80 { "print-quality", IPP_TAG_ENUM },
81 { "saturation", IPP_TAG_INTEGER },
82 { "scaling", IPP_TAG_INTEGER },
83 { "wrap", IPP_TAG_BOOLEAN }
84 };
85
86
87 /*
88 * 'cupsEncodeOptions()' - Encode printer options into IPP attributes.
89 */
90
91 void
92 cupsEncodeOptions(ipp_t *ipp, /* I - Request to add to */
93 int num_options, /* I - Number of options */
94 cups_option_t *options) /* I - Options */
95 {
96 int i, j; /* Looping vars */
97 int count; /* Number of values */
98 char *s, /* Pointer into option value */
99 *val, /* Pointer to option value */
100 *copy, /* Copy of option value */
101 *sep; /* Option separator */
102 ipp_attribute_t *attr; /* IPP job-id attribute */
103
104
105 DEBUG_printf(("cupsEncodeOptions(%p, %d, %p)\n", ipp, num_options, options));
106
107 if (ipp == NULL || num_options < 1 || options == NULL)
108 return;
109
110 /*
111 * Handle the document format stuff first...
112 */
113
114 if ((val = (char *)cupsGetOption("document-format", num_options, options)) != NULL)
115 ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
116 NULL, val);
117 else if (cupsGetOption("raw", num_options, options))
118 ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
119 NULL, "application/vnd.cups-raw");
120 else
121 ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
122 NULL, "application/octet-stream");
123
124 /*
125 * Then add all other options...
126 */
127
128 for (i = 0; i < num_options; i ++)
129 {
130 /*
131 * Skip document format options - handled above...
132 */
133
134 if (strcasecmp(options[i].name, "raw") == 0 ||
135 strcasecmp(options[i].name, "document-format") == 0 ||
136 !options[i].name[0])
137 continue;
138
139 /*
140 * Count the number of values...
141 */
142
143 for (count = 1, sep = options[i].value; *sep; sep ++)
144 {
145 if (*sep == '\'')
146 {
147 /*
148 * Skip quoted option value...
149 */
150
151 sep ++;
152
153 while (*sep && *sep != '\'')
154 sep ++;
155
156 if (!*sep)
157 sep --;
158 }
159 else if (*sep == '\"')
160 {
161 /*
162 * Skip quoted option value...
163 */
164
165 sep ++;
166
167 while (*sep && *sep != '\"')
168 sep ++;
169
170 if (!*sep)
171 sep --;
172 }
173 else if (*sep == ',')
174 count ++;
175 else if (*sep == '\\' && sep[1])
176 sep ++;
177 }
178
179 DEBUG_printf(("cupsEncodeOptions: option = \'%s\', count = %d\n",
180 options[i].name, count));
181
182 /*
183 * Allocate memory for the attribute values...
184 */
185
186 if ((attr = _ipp_add_attr(ipp, count)) == NULL)
187 {
188 /*
189 * Ran out of memory!
190 */
191
192 DEBUG_puts("cupsEncodeOptions: Ran out of memory for attributes!");
193 return;
194 }
195
196 /*
197 * Now figure out what type of value we have...
198 */
199
200 attr->group_tag = IPP_TAG_JOB;
201
202 if (strcasecmp(options[i].value, "true") == 0 ||
203 strcasecmp(options[i].value, "false") == 0)
204 attr->value_tag = IPP_TAG_BOOLEAN;
205 else
206 attr->value_tag = IPP_TAG_NAME;
207
208 for (j = 0; j < (int)(sizeof(ipp_options) / sizeof(ipp_options[0])); j ++)
209 if (strcasecmp(options[i].name, ipp_options[j].name) == 0)
210 {
211 attr->value_tag = ipp_options[j].value_tag;
212 break;
213 }
214
215 /*
216 * Copy the name over...
217 */
218
219 if ((attr->name = strdup(options[i].name)) == NULL)
220 {
221 /*
222 * Ran out of memory!
223 */
224
225 DEBUG_puts("cupsEncodeOptions: Ran out of memory for name!");
226 return;
227 }
228
229 if (count > 1)
230 {
231 /*
232 * Make a copy of the value we can fiddle with...
233 */
234
235 if ((copy = strdup(options[i].value)) == NULL)
236 {
237 /*
238 * Ran out of memory!
239 */
240
241 DEBUG_puts("cupsEncodeOptions: Ran out of memory for value copy!");
242 return;
243 }
244
245 val = copy;
246 }
247 else
248 {
249 /*
250 * Since we have a single value, use the value directly...
251 */
252
253 val = options[i].value;
254 copy = NULL;
255 }
256
257 /*
258 * Scan the value string for values...
259 */
260
261 for (j = 0; *val != '\0' || j == 0; val = sep, j ++)
262 {
263 /*
264 * Find the end of this value and mark it if needed...
265 */
266
267 if ((sep = strchr(val, ',')) != NULL)
268 *sep++ = '\0';
269 else
270 sep = val + strlen(val);
271
272 /*
273 * Copy the option value(s) over as needed by the type...
274 */
275
276 switch (attr->value_tag)
277 {
278 case IPP_TAG_INTEGER :
279 case IPP_TAG_ENUM :
280 /*
281 * Integer/enumeration value...
282 */
283
284 attr->values[j].integer = strtol(val, &s, 0);
285
286 DEBUG_printf(("cupsEncodeOptions: Adding integer option value %d...\n",
287 attr->values[j].integer));
288 break;
289
290 case IPP_TAG_BOOLEAN :
291 if (strcasecmp(val, "true") == 0)
292 {
293 /*
294 * Boolean value - true...
295 */
296
297 attr->values[j].boolean = 1;
298
299 DEBUG_puts("cupsEncodeOptions: Added boolean true value...");
300 }
301 else
302 {
303 /*
304 * Boolean value - false...
305 */
306
307 attr->values[j].boolean = 0;
308
309 DEBUG_puts("cupsEncodeOptions: Added boolean false value...");
310 }
311 break;
312
313 case IPP_TAG_RANGE :
314 /*
315 * Range...
316 */
317
318 if (*val == '-')
319 {
320 attr->values[j].range.lower = 1;
321 s = val;
322 }
323 else
324 attr->values[j].range.lower = strtol(val, &s, 0);
325
326 if (*s == '-')
327 {
328 if (s[1])
329 attr->values[j].range.upper = strtol(s + 1, NULL, 0);
330 else
331 attr->values[j].range.upper = 2147483647;
332 }
333 else
334 attr->values[j].range.upper = attr->values[j].range.lower;
335
336 DEBUG_printf(("cupsEncodeOptions: Added range option value %d-%d...\n",
337 attr->values[j].range.lower,
338 attr->values[j].range.upper));
339 break;
340
341 case IPP_TAG_RESOLUTION :
342 /*
343 * Resolution...
344 */
345
346 attr->values[j].resolution.xres = strtol(val, &s, 0);
347
348 if (*s == 'x')
349 attr->values[j].resolution.yres = strtol(s + 1, &s, 0);
350 else
351 attr->values[j].resolution.yres = attr->values[j].resolution.xres;
352
353 if (strcasecmp(s, "dpc") == 0)
354 attr->values[j].resolution.units = IPP_RES_PER_CM;
355 else
356 attr->values[j].resolution.units = IPP_RES_PER_INCH;
357
358 DEBUG_printf(("cupsEncodeOptions: Adding resolution option value %s...\n",
359 val));
360 break;
361
362 default :
363 if ((attr->values[j].string.text = strdup(val)) == NULL)
364 {
365 /*
366 * Ran out of memory!
367 */
368
369 DEBUG_puts("cupsEncodeOptions: Ran out of memory for string!");
370 return;
371 }
372
373 DEBUG_printf(("cupsEncodeOptions: Added string value \'%s\'...\n",
374 val));
375 break;
376 }
377 }
378 }
379 }
380
381
382 /*
383 * End of "$Id: encode.c,v 1.1.2.10 2003/01/07 18:26:24 mike Exp $".
384 */