diff options
Diffstat (limited to 'data/apt7/memrchr.diff')
-rw-r--r-- | data/apt7/memrchr.diff | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/data/apt7/memrchr.diff b/data/apt7/memrchr.diff new file mode 100644 index 000000000..8913e1816 --- /dev/null +++ b/data/apt7/memrchr.diff @@ -0,0 +1,195 @@ +diff -ru apt-0.7.20.2/ftparchive/cachedb.cc apt-0.7.20.2+iPhone/ftparchive/cachedb.cc +--- apt-0.7.20.2/ftparchive/cachedb.cc 2009-02-07 15:09:35.000000000 +0000 ++++ apt-0.7.20.2+iPhone/ftparchive/cachedb.cc 2009-04-14 16:10:02.000000000 +0000 +@@ -315,6 +315,14 @@ + } + } + ++void *memrchr(void *data, char value, int size) { ++ char *cdata = (char *) data; ++ for (int i = 0; i != size; ++i) ++ if (cdata[size - i - 1] == value) ++ return cdata + size - i - 1; ++ return NULL; ++} ++ + // CacheDB::GetMD5 - Get the MD5 hash /*{{{*/ + // --------------------------------------------------------------------- + /* */ +diff -ru apt-0.7.20.2/apt-pkg/deb/dpkgpm.cc apt-0.7.20.2+iPhone/apt-pkg/deb/dpkgpm.cc +--- apt-0.7.20.2/apt-pkg/deb/dpkgpm.cc 2009-02-07 15:09:35.000000000 +0000 ++++ apt-0.7.20.2+iPhone/apt-pkg/deb/dpkgpm.cc 2009-04-15 19:25:04.000000000 +0000 +@@ -501,6 +501,7 @@ + + // now move the unprocessed bits (after the final \n that is now a 0x0) + // to the start and update dpkgbuf_pos ++ void *memrchr(void const *, int, size_t); + p = (char*)memrchr(dpkgbuf, 0, dpkgbuf_pos); + if(p == NULL) + return; +@@ -974,3 +975,165 @@ + List.erase(List.begin(),List.end()); + } + /*}}}*/ ++ ++/* memrchr -- find the last occurrence of a byte in a memory block ++ ++ Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2005, ++ 2006, 2007, 2008 Free Software Foundation, Inc. ++ ++ Based on strlen implementation by Torbjorn Granlund (tege@sics.se), ++ with help from Dan Sahlin (dan@sics.se) and ++ commentary by Jim Blandy (jimb@ai.mit.edu); ++ adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), ++ and implemented by Roland McGrath (roland@ai.mit.edu). ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see <http://www.gnu.org/licenses/>. */ ++ ++#if defined _LIBC ++# include <memcopy.h> ++#else ++# include <config.h> ++# define reg_char char ++#endif ++ ++#include <string.h> ++#include <limits.h> ++ ++#undef __memrchr ++#ifdef _LIBC ++# undef memrchr ++#endif ++ ++#ifndef weak_alias ++# define __memrchr memrchr ++#endif ++ ++/* Search no more than N bytes of S for C. */ ++void * ++__memrchr (void const *s, int c_in, size_t n) ++{ ++ /* On 32-bit hardware, choosing longword to be a 32-bit unsigned ++ long instead of a 64-bit uintmax_t tends to give better ++ performance. On 64-bit hardware, unsigned long is generally 64 ++ bits already. Change this typedef to experiment with ++ performance. */ ++ typedef unsigned long int longword; ++ ++ const unsigned char *char_ptr; ++ const longword *longword_ptr; ++ longword repeated_one; ++ longword repeated_c; ++ unsigned reg_char c; ++ ++ c = (unsigned char) c_in; ++ ++ /* Handle the last few bytes by reading one byte at a time. ++ Do this until CHAR_PTR is aligned on a longword boundary. */ ++ for (char_ptr = (const unsigned char *) s + n; ++ n > 0 && (size_t) char_ptr % sizeof (longword) != 0; ++ --n) ++ if (*--char_ptr == c) ++ return (void *) char_ptr; ++ ++ longword_ptr = (const longword *) char_ptr; ++ ++ /* All these elucidatory comments refer to 4-byte longwords, ++ but the theory applies equally well to any size longwords. */ ++ ++ /* Compute auxiliary longword values: ++ repeated_one is a value which has a 1 in every byte. ++ repeated_c has c in every byte. */ ++ repeated_one = 0x01010101; ++ repeated_c = c | (c << 8); ++ repeated_c |= repeated_c << 16; ++ if (0xffffffffU < (longword) -1) ++ { ++ repeated_one |= repeated_one << 31 << 1; ++ repeated_c |= repeated_c << 31 << 1; ++ if (8 < sizeof (longword)) ++ { ++ size_t i; ++ ++ for (i = 64; i < sizeof (longword) * 8; i *= 2) ++ { ++ repeated_one |= repeated_one << i; ++ repeated_c |= repeated_c << i; ++ } ++ } ++ } ++ ++ /* Instead of the traditional loop which tests each byte, we will test a ++ longword at a time. The tricky part is testing if *any of the four* ++ bytes in the longword in question are equal to c. We first use an xor ++ with repeated_c. This reduces the task to testing whether *any of the ++ four* bytes in longword1 is zero. ++ ++ We compute tmp = ++ ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). ++ That is, we perform the following operations: ++ 1. Subtract repeated_one. ++ 2. & ~longword1. ++ 3. & a mask consisting of 0x80 in every byte. ++ Consider what happens in each byte: ++ - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, ++ and step 3 transforms it into 0x80. A carry can also be propagated ++ to more significant bytes. ++ - If a byte of longword1 is nonzero, let its lowest 1 bit be at ++ position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, ++ the byte ends in a single bit of value 0 and k bits of value 1. ++ After step 2, the result is just k bits of value 1: 2^k - 1. After ++ step 3, the result is 0. And no carry is produced. ++ So, if longword1 has only non-zero bytes, tmp is zero. ++ Whereas if longword1 has a zero byte, call j the position of the least ++ significant zero byte. Then the result has a zero at positions 0, ..., ++ j-1 and a 0x80 at position j. We cannot predict the result at the more ++ significant bytes (positions j+1..3), but it does not matter since we ++ already have a non-zero bit at position 8*j+7. ++ ++ So, the test whether any byte in longword1 is zero is equivalent to ++ testing whether tmp is nonzero. */ ++ ++ while (n >= sizeof (longword)) ++ { ++ longword longword1 = *--longword_ptr ^ repeated_c; ++ ++ if ((((longword1 - repeated_one) & ~longword1) ++ & (repeated_one << 7)) != 0) ++ { ++ longword_ptr++; ++ break; ++ } ++ n -= sizeof (longword); ++ } ++ ++ char_ptr = (const unsigned char *) longword_ptr; ++ ++ /* At this point, we know that either n < sizeof (longword), or one of the ++ sizeof (longword) bytes starting at char_ptr is == c. On little-endian ++ machines, we could determine the first such byte without any further ++ memory accesses, just by looking at the tmp result from the last loop ++ iteration. But this does not work on big-endian machines. Choose code ++ that works in both cases. */ ++ ++ while (n-- > 0) ++ { ++ if (*--char_ptr == c) ++ return (void *) char_ptr; ++ } ++ ++ return NULL; ++} ++#ifdef weak_alias ++weak_alias (__memrchr, memrchr) ++#endif |