Back to index

glibc  2.9
weightwc.h
Go to the documentation of this file.
00001 /* Copyright (C) 1996-2001,2003,2004,2005,2007 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Written by Ulrich Drepper, <drepper@cygnus.com>.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 /* Find index of weight.  */
00021 auto inline int32_t
00022 __attribute ((always_inline))
00023 findidx (const wint_t **cpp)
00024 {
00025   wint_t ch = *(*cpp)++;
00026   int32_t i = __collidx_table_lookup ((const char *) table, ch);
00027 
00028   if (i >= 0)
00029     /* This is an index into the weight table.  Cool.  */
00030     return i;
00031 
00032   /* Oh well, more than one sequence starting with this byte.
00033      Search for the correct one.  */
00034   const int32_t *cp = (const int32_t *) &extra[-i];
00035   while (1)
00036     {
00037       size_t nhere;
00038       const int32_t *usrc = (const int32_t *) *cpp;
00039 
00040       /* The first thing is the index.  */
00041       i = *cp++;
00042 
00043       /* Next is the length of the byte sequence.  These are always
00044         short byte sequences so there is no reason to call any
00045         function (even if they are inlined).  */
00046       nhere = *cp++;
00047 
00048       if (i >= 0)
00049        {
00050          /* It is a single character.  If it matches we found our
00051             index.  Note that at the end of each list there is an
00052             entry of length zero which represents the single byte
00053             sequence.  The first (and here only) byte was tested
00054             already.  */
00055          size_t cnt;
00056 
00057          for (cnt = 0; cnt < nhere; ++cnt)
00058            if (cp[cnt] != usrc[cnt])
00059              break;
00060 
00061          if (cnt == nhere)
00062            {
00063              /* Found it.  */
00064              *cpp += nhere;
00065              return i;
00066            }
00067 
00068          /* Up to the next entry.  */
00069          cp += nhere;
00070        }
00071       else
00072        {
00073          /* This is a range of characters.  First decide whether the
00074             current byte sequence lies in the range.  */
00075          size_t cnt;
00076          size_t offset;
00077 
00078          for (cnt = 0; cnt < nhere - 1; ++cnt)
00079            if (cp[cnt] != usrc[cnt])
00080              break;
00081 
00082          if (cnt < nhere - 1)
00083            {
00084              cp += 2 * nhere;
00085              continue;
00086            }
00087 
00088          if (cp[nhere - 1] > usrc[nhere -1])
00089            {
00090              cp += 2 * nhere;
00091              continue;
00092            }
00093 
00094          if (cp[2 * nhere - 1] < usrc[nhere -1])
00095            {
00096              cp += 2 * nhere;
00097              continue;
00098            }
00099 
00100          /* This range matches the next characters.  Now find
00101             the offset in the indirect table.  */
00102          offset = usrc[nhere - 1] - cp[nhere - 1];
00103          *cpp += nhere;
00104 
00105          return indirect[-i + offset];
00106        }
00107     }
00108 
00109   /* NOTREACHED */
00110   return 0x43219876;
00111 }