diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:40 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:40 +0000 |
commit | 153e8da44452905ae04a0e20ad0d85f40399b4ca (patch) | |
tree | b4e614de58d4b596dab3dcc7fd4054ec96db592a /src/util/atom.c |
R6.6 is the Xorg base-lineXORG-MAIN
Diffstat (limited to 'src/util/atom.c')
-rw-r--r-- | src/util/atom.c | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/src/util/atom.c b/src/util/atom.c new file mode 100644 index 0000000..140d774 --- /dev/null +++ b/src/util/atom.c @@ -0,0 +1,230 @@ +/* $Xorg: atom.c,v 1.5 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1994, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +/* lame atom replacement routines for font applications */ + +#include "fontmisc.h" + +typedef struct _AtomList { + char *name; + int len; + int hash; + Atom atom; +} AtomListRec, *AtomListPtr; + +static AtomListPtr *hashTable; + +static int hashSize, hashUsed; +static int hashMask; +static int rehash; + +static AtomListPtr *reverseMap; +static int reverseMapSize; +static Atom lastAtom; + +static int +Hash(string, len) + char *string; +{ + int h; + + h = 0; + while (len--) + h = (h << 3) ^ *string++; + if (h < 0) + return -h; + return h; +} + +static int +ResizeHashTable () +{ + int newHashSize; + int newHashMask; + AtomListPtr *newHashTable; + int i; + int h; + int newRehash; + int r; + + if (hashSize == 0) + newHashSize = 1024; + else + newHashSize = hashSize * 2; + newHashTable = (AtomListPtr *) xalloc (newHashSize * sizeof (AtomListPtr)); + if (!newHashTable) { + fprintf(stderr, "ResizeHashTable(): Error: Couldn't allocate newHashTable (%d)\n", newHashSize * sizeof (AtomListPtr)); + return FALSE; + } + bzero ((char *) newHashTable, newHashSize * sizeof (AtomListPtr)); + newHashMask = newHashSize - 1; + newRehash = (newHashMask - 2); + for (i = 0; i < hashSize; i++) + { + if (hashTable[i]) + { + h = (hashTable[i]->hash) & newHashMask; + if (newHashTable[h]) + { + r = hashTable[i]->hash % newRehash | 1; + do { + h += r; + if (h >= newHashSize) + h -= newHashSize; + } while (newHashTable[h]); + } + newHashTable[h] = hashTable[i]; + } + } + xfree (hashTable); + hashTable = newHashTable; + hashSize = newHashSize; + hashMask = newHashMask; + rehash = newRehash; + return TRUE; +} + +static int +ResizeReverseMap () +{ + int ret = TRUE; + if (reverseMapSize == 0) + reverseMapSize = 1000; + else + reverseMapSize *= 2; + reverseMap = (AtomListPtr *) xrealloc (reverseMap, reverseMapSize * sizeof (AtomListPtr)); + if (!reverseMap) { + fprintf(stderr, "ResizeReverseMap(): Error: Couldn't reallocate reverseMap (%d)\n", reverseMapSize * sizeof(AtomListPtr)); + ret = FALSE; + } + return ret; +} + +static int +NameEqual (a, b, l) + char *a, *b; +{ + while (l--) + if (*a++ != *b++) + return FALSE; + return TRUE; +} + +Atom +MakeAtom(string, len, makeit) + char *string; + unsigned len; + int makeit; +{ + AtomListPtr a; + int hash; + int h; + int r; + + hash = Hash (string, len); + if (hashTable) + { + h = hash & hashMask; + if (hashTable[h]) + { + if (hashTable[h]->hash == hash && hashTable[h]->len == len && + NameEqual (hashTable[h]->name, string, len)) + { + return hashTable[h]->atom; + } + r = (hash % rehash) | 1; + for (;;) + { + h += r; + if (h >= hashSize) + h -= hashSize; + if (!hashTable[h]) + break; + if (hashTable[h]->hash == hash && hashTable[h]->len == len && + NameEqual (hashTable[h]->name, string, len)) + { + return hashTable[h]->atom; + } + } + } + } + if (!makeit) + return None; + a = (AtomListPtr) xalloc (sizeof (AtomListRec) + len + 1); + if (a == NULL) { + fprintf(stderr, "MakeAtom(): Error: Couldn't allocate AtomListRec (%d)\n", sizeof (AtomListRec) + len + 1); + return None; + } + a->name = (char *) (a + 1); + a->len = len; + strncpy (a->name, string, len); + a->name[len] = '\0'; + a->atom = ++lastAtom; + a->hash = hash; + if (hashUsed >= hashSize / 2) + { + ResizeHashTable (); + h = hash & hashMask; + if (hashTable[h]) + { + r = (hash % rehash) | 1; + do { + h += r; + if (h >= hashSize) + h -= hashSize; + } while (hashTable[h]); + } + } + hashTable[h] = a; + hashUsed++; + if (reverseMapSize <= a->atom) { + if (!ResizeReverseMap()) + return None; + } + reverseMap[a->atom] = a; + return a->atom; +} + +int ValidAtom(atom) + Atom atom; +{ + return (atom != None) && (atom <= lastAtom); +} + +char * +NameForAtom(atom) + Atom atom; +{ + if (atom != None && atom <= lastAtom) + return reverseMap[atom]->name; + return 0; +} |