CRC.CPP (7609B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: /CounterStrike/CRC.CPP 1 3/03/97 10:24a Joe_bostic $ */ 17 /*********************************************************************************************** 18 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** 19 *********************************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : CRC.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : 03/02/96 * 28 * * 29 * Last Update : March 2, 1996 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * CRCEngine::operator() -- Submits one byte of data to the CRC engine. * 34 * CRCEngine::operator() -- Submits an arbitrary data block to the CRC engine. * 35 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 36 37 #include "crc.h" 38 39 40 /*********************************************************************************************** 41 * CRCEngine::operator() -- Submits one byte of data to the CRC engine. * 42 * * 43 * This routine will take the specified byte of data and submit it to the CRC engine * 44 * for processing. This routine is designed to be as fast as possible since the typical * 45 * use of this routine is to feed one of presumably many byte sized chunks of data to the * 46 * CRC engine. * 47 * * 48 * INPUT: datum -- One byte of data to submit to the CRC engine. * 49 * * 50 * OUTPUT: none * 51 * * 52 * WARNINGS: If possible, use the buffer/size operator to submit data rather than repeated * 53 * calls to this routine. * 54 * * 55 * HISTORY: * 56 * 03/02/1996 JLB : Created. * 57 *=============================================================================================*/ 58 void CRCEngine::operator() (char datum) 59 { 60 StagingBuffer.Buffer[Index++] = datum; 61 62 if (Index == sizeof(long)) { 63 CRC = Value(); 64 StagingBuffer.Composite = 0; 65 Index = 0; 66 } 67 } 68 69 70 /*********************************************************************************************** 71 * CRCEngine::operator() -- Submits an arbitrary data block to the CRC engine. * 72 * * 73 * This routine will submit the specified block to the CRC engine. The block can be of * 74 * arbitrary length. * 75 * * 76 * INPUT: buffer -- Pointer to the buffer that contains the data. The buffer will not * 77 * be modified. * 78 * * 79 * length -- The length of the buffer (in bytes). * 80 * * 81 * OUTPUT: Returns with the current CRC value accumulated so far. * 82 * * 83 * WARNINGS: none * 84 * * 85 * HISTORY: * 86 * 03/02/1996 JLB : Created. * 87 *=============================================================================================*/ 88 long CRCEngine::operator() (void const * buffer, int length) 89 { 90 if (buffer != NULL && length > 0) { 91 char const * dataptr = (char const *)buffer; 92 int bytes_left = length; 93 94 /* 95 ** If there are any leader bytes (needed to fill the staging buffer) 96 ** then process those by first using them to fill up the staging 97 ** buffer. The bulk of the data block will be processed by the high 98 ** speed longword processing loop. 99 */ 100 while (bytes_left && Buffer_Needs_Data()) { 101 operator()(*dataptr); 102 dataptr++; 103 bytes_left--; 104 } 105 106 /* 107 ** Perform the fast 'bulk' processing by reading long word sized 108 ** data blocks. 109 */ 110 long const * longptr = (long const *)dataptr; 111 int longcount = bytes_left / sizeof(long); // Whole 'long' elements remaining. 112 while (longcount--) { 113 CRC = _lrotl(CRC, 1) + *longptr++; 114 bytes_left -= sizeof(long); 115 } 116 117 /* 118 ** If there are remainder bytes, then process these by adding them 119 ** to the staging buffer. 120 */ 121 dataptr = (char const *)longptr; 122 while (bytes_left) { 123 operator()(*dataptr); 124 dataptr++; 125 bytes_left--; 126 } 127 } 128 129 /* 130 ** Return the current CRC value. 131 */ 132 return(Value()); 133 }