69 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--- CRC.cpp - Cyclic Redundancy Check implementation -----------------===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| //  This file implements llvm::crc32 function.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "llvm/Support/CRC.h"
 | |
| #include "llvm/Config/config.h"
 | |
| #include "llvm/ADT/StringRef.h"
 | |
| #include "llvm/Support/Threading.h"
 | |
| #include <array>
 | |
| 
 | |
| using namespace llvm;
 | |
| 
 | |
| #if LLVM_ENABLE_ZLIB == 0 || !HAVE_ZLIB_H
 | |
| using CRC32Table = std::array<uint32_t, 256>;
 | |
| 
 | |
| static void initCRC32Table(CRC32Table *Tbl) {
 | |
|   auto Shuffle = [](uint32_t V) {
 | |
|     return (V & 1) ? (V >> 1) ^ 0xEDB88320U : V >> 1;
 | |
|   };
 | |
| 
 | |
|   for (size_t I = 0; I < Tbl->size(); ++I) {
 | |
|     uint32_t V = Shuffle(I);
 | |
|     V = Shuffle(V);
 | |
|     V = Shuffle(V);
 | |
|     V = Shuffle(V);
 | |
|     V = Shuffle(V);
 | |
|     V = Shuffle(V);
 | |
|     V = Shuffle(V);
 | |
|     (*Tbl)[I] = Shuffle(V);
 | |
|   }
 | |
| }
 | |
| 
 | |
| uint32_t llvm::crc32(uint32_t CRC, StringRef S) {
 | |
|   static llvm::once_flag InitFlag;
 | |
|   static CRC32Table Tbl;
 | |
|   llvm::call_once(InitFlag, initCRC32Table, &Tbl);
 | |
| 
 | |
|   const uint8_t *P = reinterpret_cast<const uint8_t *>(S.data());
 | |
|   size_t Len = S.size();
 | |
|   CRC ^= 0xFFFFFFFFU;
 | |
|   for (; Len >= 8; Len -= 8) {
 | |
|     CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
 | |
|     CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
 | |
|     CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
 | |
|     CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
 | |
|     CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
 | |
|     CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
 | |
|     CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
 | |
|     CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
 | |
|   }
 | |
|   while (Len--)
 | |
|     CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
 | |
|   return CRC ^ 0xFFFFFFFFU;
 | |
| }
 | |
| #else
 | |
| #include <zlib.h>
 | |
| uint32_t llvm::crc32(uint32_t CRC, StringRef S) {
 | |
|   return ::crc32(CRC, (const Bytef *)S.data(), S.size());
 | |
| }
 | |
| #endif
 |