#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
MODULE = File::Checksum PACKAGE = File::Checksum
PROTOTYPES: ENABLE
unsigned short
Checksum(fname, count)
char *fname
int count
CODE:
unsigned short us_buffer;
unsigned long ul_sum = 0;
int i;
FILE *file = fopen(fname, "rb");
# Our algorithm is simple, using a 32 bit accumulator (ul_sum),
# we add sequential 16 bit words to it, and at the end, fold
# back all the carry bits from the top 16 bits into the lower 16 bits.
if(file)
{
for(i = 0; i < count; i += 2)
if(fread(&us_buffer, sizeof(unsigned short), 1, file))
ul_sum += us_buffer;
else
break;
fclose(file);
# Add back carry outs from top 16 bits to low 16 bits.
# Add hi 16 to low 16.
ul_sum = (ul_sum >> 16) + (ul_sum & 0xffff);
# Add carry.
ul_sum += (ul_sum >> 16);
# Truncate to 16 bits.
RETVAL = (unsigned short)~ul_sum;
}
else
RETVAL = 0;
OUTPUT:
RETVAL