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/Common/RegisterCodec.h" 11 12 EXTERN_C_BEGIN 13 14 typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); 15 16 UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); 17 18 extern CRC_FUNC g_CrcUpdate; 19 extern CRC_FUNC g_CrcUpdateT8; 20 extern CRC_FUNC g_CrcUpdateT4; 21 22 EXTERN_C_END 23 24 class CCrcHasher: 25 public IHasher, 26 public ICompressSetCoderProperties, 27 public CMyUnknownImp 28 { 29 UInt32 _crc; 30 CRC_FUNC _updateFunc; 31 Byte mtDummy[1 << 7]; 32 33 bool SetFunctions(UInt32 tSize); 34 public: 35 CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); } 36 37 MY_UNKNOWN_IMP2(IHasher, ICompressSetCoderProperties) 38 INTERFACE_IHasher(;) 39 STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); 40 }; 41 42 bool CCrcHasher::SetFunctions(UInt32 tSize) 43 { 44 _updateFunc = g_CrcUpdate; 45 46 if (tSize == 1) 47 _updateFunc = CrcUpdateT1; 48 else if (tSize == 4) 49 { 50 if (g_CrcUpdateT4) 51 _updateFunc = g_CrcUpdateT4; 52 else 53 return false; 54 } 55 else if (tSize == 8) 56 { 57 if (g_CrcUpdateT8) 58 _updateFunc = g_CrcUpdateT8; 59 else 60 return false; 61 } 62 63 return true; 64 } 65 66 STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) 67 { 68 for (UInt32 i = 0; i < numProps; i++) 69 { 70 const PROPVARIANT &prop = coderProps[i]; 71 if (propIDs[i] == NCoderPropID::kDefaultProp) 72 { 73 if (prop.vt != VT_UI4) 74 return E_INVALIDARG; 75 if (!SetFunctions(prop.ulVal)) 76 return E_NOTIMPL; 77 } 78 } 79 return S_OK; 80 } 81 82 STDMETHODIMP_(void) CCrcHasher::Init() throw() 83 { 84 _crc = CRC_INIT_VAL; 85 } 86 87 STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size) throw() 88 { 89 _crc = _updateFunc(_crc, data, size, g_CrcTable); 90 } 91 92 STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest) throw() 93 { 94 UInt32 val = CRC_GET_DIGEST(_crc); 95 SetUi32(digest, val); 96 } 97 98 REGISTER_HASHER(CCrcHasher, 0x1, "CRC32", 4) 99