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
13 EXTERN_C_BEGIN
14
15 typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
16
17 extern 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
27 EXTERN_C_END
28
29 class CCrcHasher:
30 public IHasher,
31 public ICompressSetCoderProperties,
32 public CMyUnknownImp
33 {
34 UInt32 _crc;
35 CRC_FUNC _updateFunc;
36 bool SetFunctions(UInt32 tSize);
37 public:
CCrcHasher()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
STDMETHODIMP_(void)49 STDMETHODIMP_(void) CCrcHasher::Init()
50 {
51 _crc = CRC_INIT_VAL;
52 }
53
STDMETHODIMP_(void)54 STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size)
55 {
56 _crc = _updateFunc(_crc, data, size, g_CrcTable);
57 }
58
STDMETHODIMP_(void)59 STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest)
60 {
61 UInt32 val = CRC_GET_DIGEST(_crc);
62 SetUi32(digest, val);
63 }
64
STDMETHODIMP_(UInt32)65 STDMETHODIMP_(UInt32) CCrcHasher::GetDigestSize()
66 {
67 return 4;
68 }
69
SetFunctions(UInt32 tSize)70 bool 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
SetCoderProperties(const PROPID * propIDs,const PROPVARIANT * coderProps,UInt32 numProps)90 STDMETHODIMP 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
CreateHasher()107 static IHasher *CreateHasher() { return new CCrcHasher(); }
108
109 static CHasherInfo g_HasherInfo = { CreateHasher, 0x1, L"CRC32", 4 };
110
111 REGISTER_HASHER(Crc32)
112