Blame CRC32.xs

Packit Service a275fa
/*
Packit Service a275fa
 Perl Extension for 32bit CRC computations
Packit Service a275fa
 by Soenke J. Peters
Packit Service a275fa
*/
Packit Service a275fa
Packit Service a275fa
#include "EXTERN.h"
Packit Service a275fa
#include "perl.h"
Packit Service a275fa
#include "XSUB.h"
Packit Service a275fa
Packit Service a275fa
/* 
Packit Service a275fa
 Based on CRC-32 version 1.04 by Craig Bruce, 05-Dec-1994
Packit Service a275fa
*/
Packit Service a275fa
Packit Service a275fa
#include <stdio.h>
Packit Service a275fa
#include <stdlib.h>
Packit Service a275fa
#include <string.h>
Packit Service a275fa
Packit Service a275fa
#ifdef GENTABLE
Packit Service a275fa
U32 
Packit Service a275fa
crcTable[256];
Packit Service a275fa
Packit Service a275fa
void
Packit Service a275fa
crcgen( void )
Packit Service a275fa
{
Packit Service a275fa
    U32 crc, poly;
Packit Service a275fa
    int     i, j;
Packit Service a275fa
Packit Service a275fa
    poly = 0xEDB88320L;
Packit Service a275fa
    for (i=0; i<256; i++) {
Packit Service a275fa
        crc = i;
Packit Service a275fa
        for (j=8; j>0; j--) {
Packit Service a275fa
            if (crc&1) {
Packit Service a275fa
                crc = (crc >> 1) ^ poly;
Packit Service a275fa
            } else {
Packit Service a275fa
                crc >>= 1;
Packit Service a275fa
            }
Packit Service a275fa
        }
Packit Service a275fa
        crcTable[i] = crc;
Packit Service a275fa
    }
Packit Service a275fa
}
Packit Service a275fa
#else /* GENTABLE */
Packit Service a275fa
U32
Packit Service a275fa
crcTable[256] = {
Packit Service a275fa
0x0, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
Packit Service a275fa
0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
Packit Service a275fa
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
Packit Service a275fa
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
Packit Service a275fa
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
Packit Service a275fa
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
Packit Service a275fa
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
Packit Service a275fa
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
Packit Service a275fa
0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x6b6b51f, 0x9fbfe4a5, 0xe8b8d433,
Packit Service a275fa
0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x86d3d2d, 0x91646c97, 0xe6635c01,
Packit Service a275fa
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
Packit Service a275fa
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
Packit Service a275fa
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
Packit Service a275fa
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
Packit Service a275fa
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
Packit Service a275fa
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
Packit Service a275fa
0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x4db2615, 0x73dc1683,
Packit Service a275fa
0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0xa00ae27, 0x7d079eb1,
Packit Service a275fa
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
Packit Service a275fa
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
Packit Service a275fa
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
Packit Service a275fa
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
Packit Service a275fa
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
Packit Service a275fa
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
Packit Service a275fa
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713,
Packit Service a275fa
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21,
Packit Service a275fa
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
Packit Service a275fa
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
Packit Service a275fa
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
Packit Service a275fa
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
Packit Service a275fa
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
Packit Service a275fa
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
Packit Service a275fa
};
Packit Service a275fa
#endif /* GENTABLE */
Packit Service a275fa
Packit Service a275fa
U32 
Packit Service a275fa
getcrc(char *c, int len, U32 crcinit)
Packit Service a275fa
{
Packit Service a275fa
    register U32 crc;
Packit Service a275fa
    char     *e = c + len;
Packit Service a275fa
Packit Service a275fa
    crc = crcinit^0xFFFFFFFF;
Packit Service a275fa
    while (c < e) {
Packit Service a275fa
        crc = ((crc >> 8) & 0x00FFFFFF) ^ crcTable[ (crc^ *c) & 0xFF ];
Packit Service a275fa
        ++c;
Packit Service a275fa
    }
Packit Service a275fa
    return( crc^0xFFFFFFFF );
Packit Service a275fa
}
Packit Service a275fa
Packit Service a275fa
#define BUFSIZE 32768
Packit Service a275fa
Packit Service a275fa
U32
Packit Service a275fa
getcrc_fp( PerlIO *fp, U32 crcinit )
Packit Service a275fa
{
Packit Service a275fa
    register U32 crc;
Packit Service a275fa
    register U16 len;
Packit Service a275fa
    unsigned char buf[BUFSIZE];
Packit Service a275fa
Packit Service a275fa
    crc = crcinit^0xFFFFFFFF;
Packit Service a275fa
    while((len = PerlIO_read(fp, buf, BUFSIZE)) > 0 ) {
Packit Service a275fa
        unsigned char * p = buf;
Packit Service a275fa
        do {
Packit Service a275fa
	    crc = ((crc >> 8) & 0x00FFFFFF) ^ crcTable[(unsigned char)( (crc & 0xff) ^ *(p++) )];
Packit Service a275fa
	} while (--len);
Packit Service a275fa
    }
Packit Service a275fa
    return( crc^0xFFFFFFFF );
Packit Service a275fa
}
Packit Service a275fa
Packit Service a275fa
svtype
Packit Service a275fa
getsvtype(SV *sv)
Packit Service a275fa
{
Packit Service a275fa
  if (sv == NULL )
Packit Service a275fa
    return SVt_NULL;
Packit Service a275fa
  if (SvROK(sv))
Packit Service a275fa
    return SvTYPE(SvRV(sv));
Packit Service a275fa
  else 
Packit Service a275fa
    return SvTYPE(sv);
Packit Service a275fa
}
Packit Service a275fa
Packit Service a275fa
MODULE = String::CRC32		PACKAGE = String::CRC32
Packit Service a275fa
Packit Service a275fa
VERSIONCHECK: DISABLE
Packit Service a275fa
PROTOTYPES: DISABLE 
Packit Service a275fa
Packit Service a275fa
U32
Packit Service a275fa
crc32(data, ...)
Packit Service a275fa
    char *data = NO_INIT
Packit Service a275fa
    PREINIT:
Packit Service a275fa
	U32 crcinit = 0;
Packit Service a275fa
    STRLEN data_len;
Packit Service a275fa
    PPCODE:
Packit Service a275fa
	int sv_type;
Packit Service a275fa
	IO *io;
Packit Service a275fa
	SV *sv;
Packit Service a275fa
	U32 rv = 0;
Packit Service a275fa
      {
Packit Service a275fa
#ifdef GENTABLE
Packit Service a275fa
	crcgen();
Packit Service a275fa
#endif /* GENTABLE */
Packit Service a275fa
	/* Horst Fickenscher <horst_fickenscher@sepp.de> mailed me that it
Packit Service a275fa
	   could be useful to supply an initial value other than 0, e.g.
Packit Service a275fa
	   to calculate checksums of big files without the need of keeping
Packit Service a275fa
	   them comletely in memory */
Packit Service a275fa
	if ( items > 1 )
Packit Service a275fa
		crcinit = (U32) SvNV(ST(items - 1));
Packit Service a275fa
Packit Service a275fa
	sv_type = getsvtype(ST(0));
Packit Service a275fa
Packit Service a275fa
	if (sv_type == SVt_PVGV)
Packit Service a275fa
	  {
Packit Service a275fa
		io = sv_2io(ST(0));
Packit Service a275fa
		rv = getcrc_fp(IoIFP(io), crcinit);
Packit Service a275fa
	  }
Packit Service a275fa
	else
Packit Service a275fa
	  {
Packit Service a275fa
		data = (char *)SvPV(ST(0),data_len);
Packit Service a275fa
		rv = getcrc(data, data_len, crcinit);
Packit Service a275fa
	  }
Packit Service a275fa
	EXTEND(sp, 1);
Packit Service a275fa
	sv = newSV(0);
Packit Service a275fa
	sv_setuv(sv, (UV)rv);
Packit Service a275fa
	PUSHs(sv_2mortal(sv));
Packit Service a275fa
      }