atom.c revision 6a46240f
11b18d63aSmrg/* 2317c648bSmrg 3317c648bSmrg Copyright 1990, 1994, 1998 The Open Group 4317c648bSmrg 5317c648bSmrg Permission to use, copy, modify, distribute, and sell this software and its 6317c648bSmrg documentation for any purpose is hereby granted without fee, provided that 7317c648bSmrg the above copyright notice appear in all copies and that both that 8317c648bSmrg copyright notice and this permission notice appear in supporting 9317c648bSmrg documentation. 10317c648bSmrg 11317c648bSmrg The above copyright notice and this permission notice shall be included in 12317c648bSmrg all copies or substantial portions of the Software. 13317c648bSmrg 14317c648bSmrg THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15317c648bSmrg IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16317c648bSmrg FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17317c648bSmrg OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18317c648bSmrg AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19317c648bSmrg CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20317c648bSmrg 21317c648bSmrg Except as contained in this notice, the name of The Open Group shall not be 22317c648bSmrg used in advertising or otherwise to promote the sale, use or other dealings 23317c648bSmrg in this Software without prior written authorization from The Open Group. 24317c648bSmrg 25317c648bSmrg*/ 26317c648bSmrg 27317c648bSmrg/* 28317c648bSmrg * Author: Keith Packard, MIT X Consortium 29317c648bSmrg */ 30a450e446Smrg 31317c648bSmrg/* lame atom replacement routines for font applications */ 32a450e446Smrg 33317c648bSmrg#ifdef HAVE_CONFIG_H 34317c648bSmrg#include <config.h> 35317c648bSmrg#endif 36317c648bSmrg#include "libxfontint.h" 371b18d63aSmrg#include "src/util/replace.h" 381b18d63aSmrg#include <X11/fonts/fontmisc.h> 391b18d63aSmrg 401b18d63aSmrgtypedef struct _AtomList { 411b18d63aSmrg char *name; 421b18d63aSmrg int len; 431b18d63aSmrg int hash; 441b18d63aSmrg Atom atom; 451b18d63aSmrg} AtomListRec, *AtomListPtr; 461b18d63aSmrg 471b18d63aSmrgstatic AtomListPtr *hashTable; 481b18d63aSmrg 491b18d63aSmrgstatic unsigned hashSize, hashUsed; 501b18d63aSmrgstatic unsigned hashMask; 511b18d63aSmrgstatic unsigned rehash; 521b18d63aSmrg 531b18d63aSmrgstatic AtomListPtr *reverseMap; 541b18d63aSmrgstatic int reverseMapSize; 551b18d63aSmrgstatic Atom lastAtom; 561b18d63aSmrg 571b18d63aSmrgstatic unsigned 581b18d63aSmrgHash(const char *string, unsigned len) 591b18d63aSmrg{ 601b18d63aSmrg unsigned h = 0; 611b18d63aSmrg 621b18d63aSmrg while (len--) 631b18d63aSmrg h = (h << 3) ^ *string++; 641b18d63aSmrg 651b18d63aSmrg return h; 661b18d63aSmrg} 671b18d63aSmrg 681b18d63aSmrgstatic int 691b18d63aSmrgResizeHashTable(void) 701b18d63aSmrg{ 711b18d63aSmrg unsigned newHashSize; 721b18d63aSmrg unsigned newHashMask; 731b18d63aSmrg AtomListPtr *newHashTable; 741b18d63aSmrg unsigned i; 751b18d63aSmrg unsigned h; 761b18d63aSmrg unsigned newRehash; 771b18d63aSmrg unsigned r; 781b18d63aSmrg 791b18d63aSmrg if (hashSize == 0) 801b18d63aSmrg newHashSize = 1024; 811b18d63aSmrg else 821b18d63aSmrg newHashSize = hashSize * 2; 831b18d63aSmrg newHashTable = calloc(newHashSize, sizeof(AtomListPtr)); 841b18d63aSmrg if (!newHashTable) { 851b18d63aSmrg fprintf(stderr, "ResizeHashTable(): Error: Couldn't allocate" 861b18d63aSmrg " newHashTable (%ld)\n", 871b18d63aSmrg newHashSize * (unsigned long) sizeof(AtomListPtr)); 881b18d63aSmrg return FALSE; 891b18d63aSmrg } 901b18d63aSmrg newHashMask = newHashSize - 1; 911b18d63aSmrg newRehash = (newHashMask - 2); 921b18d63aSmrg for (i = 0; i < hashSize; i++) { 931b18d63aSmrg if (hashTable[i]) { 941b18d63aSmrg h = (hashTable[i]->hash) & newHashMask; 951b18d63aSmrg if (newHashTable[h]) { 961b18d63aSmrg r = hashTable[i]->hash % newRehash | 1; 971b18d63aSmrg do { 981b18d63aSmrg h += r; 99953d7d37Smrg if (h >= newHashSize) 100953d7d37Smrg h -= newHashSize; 101953d7d37Smrg } while (newHashTable[h]); 102953d7d37Smrg } 103953d7d37Smrg newHashTable[h] = hashTable[i]; 104953d7d37Smrg } 105953d7d37Smrg } 106953d7d37Smrg free(hashTable); 107953d7d37Smrg hashTable = newHashTable; 108953d7d37Smrg hashSize = newHashSize; 109953d7d37Smrg hashMask = newHashMask; 110953d7d37Smrg rehash = newRehash; 111953d7d37Smrg return TRUE; 112953d7d37Smrg} 113953d7d37Smrg 114953d7d37Smrgstatic int 115953d7d37SmrgResizeReverseMap(void) 116953d7d37Smrg{ 1171b18d63aSmrg AtomListPtr *newMap; 1181b18d63aSmrg int newMapSize; 1191b18d63aSmrg 1201b18d63aSmrg if (reverseMapSize == 0) 1211b18d63aSmrg newMapSize = 1000; 1221b18d63aSmrg else 1231b18d63aSmrg newMapSize = reverseMapSize * 2; 1241b18d63aSmrg newMap = reallocarray(reverseMap, newMapSize, sizeof(AtomListPtr)); 1251b18d63aSmrg if (newMap == NULL) { 1261b18d63aSmrg fprintf(stderr, "ResizeReverseMap(): Error: Couldn't reallocate" 1271b18d63aSmrg " reverseMap (%ld)\n", 1281b18d63aSmrg newMapSize * (unsigned long) sizeof(AtomListPtr)); 1291b18d63aSmrg return FALSE; 1301b18d63aSmrg } 1311b18d63aSmrg reverseMap = newMap; 1321b18d63aSmrg reverseMapSize = newMapSize; 1331b18d63aSmrg return TRUE; 1341b18d63aSmrg} 1351b18d63aSmrg 1361b18d63aSmrgstatic int 1371b18d63aSmrgNameEqual(const char *a, const char *b, int l) 1381b18d63aSmrg{ 1391b18d63aSmrg while (l--) 1401b18d63aSmrg if (*a++ != *b++) 1411b18d63aSmrg return FALSE; 1421b18d63aSmrg return TRUE; 1431b18d63aSmrg} 1441b18d63aSmrg 1451b18d63aSmrgAtom 1461b18d63aSmrg__libxfont_internal__MakeAtom(const char *string, unsigned len, int makeit) 147953d7d37Smrg{ 148953d7d37Smrg AtomListPtr a; 149317c648bSmrg unsigned hash; 150317c648bSmrg unsigned h = 0; 1511b18d63aSmrg unsigned r; 1521b18d63aSmrg 1531b18d63aSmrg hash = Hash(string, len); 1541b18d63aSmrg if (hashTable) { 155317c648bSmrg h = hash & hashMask; 1561b18d63aSmrg if (hashTable[h]) { 157317c648bSmrg if (hashTable[h]->hash == hash && hashTable[h]->len == len && 1581b18d63aSmrg NameEqual(hashTable[h]->name, string, len)) { 159317c648bSmrg return hashTable[h]->atom; 1601b18d63aSmrg } 161317c648bSmrg r = (hash % rehash) | 1; 1621b18d63aSmrg for (;;) { 1631b18d63aSmrg h += r; 1641b18d63aSmrg if (h >= hashSize) 1651b18d63aSmrg h -= hashSize; 1661b18d63aSmrg if (!hashTable[h]) 1671b18d63aSmrg break; 168317c648bSmrg if (hashTable[h]->hash == hash && hashTable[h]->len == len && 1691b18d63aSmrg NameEqual(hashTable[h]->name, string, len)) { 1701b18d63aSmrg return hashTable[h]->atom; 1711b18d63aSmrg } 172317c648bSmrg } 1731b18d63aSmrg } 1741b18d63aSmrg } 1751b18d63aSmrg if (!makeit) 1761b18d63aSmrg return None; 177317c648bSmrg a = malloc(sizeof(AtomListRec) + len + 1); 1781b18d63aSmrg if (a == NULL) { 1791b18d63aSmrg fprintf(stderr, "MakeAtom(): Error: Couldn't allocate AtomListRec" 180317c648bSmrg " (%ld)\n", (unsigned long) sizeof(AtomListRec) + len + 1); 1811b18d63aSmrg return None; 1821b18d63aSmrg } 1831b18d63aSmrg a->name = (char *) (a + 1); 1841b18d63aSmrg a->len = len; 185317c648bSmrg strncpy(a->name, string, len); 1861b18d63aSmrg a->name[len] = '\0'; 1871b18d63aSmrg a->atom = ++lastAtom; 1881b18d63aSmrg a->hash = hash; 1891b18d63aSmrg if (hashUsed >= hashSize / 2) { 190317c648bSmrg if ((ResizeHashTable() == FALSE) && 1911b18d63aSmrg ((hashTable == NULL) || (hashUsed == hashSize))) { 192317c648bSmrg free(a); 1931b18d63aSmrg return None; 194317c648bSmrg } 1951b18d63aSmrg h = hash & hashMask; 196317c648bSmrg if (hashTable[h]) { 1971b18d63aSmrg r = (hash % rehash) | 1; 198317c648bSmrg do { 1991b18d63aSmrg h += r; 200317c648bSmrg if (h >= hashSize) 2011b18d63aSmrg h -= hashSize; 202317c648bSmrg } while (hashTable[h]); 2031b18d63aSmrg } 204317c648bSmrg } 2051b18d63aSmrg hashTable[h] = a; 2061b18d63aSmrg hashUsed++; 207317c648bSmrg if (reverseMapSize <= a->atom) { 2081b18d63aSmrg if (!ResizeReverseMap()) 2091b18d63aSmrg return None; 210317c648bSmrg } 2111b18d63aSmrg reverseMap[a->atom] = a; 2121b18d63aSmrg return a->atom; 2131b18d63aSmrg} 2141b18d63aSmrg 2151b18d63aSmrgint 2161b18d63aSmrg__libxfont_internal__ValidAtom(Atom atom) 217317c648bSmrg{ 2181b18d63aSmrg return (atom != None) && (atom <= lastAtom); 219317c648bSmrg} 2201b18d63aSmrg 2211b18d63aSmrgconst char * 2221b18d63aSmrg__libxfont_internal__NameForAtom(Atom atom) 223317c648bSmrg{ 2241b18d63aSmrg if (atom != None && atom <= lastAtom) 2251b18d63aSmrg return reverseMap[atom]->name; 226317c648bSmrg return NULL; 2271b18d63aSmrg} 2281b18d63aSmrg