atom.c revision a96d7823
150806d53Smrg/* 250806d53Smrg 350806d53Smrg Copyright 1990, 1994, 1998 The Open Group 4e9f7eabcSmrg 550806d53Smrg Permission to use, copy, modify, distribute, and sell this software and its 650806d53Smrg documentation for any purpose is hereby granted without fee, provided that 750806d53Smrg the above copyright notice appear in all copies and that both that 850806d53Smrg copyright notice and this permission notice appear in supporting 950806d53Smrg documentation. 1050806d53Smrg 1150806d53Smrg The above copyright notice and this permission notice shall be included in 1250806d53Smrg all copies or substantial portions of the Software. 1350806d53Smrg 1450806d53Smrg THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1550806d53Smrg IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1650806d53Smrg FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1750806d53Smrg OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1850806d53Smrg AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1950806d53Smrg CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2050806d53Smrg 2150806d53Smrg Except as contained in this notice, the name of The Open Group shall not be 2250806d53Smrg used in advertising or otherwise to promote the sale, use or other dealings 2350806d53Smrg in this Software without prior written authorization from The Open Group. 2450806d53Smrg 2550806d53Smrg*/ 2650806d53Smrg 2750806d53Smrg/* 2850806d53Smrg * Author: Keith Packard, MIT X Consortium 2950806d53Smrg */ 3050806d53Smrg 3150806d53Smrg/* lame atom replacement routines for font applications */ 3250806d53Smrg 3350806d53Smrg#ifdef HAVE_CONFIG_H 3450806d53Smrg#include <config.h> 3550806d53Smrg#endif 3650806d53Smrg#include "libxfontint.h" 3750806d53Smrg#include <X11/fonts/fontmisc.h> 384a8d91dcSmrg 3950806d53Smrgtypedef struct _AtomList { 4050806d53Smrg char *name; 4150806d53Smrg int len; 427965d9acSmrg int hash; 437965d9acSmrg Atom atom; 444a8d91dcSmrg} AtomListRec, *AtomListPtr; 457965d9acSmrg 467965d9acSmrgstatic AtomListPtr *hashTable; 474a8d91dcSmrg 4850806d53Smrgstatic int hashSize, hashUsed; 494a8d91dcSmrgstatic int hashMask; 5050806d53Smrgstatic int rehash; 517965d9acSmrg 524a8d91dcSmrgstatic AtomListPtr *reverseMap; 5350806d53Smrgstatic int reverseMapSize; 547965d9acSmrgstatic Atom lastAtom; 557965d9acSmrg 567965d9acSmrgstatic int 577965d9acSmrgHash(const char *string, int len) 587965d9acSmrg{ 597965d9acSmrg int h; 607965d9acSmrg 617965d9acSmrg h = 0; 627965d9acSmrg while (len--) 637965d9acSmrg h = (h << 3) ^ *string++; 647965d9acSmrg if (h < 0) 657965d9acSmrg return -h; 667965d9acSmrg return h; 677965d9acSmrg} 687965d9acSmrg 697965d9acSmrgstatic int 707965d9acSmrgResizeHashTable(void) 7150806d53Smrg{ 72e9f7eabcSmrg int newHashSize; 73e9f7eabcSmrg int newHashMask; 74e9f7eabcSmrg AtomListPtr *newHashTable; 75e9f7eabcSmrg int i; 76e9f7eabcSmrg int h; 7750806d53Smrg int newRehash; 787965d9acSmrg int r; 797965d9acSmrg 807965d9acSmrg if (hashSize == 0) 8150806d53Smrg newHashSize = 1024; 827965d9acSmrg else 837965d9acSmrg newHashSize = hashSize * 2; 8450806d53Smrg newHashTable = calloc(newHashSize, sizeof(AtomListPtr)); 8550806d53Smrg if (!newHashTable) { 8650806d53Smrg fprintf(stderr, "ResizeHashTable(): Error: Couldn't allocate" 877965d9acSmrg " newHashTable (%ld)\n", 887965d9acSmrg newHashSize * (unsigned long) sizeof(AtomListPtr)); 897965d9acSmrg return FALSE; 904a8d91dcSmrg } 9150806d53Smrg newHashMask = newHashSize - 1; 927965d9acSmrg newRehash = (newHashMask - 2); 937965d9acSmrg for (i = 0; i < hashSize; i++) { 9450806d53Smrg if (hashTable[i]) { 9550806d53Smrg h = (hashTable[i]->hash) & newHashMask; 9650806d53Smrg if (newHashTable[h]) { 9750806d53Smrg r = hashTable[i]->hash % newRehash | 1; 9850806d53Smrg do { 9950806d53Smrg h += r; 10050806d53Smrg if (h >= newHashSize) 10150806d53Smrg h -= newHashSize; 10250806d53Smrg } while (newHashTable[h]); 1037965d9acSmrg } 1047965d9acSmrg newHashTable[h] = hashTable[i]; 1057965d9acSmrg } 1067965d9acSmrg } 107e9f7eabcSmrg free(hashTable); 1087965d9acSmrg hashTable = newHashTable; 1097965d9acSmrg hashSize = newHashSize; 1107965d9acSmrg hashMask = newHashMask; 1117965d9acSmrg rehash = newRehash; 112e9f7eabcSmrg return TRUE; 1137965d9acSmrg} 114e9f7eabcSmrg 1157965d9acSmrgstatic int 1167965d9acSmrgResizeReverseMap(void) 11750806d53Smrg{ 11850806d53Smrg AtomListPtr *newMap; 1197965d9acSmrg int newMapSize; 1207965d9acSmrg 121e9f7eabcSmrg if (reverseMapSize == 0) 122e9f7eabcSmrg newMapSize = 1000; 123e9f7eabcSmrg else 124e9f7eabcSmrg newMapSize = reverseMapSize * 2; 125e9f7eabcSmrg newMap = realloc(reverseMap, newMapSize * sizeof(AtomListPtr)); 126e9f7eabcSmrg if (newMap == NULL) { 127e9f7eabcSmrg fprintf(stderr, "ResizeReverseMap(): Error: Couldn't reallocate" 128e9f7eabcSmrg " reverseMap (%ld)\n", 12950806d53Smrg newMapSize * (unsigned long) sizeof(AtomListPtr)); 13050806d53Smrg return FALSE; 1317965d9acSmrg } 13250806d53Smrg reverseMap = newMap; 1337965d9acSmrg reverseMapSize = newMapSize; 1347965d9acSmrg return TRUE; 1357965d9acSmrg} 13650806d53Smrg 1377965d9acSmrgstatic int 13850806d53SmrgNameEqual(const char *a, const char *b, int l) 13950806d53Smrg{ 1404a8d91dcSmrg while (l--) 14150806d53Smrg if (*a++ != *b++) 14250806d53Smrg return FALSE; 14350806d53Smrg return TRUE; 1447965d9acSmrg} 1454a8d91dcSmrg 1464a8d91dcSmrgAtom 1474a8d91dcSmrg__libxfont_internal__MakeAtom(const char *string, unsigned len, int makeit) 1484a8d91dcSmrg{ 1494a8d91dcSmrg AtomListPtr a; 1504a8d91dcSmrg int hash; 15150806d53Smrg int h = 0; 15250806d53Smrg int r; 1534a8d91dcSmrg 15450806d53Smrg hash = Hash(string, len); 155e9f7eabcSmrg if (hashTable) { 156e9f7eabcSmrg h = hash & hashMask; 1577965d9acSmrg if (hashTable[h]) { 15850806d53Smrg if (hashTable[h]->hash == hash && hashTable[h]->len == len && 159e9f7eabcSmrg NameEqual(hashTable[h]->name, string, len)) { 160e9f7eabcSmrg return hashTable[h]->atom; 161e9f7eabcSmrg } 1624a8d91dcSmrg r = (hash % rehash) | 1; 1634a8d91dcSmrg for (;;) { 1644a8d91dcSmrg h += r; 1654a8d91dcSmrg if (h >= hashSize) 1664a8d91dcSmrg h -= hashSize; 1674a8d91dcSmrg if (!hashTable[h]) 1684a8d91dcSmrg break; 1694a8d91dcSmrg if (hashTable[h]->hash == hash && hashTable[h]->len == len && 17050806d53Smrg NameEqual(hashTable[h]->name, string, len)) { 1714a8d91dcSmrg return hashTable[h]->atom; 17250806d53Smrg } 17350806d53Smrg } 17450806d53Smrg } 1754a8d91dcSmrg } 1764a8d91dcSmrg if (!makeit) 1777965d9acSmrg return None; 1784a8d91dcSmrg a = malloc(sizeof(AtomListRec) + len + 1); 1794a8d91dcSmrg if (a == NULL) { 1807965d9acSmrg fprintf(stderr, "MakeAtom(): Error: Couldn't allocate AtomListRec" 1817965d9acSmrg " (%ld)\n", (unsigned long) sizeof(AtomListRec) + len + 1); 18250806d53Smrg return None; 1837965d9acSmrg } 18450806d53Smrg a->name = (char *) (a + 1); 18550806d53Smrg a->len = len; 1864a8d91dcSmrg strncpy(a->name, string, len); 1874a8d91dcSmrg a->name[len] = '\0'; 1884a8d91dcSmrg a->atom = ++lastAtom; 1894a8d91dcSmrg a->hash = hash; 1904a8d91dcSmrg if (hashUsed >= hashSize / 2) { 1914a8d91dcSmrg ResizeHashTable(); 1924a8d91dcSmrg h = hash & hashMask; 1934a8d91dcSmrg if (hashTable[h]) { 1944a8d91dcSmrg r = (hash % rehash) | 1; 1954a8d91dcSmrg do { 1967965d9acSmrg h += r; 1977965d9acSmrg if (h >= hashSize) 1987965d9acSmrg h -= hashSize; 1997965d9acSmrg } while (hashTable[h]); 2007965d9acSmrg } 2017965d9acSmrg } 2027965d9acSmrg hashTable[h] = a; 2037965d9acSmrg hashUsed++; 2047965d9acSmrg if (reverseMapSize <= a->atom) { 2057965d9acSmrg if (!ResizeReverseMap()) 2067965d9acSmrg return None; 2077965d9acSmrg } 2087965d9acSmrg reverseMap[a->atom] = a; 2094a8d91dcSmrg return a->atom; 210a73423d7Smrg} 211a73423d7Smrg 212a73423d7Smrgint 2137965d9acSmrg__libxfont_internal__ValidAtom(Atom atom) 2147965d9acSmrg{ 2157965d9acSmrg return (atom != None) && (atom <= lastAtom); 2167965d9acSmrg} 21750806d53Smrg 21850806d53Smrgconst char * 21950806d53Smrg__libxfont_internal__NameForAtom(Atom atom) 22050806d53Smrg{ 2214a8d91dcSmrg if (atom != None && atom <= lastAtom) 22250806d53Smrg return reverseMap[atom]->name; 22350806d53Smrg return NULL; 22450806d53Smrg} 22550806d53Smrg