Advertisement
Second_Fry

glibc strlen

Apr 19th, 2019
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.52 KB | None | 0 0
  1. /* Copyright (C) 1991-2019 Free Software Foundation, Inc.
  2.    This file is part of the GNU C Library.
  3.    Written by Torbjorn Granlund (tege@sics.se),
  4.    with help from Dan Sahlin (dan@sics.se);
  5.    commentary by Jim Blandy (jimb@ai.mit.edu).
  6.  
  7.    The GNU C Library is free software; you can redistribute it and/or
  8.    modify it under the terms of the GNU Lesser General Public
  9.    License as published by the Free Software Foundation; either
  10.    version 2.1 of the License, or (at your option) any later version.
  11.  
  12.    The GNU C Library is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.    Lesser General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU Lesser General Public
  18.    License along with the GNU C Library; if not, see
  19.    <http://www.gnu.org/licenses/>.  */
  20.  
  21. #include <string.h>
  22. #include <stdlib.h>
  23.  
  24. #undef strlen
  25.  
  26. #ifndef STRLEN
  27. # define STRLEN strlen
  28. #endif
  29.  
  30. /* Return the length of the null-terminated string STR.  Scan for
  31.    the null terminator quickly by testing four bytes at a time.  */
  32. size_t
  33. STRLEN (const char *str)
  34. {
  35.   const char *char_ptr;
  36.   const unsigned long int *longword_ptr;
  37.   unsigned long int longword, himagic, lomagic;
  38.  
  39.   /* Handle the first few characters by reading one character at a time.
  40.      Do this until CHAR_PTR is aligned on a longword boundary.  */
  41.   for (char_ptr = str; ((unsigned long int) char_ptr
  42.             & (sizeof (longword) - 1)) != 0;
  43.        ++char_ptr)
  44.     if (*char_ptr == '\0')
  45.       return char_ptr - str;
  46.  
  47.   /* All these elucidatory comments refer to 4-byte longwords,
  48.      but the theory applies equally well to 8-byte longwords.  */
  49.  
  50.   longword_ptr = (unsigned long int *) char_ptr;
  51.  
  52.   /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
  53.      the "holes."  Note that there is a hole just to the left of
  54.      each byte, with an extra at the end:
  55.  
  56.      bits:  01111110 11111110 11111110 11111111
  57.      bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
  58.  
  59.      The 1-bits make sure that carries propagate to the next 0-bit.
  60.      The 0-bits provide holes for carries to fall into.  */
  61.   himagic = 0x80808080L;
  62.   lomagic = 0x01010101L;
  63.   if (sizeof (longword) > 4)
  64.     {
  65.       /* 64-bit version of the magic.  */
  66.       /* Do the shift in two steps to avoid a warning if long has 32 bits.  */
  67.       himagic = ((himagic << 16) << 16) | himagic;
  68.       lomagic = ((lomagic << 16) << 16) | lomagic;
  69.     }
  70.   if (sizeof (longword) > 8)
  71.     abort ();
  72.  
  73.   /* Instead of the traditional loop which tests each character,
  74.      we will test a longword at a time.  The tricky part is testing
  75.      if *any of the four* bytes in the longword in question are zero.  */
  76.   for (;;)
  77.     {
  78.       longword = *longword_ptr++;
  79.  
  80.       if (((longword - lomagic) & ~longword & himagic) != 0)
  81.     {
  82.       /* Which of the bytes was the zero?  If none of them were, it was
  83.          a misfire; continue the search.  */
  84.  
  85.       const char *cp = (const char *) (longword_ptr - 1);
  86.  
  87.       if (cp[0] == 0)
  88.         return cp - str;
  89.       if (cp[1] == 0)
  90.         return cp - str + 1;
  91.       if (cp[2] == 0)
  92.         return cp - str + 2;
  93.       if (cp[3] == 0)
  94.         return cp - str + 3;
  95.       if (sizeof (longword) > 4)
  96.         {
  97.           if (cp[4] == 0)
  98.         return cp - str + 4;
  99.           if (cp[5] == 0)
  100.         return cp - str + 5;
  101.           if (cp[6] == 0)
  102.         return cp - str + 6;
  103.           if (cp[7] == 0)
  104.         return cp - str + 7;
  105.         }
  106.     }
  107.     }
  108. }
  109. libc_hidden_builtin_def (strlen)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement