HRESULT CCoderMixer2ST::GetInStream( ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 streamIndex, ISequentialInStream **inStreamRes) { CMyComPtr<ISequentialInStream> seqInStream; int i; for(i = 0; i < _bindInfo.InStreams.Size(); i++) if (_bindInfo.InStreams[i] == streamIndex) { seqInStream = inStreams[i]; *inStreamRes = seqInStream.Detach(); return S_OK; } int binderIndex = _bindInfo.FindBinderForInStream(streamIndex); if (binderIndex < 0) return E_INVALIDARG; UInt32 coderIndex, coderStreamIndex; _bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex, coderIndex, coderStreamIndex); CCoderInfo &coder = _coders[coderIndex]; if (!coder.Coder) return E_NOTIMPL; coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream); if (!seqInStream) return E_NOTIMPL; UInt32 startIndex = _bindInfo.GetCoderInStreamIndex(coderIndex); CMyComPtr<ICompressSetInStream> setInStream; if (!coder.Coder) return E_NOTIMPL; coder.Coder.QueryInterface(IID_ICompressSetInStream, &setInStream); if (!setInStream) return E_NOTIMPL; if (coder.NumInStreams > 1) return E_NOTIMPL; for (i = 0; i < (int)coder.NumInStreams; i++) { CMyComPtr<ISequentialInStream> seqInStream2; RINOK(GetInStream(inStreams, inSizes, startIndex + i, &seqInStream2)); RINOK(setInStream->SetInStream(seqInStream2)); } *inStreamRes = seqInStream.Detach(); return S_OK; }
HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter) { useFilter = false; if (_decoderInStream) if (Method != _curMethod) Release(); _curMethod = Method; if (!_codecInStream) { switch (Method) { // case NMethodType::kCopy: return E_NOTIMPL; case NMethodType::kDeflate: _codecInStream = new NCompress::NDeflate::NDecoder::CNsisCOMCoder(); break; case NMethodType::kBZip2: _codecInStream = new NCompress::NBZip2::CNsisDecoder(); break; case NMethodType::kLZMA: _lzmaDecoder = new NCompress::NLzma::CDecoder(); _codecInStream = _lzmaDecoder; break; default: return E_NOTIMPL; } } if (FilterFlag) { Byte flag; RINOK(ReadStream_FALSE(inStream, &flag, 1)); if (flag > 1) return E_NOTIMPL; useFilter = (flag != 0); } if (!useFilter) _decoderInStream = _codecInStream; else { if (!_filterInStream) { _filter = new CFilterCoder(false); _filterInStream = _filter; _filter->Filter = new NCompress::NBcj::CCoder(false); } RINOK(_filter->SetInStream(_codecInStream)); _decoderInStream = _filterInStream; } if (Method == NMethodType::kLZMA) { const unsigned kPropsSize = LZMA_PROPS_SIZE; Byte props[kPropsSize]; RINOK(ReadStream_FALSE(inStream, props, kPropsSize)); RINOK(_lzmaDecoder->SetDecoderProperties2((const Byte *)props, kPropsSize)); } { CMyComPtr<ICompressSetInStream> setInStream; _codecInStream.QueryInterface(IID_ICompressSetInStream, &setInStream); if (!setInStream) return E_NOTIMPL; RINOK(setInStream->SetInStream(inStream)); } { CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize; _codecInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); if (!setOutStreamSize) return E_NOTIMPL; RINOK(setOutStreamSize->SetOutStreamSize(NULL)); } if (useFilter) { RINOK(_filter->SetOutStreamSize(NULL)); } return S_OK; }
HRESULT CDecoder::Init(IInStream *inStream, NMethodType::EEnum method, bool thereIsFilterFlag, bool &useFilter) { useFilter = false; CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; if (_decoderInStream) if (method != _method) Release(); _method = method; if (!_codecInStream) { CMyComPtr<ICompressCoder> coder; #ifndef EXCLUDE_COM const NArchive::N7z::CMethodID *methodID = 0; switch (method) { case NMethodType::kCopy: methodID = &k_Copy; break; case NMethodType::kDeflate: methodID = &k_Deflate; break; case NMethodType::kBZip2: methodID = &k_BZip2; break; case NMethodType::kLZMA: methodID = &k_LZMA; break; default: return E_NOTIMPL; } N7z::CMethodInfo methodInfo; if (!N7z::GetMethodInfo(*methodID, methodInfo)) return E_NOTIMPL; RINOK(_libraries.CreateCoder(methodInfo.FilePath, methodInfo.Decoder, &coder)); #else switch(method) { case NMethodType::kCopy: coder = new NCompress::CCopyCoder(); break; case NMethodType::kDeflate: coder = new NCompress::NDeflate::NDecoder::CCOMCoder(); break; case NMethodType::kBZip2: coder = new NCompress::NBZip2::CDecoder(); break; case NMethodType::kLZMA: new NCompress::NLZMA::CDecoder(); break; default: return E_NOTIMPL; } #endif coder.QueryInterface(IID_ISequentialInStream, &_codecInStream); if (!_codecInStream) return E_NOTIMPL; } if (thereIsFilterFlag) { UInt32 processedSize; BYTE flag; RINOK(inStream->Read(&flag, 1, &processedSize)); if (processedSize != 1) return E_FAIL; if (flag > 1) return E_NOTIMPL; useFilter = (flag != 0); } if (useFilter) { if (!_filterInStream) { #ifndef EXCLUDE_COM N7z::CMethodInfo methodInfo; if (!N7z::GetMethodInfo(k_BCJ_X86, methodInfo)) return E_NOTIMPL; CMyComPtr<ICompressCoder> coder; RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath, methodInfo.Decoder, &coder)); coder.QueryInterface(IID_ISequentialInStream, &_filterInStream); if (!_filterInStream) return E_NOTIMPL; #else return E_NOTIMPL; #endif } CMyComPtr<ICompressSetInStream> setInStream; _filterInStream.QueryInterface(IID_ICompressSetInStream, &setInStream); if (!setInStream) return E_NOTIMPL; RINOK(setInStream->SetInStream(_codecInStream)); _decoderInStream = _filterInStream; } else _decoderInStream = _codecInStream; if (method == NMethodType::kLZMA) { CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; _codecInStream.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); if (setDecoderProperties) { static const UInt32 kPropertiesSize = 5; BYTE properties[kPropertiesSize]; UInt32 processedSize; RINOK(inStream->Read(properties, kPropertiesSize, &processedSize)); if (processedSize != kPropertiesSize) return E_FAIL; RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, kPropertiesSize)); } } { CMyComPtr<ICompressSetInStream> setInStream; _codecInStream.QueryInterface(IID_ICompressSetInStream, &setInStream); if (!setInStream) return E_NOTIMPL; RINOK(setInStream->SetInStream(inStream)); } { CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize; _codecInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); if (!setOutStreamSize) return E_NOTIMPL; RINOK(setOutStreamSize->SetOutStreamSize(NULL)); } if (useFilter) { /* CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize; _filterInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); if (!setOutStreamSize) return E_NOTIMPL; RINOK(setOutStreamSize->SetOutStreamSize(NULL)); */ } return S_OK; }