diff options
Diffstat (limited to 'src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp')
-rw-r--r-- | src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp | 218 |
1 files changed, 158 insertions, 60 deletions
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp b/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp index cc82a0db5..01ccbe12a 100644 --- a/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp +++ b/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp @@ -13,12 +13,21 @@ static const unsigned int kNumCodecsMax = 64; unsigned int g_NumCodecs = 0; const CCodecInfo *g_Codecs[kNumCodecsMax]; -void RegisterCodec(const CCodecInfo *codecInfo) +void RegisterCodec(const CCodecInfo *codecInfo) throw() { if (g_NumCodecs < kNumCodecsMax) g_Codecs[g_NumCodecs++] = codecInfo; } +static const unsigned int kNumHashersMax = 16; +unsigned int g_NumHashers = 0; +const CHasherInfo *g_Hashers[kNumHashersMax]; +void RegisterHasher(const CHasherInfo *hashInfo) throw() +{ + if (g_NumHashers < kNumHashersMax) + g_Hashers[g_NumHashers++] = hashInfo; +} + #ifdef EXTERNAL_CODECS static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res) { @@ -46,56 +55,74 @@ static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, return S_OK; } -HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs) +HRESULT CExternalCodecs::LoadCodecs() { - UInt32 num; - RINOK(codecsInfo->GetNumberOfMethods(&num)); - for (UInt32 i = 0; i < num; i++) + if (GetCodecs) { - CCodecInfoEx info; - NWindows::NCOM::CPropVariant prop; - RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop)); - // if (prop.vt != VT_BSTR) - // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal); - // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize); - if (prop.vt != VT_UI8) + UInt32 num; + RINOK(GetCodecs->GetNumberOfMethods(&num)); + for (UInt32 i = 0; i < num; i++) { - continue; // old Interface - // return E_INVALIDARG; + CCodecInfoEx info; + NWindows::NCOM::CPropVariant prop; + RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop)); + // if (prop.vt != VT_BSTR) + // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal); + // memcpy(info.Id.ID, prop.bstrVal, info.Id.IDSize); + if (prop.vt != VT_UI8) + continue; // old Interface + info.Id = prop.uhVal.QuadPart; + prop.Clear(); + + RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop)); + if (prop.vt == VT_BSTR) + info.Name = prop.bstrVal; + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + + RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kInStreams, info.NumInStreams)); + RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kOutStreams, info.NumOutStreams)); + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)); + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)); + + Codecs.Add(info); + } + } + if (GetHashers) + { + UInt32 num = GetHashers->GetNumHashers(); + for (UInt32 i = 0; i < num; i++) + { + CHasherInfoEx info; + NWindows::NCOM::CPropVariant prop; + RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop)); + if (prop.vt != VT_UI8) + continue; + info.Id = prop.uhVal.QuadPart; + prop.Clear(); + + RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop)); + if (prop.vt == VT_BSTR) + info.Name = prop.bstrVal; + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + + Hashers.Add(info); } - info.Id = prop.uhVal.QuadPart; - prop.Clear(); - - RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop)); - if (prop.vt == VT_BSTR) - info.Name = prop.bstrVal; - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG;; - - RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams)); - RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams)); - RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)); - RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)); - - externalCodecs.Add(info); } return S_OK; } #endif -bool FindMethod( - #ifdef EXTERNAL_CODECS - ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs, - #endif - const UString &name, - CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams) +bool FindMethod(DECL_EXTERNAL_CODECS_LOC_VARS + const UString &name, CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams) { UInt32 i; for (i = 0; i < g_NumCodecs; i++) { const CCodecInfo &codec = *g_Codecs[i]; - if (name.CompareNoCase(codec.Name) == 0) + if (name.IsEqualToNoCase(codec.Name)) { methodId = codec.Id; numInStreams = codec.NumInStreams; @@ -104,11 +131,11 @@ bool FindMethod( } } #ifdef EXTERNAL_CODECS - if (externalCodecs) - for (i = 0; i < (UInt32)externalCodecs->Size(); i++) + if (__externalCodecs) + for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++) { - const CCodecInfoEx &codec = (*externalCodecs)[i]; - if (codec.Name.CompareNoCase(name) == 0) + const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; + if (codec.Name.IsEqualToNoCase(name)) { methodId = codec.Id; numInStreams = codec.NumInStreams; @@ -120,11 +147,8 @@ bool FindMethod( return false; } -bool FindMethod( - #ifdef EXTERNAL_CODECS - ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs, - #endif - CMethodId methodId, UString &name) +bool FindMethod(DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, UString &name) { UInt32 i; for (i = 0; i < g_NumCodecs; i++) @@ -137,10 +161,10 @@ bool FindMethod( } } #ifdef EXTERNAL_CODECS - if (externalCodecs) - for (i = 0; i < (UInt32)externalCodecs->Size(); i++) + if (__externalCodecs) + for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++) { - const CCodecInfoEx &codec = (*externalCodecs)[i]; + const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; if (methodId == codec.Id) { name = codec.Name; @@ -151,6 +175,49 @@ bool FindMethod( return false; } +bool FindHashMethod(DECL_EXTERNAL_CODECS_LOC_VARS + const UString &name, + CMethodId &methodId) +{ + UInt32 i; + for (i = 0; i < g_NumHashers; i++) + { + const CHasherInfo &codec = *g_Hashers[i]; + if (name.IsEqualToNoCase(codec.Name)) + { + methodId = codec.Id; + return true; + } + } + #ifdef EXTERNAL_CODECS + if (__externalCodecs) + for (i = 0; i < (UInt32)__externalCodecs->Hashers.Size(); i++) + { + const CHasherInfoEx &codec = __externalCodecs->Hashers[i]; + if (codec.Name.IsEqualToNoCase(name)) + { + methodId = codec.Id; + return true; + } + } + #endif + return false; +} + +void GetHashMethods(DECL_EXTERNAL_CODECS_LOC_VARS + CRecordVector<CMethodId> &methods) +{ + methods.ClearAndSetSize(g_NumHashers); + UInt32 i; + for (i = 0; i < g_NumHashers; i++) + methods[i] = (*g_Hashers[i]).Id; + #ifdef EXTERNAL_CODECS + if (__externalCodecs) + for (i = 0; i < (UInt32)__externalCodecs->Hashers.Size(); i++) + methods.Add(__externalCodecs->Hashers[i].Id); + #endif +} + HRESULT CreateCoder( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, @@ -159,7 +226,6 @@ HRESULT CreateCoder( CMyComPtr<ICompressCoder2> &coder2, bool encode, bool onlyCoder) { - bool created = false; UInt32 i; for (i = 0; i < g_NumCodecs; i++) { @@ -174,7 +240,6 @@ HRESULT CreateCoder( if (codec.IsFilter) filter = (ICompressFilter *)p; else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p; else coder2 = (ICompressCoder2 *)p; - created = (p != 0); break; } } @@ -185,17 +250,16 @@ HRESULT CreateCoder( if (codec.IsFilter) filter = (ICompressFilter *)p; else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p; else coder2 = (ICompressCoder2 *)p; - created = (p != 0); break; } } } #ifdef EXTERNAL_CODECS - if (!created && externalCodecs) - for (i = 0; i < (UInt32)externalCodecs->Size(); i++) + if (!filter && !coder && !coder2 && __externalCodecs) + for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++) { - const CCodecInfoEx &codec = (*externalCodecs)[i]; + const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; if (codec.Id == methodId) { if (encode) @@ -204,17 +268,17 @@ HRESULT CreateCoder( { if (codec.IsSimpleCodec()) { - HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder); + HRESULT result = __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder); if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE) return result; if (!coder) { - RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter)); + RINOK(__externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter)); } } else { - RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2)); + RINOK(__externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2)); } break; } @@ -224,17 +288,17 @@ HRESULT CreateCoder( { if (codec.IsSimpleCodec()) { - HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder); + HRESULT result = __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder); if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE) return result; if (!coder) { - RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter)); + RINOK(__externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter)); } } else { - RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2)); + RINOK(__externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2)); } break; } @@ -291,3 +355,37 @@ HRESULT CreateFilter( methodId, filter, coder, coder2, encode, false); } + +HRESULT CreateHasher( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + UString &name, + CMyComPtr<IHasher> &hasher) +{ + UInt32 i; + for (i = 0; i < g_NumHashers; i++) + { + const CHasherInfo &codec = *g_Hashers[i]; + if (codec.Id == methodId) + { + hasher = (IHasher *)codec.CreateHasher(); + name = codec.Name; + break; + } + } + + #ifdef EXTERNAL_CODECS + if (!hasher && __externalCodecs) + for (i = 0; i < (UInt32)__externalCodecs->Hashers.Size(); i++) + { + const CHasherInfoEx &codec = __externalCodecs->Hashers[i]; + if (codec.Id == methodId) + { + name = codec.Name; + return __externalCodecs->GetHashers->CreateHasher(i, &hasher); + } + } + #endif + + return S_OK; +} |