17dd7cddfSDavid du Colombier /* Copyright (C) 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
27dd7cddfSDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
57dd7cddfSDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
17*593dc095SDavid du Colombier /* $Id: gxclfile.c,v 1.5 2002/02/21 22:24:53 giles Exp $ */
187dd7cddfSDavid du Colombier /* File-based command list implementation */
197dd7cddfSDavid du Colombier #include "stdio_.h"
207dd7cddfSDavid du Colombier #include "string_.h"
213ff48bf5SDavid du Colombier #include "unistd_.h"
227dd7cddfSDavid du Colombier #include "gserror.h"
237dd7cddfSDavid du Colombier #include "gserrors.h"
247dd7cddfSDavid du Colombier #include "gsmemory.h"
257dd7cddfSDavid du Colombier #include "gp.h"
267dd7cddfSDavid du Colombier #include "gxclio.h"
277dd7cddfSDavid du Colombier
287dd7cddfSDavid du Colombier /* This is an implementation of the command list I/O interface */
297dd7cddfSDavid du Colombier /* that uses the file system for storage. */
307dd7cddfSDavid du Colombier
317dd7cddfSDavid du Colombier /* ------ Open/close/unlink ------ */
327dd7cddfSDavid du Colombier
337dd7cddfSDavid du Colombier 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)347dd7cddfSDavid du Colombier clist_fopen(char fname[gp_file_name_sizeof], const char *fmode,
357dd7cddfSDavid du Colombier clist_file_ptr * pcf, gs_memory_t * mem, gs_memory_t *data_mem,
367dd7cddfSDavid du Colombier bool ok_to_compress)
377dd7cddfSDavid du Colombier {
387dd7cddfSDavid du Colombier if (*fname == 0) {
397dd7cddfSDavid du Colombier if (fmode[0] == 'r')
407dd7cddfSDavid du Colombier return_error(gs_error_invalidfileaccess);
417dd7cddfSDavid du Colombier *pcf =
427dd7cddfSDavid du Colombier (clist_file_ptr) gp_open_scratch_file(gp_scratch_file_name_prefix,
437dd7cddfSDavid du Colombier fname, fmode);
447dd7cddfSDavid du Colombier } else
457dd7cddfSDavid du Colombier *pcf = gp_fopen(fname, fmode);
467dd7cddfSDavid du Colombier if (*pcf == NULL) {
477dd7cddfSDavid du Colombier eprintf1("Could not open the scratch file %s.\n", fname);
487dd7cddfSDavid du Colombier return_error(gs_error_invalidfileaccess);
497dd7cddfSDavid du Colombier }
507dd7cddfSDavid du Colombier return 0;
517dd7cddfSDavid du Colombier }
527dd7cddfSDavid du Colombier
537dd7cddfSDavid du Colombier int
clist_fclose(clist_file_ptr cf,const char * fname,bool delete)547dd7cddfSDavid du Colombier clist_fclose(clist_file_ptr cf, const char *fname, bool delete)
557dd7cddfSDavid du Colombier {
567dd7cddfSDavid du Colombier return (fclose((FILE *) cf) != 0 ? gs_note_error(gs_error_ioerror) :
577dd7cddfSDavid du Colombier delete ? clist_unlink(fname) :
587dd7cddfSDavid du Colombier 0);
597dd7cddfSDavid du Colombier }
607dd7cddfSDavid du Colombier
617dd7cddfSDavid du Colombier int
clist_unlink(const char * fname)627dd7cddfSDavid du Colombier clist_unlink(const char *fname)
637dd7cddfSDavid du Colombier {
647dd7cddfSDavid du Colombier return (unlink(fname) != 0 ? gs_note_error(gs_error_ioerror) : 0);
657dd7cddfSDavid du Colombier }
667dd7cddfSDavid du Colombier
677dd7cddfSDavid du Colombier /* ------ Writing ------ */
687dd7cddfSDavid du Colombier
697dd7cddfSDavid du Colombier long
clist_space_available(long requested)707dd7cddfSDavid du Colombier clist_space_available(long requested)
717dd7cddfSDavid du Colombier {
727dd7cddfSDavid du Colombier return requested;
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier
757dd7cddfSDavid du Colombier int
clist_fwrite_chars(const void * data,uint len,clist_file_ptr cf)767dd7cddfSDavid du Colombier clist_fwrite_chars(const void *data, uint len, clist_file_ptr cf)
777dd7cddfSDavid du Colombier {
787dd7cddfSDavid du Colombier return fwrite(data, 1, len, (FILE *) cf);
797dd7cddfSDavid du Colombier }
807dd7cddfSDavid du Colombier
817dd7cddfSDavid du Colombier /* ------ Reading ------ */
827dd7cddfSDavid du Colombier
837dd7cddfSDavid du Colombier int
clist_fread_chars(void * data,uint len,clist_file_ptr cf)847dd7cddfSDavid du Colombier clist_fread_chars(void *data, uint len, clist_file_ptr cf)
857dd7cddfSDavid du Colombier {
867dd7cddfSDavid du Colombier FILE *f = (FILE *) cf;
877dd7cddfSDavid du Colombier byte *str = data;
887dd7cddfSDavid du Colombier
897dd7cddfSDavid du Colombier /* The typical implementation of fread */
907dd7cddfSDavid du Colombier /* is extremely inefficient for small counts, */
917dd7cddfSDavid du Colombier /* so we just use straight-line code instead. */
927dd7cddfSDavid du Colombier switch (len) {
937dd7cddfSDavid du Colombier default:
947dd7cddfSDavid du Colombier return fread(str, 1, len, f);
957dd7cddfSDavid du Colombier case 8:
967dd7cddfSDavid du Colombier *str++ = (byte) getc(f);
977dd7cddfSDavid du Colombier case 7:
987dd7cddfSDavid du Colombier *str++ = (byte) getc(f);
997dd7cddfSDavid du Colombier case 6:
1007dd7cddfSDavid du Colombier *str++ = (byte) getc(f);
1017dd7cddfSDavid du Colombier case 5:
1027dd7cddfSDavid du Colombier *str++ = (byte) getc(f);
1037dd7cddfSDavid du Colombier case 4:
1047dd7cddfSDavid du Colombier *str++ = (byte) getc(f);
1057dd7cddfSDavid du Colombier case 3:
1067dd7cddfSDavid du Colombier *str++ = (byte) getc(f);
1077dd7cddfSDavid du Colombier case 2:
1087dd7cddfSDavid du Colombier *str++ = (byte) getc(f);
1097dd7cddfSDavid du Colombier case 1:
1107dd7cddfSDavid du Colombier *str = (byte) getc(f);
1117dd7cddfSDavid du Colombier }
1127dd7cddfSDavid du Colombier return len;
1137dd7cddfSDavid du Colombier }
1147dd7cddfSDavid du Colombier
1157dd7cddfSDavid du Colombier /* ------ Position/status ------ */
1167dd7cddfSDavid du Colombier
1177dd7cddfSDavid du Colombier int
clist_set_memory_warning(clist_file_ptr cf,int bytes_left)1187dd7cddfSDavid du Colombier clist_set_memory_warning(clist_file_ptr cf, int bytes_left)
1197dd7cddfSDavid du Colombier {
1207dd7cddfSDavid du Colombier return 0; /* no-op */
1217dd7cddfSDavid du Colombier }
1227dd7cddfSDavid du Colombier
1237dd7cddfSDavid du Colombier int
clist_ferror_code(clist_file_ptr cf)1247dd7cddfSDavid du Colombier clist_ferror_code(clist_file_ptr cf)
1257dd7cddfSDavid du Colombier {
1267dd7cddfSDavid du Colombier return (ferror((FILE *) cf) ? gs_error_ioerror : 0);
1277dd7cddfSDavid du Colombier }
1287dd7cddfSDavid du Colombier
1297dd7cddfSDavid du Colombier long
clist_ftell(clist_file_ptr cf)1307dd7cddfSDavid du Colombier clist_ftell(clist_file_ptr cf)
1317dd7cddfSDavid du Colombier {
1327dd7cddfSDavid du Colombier return ftell((FILE *) cf);
1337dd7cddfSDavid du Colombier }
1347dd7cddfSDavid du Colombier
1357dd7cddfSDavid du Colombier void
clist_rewind(clist_file_ptr cf,bool discard_data,const char * fname)1367dd7cddfSDavid du Colombier clist_rewind(clist_file_ptr cf, bool discard_data, const char *fname)
1377dd7cddfSDavid du Colombier {
1387dd7cddfSDavid du Colombier FILE *f = (FILE *) cf;
1397dd7cddfSDavid du Colombier
1407dd7cddfSDavid du Colombier if (discard_data) {
1417dd7cddfSDavid du Colombier /*
1427dd7cddfSDavid du Colombier * The ANSI C stdio specification provides no operation for
1437dd7cddfSDavid du Colombier * truncating a file at a given position, or even just for
1447dd7cddfSDavid du Colombier * deleting its contents; we have to use a bizarre workaround to
1457dd7cddfSDavid du Colombier * get the same effect.
1467dd7cddfSDavid du Colombier */
1477dd7cddfSDavid du Colombier char fmode[4];
1487dd7cddfSDavid du Colombier
1497dd7cddfSDavid du Colombier /* Opening with "w" mode deletes the contents when closing. */
1507dd7cddfSDavid du Colombier freopen(fname, gp_fmode_wb, f);
1517dd7cddfSDavid du Colombier strcpy(fmode, "w+");
1527dd7cddfSDavid du Colombier strcat(fmode, gp_fmode_binary_suffix);
1537dd7cddfSDavid du Colombier freopen(fname, fmode, f);
1547dd7cddfSDavid du Colombier } else {
1557dd7cddfSDavid du Colombier rewind(f);
1567dd7cddfSDavid du Colombier }
1577dd7cddfSDavid du Colombier }
1587dd7cddfSDavid du Colombier
1597dd7cddfSDavid du Colombier int
clist_fseek(clist_file_ptr cf,long offset,int mode,const char * ignore_fname)1607dd7cddfSDavid du Colombier clist_fseek(clist_file_ptr cf, long offset, int mode, const char *ignore_fname)
1617dd7cddfSDavid du Colombier {
1627dd7cddfSDavid du Colombier return fseek((FILE *) cf, offset, mode);
1637dd7cddfSDavid du Colombier }
164