xref: /plan9-contrib/sys/src/cmd/gs/src/gxclfile.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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