1 /* Copyright (C) 1995, 1996, 1997, 1998 artofcode LLC. All rights reserved. 2 3 This program is free software; you can redistribute it and/or modify it 4 under the terms of the GNU General Public License as published by the 5 Free Software Foundation; either version 2 of the License, or (at your 6 option) any later version. 7 8 This program is distributed in the hope that it will be useful, but 9 WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along 14 with this program; if not, write to the Free Software Foundation, Inc., 15 59 Temple Place, Suite 330, Boston, MA, 02111-1307. 16 17 */ 18 19 /*$Id: gxclmem.h,v 1.2.6.1.2.1 2003/01/17 00:49:03 giles Exp $ */ 20 /* Definitions and declarations for clist implementation in memory. */ 21 22 #ifndef gxclmem_INCLUDED 23 # define gxclmem_INCLUDED 24 25 #include "gxclio.h" /* defines interface */ 26 #include "strimpl.h" /* stream structures */ 27 28 /* 29 * The best values of MEMFILE_DATA_SIZE are slightly less than a power of 2, 30 * to allow typical malloc implementations to allocate in units of a power 31 * of 2 rather than having to go slightly over. 32 */ 33 #define MEMFILE_DATA_SIZE (16384 - 160) 34 35 /* ============================================================ */ 36 /* */ 37 /* Memfile structure definitions. */ 38 /* */ 39 /* The PHYS structures are the elements actually allocated in */ 40 /* RAM, containing the compressed data (or optionally raw data) */ 41 /* */ 42 /* There can be several LOG (logical) elements per physical */ 43 /* element, depending on the compression. The MEMFILE pdata */ 44 /* item always points into a raw block of data. */ 45 /* */ 46 /* ============================================================ */ 47 48 typedef struct RAW_BUFFER { 49 struct RAW_BUFFER *fwd, *back; 50 struct LOG_MEMFILE_BLK *log_blk; 51 char data[MEMFILE_DATA_SIZE]; 52 } RAW_BUFFER; 53 54 typedef struct PHYS_MEMFILE_BLK { 55 struct PHYS_MEMFILE_BLK *link; 56 char *data_limit; /* end of data when compressed */ 57 /* NULL if not compressed */ 58 char data_spare[4]; /* used during de-compress */ 59 char data[MEMFILE_DATA_SIZE]; 60 } PHYS_MEMFILE_BLK; 61 62 typedef struct LOG_MEMFILE_BLK { 63 struct LOG_MEMFILE_BLK *link; 64 PHYS_MEMFILE_BLK *phys_blk; 65 char *phys_pdata; 66 RAW_BUFFER *raw_block; /* or NULL */ 67 } LOG_MEMFILE_BLK; 68 69 typedef struct MEMFILE { 70 gs_memory_t *memory; /* storage allocator */ 71 gs_memory_t *data_memory; /* storage allocator for data */ 72 bool ok_to_compress; /* if true, OK to compress this file */ 73 /* 74 * Reserve memory blocks: these are used to guarantee that a 75 * given-sized write (or sequence of writes) will always succeed. 76 * More specifically, the guarantee is that N bytes can successfully 77 * be written after a low-memory warning is first returned by 78 * fwrite. The reserve of N bytes for a given file is (re)allocated 79 * by a successful call to memfile_set_memory_warning(N). Fwrite 80 * allocates memory only from the reserve when its normal allocation 81 * attempts fail; in such cases, it allocates blocks from the 82 * reserve pool as needed and completes normally, but returns a 83 * low-memory warning status. Once a low-memory warning has been 84 * returned, fwrite will continue to attempt to allocate memory from 85 * the usual allocator on subsequent fwrites, but does *not* try to 86 * "top up" the reserve if becomes available -- only an explicit 87 * memfile_set_memory_warning does so. 88 */ 89 PHYS_MEMFILE_BLK *reservePhysBlockChain; /* chain of reserve phys blks */ 90 int reservePhysBlockCount; /* count of entries on reservePhysBlockChain */ 91 LOG_MEMFILE_BLK *reserveLogBlockChain; /* chain of reserve log blks */ 92 int reserveLogBlockCount; /* count of entries on reserveLogBlockChain */ 93 /* logical file properties */ 94 LOG_MEMFILE_BLK *log_head; 95 LOG_MEMFILE_BLK *log_curr_blk; 96 long log_length; /* updated during write */ 97 long log_curr_pos; /* updated during seek, close, read */ 98 char *pdata; /* raw data */ 99 char *pdata_end; 100 /* physical file properties */ 101 long total_space; /* so we know when to start compress */ 102 PHYS_MEMFILE_BLK *phys_curr; /* NULL if not compressing */ 103 RAW_BUFFER *raw_head, *raw_tail; 104 int error_code; /* used by CLIST_ferror */ 105 stream_cursor_read rd; /* use .ptr, .limit */ 106 stream_cursor_write wt; /* use .ptr, .limit */ 107 bool compressor_initialized; 108 stream_state *compress_state; 109 stream_state *decompress_state; 110 } MEMFILE; 111 112 /* 113 * Only the MEMFILE and stream_state structures are GC-compatible, so we 114 * allocate all the other structures on the C heap. 115 */ 116 117 #define private_st_MEMFILE() /* in gxclmem.c */\ 118 gs_private_st_ptrs2(st_MEMFILE, MEMFILE, "MEMFILE",\ 119 MEMFILE_enum_ptrs, MEMFILE_reloc_ptrs, compress_state, decompress_state) 120 121 /* Make the memfile_... operations aliases for the clist_... operations. */ 122 123 #define memfile_fopen(fname, fmode, pcf, mem, data_mem, compress)\ 124 clist_fopen(fname, fmode, pcf, mem, data_mem, compress) 125 #define memfile_fclose(cf, fname, delete)\ 126 clist_fclose(cf, fname, delete) 127 #define memfile_unlink(fname)\ 128 clist_unlink(fname) 129 130 #define memfile_space_available(req)\ 131 clist_space_available(req) 132 #define memfile_fwrite_chars(data, len, cf)\ 133 clist_fwrite_chars(data, len, cf) 134 135 #define memfile_fread_chars(data, len, cf)\ 136 clist_fread_chars(data, len, cf) 137 138 #define memfile_set_memory_warning(cf, nbytes) clist_set_memory_warning(cf, nbytes) 139 #define memfile_ferror_code(cf) clist_ferror_code(cf) 140 #define memfile_ftell(cf) clist_ftell(cf) 141 #define memfile_rewind(cf, discard, fname) clist_rewind(cf, discard, fname) 142 #define memfile_fseek(cf, offset, mode, fname) clist_fseek(cf, offset, mode, fname) 143 144 /* Declare the procedures for returning the prototype filter states */ 145 /* for compressing and decompressing the band list. */ 146 const stream_state *clist_compressor_state(P1(void *)); 147 const stream_state *clist_decompressor_state(P1(void *)); 148 149 #endif /* gxclmem_INCLUDED */ 150