Home | History | Annotate | Download | only in Common
      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