/* * Copyright (c) 1987, 1988, 1989 Stanford University * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Stanford not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Stanford makes no representations about * the suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * A catalog maps names to objects. */ #include #include Catalog::Catalog (int n) { nelements = 128; while (nelements < n) { nelements <<= 1; } first = new CatalogEntry*[nelements]; memset(first, 0, nelements * sizeof(CatalogEntry*)); --nelements; last = &first[nelements]; } Catalog::~Catalog () { register CatalogEntry** i; register CatalogEntry* e; register CatalogEntry* next; for (i = first; i <= last; i++) { for (e = *i; e != nil; e = next) { next = e->chain; delete e->name; Unref(e->obj); delete e; } } delete first; } /* * Enter a new object into a catalog. */ void Catalog::Register (const char* name, ObjectStub* s) { register unsigned h; int len; register CatalogEntry* e; h = Hash(name, len); e = new CatalogEntry; e->name = new char[len+1]; e->len = len; strcpy(e->name, name); e->obj = s; e->chain = first[h]; first[h] = e; } void Catalog::UnRegister (const char* name) { register unsigned h; int len; register CatalogEntry* e; register CatalogEntry* prev; h = Hash(name, len); e = first[h]; prev = nil; while (e != nil && (e->len != len || strcmp(e->name, name) != 0)) { prev = e; e = e->chain; } if (e != nil) { if (prev == nil) { first[h] = e->chain; } else { prev->chain = e->chain; } delete e->name; delete e; } } bool Catalog::Find (ObjectStub*& s, const char* name) { int len; register CatalogEntry* e; for (e = first[Hash(name, len)]; e != nil; e = e->chain) { if (e->len == len && strcmp(e->name, name) == 0) { s = e->obj; return true; } } return false; } /* * Return a hash value for a string name and set the length of the name * as a side effect. */ unsigned Catalog::Hash (const char *name, int& len) { register const char *c; register unsigned h; h = 0; c = name; while (*c != '\0') { h = (h << 1) ^ ((int) (*c)); ++c; } len = (c - name); return h & nelements; }