Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/cmd/gs/src/idict.h – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: idict.h,v 1.6 2004/08/04 19:36:12 stefan Exp $ */
18
/* Interfaces for Ghostscript dictionary package */
19
 
20
#ifndef idict_INCLUDED
21
#  define idict_INCLUDED
22
 
23
#include "iddstack.h"
24
 
25
/*
26
 * Contrary to our usual practice, we expose the (first-level)
27
 * representation of a dictionary in the interface file,
28
 * because it is so important that access checking go fast.
29
 * The access attributes for the dictionary are stored in
30
 * the values ref.
31
 */
32
struct dict_s {
33
    ref values;			/* t_array, values */
34
    ref keys;			/* t_shortarray or t_array, keys */
35
    ref count;			/* t_integer, count of occupied entries */
36
    /* (length) */
37
    ref maxlength;		/* t_integer, maxlength as seen by client. */
38
    ref memory;			/* foreign t_struct, the allocator that */
39
    /* created this dictionary */
40
#define dict_memory(pdict) r_ptr(&(pdict)->memory, gs_ref_memory_t)
41
#define dict_mem(pdict) r_ptr(&(pdict)->memory, gs_memory_t)
42
};
43
 
44
/*
45
 * Define the maximum size of a dictionary.
46
 */
47
extern const uint dict_max_size;
48
 
49
/*
50
 * Define whether dictionaries expand automatically when full.  Note that
51
 * if dict_auto_expand is true, dict_put, dict_copy, dict_resize, and
52
 * dict_grow cannot return e_dictfull; however, they can return e_VMerror.
53
 * (dict_find can return e_dictfull even if dict_auto_expand is true.)
54
 */
55
extern bool dict_auto_expand;
56
 
57
/*
58
 * Create a dictionary.
59
 */
60
#ifndef gs_ref_memory_DEFINED
61
#  define gs_ref_memory_DEFINED
62
typedef struct gs_ref_memory_s gs_ref_memory_t;
63
#endif
64
int dict_alloc(gs_ref_memory_t *, uint maxlength, ref * pdref);
65
 
66
#define dict_create(maxlen, pdref)\
67
  dict_alloc(iimemory, maxlen, pdref)
68
 
69
/*
70
 * Return a pointer to a ref that holds the access attributes
71
 * for a dictionary.
72
 */
73
#define dict_access_ref(pdref) (&(pdref)->value.pdict->values)
74
/*
75
 * Check a dictionary for read or write permission.
76
 * Note: this does NOT check the type of its operand!
77
 */
78
#define check_dict_read(dref) check_read(*dict_access_ref(&dref))
79
#define check_dict_write(dref) check_write(*dict_access_ref(&dref))
80
 
81
/*
82
 * Look up a key in a dictionary.  Store a pointer to the value slot
83
 * where found, or to the (value) slot for inserting.
84
 * The caller is responsible for checking that the dictionary is readable.
85
 * Return 1 if found, 0 if not and there is room for a new entry,
86
 * Failure returns:
87
 *      e_typecheck if the key is null;
88
 *      e_invalidaccess if the key is a string lacking read access;
89
 *      e_VMerror or e_limitcheck if the key is a string and the corresponding
90
 *        error occurs from attempting to convert it to a name;
91
 *      e_dictfull if the dictionary is full and the key is missing.
92
 */
93
int dict_find(const ref * pdref, const ref * key, ref ** ppvalue);
94
 
95
/*
96
 * Look up a (constant) C string in a dictionary.
97
 * Return 1 if found, <= 0 if not.
98
 */
99
int dict_find_string(const ref * pdref, const char *kstr, ref ** ppvalue);
100
 
101
/*
102
 * Enter a key-value pair in a dictionary.
103
 * The caller is responsible for checking that the dictionary is writable.
104
 * Return 1 if this was a new entry, 0 if this replaced an existing entry.
105
 * Failure returns are as for dict_find, except that e_dictfull doesn't
106
 * occur if the dictionary is full but expandable, plus:
107
 *      e_invalidaccess for an attempt to store a younger key or value into
108
 *        an older dictionary, or as described just below;
109
 *      e_VMerror if a VMerror occurred while trying to expand the
110
 *        dictionary.
111
 * Note that this procedure, and all procedures that may change the
112
 * contents of a dictionary, take a pointer to a dictionary stack,
113
 * so they can update the cached 'top' values and also update the cached
114
 * value pointer in names.  A NULL pointer for the dictionary stack is
115
 * allowed, but in this case, if the dictionary is present on any dictionary
116
 * stack, an e_invalidaccess error will occur if cached values need updating.
117
 * THIS ERROR CHECK IS NOT IMPLEMENTED YET.
118
 */
119
int dict_put(ref * pdref, const ref * key, const ref * pvalue,
120
	     dict_stack_t *pds);
121
 
122
/*
123
 * Enter a key-value pair where the key is a (constant) C string.
124
 */
125
int dict_put_string(ref * pdref, const char *kstr, const ref * pvalue,
126
		    dict_stack_t *pds);
127
 
128
/*
129
 * Remove a key-value pair from a dictionary.
130
 * Return 0 or e_undefined.
131
 */
132
int dict_undef(ref * pdref, const ref * key, dict_stack_t *pds);
133
 
134
/*
135
 * Return the number of elements in a dictionary.
136
 */
137
uint dict_length(const ref * pdref);
138
 
139
/*
140
 * Return the capacity of a dictionary.
141
 */
142
uint dict_maxlength(const ref * pdref);
143
 
144
/*
145
 * Return the maximum index of a slot within a dictionary.
146
 * Note that this may be greater than maxlength.
147
 */
148
uint dict_max_index(const ref * pdref);
149
 
150
/*
151
 * Copy one dictionary into another.
152
 * Return 0 or e_dictfull.
153
 * If new_only is true, only copy entries whose keys
154
 * aren't already present in the destination.
155
 */
156
int dict_copy_entries(const ref * dfrom, ref * dto, bool new_only,
157
		      dict_stack_t *pds);
158
 
159
#define dict_copy(dfrom, dto, pds) dict_copy_entries(dfrom, dto, false, pds)
160
#define dict_copy_new(dfrom, dto, pds) dict_copy_entries(dfrom, dto, true, pds)
161
 
162
/*
163
 * Grow or shrink a dictionary.
164
 * Return 0, e_dictfull, or e_VMerror.
165
 */
166
int dict_resize(ref * pdref, uint newmaxlength, dict_stack_t *pds);
167
 
168
/*
169
 * Grow a dictionary in the same way as dict_put does.
170
 * We export this for some special-case code in zop_def.
171
 */
172
int dict_grow(ref * pdref, dict_stack_t *pds);
173
 
174
/*
175
 * Ensure that a dictionary uses the unpacked representation for keys.
176
 * (This is of no interest to ordinary clients.)
177
 */
178
int dict_unpack(ref * pdref, dict_stack_t *pds);
179
 
180
/*
181
 * Prepare to enumerate a dictionary.
182
 * Return an integer suitable for the first call to dict_next.
183
 */
184
int dict_first(const ref * pdref);
185
 
186
/*
187
 * Enumerate the next element of a dictionary.
188
 * index is initially the result of a call on dict_first.
189
 * Either store a key and value at eltp[0] and eltp[1]
190
 * and return an updated index, or return -1
191
 * to signal that there are no more elements in the dictionary.
192
 */
193
int dict_next(const ref * pdref, int index, ref * eltp);
194
 
195
/*
196
 * Given a value pointer return by dict_find, return an index that
197
 * identifies the entry within the dictionary. (This may, but need not,
198
 * be the same as the index returned by dict_next.)
199
 * The index is in the range [0..max_index-1].
200
 */
201
int dict_value_index(const ref * pdref, const ref * pvalue);
202
 
203
/*
204
 * Given an index in [0..max_index-1], as returned by dict_value_index,
205
 * return the key and value, as returned by dict_next.
206
 * If the index designates an unoccupied entry, return e_undefined.
207
 */
208
int dict_index_entry(const ref * pdref, int index, ref * eltp);
209
 
210
/*
211
 * The following are some internal details that are used in both the
212
 * implementation and some high-performance clients.
213
 */
214
 
215
/* On machines with reasonable amounts of memory, we round up dictionary
216
 * sizes to the next power of 2 whenever possible, to allow us to use
217
 * masking rather than division for computing the hash index.
218
 * Unfortunately, if we required this, it would cut the maximum size of a
219
 * dictionary in half.  Therefore, on such machines, we distinguish
220
 * "huge" dictionaries (dictionaries whose size is larger than the largest
221
 * power of 2 less than dict_max_size) as a special case:
222
 *
223
 *      - If the top dictionary on the stack is huge, we set the dtop
224
 *      parameters so that the fast inline lookup will always fail.
225
 *
226
 *      - For general lookup, we use the slower hash_mod algorithm for
227
 *      huge dictionaries.
228
 */
229
#define dict_max_non_huge ((uint)(max_array_size / 2 + 1))
230
 
231
/* Define the hashing function for names. */
232
/* We don't have to scramble the index, because */
233
/* indices are assigned in a scattered order (see name_ref in iname.c). */
234
#define dict_name_index_hash(nidx) (nidx)
235
 
236
/* Hash an arbitrary non-negative or unsigned integer into a dictionary. */
237
#define dict_hash_mod_rem(hash, size) ((hash) % (size))
238
#define dict_hash_mod_mask(hash, size) ((hash) & ((size) - 1))
239
#define dict_hash_mod_small(hash, size) dict_hash_mod_rem(hash, size)
240
#define dict_hash_mod_inline_small(hash, size) dict_hash_mod_rem(hash, size)
241
#define dict_hash_mod_large(hash, size)\
242
  (size > dict_max_non_huge ? dict_hash_mod_rem(hash, size) :\
243
   dict_hash_mod_mask(hash, size))
244
#define dict_hash_mod_inline_large(hash, size) dict_hash_mod_mask(hash, size)
245
/* Round up the requested size of a dictionary.  Return 0 if too big. */
246
uint dict_round_size_small(uint rsize);
247
uint dict_round_size_large(uint rsize);
248
 
249
/* Choose the algorithms depending on the size of memory. */
250
#if arch_small_memory
251
#  define dict_hash_mod(h, s) dict_hash_mod_small(h, s)
252
#  define dict_hash_mod_inline(h, s) dict_hash_mod_inline_small(h, s)
253
#  define dict_round_size(s) dict_round_size_small(s)
254
#else
255
#  ifdef DEBUG
256
#    define dict_hash_mod(h, s)\
257
       (gs_debug_c('.') ? dict_hash_mod_small(h, s) :\
258
	dict_hash_mod_large(h, s))
259
#    define dict_hash_mod_inline(h, s)\
260
       (gs_debug_c('.') ? dict_hash_mod_inline_small(h, s) :\
261
	dict_hash_mod_inline_large(h, s))
262
#    define dict_round_size(s)\
263
       (gs_debug_c('.') ? dict_round_size_small(s) :\
264
	dict_round_size_large(s))
265
#  else
266
#    define dict_hash_mod(h, s) dict_hash_mod_large(h, s)
267
#    define dict_hash_mod_inline(h, s) dict_hash_mod_inline_large(h, s)
268
#    define dict_round_size(s) dict_round_size_large(s)
269
#  endif
270
#endif
271
 
272
#endif /* idict_INCLUDED */