semi合集-English.pdf - 第5931页
SEMI P39-0304 E2 © SEMI 2004 34 A1-2 Sample CHECKSUM32 C-Langua ge Source Code /* (c) Copyright 2003 SEMI no warranty, express or implied not liable for damages resulting from or in connection with use of this software *…

SEMI P39-0304
E2
© SEMI 2004 33
main(int argc, char **argv)
{
char *path;
FILE *fptr;
size_t len;
byte buf[BUFFER_SZ];
uint32 crc;
uint32 crc_to_file;
switch (argc)
{
case 1 :
path = "<stdin>";
fptr = stdin; /* read from standard input */
break;
case 2 :
/* open input file (use the ’b’ flag to read as binary rather than text) */
path = argv[1];
if ( (fptr = fopen(path, "rb") ) == NULL)
{
fprintf(stderr, "\nerror opening %s (%s)\n", path, strerror(errno) );
exit(1);
}
break;
default :
fprintf(stderr, "\nusage: %s pathname\n", argv[0]);
fprintf(stderr, " -or-");
fprintf(stderr, "\n %s < pathname\n", argv[0]);
exit(1);
}
/* initialize */
crc32_init(&crc);
/* calculate crc for all data in file */
while (len = (fread(buf, 1, BUFFER_SZ, fptr) ) )
crc32_add(&crc, buf, len);
if (!feof(fptr) )
{
fprintf(stderr, "\nerror reading %s (%s)\n", path, strerror(errno) );
if (fptr != stdin)
fclose(fptr);
exit(1);
}
if (fptr != stdin)
fclose(fptr);
crc_to_file = crc;
/* ensure CRC32 is written to OASIS file in LITTLE_ENDIAN byte order */
#ifdef BIG_ENDIAN_MACHINE
CHG_ENDIAN(crc_to_file);
#endif
#ifdef TEST
/* this is the crc value that should be the last 4 bytes in the file */
printf("crc_to_file = 0x%08x\n", crc_to_file);
/* assume the CRC32 value crc_to_file was appended to the end of the Oasis file */
/* add the CRC32 (in LITTLE_ENDIAN order) to the data stream and continue CRC calculation */
crc32_add(&crc, (byte *) &crc_to_file, size of(crc_to_file) );
#endif
printf("crc_constant (should be 0x%08x) = 0x%08x\n", CRC32_CONSTANT, crc);
exit(0);
}

SEMI P39-0304
E2
© SEMI 2004 34
A1-2 Sample CHECKSUM32 C-Language Source Code
/*
(c) Copyright 2003 SEMI
no warranty, express or implied
not liable for damages resulting from or in connection with use of this software
*/
#include <stdio.h>
#include <errno.h>
/********************/
/* basic data types */
/********************/
typedef unsigned char byte;
typedef unsigned int uint32;
#ifdef _ILP32
typedef unsigned long long uint64;
#else
typedef unsigned long uint64;
#endif
/*************/
/* constants */
/*************/
#define BUFFER_SZ 8 * 1024
#define BITS_IN_BYTE 8
/**********/
/* macros */
/**********/
#define CHG_ENDIAN(a) {byte *p, t; p=(byte *)&(a); t=p[0]; p[0]=p[3]; p[3]=t; t=p[1]; p[1]=p[2];
p[2]=t;}
void
checksum_init(uint32 *chksum)
{
*chksum = 0;
}
void
checksum_add(uint32 *chksum,
byte *buf,
size_t len
)
{
uint64 val; /* could be a uint32, but overflow handling is undefined */
size_t i;
val = (uint64) *chksum;
for (i = 0; i < len; i++)
{
val += buf[i]; /* sum */
val &= 0xffffffff; /* limit to 32 bits */
}
*chksum = (uint32) val;
}
main(int argc, char **argv)
{
char *path;
FILE *fptr;
size_t len;
byte buf[BUFFER_SZ];
uint32 chksum;
uint32 chksum_to_file;
switch (argc)

SEMI P39-0304
E2
© SEMI 2004 35
{
case 1 :
path = "<stdin>";
fptr = stdin; /* read from standard input */
break;
case 2 :
/* open input file (use the ’b’ flag to read as binary rather than text) */
path = argv[1];
if ( (fptr = fopen(path, "rb") ) == NULL)
{
fprintf(stderr, "\nerror opening %s (%s)\n", path, strerror(errno) );
exit(1);
}
break;
default :
fprintf(stderr, "\nusage: %s pathname\n", argv[0]);
fprintf(stderr, " -or-");
fprintf(stderr, "\n %s < pathname\n", argv[0]);
exit(1);
}
/* initialize */
checksum_init(&chksum);
/* calculate checksum for all data in file */
while (len = (fread(buf, 1, BUFFER_SZ, fptr) ) )
checksum_add(&chksum, buf, len);
if (!feof(fptr) )
{
fprintf(stderr, "\nerror reading %s (%s)\n", path, strerror(errno) );
if (fptr != stdin)
fclose(fptr);
exit(1);
}
if (fptr != stdin)
fclose(fptr);
chksum_to_file = chksum;
/* ensure CHECKSUM32 is written to OASIS file in LITTLE_ENDIAN byte order */
#ifdef BIG_ENDIAN_MACHINE
CHG_ENDIAN(chksum_to_file);
#endif
/* this is the checksum value that should be the last 4 bytes in the file */
printf("chksum_to_file = 0x%08x\n", chksum_to_file);
exit(0);
}