1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied, modified
8 or distributed except as expressly authorized under the terms of that
9 license. Refer to licensing information at http://www.artifex.com/
10 or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11 San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
12 */
13
14 /* $Id: gsfname.c 8022 2007-06-05 22:23:38Z giles $ */
15 /* File name utilities */
16 #include "memory_.h"
17 #include "gserror.h"
18 #include "gserrors.h"
19 #include "gsmemory.h"
20 #include "gstypes.h"
21 #include "gsfname.h"
22 #include "gxiodev.h"
23
24 /* Parse a file name into device and individual name. */
25 /* The device may be NULL, or the name may be NULL, but not both. */
26 /* According to the Adobe documentation, %device and %device% */
27 /* are equivalent; both return name==NULL. */
28 int
gs_parse_file_name(gs_parsed_file_name_t * pfn,const char * pname,uint len)29 gs_parse_file_name(gs_parsed_file_name_t * pfn, const char *pname, uint len)
30 {
31 uint dlen;
32 const char *pdelim;
33 gx_io_device *iodev;
34
35 if (len == 0)
36 return_error(gs_error_undefinedfilename); /* null name not allowed */
37 if (pname[0] != '%') { /* no device */
38 pfn->memory = 0;
39 pfn->iodev = NULL;
40 pfn->fname = pname;
41 pfn->len = len;
42 return 0;
43 }
44 pdelim = memchr(pname + 1, '%', len - 1);
45 if (pdelim == NULL) /* %device */
46 dlen = len;
47 else if (pdelim[1] == 0) { /* %device% */
48 pdelim = NULL;
49 dlen = len;
50 } else {
51 dlen = pdelim - pname;
52 pdelim++, len--;
53 }
54 iodev = gs_findiodevice((const byte *)pname, dlen);
55 if (iodev == 0)
56 return_error(gs_error_undefinedfilename);
57 pfn->memory = 0;
58 pfn->iodev = iodev;
59 pfn->fname = pdelim;
60 pfn->len = len - dlen;
61 return 0;
62 }
63
64 /* Parse a real (non-device) file name and convert to a C string. */
65 int
gs_parse_real_file_name(gs_parsed_file_name_t * pfn,const char * pname,uint len,gs_memory_t * mem,client_name_t cname)66 gs_parse_real_file_name(gs_parsed_file_name_t * pfn, const char *pname,
67 uint len, gs_memory_t *mem, client_name_t cname)
68 {
69 int code = gs_parse_file_name(pfn, pname, len);
70
71 if (code < 0)
72 return code;
73 if (pfn->len == 0) /* device only */
74 return_error(gs_error_undefinedfilename); /* for CET 23-23.ps */
75 return gs_terminate_file_name(pfn, mem, cname);
76 }
77
78 /* Convert a file name to a C string by adding a null terminator. */
79 int
gs_terminate_file_name(gs_parsed_file_name_t * pfn,gs_memory_t * mem,client_name_t cname)80 gs_terminate_file_name(gs_parsed_file_name_t * pfn, gs_memory_t *mem,
81 client_name_t cname)
82 {
83 uint len = pfn->len;
84 char *fname;
85
86 if (pfn->iodev == NULL) /* no device */
87 pfn->iodev = iodev_default;
88 if (pfn->memory)
89 return 0; /* already copied */
90 /* Copy the file name to a C string. */
91 fname = (char *)gs_alloc_string(mem, len + 1, cname);
92 if (fname == 0)
93 return_error(gs_error_VMerror);
94 memcpy(fname, pfn->fname, len);
95 fname[len] = 0;
96 pfn->memory = mem;
97 pfn->fname = fname;
98 pfn->len = len + 1; /* null terminator */
99 return 0;
100 }
101
102 /* Free a file name that was copied to a C string. */
103 void
gs_free_file_name(gs_parsed_file_name_t * pfn,client_name_t cname)104 gs_free_file_name(gs_parsed_file_name_t * pfn, client_name_t cname)
105 {
106 if (pfn->fname != 0)
107 gs_free_const_string(pfn->memory, (const byte *)pfn->fname, pfn->len,
108 cname);
109 }
110