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