1// CrcReg.cpp 2 3#include "StdAfx.h" 4 5#include "../../C/7zCrc.h" 6#include "../../C/CpuArch.h" 7 8#include "../Common/MyCom.h" 9 10#include "../7zip/ICoder.h" 11#include "../7zip/Common/RegisterCodec.h" 12 13EXTERN_C_BEGIN 14 15typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); 16 17extern CRC_FUNC g_CrcUpdate; 18 19#ifdef MY_CPU_X86_OR_AMD64 20 UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); 21#endif 22 23#ifndef MY_CPU_BE 24 UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); 25#endif 26 27EXTERN_C_END 28 29class CCrcHasher: 30 public IHasher, 31 public ICompressSetCoderProperties, 32 public CMyUnknownImp 33{ 34 UInt32 _crc; 35 CRC_FUNC _updateFunc; 36 bool SetFunctions(UInt32 tSize); 37public: 38 CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); } 39 40 MY_UNKNOWN_IMP1(ICompressSetCoderProperties) 41 42 STDMETHOD_(void, Init)(); 43 STDMETHOD_(void, Update)(const void *data, UInt32 size); 44 STDMETHOD_(void, Final)(Byte *digest); 45 STDMETHOD_(UInt32, GetDigestSize)(); 46 STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); 47}; 48 49STDMETHODIMP_(void) CCrcHasher::Init() 50{ 51 _crc = CRC_INIT_VAL; 52} 53 54STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size) 55{ 56 _crc = _updateFunc(_crc, data, size, g_CrcTable); 57} 58 59STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest) 60{ 61 UInt32 val = CRC_GET_DIGEST(_crc); 62 SetUi32(digest, val); 63} 64 65STDMETHODIMP_(UInt32) CCrcHasher::GetDigestSize() 66{ 67 return 4; 68} 69 70bool CCrcHasher::SetFunctions(UInt32 tSize) 71{ 72 _updateFunc = g_CrcUpdate; 73 if (tSize == 4) 74 { 75 #ifndef MY_CPU_BE 76 _updateFunc = CrcUpdateT4; 77 #endif 78 } 79 else if (tSize == 8) 80 { 81 #ifdef MY_CPU_X86_OR_AMD64 82 _updateFunc = CrcUpdateT8; 83 #else 84 return false; 85 #endif 86 } 87 return true; 88} 89 90STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs, 91 const PROPVARIANT *coderProps, UInt32 numProps) 92{ 93 for (UInt32 i = 0; i < numProps; i++) 94 { 95 const PROPVARIANT &prop = coderProps[i]; 96 if (propIDs[i] == NCoderPropID::kDefaultProp) 97 { 98 if (prop.vt != VT_UI4) 99 return E_INVALIDARG; 100 if (!SetFunctions(prop.ulVal)) 101 return E_NOTIMPL; 102 } 103 } 104 return S_OK; 105} 106 107static IHasher *CreateHasher() { return new CCrcHasher(); } 108 109static CHasherInfo g_HasherInfo = { CreateHasher, 0x1, L"CRC32", 4 }; 110 111REGISTER_HASHER(Crc32) 112