1 /* Copyright (C) 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gxclfile.c,v 1.5 2002/02/21 22:24:53 giles Exp $ */
18 /* File-based command list implementation */
19 #include "stdio_.h"
20 #include "string_.h"
21 #include "unistd_.h"
22 #include "gserror.h"
23 #include "gserrors.h"
24 #include "gsmemory.h"
25 #include "gp.h"
26 #include "gxclio.h"
27
28 /* This is an implementation of the command list I/O interface */
29 /* that uses the file system for storage. */
30
31 /* ------ Open/close/unlink ------ */
32
33 int
clist_fopen(char fname[gp_file_name_sizeof],const char * fmode,clist_file_ptr * pcf,gs_memory_t * mem,gs_memory_t * data_mem,bool ok_to_compress)34 clist_fopen(char fname[gp_file_name_sizeof], const char *fmode,
35 clist_file_ptr * pcf, gs_memory_t * mem, gs_memory_t *data_mem,
36 bool ok_to_compress)
37 {
38 if (*fname == 0) {
39 if (fmode[0] == 'r')
40 return_error(gs_error_invalidfileaccess);
41 *pcf =
42 (clist_file_ptr) gp_open_scratch_file(gp_scratch_file_name_prefix,
43 fname, fmode);
44 } else
45 *pcf = gp_fopen(fname, fmode);
46 if (*pcf == NULL) {
47 eprintf1("Could not open the scratch file %s.\n", fname);
48 return_error(gs_error_invalidfileaccess);
49 }
50 return 0;
51 }
52
53 int
clist_fclose(clist_file_ptr cf,const char * fname,bool delete)54 clist_fclose(clist_file_ptr cf, const char *fname, bool delete)
55 {
56 return (fclose((FILE *) cf) != 0 ? gs_note_error(gs_error_ioerror) :
57 delete ? clist_unlink(fname) :
58 0);
59 }
60
61 int
clist_unlink(const char * fname)62 clist_unlink(const char *fname)
63 {
64 return (unlink(fname) != 0 ? gs_note_error(gs_error_ioerror) : 0);
65 }
66
67 /* ------ Writing ------ */
68
69 long
clist_space_available(long requested)70 clist_space_available(long requested)
71 {
72 return requested;
73 }
74
75 int
clist_fwrite_chars(const void * data,uint len,clist_file_ptr cf)76 clist_fwrite_chars(const void *data, uint len, clist_file_ptr cf)
77 {
78 return fwrite(data, 1, len, (FILE *) cf);
79 }
80
81 /* ------ Reading ------ */
82
83 int
clist_fread_chars(void * data,uint len,clist_file_ptr cf)84 clist_fread_chars(void *data, uint len, clist_file_ptr cf)
85 {
86 FILE *f = (FILE *) cf;
87 byte *str = data;
88
89 /* The typical implementation of fread */
90 /* is extremely inefficient for small counts, */
91 /* so we just use straight-line code instead. */
92 switch (len) {
93 default:
94 return fread(str, 1, len, f);
95 case 8:
96 *str++ = (byte) getc(f);
97 case 7:
98 *str++ = (byte) getc(f);
99 case 6:
100 *str++ = (byte) getc(f);
101 case 5:
102 *str++ = (byte) getc(f);
103 case 4:
104 *str++ = (byte) getc(f);
105 case 3:
106 *str++ = (byte) getc(f);
107 case 2:
108 *str++ = (byte) getc(f);
109 case 1:
110 *str = (byte) getc(f);
111 }
112 return len;
113 }
114
115 /* ------ Position/status ------ */
116
117 int
clist_set_memory_warning(clist_file_ptr cf,int bytes_left)118 clist_set_memory_warning(clist_file_ptr cf, int bytes_left)
119 {
120 return 0; /* no-op */
121 }
122
123 int
clist_ferror_code(clist_file_ptr cf)124 clist_ferror_code(clist_file_ptr cf)
125 {
126 return (ferror((FILE *) cf) ? gs_error_ioerror : 0);
127 }
128
129 long
clist_ftell(clist_file_ptr cf)130 clist_ftell(clist_file_ptr cf)
131 {
132 return ftell((FILE *) cf);
133 }
134
135 void
clist_rewind(clist_file_ptr cf,bool discard_data,const char * fname)136 clist_rewind(clist_file_ptr cf, bool discard_data, const char *fname)
137 {
138 FILE *f = (FILE *) cf;
139
140 if (discard_data) {
141 /*
142 * The ANSI C stdio specification provides no operation for
143 * truncating a file at a given position, or even just for
144 * deleting its contents; we have to use a bizarre workaround to
145 * get the same effect.
146 */
147 char fmode[4];
148
149 /* Opening with "w" mode deletes the contents when closing. */
150 freopen(fname, gp_fmode_wb, f);
151 strcpy(fmode, "w+");
152 strcat(fmode, gp_fmode_binary_suffix);
153 freopen(fname, fmode, f);
154 } else {
155 rewind(f);
156 }
157 }
158
159 int
clist_fseek(clist_file_ptr cf,long offset,int mode,const char * ignore_fname)160 clist_fseek(clist_file_ptr cf, long offset, int mode, const char *ignore_fname)
161 {
162 return fseek((FILE *) cf, offset, mode);
163 }
164