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