1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 // Copyright � NetworkDLS 2002, All rights reserved
3 //
4 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
5 // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
6 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
7 // PARTICULAR PURPOSE.
8 //
9 // Modified by Bohdan Stelmakh for use in Freesynd
10 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11 #ifndef _CCRC32_CPP
12 #define _CCRC32_CPP
13 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include "ccrc32.h"
19
20 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
21 /*
22 This function initializes "CRC Lookup Table". You only need to call it once to
23 initalize the table before using any of the other CRC32 calculation functions.
24 */
25
26 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
27
CCRC32(void)28 CCRC32::CCRC32(void)
29 {
30 this->Initialize();
31 }
32
33
34 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
35
~CCRC32(void)36 CCRC32::~CCRC32(void)
37 {
38 //No destructor code.
39 }
40
41 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
42 /*
43 This function initializes "CRC Lookup Table". You only need to call it once to
44 initalize the table before using any of the other CRC32 calculation functions.
45 */
46
Initialize(void)47 void CCRC32::Initialize(void)
48 {
49 //0x04C11DB7 is the official polynomial used by PKZip, WinZip and Ethernet.
50 unsigned int ulPolynomial = 0x04C11DB7;
51
52 memset(&this->ulTable, 0, sizeof(this->ulTable));
53
54 // 256 values representing ASCII character codes.
55 for(int iCodes = 0; iCodes <= 0xFF; iCodes++)
56 {
57 this->ulTable[iCodes] = this->Reflect(iCodes, 8) << 24;
58
59 for(int iPos = 0; iPos < 8; iPos++)
60 {
61 this->ulTable[iCodes] = (this->ulTable[iCodes] << 1)
62 ^ ((this->ulTable[iCodes] & (1 << 31)) ? ulPolynomial : 0);
63 }
64
65 this->ulTable[iCodes] = this->Reflect(this->ulTable[iCodes], 32);
66 }
67 }
68
69 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
70 /*
71 Reflection is a requirement for the official CRC-32 standard.
72 You can create CRCs without it, but they won't conform to the standard.
73 */
74
Reflect(unsigned int ulReflect,const char cChar)75 unsigned int CCRC32::Reflect(unsigned int ulReflect, const char cChar)
76 {
77 unsigned int ulValue = 0;
78
79 // Swap bit 0 for bit 7, bit 1 For bit 6, etc....
80 for(int iPos = 1; iPos < (cChar + 1); iPos++)
81 {
82 if(ulReflect & 1)
83 {
84 ulValue |= (1 << (cChar - iPos));
85 }
86 ulReflect >>= 1;
87 }
88
89 return ulValue;
90 }
91
92 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 /*
94 Calculates the CRC32 by looping through each of the bytes in sData.
95
96 Note: For Example usage example, see FileCRC().
97 */
98
PartialCRC(unsigned int * ulCRC,const unsigned char * sData,size_t ulDataLength)99 void CCRC32::PartialCRC(unsigned int *ulCRC, const unsigned char *sData, size_t ulDataLength)
100 {
101 while(ulDataLength--)
102 {
103 //If your compiler complains about the following line, try changing
104 // each occurrence of *ulCRC with ((unsigned int)*ulCRC).
105
106 *ulCRC = (*ulCRC >> 8) ^ this->ulTable[(*ulCRC & 0xFF) ^ *sData++];
107 }
108 }
109
110 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
111 /*
112 Returns the calculated CRC32 (through ulOutCRC) for the given string.
113 */
114
FullCRC(const unsigned char * sData,size_t ulDataLength,unsigned int * ulOutCRC)115 void CCRC32::FullCRC(const unsigned char *sData, size_t ulDataLength, unsigned int *ulOutCRC)
116 {
117 *((unsigned int *)ulOutCRC) = 0xffffffff; //Initilaize the CRC.
118
119 this->PartialCRC(ulOutCRC, sData, ulDataLength);
120
121 *((unsigned int *)ulOutCRC) ^= 0xffffffff; //Finalize the CRC.
122 }
123
124 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
125 /*
126 Returns the calculated CRC23 for the given string.
127 */
128
FullCRC(const unsigned char * sData,size_t ulDataLength)129 unsigned int CCRC32::FullCRC(const unsigned char *sData, size_t ulDataLength)
130 {
131 unsigned int ulCRC = 0xffffffff; //Initilaize the CRC.
132
133 this->PartialCRC(&ulCRC, sData, ulDataLength);
134
135 return(ulCRC ^ 0xffffffff); //Finalize the CRC and return.
136 }
137
138 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
139 /*
140 Calculates the CRC32 of a file using the a user defined buffer.
141
142 Note: The buffer size DOES NOT affect the resulting CRC,
143 it has been provided for performance purposes only.
144 */
145
FileCRC(const char * sFileName,unsigned int * ulOutCRC,size_t ulBufferSize)146 bool CCRC32::FileCRC(const char *sFileName, unsigned int *ulOutCRC, size_t ulBufferSize)
147 {
148 *((unsigned int *)ulOutCRC) = 0xffffffff; //Initilaize the CRC.
149
150 FILE *fSource = NULL;
151 unsigned char *sBuf = NULL;
152 size_t iBytesRead = 0;
153
154 if((fSource = fopen(sFileName, "rb")) == NULL)
155 {
156 return false; //Failed to open file for read access.
157 }
158
159 if(!(sBuf = (unsigned char *)malloc(ulBufferSize))) //Allocate memory for file buffering.
160 {
161 fclose(fSource);
162 return false; //Out of memory.
163 }
164
165 while((iBytesRead = fread(sBuf, sizeof(char), ulBufferSize, fSource)))
166 {
167 this->PartialCRC(ulOutCRC, sBuf, iBytesRead);
168 }
169
170 free(sBuf);
171 fclose(fSource);
172
173 *((unsigned int *)ulOutCRC) ^= 0xffffffff; //Finalize the CRC.
174
175 return true;
176 }
177
178 #endif
179