1 /* Copyright (C) 2000 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 Contributed by Bruno Haible <haible@clisp.cons.org>, 2000. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, write to the Free 17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 02111-1307 USA. */ 19 20 /* Word tables are accessed by cutting wc in three blocks of bits: 21 - the high 32-q-p bits, 22 - the next q bits, 23 - the next p bits. 24 25 +------------------+-----+-----+ 26 wc = + 32-q-p | q | p | 27 +------------------+-----+-----+ 28 29 p and q are variable. For 16-bit Unicode it is sufficient to 30 choose p and q such that q+p <= 16. 31 32 The table contains the following uint32_t words: 33 - q+p, 34 - s = upper exclusive bound for wc >> (q+p), 35 - p, 36 - 2^q-1, 37 - 2^p-1, 38 - 1st-level table: s offsets, pointing into the 2nd-level table, 39 - 2nd-level table: k*2^q offsets, pointing into the 3rd-level table, 40 - 3rd-level table: j*2^p words, each containing 32 bits of data. 41 */ 42 43 #include <stdint.h> 44 45 /* Lookup in a table of int32_t, with default value 0. */ 46 static inline int32_t 47 collidx_table_lookup (const char *table, uint32_t wc) 48 { 49 uint32_t shift1 = ((const uint32_t *) table)[0]; 50 uint32_t index1 = wc >> shift1; 51 uint32_t bound = ((const uint32_t *) table)[1]; 52 if (index1 < bound) 53 { 54 uint32_t lookup1 = ((const uint32_t *) table)[5 + index1]; 55 if (lookup1 != 0) 56 { 57 uint32_t shift2 = ((const uint32_t *) table)[2]; 58 uint32_t mask2 = ((const uint32_t *) table)[3]; 59 uint32_t index2 = (wc >> shift2) & mask2; 60 uint32_t lookup2 = ((const uint32_t *)(table + lookup1))[index2]; 61 if (lookup2 != 0) 62 { 63 uint32_t mask3 = ((const uint32_t *) table)[4]; 64 uint32_t index3 = wc & mask3; 65 int32_t lookup3 = ((const int32_t *)(table + lookup2))[index3]; 66 67 return lookup3; 68 } 69 } 70 } 71 return 0; 72 } 73 74 /* Lookup in a table of uint32_t, with default value 0xffffffff. */ 75 static inline uint32_t 76 collseq_table_lookup (const char *table, uint32_t wc) 77 { 78 uint32_t shift1 = ((const uint32_t *) table)[0]; 79 uint32_t index1 = wc >> shift1; 80 uint32_t bound = ((const uint32_t *) table)[1]; 81 if (index1 < bound) 82 { 83 uint32_t lookup1 = ((const uint32_t *) table)[5 + index1]; 84 if (lookup1 != 0) 85 { 86 uint32_t shift2 = ((const uint32_t *) table)[2]; 87 uint32_t mask2 = ((const uint32_t *) table)[3]; 88 uint32_t index2 = (wc >> shift2) & mask2; 89 uint32_t lookup2 = ((const uint32_t *)(table + lookup1))[index2]; 90 if (lookup2 != 0) 91 { 92 uint32_t mask3 = ((const uint32_t *) table)[4]; 93 uint32_t index3 = wc & mask3; 94 uint32_t lookup3 = ((const uint32_t *)(table + lookup2))[index3]; 95 96 return lookup3; 97 } 98 } 99 } 100 return ~((uint32_t) 0); 101 } 102