Back to index

glibc  2.9
weight.h
Go to the documentation of this file.
00001 /* Copyright (C) 1996,1997,1998,1999,2000,2003,2004 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 unsigned char **cpp)
00024 {
00025   int_fast32_t i = table[*(*cpp)++];
00026   const unsigned char *cp;
00027   const unsigned char *usrc;
00028 
00029   if (i >= 0)
00030     /* This is an index into the weight table.  Cool.  */
00031     return i;
00032 
00033   /* Oh well, more than one sequence starting with this byte.
00034      Search for the correct one.  */
00035   cp = &extra[-i];
00036   usrc = *cpp;
00037   while (1)
00038     {
00039       size_t nhere;
00040 
00041       /* The first thing is the index.  */
00042       i = *((const int32_t *) cp);
00043       cp += sizeof (int32_t);
00044 
00045       /* Next is the length of the byte sequence.  These are always
00046         short byte sequences so there is no reason to call any
00047         function (even if they are inlined).  */
00048       nhere = *cp++;
00049 
00050       if (i >= 0)
00051        {
00052          /* It is a single character.  If it matches we found our
00053             index.  Note that at the end of each list there is an
00054             entry of length zero which represents the single byte
00055             sequence.  The first (and here only) byte was tested
00056             already.  */
00057          size_t cnt;
00058 
00059          for (cnt = 0; cnt < nhere; ++cnt)
00060            if (cp[cnt] != usrc[cnt])
00061              break;
00062 
00063          if (cnt == nhere)
00064            {
00065              /* Found it.  */
00066              *cpp += nhere;
00067              return i;
00068            }
00069 
00070          /* Up to the next entry.  */
00071          cp += nhere;
00072          if ((1 + nhere) % __alignof__ (int32_t) != 0)
00073            cp += __alignof__ (int32_t) - (1 + nhere) % __alignof__ (int32_t);
00074        }
00075       else
00076        {
00077          /* This is a range of characters.  First decide whether the
00078             current byte sequence lies in the range.  */
00079          size_t cnt;
00080          size_t offset = 0;
00081 
00082          for (cnt = 0; cnt < nhere; ++cnt)
00083            if (cp[cnt] != usrc[cnt])
00084              break;
00085 
00086          if (cnt != nhere)
00087            {
00088              if (cp[cnt] > usrc[cnt])
00089               {
00090                 /* Cannot be in this range.  */
00091                 cp += 2 * nhere;
00092                 if ((1 + 2 * nhere) % __alignof__ (int32_t) != 0)
00093                   cp += (__alignof__ (int32_t)
00094                         - (1 + 2 * nhere) % __alignof__ (int32_t));
00095                 continue;
00096               }
00097 
00098              /* Test against the end of the range.  */
00099              for (cnt = 0; cnt < nhere; ++cnt)
00100               if (cp[nhere + cnt] != usrc[cnt])
00101                 break;
00102 
00103              if (cnt != nhere && cp[nhere + cnt] < usrc[cnt])
00104               {
00105                 /* Cannot be in this range.  */
00106                 cp += 2 * nhere;
00107                 if ((1 + 2 * nhere) % __alignof__ (int32_t) != 0)
00108                   cp += (__alignof__ (int32_t)
00109                         - (1 + 2 * nhere) % __alignof__ (int32_t));
00110                 continue;
00111               }
00112 
00113              /* This range matches the next characters.  Now find
00114                the offset in the indirect table.  */
00115              for (cnt = 0; cp[cnt] == usrc[cnt]; ++cnt);
00116 
00117              do
00118               {
00119                 offset <<= 8;
00120                 offset += usrc[cnt] - cp[cnt];
00121               }
00122              while (++cnt < nhere);
00123            }
00124 
00125          *cpp += nhere;
00126          return indirect[-i + offset];
00127        }
00128     }
00129 
00130   /* NOTREACHED */
00131   return 0x43219876;
00132 }