00001 /* 00002 * rdChecksum.h - definition of MINOS Rotorooter command functions 00003 * 00004 * Author: rhatcher@fnal.gov 2001-06 00005 * 00006 * CVS Tag: "$Id: rdChecksum.c,v 1.1 2003/01/17 21:41:58 rhatcher Exp $" 00007 * 00008 */ 00009 #include <sys/types.h> 00010 00011 #include "rdChecksum.h" 00012 /* 00013 *========================================================================= 00014 * rdxsum_calc(const long* ptr, char version) 00015 * 00016 * Purpose: 00017 * Calculate the checksum value 00018 * 00019 * Arguments: 00020 * ptr: pointer to the buffer of 32bit words 00021 * version: checksum algorithm version (only low 4 bits significant) 00022 * 00023 * Return Value: 00024 * the calculated checksum 00025 *========================================================================= 00026 */ 00027 unsigned long rdxsum_calc(const long* ptr, char version) 00028 { 00029 unsigned long sum = 0; 00030 const long *begin = ptr + 2; /* contiguous data starts here */ 00031 const long *end = ptr + (*ptr); /* this is one word too far */ 00032 int v2 = version & 0x3; 00033 00034 /* protect against null pointers */ 00035 if (!ptr) return 0; 00036 00037 /* 00038 * By reserving 2 bits at the top we can support 4 possible 00039 * checksum algorithms, in case we wish to switch at a later 00040 * time, while still retaining the ability to know which 00041 * algorithm was used. Until all are implemented, cascade 00042 * downward until an existing one is found. 00043 */ 00044 switch (v2) { 00045 case 0x3: 00046 v2 = 0x3; /* tag with what we used, not requested */ 00047 /* break; */ /* this version not supported: fall through */ 00048 case 0x2: 00049 v2 = 0x2; /* tag with what we used, not requested */ 00050 /* break; */ /* this version not supported: fall through */ 00051 case 0x1: 00052 v2 = 0x1 ; /* tag with what we used, not requested */ 00053 /* --- add next algorithm here, make break "active" */ 00054 /* break; */ /* this version not supported: fall through */ 00055 case 0x0: 00056 default: 00057 /* the "0" and default algorithm is very simple ... */ 00058 /* simply add up everything ignoring overflows */ 00059 00060 v2 = 0x0; /* tag with what we used, not requested */ 00061 sum = *ptr; /* prime the pump with the word count */ 00062 while (begin<end) sum += *begin++; 00063 } 00064 /* remove top two bits and replace them with the version */ 00065 return (sum & 0x3fffffff) | ( version << 30 ); 00066 } 00067 00068 /* 00069 *========================================================================= 00070 * rdxsum_fill(long* ptr, char version) 00071 * 00072 * Purpose: 00073 * Fill in the checksum value 00074 * 00075 * Arguments: 00076 * ptr: pointer to the buffer of 32bit words 00077 * version: checksum algorithm version (only low 4 bits significant) 00078 * 00079 * Return Value: 00080 * (nothing) 00081 *========================================================================= 00082 */ 00083 void rdxsum_fill(long* ptr, char version) 00084 { 00085 /* protect against null pointers */ 00086 if (!ptr) return; 00087 00088 *(ptr+1) = rdxsum_calc(ptr,version); 00089 } 00090 00091 /* 00092 *========================================================================= 00093 * rdxsum_test(const long* ptr) 00094 * 00095 * Purpose: 00096 * Test the checksum value 00097 * 00098 * Arguments: 00099 * ptr: pointer to the buffer of 32bit words 00100 * 00101 * Return Value: 00102 * non-zero if there was an mismatch 00103 *========================================================================= 00104 */ 00105 int rdxsum_test(const long* ptr) 00106 { 00107 unsigned long stored; 00108 int version; 00109 00110 /* protect against null pointers */ 00111 if (!ptr) return 1; 00112 00113 stored = *(ptr+1); 00114 version = ( 0x3 & ( stored >> 30 ) ); 00115 return stored != rdxsum_calc(ptr,version); 00116 }
1.3.9.1