4 * PWG load/save API implementation for CUPS.
6 * Copyright 2010 by Apple Inc.
8 * These coded instructions, statements, and computer programs are the
9 * property of Apple Inc. and are protected by Federal copyright
10 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
11 * which should have been included with this file. If this file is
12 * file is missing or damaged, see the license at "http://www.cups.org/".
14 * This file is subject to the Apple OS-Developed Software exception.
18 * _pwgCreateWithFile() - Create PWG mapping data from a written file.
19 * _pwgDestroy() - Free all memory used for PWG mapping data.
20 * _pwgWriteFile() - Write PWG mapping data to a file.
24 * Include necessary headers...
27 #include "cups-private.h"
32 * '_pwgCreateWithFile()' - Create PWG mapping data from a written file.
34 * Use the @link _pwgWriteFile@ function to write PWG mapping data to a file.
37 _pwg_t
* /* O - PWG mapping data */
38 _pwgCreateWithFile(const char *filename
)/* I - File to read */
40 cups_file_t
*fp
; /* File */
41 _pwg_t
*pwg
; /* PWG mapping data */
42 _pwg_size_t
*size
; /* Current size */
43 _pwg_map_t
*map
; /* Current map */
44 int linenum
, /* Current line number */
45 num_bins
, /* Number of bins in file */
46 num_sizes
, /* Number of sizes in file */
47 num_sources
, /* Number of sources in file */
48 num_types
; /* Number of types in file */
49 char line
[2048], /* Current line */
50 *value
, /* Pointer to value in line */
51 *valueptr
, /* Pointer into value */
52 pwg_keyword
[128], /* PWG keyword */
53 ppd_keyword
[PPD_MAX_NAME
];
55 _pwg_output_mode_t output_mode
; /* Output mode for preset */
56 _pwg_print_quality_t print_quality
; /* Print quality for preset */
59 DEBUG_printf(("_pwgCreateWithFile(filename=\"%s\")", filename
));
62 * Range check input...
67 _cupsSetError(IPP_INTERNAL_ERROR
, strerror(EINVAL
), 0);
75 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
77 _cupsSetError(IPP_INTERNAL_ERROR
, strerror(errno
), 0);
82 * Allocate the mapping data structure...
85 if ((pwg
= calloc(1, sizeof(_pwg_t
))) == NULL
)
87 DEBUG_puts("_pwgCreateWithFile: Unable to allocate pwg_t.");
88 _cupsSetError(IPP_INTERNAL_ERROR
, strerror(errno
), 0);
102 while (cupsFileGetConf(fp
, line
, sizeof(line
), &value
, &linenum
))
104 DEBUG_printf(("_pwgCreateWithFile: line=\"%s\", value=\"%s\", linenum=%d",
105 line
, value
, linenum
));
109 DEBUG_printf(("_pwgCreateWithFile: Missing value on line %d.", linenum
));
110 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
113 else if (!strcasecmp(line
, "NumBins"))
117 DEBUG_puts("_pwgCreateWithFile: NumBins listed multiple times.");
118 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
122 if ((num_bins
= atoi(value
)) <= 0 || num_bins
> 65536)
124 DEBUG_printf(("_pwgCreateWithFile: Bad NumBins value %d on line %d.",
125 num_sizes
, linenum
));
126 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
130 if ((pwg
->bins
= calloc(num_bins
, sizeof(_pwg_map_t
))) == NULL
)
132 DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d bins.",
134 _cupsSetError(IPP_INTERNAL_ERROR
, strerror(errno
), 0);
138 else if (!strcasecmp(line
, "Bin"))
140 if (sscanf(value
, "%127s%40s", pwg_keyword
, ppd_keyword
) != 2)
142 DEBUG_printf(("_pwgCreateWithFile: Bad Bin on line %d.", linenum
));
143 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
147 if (pwg
->num_bins
>= num_bins
)
149 DEBUG_printf(("_pwgCreateWithFile: Too many Bin's on line %d.",
151 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
155 map
= pwg
->bins
+ pwg
->num_bins
;
156 map
->pwg
= _cupsStrAlloc(pwg_keyword
);
157 map
->ppd
= _cupsStrAlloc(ppd_keyword
);
161 else if (!strcasecmp(line
, "NumSizes"))
165 DEBUG_puts("_pwgCreateWithFile: NumSizes listed multiple times.");
166 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
170 if ((num_sizes
= atoi(value
)) <= 0 || num_sizes
> 65536)
172 DEBUG_printf(("_pwgCreateWithFile: Bad NumSizes value %d on line %d.",
173 num_sizes
, linenum
));
174 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
178 if ((pwg
->sizes
= calloc(num_sizes
, sizeof(_pwg_size_t
))) == NULL
)
180 DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d sizes.",
182 _cupsSetError(IPP_INTERNAL_ERROR
, strerror(errno
), 0);
186 else if (!strcasecmp(line
, "Size"))
188 if (pwg
->num_sizes
>= num_sizes
)
190 DEBUG_printf(("_pwgCreateWithFile: Too many Size's on line %d.",
192 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
196 size
= pwg
->sizes
+ pwg
->num_sizes
;
198 if (sscanf(value
, "%127s%40s%d%d%d%d%d%d", pwg_keyword
, ppd_keyword
,
199 &(size
->width
), &(size
->length
), &(size
->left
),
200 &(size
->bottom
), &(size
->right
), &(size
->top
)) != 8)
202 DEBUG_printf(("_pwgCreateWithFile: Bad Size on line %d.", linenum
));
203 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
207 size
->map
.pwg
= _cupsStrAlloc(pwg_keyword
);
208 size
->map
.ppd
= _cupsStrAlloc(ppd_keyword
);
212 else if (!strcasecmp(line
, "CustomSize"))
214 if (pwg
->custom_max_width
> 0)
216 DEBUG_printf(("_pwgCreateWithFile: Too many CustomSize's on line %d.",
218 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
222 if (sscanf(value
, "%d%d%d%d%d%d%d%d", &(pwg
->custom_max_width
),
223 &(pwg
->custom_max_length
), &(pwg
->custom_min_width
),
224 &(pwg
->custom_min_length
), &(pwg
->custom_size
.left
),
225 &(pwg
->custom_size
.bottom
), &(pwg
->custom_size
.right
),
226 &(pwg
->custom_size
.top
)) != 8)
228 DEBUG_printf(("_pwgCreateWithFile: Bad CustomSize on line %d.", linenum
));
229 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
233 _pwgGenerateSize(pwg_keyword
, sizeof(pwg_keyword
), "custom", "max",
234 pwg
->custom_max_width
, pwg
->custom_max_length
);
235 pwg
->custom_max_keyword
= _cupsStrAlloc(pwg_keyword
);
237 _pwgGenerateSize(pwg_keyword
, sizeof(pwg_keyword
), "custom", "min",
238 pwg
->custom_min_width
, pwg
->custom_min_length
);
239 pwg
->custom_min_keyword
= _cupsStrAlloc(pwg_keyword
);
241 else if (!strcasecmp(line
, "SourceOption"))
243 pwg
->source_option
= _cupsStrAlloc(value
);
245 else if (!strcasecmp(line
, "NumSources"))
249 DEBUG_puts("_pwgCreateWithFile: NumSources listed multiple times.");
250 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
254 if ((num_sources
= atoi(value
)) <= 0 || num_sources
> 65536)
256 DEBUG_printf(("_pwgCreateWithFile: Bad NumSources value %d on line %d.",
257 num_sources
, linenum
));
258 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
262 if ((pwg
->sources
= calloc(num_sources
, sizeof(_pwg_map_t
))) == NULL
)
264 DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d sources.",
266 _cupsSetError(IPP_INTERNAL_ERROR
, strerror(errno
), 0);
270 else if (!strcasecmp(line
, "Source"))
272 if (sscanf(value
, "%127s%40s", pwg_keyword
, ppd_keyword
) != 2)
274 DEBUG_printf(("_pwgCreateWithFile: Bad Source on line %d.", linenum
));
275 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
279 if (pwg
->num_sources
>= num_sources
)
281 DEBUG_printf(("_pwgCreateWithFile: Too many Source's on line %d.",
283 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
287 map
= pwg
->sources
+ pwg
->num_sources
;
288 map
->pwg
= _cupsStrAlloc(pwg_keyword
);
289 map
->ppd
= _cupsStrAlloc(ppd_keyword
);
293 else if (!strcasecmp(line
, "NumTypes"))
297 DEBUG_puts("_pwgCreateWithFile: NumTypes listed multiple times.");
298 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
302 if ((num_types
= atoi(value
)) <= 0 || num_types
> 65536)
304 DEBUG_printf(("_pwgCreateWithFile: Bad NumTypes value %d on line %d.",
305 num_types
, linenum
));
306 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
310 if ((pwg
->types
= calloc(num_types
, sizeof(_pwg_map_t
))) == NULL
)
312 DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d types.",
314 _cupsSetError(IPP_INTERNAL_ERROR
, strerror(errno
), 0);
318 else if (!strcasecmp(line
, "Type"))
320 if (sscanf(value
, "%127s%40s", pwg_keyword
, ppd_keyword
) != 2)
322 DEBUG_printf(("_pwgCreateWithFile: Bad Type on line %d.", linenum
));
323 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
327 if (pwg
->num_types
>= num_types
)
329 DEBUG_printf(("_pwgCreateWithFile: Too many Type's on line %d.",
331 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
335 map
= pwg
->types
+ pwg
->num_types
;
336 map
->pwg
= _cupsStrAlloc(pwg_keyword
);
337 map
->ppd
= _cupsStrAlloc(ppd_keyword
);
341 else if (!strcasecmp(line
, "Preset"))
344 * Preset output-mode print-quality name=value ...
347 output_mode
= (_pwg_output_mode_t
)strtol(value
, &valueptr
, 10);
348 print_quality
= (_pwg_print_quality_t
)strtol(valueptr
, &valueptr
, 10);
350 if (output_mode
< _PWG_OUTPUT_MODE_MONOCHROME
||
351 output_mode
>= _PWG_OUTPUT_MODE_MAX
||
352 print_quality
< _PWG_PRINT_QUALITY_DRAFT
||
353 print_quality
>= _PWG_PRINT_QUALITY_MAX
||
354 valueptr
== value
|| !*valueptr
)
356 DEBUG_printf(("_pwgCreateWithFile: Bad Preset on line %d.", linenum
));
357 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
361 pwg
->num_presets
[output_mode
][print_quality
] =
362 cupsParseOptions(valueptr
, 0,
363 pwg
->presets
[output_mode
] + print_quality
);
365 else if (!strcasecmp(line
, "SidesOption"))
366 pwg
->sides_option
= _cupsStrAlloc(value
);
367 else if (!strcasecmp(line
, "Sides1Sided"))
368 pwg
->sides_1sided
= _cupsStrAlloc(value
);
369 else if (!strcasecmp(line
, "Sides2SidedLong"))
370 pwg
->sides_2sided_long
= _cupsStrAlloc(value
);
371 else if (!strcasecmp(line
, "Sides2SidedShort"))
372 pwg
->sides_2sided_short
= _cupsStrAlloc(value
);
375 DEBUG_printf(("_pwgCreateWithFile: Unknown %s on line %d.", line
,
377 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
382 if (pwg
->num_sizes
< num_sizes
)
384 DEBUG_printf(("_pwgCreateWithFile: Not enough sizes (%d < %d).",
385 pwg
->num_sizes
, num_sizes
));
386 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
390 if (pwg
->num_sources
< num_sources
)
392 DEBUG_printf(("_pwgCreateWithFile: Not enough sources (%d < %d).",
393 pwg
->num_sources
, num_sources
));
394 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
398 if (pwg
->num_types
< num_types
)
400 DEBUG_printf(("_pwgCreateWithFile: Not enough types (%d < %d).",
401 pwg
->num_types
, num_types
));
402 _cupsSetError(IPP_INTERNAL_ERROR
, _("Bad PWG mapping file."), 1);
411 * If we get here the file was bad - free any data and return...
424 * '_pwgDestroy()' - Free all memory used for PWG mapping data.
428 _pwgDestroy(_pwg_t
*pwg
) /* I - PWG mapping data */
430 int i
; /* Looping var */
431 _pwg_map_t
*map
; /* Current map */
432 _pwg_size_t
*size
; /* Current size */
436 * Range check input...
443 * Free memory as needed...
448 for (i
= pwg
->num_bins
, map
= pwg
->bins
; i
> 0; i
--, map
++)
450 _cupsStrFree(map
->pwg
);
451 _cupsStrFree(map
->ppd
);
459 for (i
= pwg
->num_sizes
, size
= pwg
->sizes
; i
> 0; i
--, size
++)
461 _cupsStrFree(size
->map
.pwg
);
462 _cupsStrFree(size
->map
.ppd
);
468 if (pwg
->source_option
)
469 _cupsStrFree(pwg
->source_option
);
473 for (i
= pwg
->num_sources
, map
= pwg
->sources
; i
> 0; i
--, map
++)
475 _cupsStrFree(map
->pwg
);
476 _cupsStrFree(map
->ppd
);
484 for (i
= pwg
->num_types
, map
= pwg
->types
; i
> 0; i
--, map
++)
486 _cupsStrFree(map
->pwg
);
487 _cupsStrFree(map
->ppd
);
493 if (pwg
->custom_max_keyword
)
494 _cupsStrFree(pwg
->custom_max_keyword
);
496 if (pwg
->custom_min_keyword
)
497 _cupsStrFree(pwg
->custom_min_keyword
);
504 * '_pwgWriteFile()' - Write PWG mapping data to a file.
507 int /* O - 1 on success, 0 on failure */
508 _pwgWriteFile(_pwg_t
*pwg
, /* I - PWG mapping data */
509 const char *filename
) /* I - File to write */
511 int i
, j
, k
; /* Looping vars */
512 cups_file_t
*fp
; /* Output file */
513 _pwg_size_t
*size
; /* Current size */
514 _pwg_map_t
*map
; /* Current map */
515 cups_option_t
*option
; /* Current option */
519 * Range check input...
522 if (!pwg
|| !filename
)
524 _cupsSetError(IPP_INTERNAL_ERROR
, strerror(EINVAL
), 0);
529 * Open the file and write with compression...
532 if ((fp
= cupsFileOpen(filename
, "w9")) == NULL
)
534 _cupsSetError(IPP_INTERNAL_ERROR
, strerror(errno
), 0);
542 cupsFilePuts(fp
, "#CUPS-PWGPPD\n");
548 if (pwg
->num_bins
> 0)
550 cupsFilePrintf(fp
, "NumBins %d\n", pwg
->num_bins
);
551 for (i
= pwg
->num_bins
, map
= pwg
->bins
; i
> 0; i
--, map
++)
552 cupsFilePrintf(fp
, "Bin %s %s\n", map
->pwg
, map
->ppd
);
559 cupsFilePrintf(fp
, "NumSizes %d\n", pwg
->num_sizes
);
560 for (i
= pwg
->num_sizes
, size
= pwg
->sizes
; i
> 0; i
--, size
++)
561 cupsFilePrintf(fp
, "Size %s %s %d %d %d %d %d %d\n", size
->map
.pwg
,
562 size
->map
.ppd
, size
->width
, size
->length
, size
->left
,
563 size
->bottom
, size
->right
, size
->top
);
564 if (pwg
->custom_max_width
> 0)
565 cupsFilePrintf(fp
, "CustomSize %d %d %d %d %d %d %d %d\n",
566 pwg
->custom_max_width
, pwg
->custom_max_length
,
567 pwg
->custom_min_width
, pwg
->custom_min_length
,
568 pwg
->custom_size
.left
, pwg
->custom_size
.bottom
,
569 pwg
->custom_size
.right
, pwg
->custom_size
.top
);
575 if (pwg
->source_option
)
576 cupsFilePrintf(fp
, "SourceOption %s\n", pwg
->source_option
);
578 if (pwg
->num_sources
> 0)
580 cupsFilePrintf(fp
, "NumSources %d\n", pwg
->num_sources
);
581 for (i
= pwg
->num_sources
, map
= pwg
->sources
; i
> 0; i
--, map
++)
582 cupsFilePrintf(fp
, "Source %s %s\n", map
->pwg
, map
->ppd
);
589 if (pwg
->num_types
> 0)
591 cupsFilePrintf(fp
, "NumTypes %d\n", pwg
->num_types
);
592 for (i
= pwg
->num_types
, map
= pwg
->types
; i
> 0; i
--, map
++)
593 cupsFilePrintf(fp
, "Type %s %s\n", map
->pwg
, map
->ppd
);
600 for (i
= _PWG_OUTPUT_MODE_MONOCHROME
; i
< _PWG_OUTPUT_MODE_MAX
; i
++)
601 for (j
= _PWG_PRINT_QUALITY_DRAFT
; i
< _PWG_PRINT_QUALITY_MAX
; i
++)
602 if (pwg
->num_presets
[i
][j
])
604 cupsFilePrintf(fp
, "Preset %d %d", i
, j
);
605 for (k
= pwg
->num_presets
[i
][j
], option
= pwg
->presets
[i
][j
];
608 cupsFilePrintf(fp
, " %s=%s", option
->name
, option
->value
);
609 cupsFilePutChar(fp
, '\n');
616 if (pwg
->sides_option
)
617 cupsFilePrintf(fp
, "SidesOption %s\n", pwg
->sides_option
);
619 if (pwg
->sides_1sided
)
620 cupsFilePrintf(fp
, "Sides1Sided %s\n", pwg
->sides_1sided
);
622 if (pwg
->sides_2sided_long
)
623 cupsFilePrintf(fp
, "Sides2SidedLong %s\n", pwg
->sides_2sided_long
);
625 if (pwg
->sides_2sided_short
)
626 cupsFilePrintf(fp
, "Sides2SidedShort %s\n", pwg
->sides_2sided_short
);
629 * Close and return...
632 return (!cupsFileClose(fp
));