/* Copyright (C) 1995, 1996, 1997, 1998 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: gxclmem.h,v 1.2.6.1.2.1 2003/01/17 00:49:03 giles Exp $ */ /* Definitions and declarations for clist implementation in memory. */ #ifndef gxclmem_INCLUDED # define gxclmem_INCLUDED #include "gxclio.h" /* defines interface */ #include "strimpl.h" /* stream structures */ /* * The best values of MEMFILE_DATA_SIZE are slightly less than a power of 2, * to allow typical malloc implementations to allocate in units of a power * of 2 rather than having to go slightly over. */ #define MEMFILE_DATA_SIZE (16384 - 160) /* ============================================================ */ /* */ /* Memfile structure definitions. */ /* */ /* The PHYS structures are the elements actually allocated in */ /* RAM, containing the compressed data (or optionally raw data) */ /* */ /* There can be several LOG (logical) elements per physical */ /* element, depending on the compression. The MEMFILE pdata */ /* item always points into a raw block of data. */ /* */ /* ============================================================ */ typedef struct RAW_BUFFER { struct RAW_BUFFER *fwd, *back; struct LOG_MEMFILE_BLK *log_blk; char data[MEMFILE_DATA_SIZE]; } RAW_BUFFER; typedef struct PHYS_MEMFILE_BLK { struct PHYS_MEMFILE_BLK *link; char *data_limit; /* end of data when compressed */ /* NULL if not compressed */ char data_spare[4]; /* used during de-compress */ char data[MEMFILE_DATA_SIZE]; } PHYS_MEMFILE_BLK; typedef struct LOG_MEMFILE_BLK { struct LOG_MEMFILE_BLK *link; PHYS_MEMFILE_BLK *phys_blk; char *phys_pdata; RAW_BUFFER *raw_block; /* or NULL */ } LOG_MEMFILE_BLK; typedef struct MEMFILE { gs_memory_t *memory; /* storage allocator */ gs_memory_t *data_memory; /* storage allocator for data */ bool ok_to_compress; /* if true, OK to compress this file */ /* * Reserve memory blocks: these are used to guarantee that a * given-sized write (or sequence of writes) will always succeed. * More specifically, the guarantee is that N bytes can successfully * be written after a low-memory warning is first returned by * fwrite. The reserve of N bytes for a given file is (re)allocated * by a successful call to memfile_set_memory_warning(N). Fwrite * allocates memory only from the reserve when its normal allocation * attempts fail; in such cases, it allocates blocks from the * reserve pool as needed and completes normally, but returns a * low-memory warning status. Once a low-memory warning has been * returned, fwrite will continue to attempt to allocate memory from * the usual allocator on subsequent fwrites, but does *not* try to * "top up" the reserve if becomes available -- only an explicit * memfile_set_memory_warning does so. */ PHYS_MEMFILE_BLK *reservePhysBlockChain; /* chain of reserve phys blks */ int reservePhysBlockCount; /* count of entries on reservePhysBlockChain */ LOG_MEMFILE_BLK *reserveLogBlockChain; /* chain of reserve log blks */ int reserveLogBlockCount; /* count of entries on reserveLogBlockChain */ /* logical file properties */ LOG_MEMFILE_BLK *log_head; LOG_MEMFILE_BLK *log_curr_blk; long log_length; /* updated during write */ long log_curr_pos; /* updated during seek, close, read */ char *pdata; /* raw data */ char *pdata_end; /* physical file properties */ long total_space; /* so we know when to start compress */ PHYS_MEMFILE_BLK *phys_curr; /* NULL if not compressing */ RAW_BUFFER *raw_head, *raw_tail; int error_code; /* used by CLIST_ferror */ stream_cursor_read rd; /* use .ptr, .limit */ stream_cursor_write wt; /* use .ptr, .limit */ bool compressor_initialized; stream_state *compress_state; stream_state *decompress_state; } MEMFILE; /* * Only the MEMFILE and stream_state structures are GC-compatible, so we * allocate all the other structures on the C heap. */ #define private_st_MEMFILE() /* in gxclmem.c */\ gs_private_st_ptrs2(st_MEMFILE, MEMFILE, "MEMFILE",\ MEMFILE_enum_ptrs, MEMFILE_reloc_ptrs, compress_state, decompress_state) /* Make the memfile_... operations aliases for the clist_... operations. */ #define memfile_fopen(fname, fmode, pcf, mem, data_mem, compress)\ clist_fopen(fname, fmode, pcf, mem, data_mem, compress) #define memfile_fclose(cf, fname, delete)\ clist_fclose(cf, fname, delete) #define memfile_unlink(fname)\ clist_unlink(fname) #define memfile_space_available(req)\ clist_space_available(req) #define memfile_fwrite_chars(data, len, cf)\ clist_fwrite_chars(data, len, cf) #define memfile_fread_chars(data, len, cf)\ clist_fread_chars(data, len, cf) #define memfile_set_memory_warning(cf, nbytes) clist_set_memory_warning(cf, nbytes) #define memfile_ferror_code(cf) clist_ferror_code(cf) #define memfile_ftell(cf) clist_ftell(cf) #define memfile_rewind(cf, discard, fname) clist_rewind(cf, discard, fname) #define memfile_fseek(cf, offset, mode, fname) clist_fseek(cf, offset, mode, fname) /* Declare the procedures for returning the prototype filter states */ /* for compressing and decompressing the band list. */ const stream_state *clist_compressor_state(P1(void *)); const stream_state *clist_decompressor_state(P1(void *)); #endif /* gxclmem_INCLUDED */