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