Here is improved version of crc32() function. Features: 1) Automatic initialization of crc32tab[] at first call. So, the file crc32.h with definition of this tab is not nessesary any more now. 2) Speed is improved on large amount of data. 3) Less source size. Current verison has near 6.5Kb length (including crc32.h). My version has only 2.5Kb length.
Below I provided a test (just copy->compile->test) and unified diff of /ext/standard/crc32.c
=============cut============ #include <stdio.h>
/****************************************************/ /* test data structure */ typedef struct { char *p; /* pointer to a data */ size_t len; /* length of a data */ } my_str;
/* set of test data */ my_str s[] = { /* test strings from /ext/standard/tests/strings/crc32.phpt */ {"foo", 3}, {"bar", 3}, {"baz", 3}, {"grldsajkopallkjasd", 18}, /* my test strings */ {"", 0}, /* empty string */ {"\0", 1}, /* one null char */ {"a", 1}, /* one char */ {"ab", 2}, /* two chars */ {"a\0\0b", 4}, /* four chars */ {NULL, 0} }; /****************************************************/
/* faked PHP definitions */
#define PHP_NAMED_FUNCTION(a) void a(char *str1, size_t len1)
#define zend_parse_parameters(foo, bar, s1, len) (*(s1) = str1, *(len) = len1, 1)
#define TSRMLS_CC
#define FAILURE 0
#define RETVAL_LONG(c) do {printf("str=[%s], len=[%d], crc32(unsigned)=[%lu]\n", str1, len1, (c)); return;} while (0)
/****************************************************/
/* my crc32 function */
PHP_NAMED_FUNCTION(php_if_crc32)
{
static unsigned long int crc32tab[256], not_init = 1;
if (not_init) {
/* init crc32 table */
register unsigned long int tmp, i, j, flag_c;
for (i = 0; i < 256; i++) {
tmp = i;
j = 8;
do {
if (tmp & 1) {
tmp >>= 1;
tmp ^= 0xEDB88320; /* CRC32 (CCITT-32) poly g(x) = 1 0000 0100 1100 0001 0001 1101 1011 0111 */
} else tmp >>= 1;
j--;
} while (j);
crc32tab[i] = tmp;
}
not_init = 0;
}
/* crc32 calculations */
char *str;
int len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE || len < 0) return;
if (len == 0) RETVAL_LONG(0);
register unsigned long int crc = ~0ul;
register unsigned char *p = (unsigned char *) str;
register int n = len;
do {
crc = (crc >> 8) ^ crc32tab[(crc ^ *p++) & 0xff];
n--;
} while (n);
RETVAL_LONG(~crc);
}
/***************************************************/
int main(int argc,char *argv[]) { int i = 0; while (s[i].p != NULL) { php_if_crc32(s[i].p, s[i].len); i++; } return 0; }
=============cut============
the unified diff of crc32.c: =============cut============ --- crc32.c Tue Dec 31 19:35:26 2002 +++ crc32_new.c Sat Jun 12 19:01:56 2004 @@ -20,24 +20,41 @@
#include "php.h" #include "basic_functions.h" -#include "crc32.h"
/* {{{ proto string crc32(string str)
Calculate the crc32 polynomial of a string */
PHP_NAMED_FUNCTION(php_if_crc32)
{
- unsigned int crc = ~0;
- char *p;
- int len, nr;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &p, &nr) == FAILURE) {
- return;
+ static unsigned long int crc32tab[256], not_init = 1;
+ if (not_init) {
+ /* init crc32 table */
+ register unsigned long int tmp, i, j, flag_c;
+ for (i = 0; i < 256; i++) {
+ tmp = i;
+ j = 8;
+ do {
+ if (tmp & 1) {
+ tmp >>= 1;
+ tmp ^= 0xEDB88320; /* CRC32 (CCITT-32) poly g(x) = 1 0000 0100 1100 0001 0001 1101 1011 0111 */
+ } else tmp >>= 1;
+ j--;
+ } while (j);
+ crc32tab[i] = tmp;
}
-
- len = 0 ;
- for (len += nr; nr--; ++p) {
- CRC32(crc, *p);
+ not_init = 0;
}
+ /* crc32 calculations */
+ char *str;
+ int len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE || len < 0) return;
+ if (len == 0) RETVAL_LONG(0);
+ register unsigned long int crc = ~0ul;
+ register unsigned char *p = (unsigned char *) str;
+ register int n = len;
+ do {
+ crc = (crc >> 8) ^ crc32tab[(crc ^ *p++) & 0xff];
+ n--;
+ } while (n);
RETVAL_LONG(~crc);
}
/* }}} */
=============cut============
-- Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php