diff options
Diffstat (limited to 'pl/pldict.h')
-rw-r--r-- | pl/pldict.h | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/pl/pldict.h b/pl/pldict.h new file mode 100644 index 000000000..b18da8902 --- /dev/null +++ b/pl/pldict.h @@ -0,0 +1,164 @@ +/* Portions Copyright (C) 2001 artofcode LLC. + Portions Copyright (C) 1996, 2001 Artifex Software Inc. + Portions Copyright (C) 1988, 2000 Aladdin Enterprises. + This software is based in part on the work of the Independent JPEG Group. + All Rights Reserved. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ or + contact Artifex Software, Inc., 101 Lucas Valley Road #110, + San Rafael, CA 94903, (415)492-9861, for further information. */ +/*$Id$ */ + +/* pldict.h */ +/* Dictionary interface for PCL parsers */ +/* Requires gsmemory.h */ + +#ifndef pldict_INCLUDED +# define pldict_INCLUDED + +/* + * We use dictionaries to catalog various kinds of entities. The keys are + * strings; the values are 'objects'. The current implementation is slow + * but simple. + * + * Dictionaries can be stacked. Lookups search the stack, but additions, + * deletions, and replacements always work in the top dictionary. + * + * The implementation copies keys, but does not copy values. Instead, it + * calls a client-supplied freeing procedure whenever a value must be freed + * (by being deleted or replaced). The prototype for this procedure is + * identical to that of gs_free_object (which, however, is a macro.) + */ +typedef void (*pl_dict_value_free_proc_t)(gs_memory_t *, void *, + client_name_t); +#ifndef pl_dict_entry_DEFINED +# define pl_dict_entry_DEFINED +typedef struct pl_dict_entry_s pl_dict_entry_t; +#endif +typedef struct pl_dict_s pl_dict_t; +struct pl_dict_s { + pl_dict_entry_t *entries; + uint entry_count; + pl_dict_value_free_proc_t free_proc; + pl_dict_t *parent; /* next dictionary up the stack */ + gs_memory_t *memory; +}; +#ifdef extern_st +extern_st(st_pl_dict); /* only for embedders */ +#endif +#define public_st_pl_dict() /* in pldict.c */\ + gs_public_st_ptrs2(st_pl_dict, pl_dict_t, "pl_dict_t",\ + pl_dict_enum_ptrs, pl_dict_reloc_ptrs, entries, parent) +#define st_pl_dict_max_ptrs 2 + +/* + * Define the maximum length of keys stored in the dictionary entries + * themselves. This is a time/space tradeoff. + */ +#define pl_dict_max_short_key 16 + +/* Initialize a dictionary. */ +void pl_dict_init(pl_dict_t *pdict, gs_memory_t *memory, + pl_dict_value_free_proc_t free_proc); + +/* + * Look up an entry in a dictionary, optionally searching the stack, and + * optionally returning a pointer to the actual dictionary where the + * entry was found. Return true, setting *pvalue (and, if ppdict is not + * NULL, *ppdict), if found. + */ +bool pl_dict_lookup(pl_dict_t *pdict, const byte *kdata, uint ksize, + void **pvalue, bool with_stack, pl_dict_t **ppdict); +#define pl_dict_find(pdict, kdata, ksize, pvalue)\ + pl_dict_lookup(pdict, kdata, ksize, pvalue, true, (pl_dict_t **)0) + +#define pl_dict_find_no_stack(pdict, kdata, ksize, pvalue)\ + pl_dict_lookup(pdict, kdata, ksize, pvalue, false, (pl_dict_t **)0) + +/* + * Add an entry to a dictionary. Return 1 if it replaces an existing entry. + * Return -1 if we couldn't allocate memory. + */ +int pl_dict_put(pl_dict_t *pdict, const byte *kdata, uint ksize, + void *value); + +/* + * When a dictionary entry is created, it can be designated as being a + * synonym or alias of an existing entry, rather than having a value + * of its own. All entries in a synonym group are equivalent: there + * is no distinction between the "original" entry and subsequent ones, + * and synonymy is commutative and transitive. All entries in a + * synonym group have the same value: when the value of one member of + * a group is changed, the values of all members of the group are + * changed. When any member of a synonym group is deleted, all + * members of the group are deleted. (Note that the client-supplied + * freeing procedure is only called once in the case of a change or + * deletion.) When deleting an entry that is potentially a synonym or + * an entry that has associated synonyms the client should use + * pl_undef_purge_synonyms() (see below). + */ + +int pl_dict_put_synonym(pl_dict_t *pdict, const byte *old_kdata, + uint old_ksize, const byte *new_kdata, + uint new_ksize); + +/* + * Remove an entry from a dictionary. Return true if the entry was present. + */ +bool pl_dict_undef(pl_dict_t *pdict, const byte *kdata, uint ksize); + +/* + * Get or set the parent of a dictionary. + */ +#define pl_dict_parent(pdict) ((pdict)->parent) +#define pl_dict_set_parent(pdict, pardict) ((pdict)->parent = (pardict)) + +/* + * Return the number of entries in a dictionary. + */ +uint pl_dict_length(const pl_dict_t *pdict, bool with_stack); + +/* + * Enumerate a dictionary. If entries are added during enumeration, + * they may or may not be enumerated; it is OK to delete entries that have + * already been enumerated (including the current entry), but not + * entries that have not been enumerated yet. Use as follows: + * gs_const_string keyvar; + * void *valuevar; + * pl_dict_enum_t denum; + * ... + * pl_dict_enum_begin(pdict, &denum); + * -or- + * pl_dict_enum_stack_begin(pdict, &denum, with_stack); + * while ( pl_dict_enum_next(&denum, &keyvar, &valuevar) ) + * ... process <keyvar, valuevar> ... + */ +typedef struct pl_dict_enum_s { + const pl_dict_t *pdict; + pl_dict_entry_t *next; + bool first; + const pl_dict_t *next_dict; +} pl_dict_enum_t; +void pl_dict_enum_stack_begin(const pl_dict_t *pdict, pl_dict_enum_t *penum, + bool with_stack); +#define pl_dict_enum_begin(pdict, penum)\ + pl_dict_enum_stack_begin(pdict, penum, true) +bool pl_dict_enum_next(pl_dict_enum_t *penum, gs_const_string *pkey, + void **pvalue); + +/* + * Release a dictionary by freeing all keys, values, and other storage. + */ +void pl_dict_release(pl_dict_t *pdict); + +/* + * Delete an entry that is a synonym or a canonical entry that has + * related synonyms. The entire group of entries is deleted. Note + * that this routine should be used in liueu of pl_dict_undef() if + * synonyms are potentially used. + */ +void pl_dict_undef_purge_synonyms(pl_dict_t *pdict, const byte *kdata, uint ksize); + +#endif /* pldict_INCLUDED */ |