Blame CRC.xs

Packit cf0d07
#define PERL_NO_GET_CONTEXT
Packit cf0d07
#include "EXTERN.h"
Packit cf0d07
#include "perl.h"
Packit cf0d07
#include "XSUB.h"
Packit cf0d07
Packit cf0d07
#ifndef NVTYPE
Packit cf0d07
#  if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE)
Packit cf0d07
#    define NVTYPE long double
Packit cf0d07
#  else
Packit cf0d07
#    define NVTYPE double
Packit cf0d07
#  endif
Packit cf0d07
typedef NVTYPE NV;
Packit cf0d07
#endif
Packit cf0d07
Packit cf0d07
#ifndef newSVuv
Packit cf0d07
#  define newSVuv(uv) (uv > ((~((UV)0))>>1) ? newSVnv((NV)uv) : newSViv((IV)uv))
Packit cf0d07
#endif
Packit cf0d07
Packit cf0d07
#ifndef aTHX_
Packit cf0d07
#  define aTHX_
Packit cf0d07
#endif
Packit cf0d07
Packit cf0d07
#ifndef SvGETMAGIC
Packit cf0d07
#  define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
Packit cf0d07
#endif
Packit cf0d07
Packit cf0d07
#define TABSIZE 256
Packit cf0d07
Packit cf0d07
static UV reflect(UV in, int width)
Packit cf0d07
{
Packit cf0d07
  int i;
Packit cf0d07
  UV out = 0;
Packit cf0d07
Packit cf0d07
  for (i = width; in && i; i--, in >>= 1)
Packit cf0d07
    out = (out << 1) | (in & 1);
Packit cf0d07
Packit cf0d07
  return out << i;
Packit cf0d07
}
Packit cf0d07
Packit cf0d07
MODULE = Digest::CRC		PACKAGE = Digest::CRC		
Packit cf0d07
Packit cf0d07
PROTOTYPES: ENABLE
Packit cf0d07
Packit cf0d07
UV
Packit cf0d07
_reflect(in, width)
Packit cf0d07
	UV in
Packit cf0d07
	IV width
Packit cf0d07
Packit cf0d07
	CODE:
Packit cf0d07
		RETVAL = reflect(in, width);
Packit cf0d07
Packit cf0d07
	OUTPUT:
Packit cf0d07
		RETVAL
Packit cf0d07
Packit cf0d07
SV *
Packit cf0d07
_tabinit(width, poly, ref)
Packit cf0d07
	IV width
Packit cf0d07
	UV poly
Packit cf0d07
	IV ref
Packit cf0d07
Packit cf0d07
	PREINIT:
Packit cf0d07
		UV *tab;
Packit cf0d07
		UV mask, t, r, i;
Packit cf0d07
		int j, wm8;
Packit cf0d07
Packit cf0d07
	CODE:
Packit cf0d07
		if (ref)
Packit cf0d07
		  poly = reflect(poly, width);
Packit cf0d07
Packit cf0d07
		mask = ((UV)1)<<(width-1);
Packit cf0d07
		mask = mask + (mask-1);
Packit cf0d07
Packit cf0d07
		i = TABSIZE*sizeof(UV);
Packit cf0d07
		RETVAL = newSV(i);
Packit cf0d07
		SvPOK_only(RETVAL);
Packit cf0d07
		SvCUR_set(RETVAL, i);
Packit cf0d07
		tab = (UV *) SvPVX(RETVAL);
Packit cf0d07
Packit cf0d07
		if (!ref) {
Packit cf0d07
		  t = ((UV)1) << (width - 1);
Packit cf0d07
		  wm8 = width - 8;
Packit cf0d07
		}
Packit cf0d07
Packit cf0d07
		for (i = 0; i < TABSIZE; i++) {
Packit cf0d07
		  if (ref) {
Packit cf0d07
		    r = i;
Packit cf0d07
		    for (j = 0; j < 8; j++)
Packit cf0d07
		      if (r & 1)
Packit cf0d07
		        r = (r >> 1) ^ poly;
Packit cf0d07
		      else
Packit cf0d07
		        r >>= 1;
Packit cf0d07
		  }
Packit cf0d07
		  else {
Packit cf0d07
		    r = i << (width - 8);
Packit cf0d07
		    for (j = 0; j < 8; j++)
Packit cf0d07
		      if (r & t)
Packit cf0d07
		        r = (r << 1) ^ poly;
Packit cf0d07
		      else
Packit cf0d07
		        r <<= 1;
Packit cf0d07
		  }
Packit cf0d07
		  tab[i] = r & mask;
Packit cf0d07
		}
Packit cf0d07
Packit cf0d07
	OUTPUT:
Packit cf0d07
		RETVAL
Packit cf0d07
Packit cf0d07
SV *
Packit cf0d07
_crc(message, width, init, xorout, refin, refout, cont, table)
Packit cf0d07
	SV *message
Packit cf0d07
	IV  width
Packit cf0d07
	UV  init
Packit cf0d07
	UV  xorout
Packit cf0d07
	IV  refin
Packit cf0d07
	IV  refout
Packit cf0d07
	IV  cont
Packit cf0d07
	SV *table
Packit cf0d07
Packit cf0d07
	PREINIT:
Packit cf0d07
		UV crc, mask, *tab;
Packit cf0d07
		STRLEN len;
Packit cf0d07
		const char *msg, *end;
Packit cf0d07
Packit cf0d07
        CODE:
Packit cf0d07
		SvGETMAGIC(message);
Packit cf0d07
Packit cf0d07
		msg  = SvPV(message, len);
Packit cf0d07
		end  = msg + len;
Packit cf0d07
		mask = ((UV)1)<<(width-1);
Packit cf0d07
		mask = mask + (mask-1);
Packit cf0d07
		tab  = (UV *) SvPVX(table);
Packit cf0d07
Packit cf0d07
		crc  = refin ? reflect(init, width) : init;
Packit cf0d07
		if (cont) {
Packit cf0d07
		  crc = (init ^ xorout) & mask;
Packit cf0d07
		  if (refout ^ refin)
Packit cf0d07
		    crc = reflect(crc, width);
Packit cf0d07
		}
Packit cf0d07
Packit cf0d07
		if (refin) {
Packit cf0d07
		  while (msg < end)
Packit cf0d07
		    crc = (crc >> 8) ^ tab[(crc ^ *msg++) & 0xFF];
Packit cf0d07
		}
Packit cf0d07
		else {
Packit cf0d07
		  int wm8 = width - 8;
Packit cf0d07
		  while (msg < end)
Packit cf0d07
		    crc = (crc << 8) ^ tab[((crc >> wm8) ^ *msg++) & 0xFF];
Packit cf0d07
		}
Packit cf0d07
Packit cf0d07
		if (refout ^ refin)
Packit cf0d07
		  crc = reflect(crc, width);
Packit cf0d07
Packit cf0d07
		crc = (crc ^ xorout) & mask;
Packit cf0d07
Packit cf0d07
		RETVAL = newSVuv(crc);
Packit cf0d07
Packit cf0d07
        OUTPUT:
Packit cf0d07
		RETVAL
Packit cf0d07
Packit cf0d07
SV *
Packit cf0d07
_crc64(message, crc=0)
Packit cf0d07
          SV * message
Packit cf0d07
          UV crc
Packit cf0d07
Packit cf0d07
          PREINIT:
Packit cf0d07
                  unsigned long long poly64rev = 0xd800000000000000ULL;
Packit cf0d07
                  unsigned long long part;
Packit cf0d07
                  int i, j;
Packit cf0d07
                  static int init = 0;
Packit cf0d07
                  static unsigned long long CRCTable[256];
Packit cf0d07
                  STRLEN len;
Packit cf0d07
                  const char *msg, *end;
Packit cf0d07
Packit cf0d07
          CODE:
Packit cf0d07
               SvGETMAGIC(message);
Packit cf0d07
               msg = SvPV(message, len);
Packit cf0d07
               end = msg + len;
Packit cf0d07
Packit cf0d07
               if (!init) {
Packit cf0d07
                 init = 1;
Packit cf0d07
Packit cf0d07
                 for (i = 0; i < 256; i++) {
Packit cf0d07
                   part = i;
Packit cf0d07
                   for (j = 0; j < 8; j++) {
Packit cf0d07
                     if (part & 1)
Packit cf0d07
                       part = (part >> 1) ^ poly64rev;
Packit cf0d07
                     else
Packit cf0d07
                       part >>= 1;
Packit cf0d07
                   }
Packit cf0d07
                   CRCTable[i] = part;
Packit cf0d07
                 }
Packit cf0d07
               }
Packit cf0d07
               while (msg < end)
Packit cf0d07
                 crc = CRCTable[(crc ^ *msg++) & 0xff] ^ (crc >> 8);
Packit cf0d07
Packit cf0d07
               RETVAL = newSVuv(crc);
Packit cf0d07
Packit cf0d07
        OUTPUT:
Packit cf0d07
               RETVAL
Packit cf0d07