atom.c revision fa2b3b63
1fa2b3b63Smrg/* 2fa2b3b63Smrg 3fa2b3b63SmrgCopyright 1990, 1994, 1998 The Open Group 4fa2b3b63Smrg 5fa2b3b63SmrgPermission to use, copy, modify, distribute, and sell this software and its 6fa2b3b63Smrgdocumentation for any purpose is hereby granted without fee, provided that 7fa2b3b63Smrgthe above copyright notice appear in all copies and that both that 8fa2b3b63Smrgcopyright notice and this permission notice appear in supporting 9fa2b3b63Smrgdocumentation. 10fa2b3b63Smrg 11fa2b3b63SmrgThe above copyright notice and this permission notice shall be included in 12fa2b3b63Smrgall copies or substantial portions of the Software. 13fa2b3b63Smrg 14fa2b3b63SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15fa2b3b63SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16fa2b3b63SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17fa2b3b63SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18fa2b3b63SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19fa2b3b63SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20fa2b3b63Smrg 21fa2b3b63SmrgExcept as contained in this notice, the name of The Open Group shall not be 22fa2b3b63Smrgused in advertising or otherwise to promote the sale, use or other dealings 23fa2b3b63Smrgin this Software without prior written authorization from The Open Group. 24fa2b3b63Smrg 25fa2b3b63Smrg*/ 26fa2b3b63Smrg 27fa2b3b63Smrg/* 28fa2b3b63Smrg * Author: Keith Packard, MIT X Consortium 29fa2b3b63Smrg */ 30fa2b3b63Smrg 31fa2b3b63Smrg/* lame atom replacement routines for font applications */ 32fa2b3b63Smrg 33fa2b3b63Smrg#ifdef HAVE_CONFIG_H 34fa2b3b63Smrg#include <config.h> 35fa2b3b63Smrg#endif 36fa2b3b63Smrg#include "fontmisc.h" 37fa2b3b63Smrg#include "stubs.h" 38fa2b3b63Smrg 39fa2b3b63Smrgtypedef struct _AtomList { 40fa2b3b63Smrg char *name; 41fa2b3b63Smrg int len; 42fa2b3b63Smrg int hash; 43fa2b3b63Smrg Atom atom; 44fa2b3b63Smrg} AtomListRec, *AtomListPtr; 45fa2b3b63Smrg 46fa2b3b63Smrgstatic AtomListPtr *hashTable; 47fa2b3b63Smrg 48fa2b3b63Smrgstatic int hashSize, hashUsed; 49fa2b3b63Smrgstatic int hashMask; 50fa2b3b63Smrgstatic int rehash; 51fa2b3b63Smrg 52fa2b3b63Smrgstatic AtomListPtr *reverseMap; 53fa2b3b63Smrgstatic int reverseMapSize; 54fa2b3b63Smrgstatic Atom lastAtom; 55fa2b3b63Smrg 56fa2b3b63Smrgstatic int 57fa2b3b63SmrgHash(const char *string, int len) 58fa2b3b63Smrg{ 59fa2b3b63Smrg int h; 60fa2b3b63Smrg 61fa2b3b63Smrg h = 0; 62fa2b3b63Smrg while (len--) 63fa2b3b63Smrg h = (h << 3) ^ *string++; 64fa2b3b63Smrg if (h < 0) 65fa2b3b63Smrg return -h; 66fa2b3b63Smrg return h; 67fa2b3b63Smrg} 68fa2b3b63Smrg 69fa2b3b63Smrgstatic int 70fa2b3b63SmrgResizeHashTable (void) 71fa2b3b63Smrg{ 72fa2b3b63Smrg int newHashSize; 73fa2b3b63Smrg int newHashMask; 74fa2b3b63Smrg AtomListPtr *newHashTable; 75fa2b3b63Smrg int i; 76fa2b3b63Smrg int h; 77fa2b3b63Smrg int newRehash; 78fa2b3b63Smrg int r; 79fa2b3b63Smrg 80fa2b3b63Smrg if (hashSize == 0) 81fa2b3b63Smrg newHashSize = 1024; 82fa2b3b63Smrg else 83fa2b3b63Smrg newHashSize = hashSize * 2; 84fa2b3b63Smrg newHashTable = calloc (newHashSize, sizeof (AtomListPtr)); 85fa2b3b63Smrg if (!newHashTable) { 86fa2b3b63Smrg fprintf(stderr, "ResizeHashTable(): Error: Couldn't allocate" 87fa2b3b63Smrg " newHashTable (%ld)\n", 88fa2b3b63Smrg newHashSize * (unsigned long)sizeof (AtomListPtr)); 89fa2b3b63Smrg return FALSE; 90fa2b3b63Smrg } 91fa2b3b63Smrg newHashMask = newHashSize - 1; 92fa2b3b63Smrg newRehash = (newHashMask - 2); 93fa2b3b63Smrg for (i = 0; i < hashSize; i++) 94fa2b3b63Smrg { 95fa2b3b63Smrg if (hashTable[i]) 96fa2b3b63Smrg { 97fa2b3b63Smrg h = (hashTable[i]->hash) & newHashMask; 98fa2b3b63Smrg if (newHashTable[h]) 99fa2b3b63Smrg { 100fa2b3b63Smrg r = hashTable[i]->hash % newRehash | 1; 101fa2b3b63Smrg do { 102fa2b3b63Smrg h += r; 103fa2b3b63Smrg if (h >= newHashSize) 104fa2b3b63Smrg h -= newHashSize; 105fa2b3b63Smrg } while (newHashTable[h]); 106fa2b3b63Smrg } 107fa2b3b63Smrg newHashTable[h] = hashTable[i]; 108fa2b3b63Smrg } 109fa2b3b63Smrg } 110fa2b3b63Smrg free (hashTable); 111fa2b3b63Smrg hashTable = newHashTable; 112fa2b3b63Smrg hashSize = newHashSize; 113fa2b3b63Smrg hashMask = newHashMask; 114fa2b3b63Smrg rehash = newRehash; 115fa2b3b63Smrg return TRUE; 116fa2b3b63Smrg} 117fa2b3b63Smrg 118fa2b3b63Smrgstatic int 119fa2b3b63SmrgResizeReverseMap (void) 120fa2b3b63Smrg{ 121fa2b3b63Smrg AtomListPtr *newMap; 122fa2b3b63Smrg int newMapSize; 123fa2b3b63Smrg 124fa2b3b63Smrg if (reverseMapSize == 0) 125fa2b3b63Smrg newMapSize = 1000; 126fa2b3b63Smrg else 127fa2b3b63Smrg newMapSize = reverseMapSize * 2; 128fa2b3b63Smrg newMap = realloc (reverseMap, newMapSize * sizeof (AtomListPtr)); 129fa2b3b63Smrg if (newMap == NULL) { 130fa2b3b63Smrg fprintf(stderr, "ResizeReverseMap(): Error: Couldn't reallocate" 131fa2b3b63Smrg " reverseMap (%ld)\n", 132fa2b3b63Smrg newMapSize * (unsigned long)sizeof(AtomListPtr)); 133fa2b3b63Smrg return FALSE; 134fa2b3b63Smrg } 135fa2b3b63Smrg reverseMap = newMap; 136fa2b3b63Smrg reverseMapSize = newMapSize; 137fa2b3b63Smrg return TRUE; 138fa2b3b63Smrg} 139fa2b3b63Smrg 140fa2b3b63Smrgstatic int 141fa2b3b63SmrgNameEqual (const char *a, const char *b, int l) 142fa2b3b63Smrg{ 143fa2b3b63Smrg while (l--) 144fa2b3b63Smrg if (*a++ != *b++) 145fa2b3b63Smrg return FALSE; 146fa2b3b63Smrg return TRUE; 147fa2b3b63Smrg} 148fa2b3b63Smrg 149fa2b3b63Smrg#ifdef __SUNPRO_C 150fa2b3b63Smrg#pragma weak MakeAtom 151fa2b3b63Smrg#endif 152fa2b3b63Smrg 153fa2b3b63Smrgweak Atom 154fa2b3b63SmrgMakeAtom(const char *string, unsigned len, int makeit) 155fa2b3b63Smrg{ 156fa2b3b63Smrg AtomListPtr a; 157fa2b3b63Smrg int hash; 158fa2b3b63Smrg int h = 0; 159fa2b3b63Smrg int r; 160fa2b3b63Smrg 161fa2b3b63Smrg OVERRIDE_SYMBOL(MakeAtom, string, len, makeit); 162fa2b3b63Smrg 163fa2b3b63Smrg hash = Hash (string, len); 164fa2b3b63Smrg if (hashTable) 165fa2b3b63Smrg { 166fa2b3b63Smrg h = hash & hashMask; 167fa2b3b63Smrg if (hashTable[h]) 168fa2b3b63Smrg { 169fa2b3b63Smrg if (hashTable[h]->hash == hash && hashTable[h]->len == len && 170fa2b3b63Smrg NameEqual (hashTable[h]->name, string, len)) 171fa2b3b63Smrg { 172fa2b3b63Smrg return hashTable[h]->atom; 173fa2b3b63Smrg } 174fa2b3b63Smrg r = (hash % rehash) | 1; 175fa2b3b63Smrg for (;;) 176fa2b3b63Smrg { 177fa2b3b63Smrg h += r; 178fa2b3b63Smrg if (h >= hashSize) 179fa2b3b63Smrg h -= hashSize; 180fa2b3b63Smrg if (!hashTable[h]) 181fa2b3b63Smrg break; 182fa2b3b63Smrg if (hashTable[h]->hash == hash && hashTable[h]->len == len && 183fa2b3b63Smrg NameEqual (hashTable[h]->name, string, len)) 184fa2b3b63Smrg { 185fa2b3b63Smrg return hashTable[h]->atom; 186fa2b3b63Smrg } 187fa2b3b63Smrg } 188fa2b3b63Smrg } 189fa2b3b63Smrg } 190fa2b3b63Smrg if (!makeit) 191fa2b3b63Smrg return None; 192fa2b3b63Smrg a = malloc (sizeof (AtomListRec) + len + 1); 193fa2b3b63Smrg if (a == NULL) { 194fa2b3b63Smrg fprintf(stderr, "MakeAtom(): Error: Couldn't allocate AtomListRec" 195fa2b3b63Smrg " (%ld)\n", (unsigned long)sizeof (AtomListRec) + len + 1); 196fa2b3b63Smrg return None; 197fa2b3b63Smrg } 198fa2b3b63Smrg a->name = (char *) (a + 1); 199fa2b3b63Smrg a->len = len; 200fa2b3b63Smrg strncpy (a->name, string, len); 201fa2b3b63Smrg a->name[len] = '\0'; 202fa2b3b63Smrg a->atom = ++lastAtom; 203fa2b3b63Smrg a->hash = hash; 204fa2b3b63Smrg if (hashUsed >= hashSize / 2) 205fa2b3b63Smrg { 206fa2b3b63Smrg ResizeHashTable (); 207fa2b3b63Smrg h = hash & hashMask; 208fa2b3b63Smrg if (hashTable[h]) 209fa2b3b63Smrg { 210fa2b3b63Smrg r = (hash % rehash) | 1; 211fa2b3b63Smrg do { 212fa2b3b63Smrg h += r; 213fa2b3b63Smrg if (h >= hashSize) 214fa2b3b63Smrg h -= hashSize; 215fa2b3b63Smrg } while (hashTable[h]); 216fa2b3b63Smrg } 217fa2b3b63Smrg } 218fa2b3b63Smrg hashTable[h] = a; 219fa2b3b63Smrg hashUsed++; 220fa2b3b63Smrg if (reverseMapSize <= a->atom) { 221fa2b3b63Smrg if (!ResizeReverseMap()) 222fa2b3b63Smrg return None; 223fa2b3b63Smrg } 224fa2b3b63Smrg reverseMap[a->atom] = a; 225fa2b3b63Smrg return a->atom; 226fa2b3b63Smrg} 227fa2b3b63Smrg 228fa2b3b63Smrg#ifdef __SUNPRO_C 229fa2b3b63Smrg#pragma weak ValidAtom 230fa2b3b63Smrg#endif 231fa2b3b63Smrg 232fa2b3b63Smrgweak int 233fa2b3b63SmrgValidAtom(Atom atom) 234fa2b3b63Smrg{ 235fa2b3b63Smrg OVERRIDE_SYMBOL(ValidAtom, atom); 236fa2b3b63Smrg return (atom != None) && (atom <= lastAtom); 237fa2b3b63Smrg} 238fa2b3b63Smrg 239fa2b3b63Smrg#ifdef __SUNPRO_C 240fa2b3b63Smrg#pragma weak NameForAtom 241fa2b3b63Smrg#endif 242fa2b3b63Smrg 243fa2b3b63Smrgweak char * 244fa2b3b63SmrgNameForAtom(Atom atom) 245fa2b3b63Smrg{ 246fa2b3b63Smrg OVERRIDE_SYMBOL(NameForAtom, atom); 247fa2b3b63Smrg if (atom != None && atom <= lastAtom) 248fa2b3b63Smrg return reverseMap[atom]->name; 249fa2b3b63Smrg return NULL; 250fa2b3b63Smrg} 251