aboutsummaryrefslogtreecommitdiff
path: root/CPP/Common/CrcReg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/Common/CrcReg.cpp')
-rw-r--r--CPP/Common/CrcReg.cpp111
1 files changed, 111 insertions, 0 deletions
diff --git a/CPP/Common/CrcReg.cpp b/CPP/Common/CrcReg.cpp
new file mode 100644
index 0000000..cfa1996
--- /dev/null
+++ b/CPP/Common/CrcReg.cpp
@@ -0,0 +1,111 @@
+// CrcReg.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/7zCrc.h"
+#include "../../C/CpuArch.h"
+
+#include "../Common/MyCom.h"
+
+#include "../7zip/ICoder.h"
+#include "../7zip/Common/RegisterCodec.h"
+
+EXTERN_C_BEGIN
+
+typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
+
+extern CRC_FUNC g_CrcUpdate;
+
+#ifdef MY_CPU_X86_OR_AMD64
+ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
+#endif
+
+#ifndef MY_CPU_BE
+ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
+#endif
+
+EXTERN_C_END
+
+class CCrcHasher:
+ public IHasher,
+ public ICompressSetCoderProperties,
+ public CMyUnknownImp
+{
+ UInt32 _crc;
+ CRC_FUNC _updateFunc;
+ bool SetFunctions(UInt32 tSize);
+public:
+ CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); }
+
+ MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
+
+ STDMETHOD_(void, Init)();
+ STDMETHOD_(void, Update)(const void *data, UInt32 size);
+ STDMETHOD_(void, Final)(Byte *digest);
+ STDMETHOD_(UInt32, GetDigestSize)();
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+};
+
+STDMETHODIMP_(void) CCrcHasher::Init()
+{
+ _crc = CRC_INIT_VAL;
+}
+
+STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size)
+{
+ _crc = _updateFunc(_crc, data, size, g_CrcTable);
+}
+
+STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest)
+{
+ UInt32 val = CRC_GET_DIGEST(_crc);
+ SetUi32(digest, val);
+}
+
+STDMETHODIMP_(UInt32) CCrcHasher::GetDigestSize()
+{
+ return 4;
+}
+
+bool CCrcHasher::SetFunctions(UInt32 tSize)
+{
+ _updateFunc = g_CrcUpdate;
+ if (tSize == 4)
+ {
+ #ifndef MY_CPU_BE
+ _updateFunc = CrcUpdateT4;
+ #endif
+ }
+ else if (tSize == 8)
+ {
+ #ifdef MY_CPU_X86_OR_AMD64
+ _updateFunc = CrcUpdateT8;
+ #else
+ return false;
+ #endif
+ }
+ return true;
+}
+
+STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ if (propIDs[i] == NCoderPropID::kDefaultProp)
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ if (!SetFunctions(prop.ulVal))
+ return E_NOTIMPL;
+ }
+ }
+ return S_OK;
+}
+
+static IHasher *CreateHasher() { return new CCrcHasher(); }
+
+static CHasherInfo g_HasherInfo = { CreateHasher, 0x1, L"CRC32", 4 };
+
+REGISTER_HASHER(Crc32)