summaryrefslogtreecommitdiffstats
path: root/lib/libaccess/symbols.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libaccess/symbols.cpp')
-rw-r--r--lib/libaccess/symbols.cpp350
1 files changed, 350 insertions, 0 deletions
diff --git a/lib/libaccess/symbols.cpp b/lib/libaccess/symbols.cpp
new file mode 100644
index 00000000..ca1e18b1
--- /dev/null
+++ b/lib/libaccess/symbols.cpp
@@ -0,0 +1,350 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+/*
+ * Description (symbols.c)
+ *
+ * This module implements a symbol table for ACL-related structures.
+ * The symbol table associates string names and types with pointers
+ * to various kinds of structures.
+ */
+/*
+#include <base/systems.h>
+*/
+#include <plhash.h>
+#include <base/util.h>
+#include <netsite.h>
+#define __PRIVATE_SYMBOLS
+#include "libaccess/symbols.h"
+#include <ctype.h>
+
+static PLHashEntry * symAllocEntry(void * pool, const void *unused);
+static void * symAllocTable(void * pool, PRSize size);
+static int symCmpName(const void * name1, const void * name2);
+static int symCmpValue(const void * value1, const void * value2);
+static PLHashNumber symHash(const void * symkey);
+static void symFreeEntry(void * pool, PLHashEntry * he, PRUintn flag);
+static void symFreeTable(void * pool, void * item);
+
+/* Table of pointers to functions associated with the hash table */
+static PLHashAllocOps SymAllocOps = {
+ symAllocTable, /* allocate the hash table */
+ symFreeTable, /* free the hash table */
+ symAllocEntry, /* allocate a table entry */
+ symFreeEntry, /* free a table entry */
+};
+
+static void * symAllocTable(void * pool, PRSize size)
+{
+ return (void *)PERM_MALLOC(size);
+}
+
+static void symFreeTable(void * pool, void * item)
+{
+ PERM_FREE(item);
+}
+
+
+
+static PLHashEntry * symAllocEntry(void * pool, const void *ignored)
+{
+ PLHashEntry * he;
+
+ he = (PLHashEntry *) PERM_MALLOC(sizeof(PLHashEntry));
+
+ return he;
+}
+
+static void symFreeEntry(void * pool, PLHashEntry * he, PRUintn flag)
+{
+ if (flag == HT_FREE_ENTRY) {
+ /* Just free the hash entry, not anything it references */
+ PERM_FREE(he);
+ }
+}
+
+
+static int symCmpName(const void * name1, const void * name2)
+{
+ Symbol_t * sym1 = (Symbol_t *)name1;
+ Symbol_t * sym2 = (Symbol_t *)name2;
+
+ return ((sym1->sym_type == sym2->sym_type) &&
+ !strcasecmp(sym1->sym_name, sym2->sym_name));
+}
+
+static int symCmpValue(const void * value1, const void * value2)
+{
+ return (value1 == value2);
+}
+
+static PLHashNumber symHash(const void * symkey)
+{
+ Symbol_t * sym = (Symbol_t *)symkey;
+ char * cp;
+ PLHashNumber h;
+
+ h = sym->sym_type;
+ cp = sym->sym_name;
+ if (cp) {
+ while (*cp) {
+ h = (h << 3) ^ tolower(*cp);
+ ++cp;
+ }
+ }
+
+ return h;
+}
+
+/* Helper function for symTableEnumerate() */
+typedef struct {
+ int (*func)(Symbol_t * sym, void * parg);
+ void * argp;
+} SymTableEnum_t;
+
+static int symTableEnumHelp(PLHashEntry * he, int n, void * step)
+{
+ SymTableEnum_t * ste = (SymTableEnum_t *)step;
+ int ret = 0;
+ int rv;
+
+ rv = (*ste->func)((Symbol_t *)(he->key), ste->argp);
+ if (rv != 0) {
+ if (rv & SYMENUMREMOVE) ret = HT_ENUMERATE_REMOVE;
+ if (rv & SYMENUMSTOP) ret |= HT_ENUMERATE_STOP;
+ }
+
+ return ret;
+}
+
+NSPR_BEGIN_EXTERN_C
+
+/*
+ * Description (symTableAddSym)
+ *
+ * This function adds a symbol definition to the symbol table.
+ * The symbol definition includes a name string, a type, and a
+ * reference to a structure.
+ *
+ * Arguments:
+ *
+ * table - handle for symbol table
+ * newsym - pointer to new symbol name and type
+ * symref - pointer to structure named by symbol
+ *
+ * Returns:
+ *
+ * If successful, the return code is zero. An error is indicated
+ * by a negative return code (SYMERRxxxx - see symbols.h).
+ */
+
+int symTableAddSym(void * table, Symbol_t * newsym, void * symref)
+{
+ SymTable_t * st = (SymTable_t *)table;
+ PLHashEntry * he;
+ PLHashEntry **hep;
+ PLHashNumber keyhash;
+ int rv = 0;
+
+ /* Compute the hash value for this symbol */
+ keyhash = symHash((const void *)newsym);
+
+ crit_enter(st->stb_crit);
+
+ /* See if another symbol already has the same name and type */
+ hep = PL_HashTableRawLookup(st->stb_ht, keyhash, (void *)newsym);
+ if (*hep == 0) {
+
+ /* Expand the hash table if necessary and allocate an entry */
+ he = PL_HashTableRawAdd(st->stb_ht,
+ hep, keyhash, (void *)newsym, symref);
+ }
+ else {
+ /* The symbol is already there. It's an error */
+ rv = SYMERRDUPSYM;
+ }
+
+ crit_exit(st->stb_crit);
+ return rv;
+}
+
+/*
+ * Description (symTableRemoveSym)
+ *
+ * This function removes an entry from a symbol table. It does
+ * not free the entry itself, just the hash entry that references
+ * it.
+ *
+ * Arguments:
+ *
+ * table - symbol table handle
+ * sym - pointer to symbol structure
+ */
+
+void symTableRemoveSym(void * table, Symbol_t * sym)
+{
+ SymTable_t * st = (SymTable_t *)table;
+
+ if (sym->sym_name != 0) {
+ crit_enter(st->stb_crit);
+ PL_HashTableRemove(st->stb_ht, (void *)sym);
+ crit_exit(st->stb_crit);
+ }
+}
+
+/*
+ * Description (symTableEnumerate)
+ *
+ * This function enumerates all of the entries in a symbol table,
+ * calling a specified function for each entry. The function
+ * specified by the caller may return flags indicating actions
+ * to be taken for each entry or whether to terminate the
+ * enumeration. These flags are defined in symbols.h as
+ * SYMENUMxxxx.
+ *
+ * Arguments:
+ *
+ * table - symbol table handle
+ * argp - argument for caller function
+ * func - function to be called for each entry
+ */
+
+void symTableEnumerate(void * table, void * argp,
+#ifdef UnixWare /* Fix bug in UnixWare compiler for name mangeling - nedh@sco.com */
+ ArgFn_symTableEnum func)
+#else
+ int (*func)(Symbol_t * sym, void * parg))
+#endif
+{
+ SymTable_t * st = (SymTable_t *)table;
+ SymTableEnum_t ste; /* enumeration arguments */
+
+ ste.func = func;
+ ste.argp = argp;
+
+ crit_enter(st->stb_crit);
+ (void)PL_HashTableEnumerateEntries(st->stb_ht,
+ symTableEnumHelp, (void *)&ste);
+ crit_exit(st->stb_crit);
+}
+
+/*
+ * Description (symTableFindSym)
+ *
+ * This function locates a symbol with a specified name and type
+ * in a given symbol table. It returns a pointer to the structure
+ * named by the symbol.
+ *
+ * Arguments:
+ *
+ * table - symbol table handle
+ * symname - symbol name string pointer
+ * symtype - symbol type code
+ * psymref - pointer to returned structure pointer
+ *
+ * Returns:
+ *
+ * If successful, the return code is zero and the structure pointer
+ * associated with the symbol name and type is returned in the
+ * location specified by 'psymref'. An error is indicated by a
+ * negative return code (SYMERRxxxx - see symbols.h).
+ */
+
+int symTableFindSym(void * table, char * symname,
+ int symtype, void **psymref)
+{
+ SymTable_t * st = (SymTable_t *)table;
+ Symbol_t sym;
+ void * symref;
+
+ /* Create temporary entry with fields needed by symHash() */
+ sym.sym_name = symname;
+ sym.sym_type = symtype;
+
+ crit_enter(st->stb_crit);
+
+ symref = PL_HashTableLookup(st->stb_ht, (void *)&sym);
+
+ crit_exit(st->stb_crit);
+
+ *psymref = symref;
+
+ return (symref) ? 0 : SYMERRNOSYM;
+}
+
+/*
+ * Description (symTableDestroy)
+ *
+ * This function destroys a symbol table created by symTableNew().
+ *
+ * Arguments:
+ *
+ * table - symbol table handle from symTableNew()
+ * flags - bit flags (unused - must be zero)
+ */
+
+void symTableDestroy(void * table, int flags)
+{
+ SymTable_t * st = (SymTable_t *)table;
+
+ if (st) {
+ if (st->stb_crit) {
+ crit_terminate(st->stb_crit);
+ }
+
+ if (st->stb_ht) {
+ PL_HashTableDestroy(st->stb_ht);
+ }
+
+ PERM_FREE(st);
+ }
+}
+
+/*
+ * Description (symTableNew)
+ *
+ * This function creates a new symbol table, and returns a handle
+ * for it.
+ *
+ * Arguments:
+ *
+ * ptable - pointer to returned symbol table handle
+ *
+ * Returns:
+ *
+ * If successful, the return code is zero and a handle for the new
+ * symbol table is returned in the location specified by 'ptable'.
+ * An error is indicated by a negative return code (SYMERRxxxx
+ * - see symbols.h).
+ */
+
+int symTableNew(void **ptable)
+{
+ SymTable_t * st;
+
+ /* Allocate the symbol table object */
+ st = (SymTable_t *)PERM_MALLOC(sizeof(SymTable_t));
+ if (st == 0) goto err_nomem;
+
+ /* Get a monitor for it */
+ st->stb_crit = crit_init();
+
+ st->stb_ht = PL_NewHashTable(0, symHash, symCmpName, symCmpValue,
+ &SymAllocOps, 0);
+ if (st->stb_ht == 0) goto err_nomem;
+
+ *ptable = st;
+ return 0;
+
+ err_nomem:
+ if (st) {
+ symTableDestroy(st, 0);
+ }
+ return SYMERRNOMEM;
+}
+
+NSPR_END_EXTERN_C
+