diff options
Diffstat (limited to 'CPP/7zip/Archive')
52 files changed, 1332 insertions, 1156 deletions
diff --git a/CPP/7zip/Archive/7z/7z.dsp b/CPP/7zip/Archive/7z/7z.dsp index de892631..fc4c3698 100755 --- a/CPP/7zip/Archive/7z/7z.dsp +++ b/CPP/7zip/Archive/7z/7z.dsp @@ -290,43 +290,43 @@ SOURCE=..\..\..\Common\IntToString.h # End Source File # Begin Source File -SOURCE=..\..\..\Common\NewHandler.cpp +SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Common\NewHandler.h +SOURCE=..\..\..\Common\MyString.h # End Source File # Begin Source File -SOURCE=..\..\..\Common\String.cpp +SOURCE=..\..\..\Common\MyVector.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Common\String.h +SOURCE=..\..\..\Common\MyVector.h # End Source File # Begin Source File -SOURCE=..\..\..\Common\StringConvert.cpp +SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Common\StringConvert.h +SOURCE=..\..\..\Common\NewHandler.h # End Source File # Begin Source File -SOURCE=..\..\..\Common\StringToInt.cpp +SOURCE=..\..\..\Common\StringConvert.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Common\StringToInt.h +SOURCE=..\..\..\Common\StringConvert.h # End Source File # Begin Source File -SOURCE=..\..\..\Common\Vector.cpp +SOURCE=..\..\..\Common\StringToInt.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Common\Vector.h +SOURCE=..\..\..\Common\StringToInt.h # End Source File # End Group # Begin Group "Archive Common" @@ -358,6 +358,14 @@ SOURCE=..\Common\CrossThreadProgress.h # End Source File # Begin Source File +SOURCE=..\Common\HandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerOut.h +# End Source File +# Begin Source File + SOURCE=..\Common\InStreamWithCRC.cpp # End Source File # Begin Source File @@ -450,6 +458,14 @@ SOURCE=..\..\Common\MethodId.h # End Source File # Begin Source File +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\OutBuffer.cpp # End Source File # Begin Source File @@ -496,6 +512,14 @@ SOURCE=..\..\Common\StreamUtils.cpp SOURCE=..\..\Common\StreamUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.h +# End Source File # End Group # Begin Group "Windows" @@ -558,6 +582,14 @@ SOURCE=..\..\..\Windows\Synchronization.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Thread.h # End Source File # End Group @@ -594,6 +626,15 @@ SOURCE=..\..\..\..\C\Alloc.c SOURCE=..\..\..\..\C\Alloc.h # End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File # End Group # Begin Source File diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.h b/CPP/7zip/Archive/7z/7zCompressionMode.h index 65e573d1..5753606f 100755 --- a/CPP/7zip/Archive/7z/7zCompressionMode.h +++ b/CPP/7zip/Archive/7z/7zCompressionMode.h @@ -3,28 +3,20 @@ #ifndef __7Z_COMPRESSION_MODE_H #define __7Z_COMPRESSION_MODE_H -#include "../../../Common/String.h" +#include "../../../Common/MyString.h" #include "../../../Windows/PropVariant.h" -#include "../../Common/MethodId.h" +#include "../../Common/MethodProps.h" namespace NArchive { namespace N7z { -struct CProperty +struct CMethodFull: public CMethod { - PROPID PropID; - NWindows::NCOM::CPropVariant Value; -}; - -struct CMethodFull -{ - CMethodId MethodID; UInt32 NumInStreams; UInt32 NumOutStreams; bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); } - CObjectVector<CProperty> CoderProperties; }; struct CBind diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp index 19b08b78..0f81de40 100755 --- a/CPP/7zip/Archive/7z/7zDecode.cpp +++ b/CPP/7zip/Archive/7z/7zDecode.cpp @@ -22,7 +22,7 @@ static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, int i; for (i = 0; i < folder.BindPairs.Size(); i++) { - NCoderMixer2::CBindPair bindPair; + NCoderMixer::CBindPair bindPair; bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex; bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex; bindInfo.BindPairs.Add(bindPair); @@ -30,7 +30,7 @@ static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, UInt32 outStreamIndex = 0; for (i = 0; i < folder.Coders.Size(); i++) { - NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; + NCoderMixer::CCoderStreamsInfo coderStreamsInfo; const CCoderInfo &coderInfo = folder.Coders[i]; coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams; coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams; @@ -44,14 +44,14 @@ static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]); } -static bool AreCodersEqual(const NCoderMixer2::CCoderStreamsInfo &a1, - const NCoderMixer2::CCoderStreamsInfo &a2) +static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1, + const NCoderMixer::CCoderStreamsInfo &a2) { return (a1.NumInStreams == a2.NumInStreams) && (a1.NumOutStreams == a2.NumOutStreams); } -static bool AreBindPairsEqual(const NCoderMixer2::CBindPair &a1, const NCoderMixer2::CBindPair &a2) +static bool AreBindPairsEqual(const NCoderMixer::CBindPair &a1, const NCoderMixer::CBindPair &a2) { return (a1.InIndex == a2.InIndex) && (a1.OutIndex == a2.OutIndex); @@ -145,14 +145,14 @@ HRESULT CDecoder::Decode( if (_multiThread) { - _mixerCoderMTSpec = new NCoderMixer2::CCoderMixer2MT; + _mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT; _mixerCoder = _mixerCoderMTSpec; _mixerCoderCommon = _mixerCoderMTSpec; } else { #ifdef _ST_MODE - _mixerCoderSTSpec = new NCoderMixer2::CCoderMixer2ST; + _mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST; _mixerCoder = _mixerCoderSTSpec; _mixerCoderCommon = _mixerCoderSTSpec; #endif diff --git a/CPP/7zip/Archive/7z/7zDecode.h b/CPP/7zip/Archive/7z/7zDecode.h index 2e493c37..7c10dfe2 100755 --- a/CPP/7zip/Archive/7z/7zDecode.h +++ b/CPP/7zip/Archive/7z/7zDecode.h @@ -19,7 +19,7 @@ namespace NArchive { namespace N7z { -struct CBindInfoEx: public NCoderMixer2::CBindInfo +struct CBindInfoEx: public NCoderMixer::CBindInfo { CRecordVector<CMethodId> CoderMethodIDs; void Clear() @@ -36,10 +36,10 @@ class CDecoder bool _multiThread; #ifdef _ST_MODE - NCoderMixer2::CCoderMixer2ST *_mixerCoderSTSpec; + NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec; #endif - NCoderMixer2::CCoderMixer2MT *_mixerCoderMTSpec; - NCoderMixer2::CCoderMixer2 *_mixerCoderCommon; + NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec; + NCoderMixer::CCoderMixer2 *_mixerCoderCommon; CMyComPtr<ICompressCoder2> _mixerCoder; CObjectVector<CMyComPtr<IUnknown> > _decoders; diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp index ef74b9bf..8c229362 100755 --- a/CPP/7zip/Archive/7z/7zEncode.cpp +++ b/CPP/7zip/Archive/7z/7zEncode.cpp @@ -13,14 +13,12 @@ #include "../../Common/CreateCoder.h" #include "../../Common/FilterCoder.h" -static UInt64 k_LZMA = 0x030101; -// static UInt64 k_LZMA2 = 0x030102; static UInt64 k_AES = 0x06F10701; namespace NArchive { namespace N7z { -static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindInfo, +static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindInfo, const CRecordVector<CMethodId> decompressionMethods, CFolder &folder) { @@ -40,7 +38,7 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindI for (i = 0; i < bindInfo.Coders.Size(); i++) { CCoderInfo coderInfo; - const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i]; + const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i]; coderInfo.NumInStreams = coderStreamsInfo.NumInStreams; coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams; coderInfo.MethodID = decompressionMethods[i]; @@ -54,49 +52,25 @@ HRESULT CEncoder::CreateMixerCoder( DECL_EXTERNAL_CODECS_LOC_VARS const UInt64 *inSizeForReduce) { - _mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT; + _mixerCoderSpec = new NCoderMixer::CCoderMixer2MT; _mixerCoder = _mixerCoderSpec; RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo)); for (int i = 0; i < _options.Methods.Size(); i++) { const CMethodFull &methodFull = _options.Methods[i]; _codersInfo.Add(CCoderInfo()); - CCoderInfo &encodingInfo = _codersInfo.Back(); + // CCoderInfo &encodingInfo = _codersInfo.Back(); CMyComPtr<ICompressCoder> encoder; CMyComPtr<ICompressCoder2> encoder2; RINOK(CreateCoder( EXTERNAL_CODECS_LOC_VARS - methodFull.MethodID, encoder, encoder2, true)); + methodFull.Id, encoder, encoder2, true)); if (!encoder && !encoder2) return E_FAIL; - bool tryReduce = false; - UInt32 reducedDictionarySize = 1 << 10; - if (inSizeForReduce != 0 && (methodFull.MethodID == k_LZMA /* || methodFull.MethodID == k_LZMA2 */)) - { - for (;;) - { - const UInt32 step = (reducedDictionarySize >> 1); - if (reducedDictionarySize >= *inSizeForReduce) - { - tryReduce = true; - break; - } - reducedDictionarySize += step; - if (reducedDictionarySize >= *inSizeForReduce) - { - tryReduce = true; - break; - } - if (reducedDictionarySize >= ((UInt32)11 << 30)) - break; - reducedDictionarySize += step; - } - } - CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2; #ifdef COMPRESS_MT @@ -110,50 +84,17 @@ HRESULT CEncoder::CreateMixerCoder( } #endif - if (methodFull.CoderProperties.Size() > 0) + + RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon)); + + /* + CMyComPtr<ICryptoResetSalt> resetSalt; + encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt); + if (resetSalt != NULL) { - CRecordVector<PROPID> propIDs; - int numProperties = methodFull.CoderProperties.Size(); - NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties]; - try - { - for (int i = 0; i < numProperties; i++) - { - const CProperty &property = methodFull.CoderProperties[i]; - propIDs.Add(property.PropID); - NWindows::NCOM::CPropVariant value = property.Value; - if (tryReduce && property.PropID == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal) - value.ulVal = reducedDictionarySize; - values[i] = value; - } - CMyComPtr<ICompressSetCoderProperties> setCoderProperties; - RINOK(encoderCommon.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties)); - RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties)); - } - catch(...) - { - delete []values; - throw; - } - delete []values; - } - - CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties; - - encoderCommon.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties); - - if (writeCoderProperties != NULL) - { - CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp; - CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); - outStreamSpec->Init(); - writeCoderProperties->WriteCoderProperties(outStream); - - size_t size = outStreamSpec->GetSize(); - - encodingInfo.Properties.SetCapacity(size); - memmove(encodingInfo.Properties, outStreamSpec->GetBuffer(), size); + resetSalt->ResetSalt(); } + */ #ifdef EXTERNAL_CODECS CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; @@ -268,6 +209,31 @@ HRESULT CEncoder::Encode( outStreamPointers.Add(outStreamSizeCount); for (i = 1; i < _bindInfo.OutStreams.Size(); i++) outStreamPointers.Add(tempBuffers[i - 1]); + + for (i = 0; i < _codersInfo.Size(); i++) + { + CCoderInfo &encodingInfo = _codersInfo[i]; + + CMyComPtr<ICryptoResetInitVector> resetInitVector; + _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector); + if (resetInitVector != NULL) + { + resetInitVector->ResetInitVector(); + } + + CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties; + _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties); + if (writeCoderProperties != NULL) + { + CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + outStreamSpec->Init(); + writeCoderProperties->WriteCoderProperties(outStream); + size_t size = outStreamSpec->GetSize(); + encodingInfo.Properties.SetCapacity(size); + memmove(encodingInfo.Properties, outStreamSpec->GetBuffer(), size); + } + } RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1, &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress)); @@ -325,14 +291,14 @@ HRESULT CEncoder::EncoderConstr() throw 1; if (!_options.Binds.IsEmpty()) throw 1; - NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; + NCoderMixer::CCoderStreamsInfo coderStreamsInfo; CMethodFull method; method.NumInStreams = 1; method.NumOutStreams = 1; coderStreamsInfo.NumInStreams = 1; coderStreamsInfo.NumOutStreams = 1; - method.MethodID = k_AES; + method.Id = k_AES; _options.Methods.Add(method); _bindInfo.Coders.Add(coderStreamsInfo); @@ -348,14 +314,14 @@ HRESULT CEncoder::EncoderConstr() for (i = 0; i < _options.Methods.Size(); i++) { const CMethodFull &methodFull = _options.Methods[i]; - NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; + NCoderMixer::CCoderStreamsInfo coderStreamsInfo; coderStreamsInfo.NumInStreams = methodFull.NumOutStreams; coderStreamsInfo.NumOutStreams = methodFull.NumInStreams; if (_options.Binds.IsEmpty()) { if (i < _options.Methods.Size() - 1) { - NCoderMixer2::CBindPair bindPair; + NCoderMixer::CBindPair bindPair; bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams; bindPair.OutIndex = numOutStreams; _bindInfo.BindPairs.Add(bindPair); @@ -376,7 +342,7 @@ HRESULT CEncoder::EncoderConstr() { for (i = 0; i < _options.Binds.Size(); i++) { - NCoderMixer2::CBindPair bindPair; + NCoderMixer::CBindPair bindPair; const CBind &bind = _options.Binds[i]; bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream; bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream; @@ -423,7 +389,7 @@ HRESULT CEncoder::EncoderConstr() for (i = 0; i < numCryptoStreams; i++) { - NCoderMixer2::CBindPair bindPair; + NCoderMixer::CBindPair bindPair; bindPair.InIndex = numInStreams + i; bindPair.OutIndex = _bindInfo.OutStreams[i]; _bindInfo.BindPairs.Add(bindPair); @@ -437,13 +403,13 @@ HRESULT CEncoder::EncoderConstr() for (i = 0; i < numCryptoStreams; i++) { - NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; + NCoderMixer::CCoderStreamsInfo coderStreamsInfo; CMethodFull method; method.NumInStreams = 1; method.NumOutStreams = 1; coderStreamsInfo.NumInStreams = method.NumOutStreams; coderStreamsInfo.NumOutStreams = method.NumInStreams; - method.MethodID = k_AES; + method.Id = k_AES; _options.Methods.Add(method); _bindInfo.Coders.Add(coderStreamsInfo); @@ -456,10 +422,10 @@ HRESULT CEncoder::EncoderConstr() for (int i = _options.Methods.Size() - 1; i >= 0; i--) { const CMethodFull &methodFull = _options.Methods[i]; - _decompressionMethods.Add(methodFull.MethodID); + _decompressionMethods.Add(methodFull.Id); } - _bindReverseConverter = new NCoderMixer2::CBindReverseConverter(_bindInfo); + _bindReverseConverter = new NCoderMixer::CBindReverseConverter(_bindInfo); _bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo); _constructed = true; return S_OK; diff --git a/CPP/7zip/Archive/7z/7zEncode.h b/CPP/7zip/Archive/7z/7zEncode.h index 588105c3..4909a6e8 100755 --- a/CPP/7zip/Archive/7z/7zEncode.h +++ b/CPP/7zip/Archive/7z/7zEncode.h @@ -21,15 +21,15 @@ namespace N7z { class CEncoder { - NCoderMixer2::CCoderMixer2MT *_mixerCoderSpec; + NCoderMixer::CCoderMixer2MT *_mixerCoderSpec; CMyComPtr<ICompressCoder2> _mixerCoder; CObjectVector<CCoderInfo> _codersInfo; CCompressionMethodMode _options; - NCoderMixer2::CBindInfo _bindInfo; - NCoderMixer2::CBindInfo _decompressBindInfo; - NCoderMixer2::CBindReverseConverter *_bindReverseConverter; + NCoderMixer::CBindInfo _bindInfo; + NCoderMixer::CBindInfo _decompressBindInfo; + NCoderMixer::CBindReverseConverter *_bindReverseConverter; CRecordVector<CMethodId> _decompressionMethods; HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp index dc0a6505..9fc45848 100755 --- a/CPP/7zip/Archive/7z/7zHandler.cpp +++ b/CPP/7zip/Archive/7z/7zHandler.cpp @@ -20,6 +20,10 @@ #endif #endif +#ifdef COMPRESS_MT +#include "../../../Windows/System.h" +#endif + using namespace NWindows; extern UString ConvertMethodIdToString(UInt64 id); @@ -29,10 +33,11 @@ namespace N7z { CHandler::CHandler() { + #ifdef EXTRACT_ONLY #ifdef COMPRESS_MT _numThreads = NWindows::NSystem::GetNumberOfProcessors(); #endif - #ifndef EXTRACT_ONLY + #else Init(); #endif } diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h index 77e4d25c..95e53340 100755 --- a/CPP/7zip/Archive/7z/7zHandler.h +++ b/CPP/7zip/Archive/7z/7zHandler.h @@ -9,12 +9,12 @@ #include "7zCompressionMode.h" -#ifdef COMPRESS_MT -#include "../../../Windows/System.h" -#endif - #include "../../Common/CreateCoder.h" +#ifndef EXTRACT_ONLY +#include "../Common/HandlerOut.h" +#endif + namespace NArchive { namespace N7z { @@ -44,15 +44,6 @@ struct CVolume }; #endif -#ifndef EXTRACT_ONLY - -struct COneMethodInfo -{ - CObjectVector<CProperty> CoderProperties; - UString MethodName; -}; -#endif - // {23170F69-40C1-278A-1000-000110070000} DEFINE_GUID(CLSID_CFormat7z, 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00); @@ -71,6 +62,9 @@ DEFINE_GUID(CLSID_CFormat7z, class CHandler: + #ifndef EXTRACT_ONLY + public NArchive::COutHandler, + #endif public IInArchive, #ifdef _7Z_VOL public IInArchiveGetStream, @@ -137,8 +131,6 @@ public: // ISetProperties - HRESULT SetSolidSettings(const UString &s); - HRESULT SetSolidSettings(const PROPVARIANT &value); #endif DECL_ISetCompressCodecsInfo @@ -154,37 +146,15 @@ private: NArchive::N7z::CArchiveDatabaseEx _database; #endif - + #ifdef EXTRACT_ONLY + #ifdef COMPRESS_MT UInt32 _numThreads; #endif - - #ifndef EXTRACT_ONLY - CObjectVector<COneMethodInfo> _methods; + + #else + CRecordVector<CBind> _binds; - bool _removeSfxBlock; - UInt64 _numSolidFiles; - UInt64 _numSolidBytes; - bool _numSolidBytesDefined; - bool _solidExtension; - - bool _compressHeaders; - bool _encryptHeaders; - - bool WriteModified; - bool WriteCreated; - bool WriteAccessed; - - - bool _autoFilter; - UInt32 _level; - - bool _volumeMode; - - DECL_EXTERNAL_CODECS_VARS - - HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value); - HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString); HRESULT SetPassword(CCompressionMethodMode &methodMode, IArchiveUpdateCallback *updateCallback); @@ -208,39 +178,6 @@ private: void FillPopIDs(); #endif - - #ifndef EXTRACT_ONLY - - void InitSolidFiles() { _numSolidFiles = UInt64(Int64(-1)); } - void InitSolidSize() { _numSolidBytes = UInt64(Int64(-1)); } - void InitSolid() - { - InitSolidFiles(); - InitSolidSize(); - _solidExtension = false; - _numSolidBytesDefined = false; - } - - void Init() - { - _removeSfxBlock = false; - _compressHeaders = true; - _encryptHeaders = false; - - WriteModified = true; - WriteCreated = false; - WriteAccessed = false; - - #ifdef COMPRESS_MT - _numThreads = NWindows::NSystem::GetNumberOfProcessors(); - #endif - - _level = 5; - _autoFilter = true; - _volumeMode = false; - InitSolid(); - } - #endif }; }} diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp index 80d63931..af4b9427 100755 --- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp +++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp @@ -1,4 +1,4 @@ -// 7z/OutHandler.cpp +// 7zHandlerOut.cpp #include "StdAfx.h" @@ -21,90 +21,19 @@ using namespace NWindows; namespace NArchive { namespace N7z { -const wchar_t *kCopyMethod = L"Copy"; -const wchar_t *kLZMAMethodName = L"LZMA"; -const wchar_t *kLZMA2MethodName = L"LZMA2"; -const wchar_t *kBZip2MethodName = L"BZip2"; -const wchar_t *kPpmdMethodName = L"PPMd"; -const wchar_t *kDeflateMethodName = L"Deflate"; -const wchar_t *kDeflate64MethodName = L"Deflate64"; +static const wchar_t *kLZMAMethodName = L"LZMA"; +static const wchar_t *kCopyMethod = L"Copy"; +static const wchar_t *kDefaultMethodName = kLZMAMethodName; -static const wchar_t *kLzmaMatchFinderX1 = L"HC4"; -static const wchar_t *kLzmaMatchFinderX5 = L"BT4"; - -static const UInt32 kLzmaAlgorithmX1 = 0; static const UInt32 kLzmaAlgorithmX5 = 1; - -static const UInt32 kLzmaDicSizeX1 = 1 << 16; -static const UInt32 kLzmaDicSizeX3 = 1 << 20; -static const UInt32 kLzmaDicSizeX5 = 1 << 24; -static const UInt32 kLzmaDicSizeX7 = 1 << 25; -static const UInt32 kLzmaDicSizeX9 = 1 << 26; - -static const UInt32 kLzmaFastBytesX1 = 32; -static const UInt32 kLzmaFastBytesX7 = 64; - -static const UInt32 kPpmdMemSizeX1 = (1 << 22); -static const UInt32 kPpmdMemSizeX5 = (1 << 24); -static const UInt32 kPpmdMemSizeX7 = (1 << 26); -static const UInt32 kPpmdMemSizeX9 = (192 << 20); - -static const UInt32 kPpmdOrderX1 = 4; -static const UInt32 kPpmdOrderX5 = 6; -static const UInt32 kPpmdOrderX7 = 16; -static const UInt32 kPpmdOrderX9 = 32; - -static const UInt32 kDeflateAlgoX1 = 0; -static const UInt32 kDeflateAlgoX5 = 1; - -static const UInt32 kDeflateFastBytesX1 = 32; -static const UInt32 kDeflateFastBytesX7 = 64; -static const UInt32 kDeflateFastBytesX9 = 128; - -static const UInt32 kDeflatePassesX1 = 1; -static const UInt32 kDeflatePassesX7 = 3; -static const UInt32 kDeflatePassesX9 = 10; - -static const UInt32 kBZip2NumPassesX1 = 1; -static const UInt32 kBZip2NumPassesX7 = 2; -static const UInt32 kBZip2NumPassesX9 = 7; - -static const UInt32 kBZip2DicSizeX1 = 100000; -static const UInt32 kBZip2DicSizeX3 = 500000; -static const UInt32 kBZip2DicSizeX5 = 900000; - -const wchar_t *kDefaultMethodName = kLZMAMethodName; - static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2"; static const UInt32 kDictionaryForHeaders = 1 << 20; static const UInt32 kNumFastBytesForHeaders = 273; static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5; -static bool IsCopyMethod(const UString &methodName) +static inline bool IsCopyMethod(const UString &methodName) { return (methodName.CompareNoCase(kCopyMethod) == 0); } -static bool IsLZMAMethod(const UString &methodName) -{ - return - (methodName.CompareNoCase(kLZMAMethodName) == 0) || - (methodName.CompareNoCase(kLZMA2MethodName) == 0); -} - -/* -static bool IsLZMethod(const UString &methodName) - { return IsLZMAMethod(methodName); } -*/ - -static bool IsBZip2Method(const UString &methodName) - { return (methodName.CompareNoCase(kBZip2MethodName) == 0); } - -static bool IsPpmdMethod(const UString &methodName) - { return (methodName.CompareNoCase(kPpmdMethodName) == 0); } - -static bool IsDeflateMethod(const UString &methodName) - { return (methodName.CompareNoCase(kDeflateMethodName) == 0) || - (methodName.CompareNoCase(kDeflate64MethodName) == 0); } - STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) { *type = NFileTimeType::kWindows; @@ -136,60 +65,6 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode, return S_OK; } -struct CNameToPropID -{ - PROPID PropID; - VARTYPE VarType; - const wchar_t *Name; -}; - -CNameToPropID g_NameToPropID[] = -{ - { NCoderPropID::kOrder, VT_UI4, L"O" }, - { NCoderPropID::kPosStateBits, VT_UI4, L"PB" }, - { NCoderPropID::kLitContextBits, VT_UI4, L"LC" }, - { NCoderPropID::kLitPosBits, VT_UI4, L"LP" }, - - { NCoderPropID::kNumPasses, VT_UI4, L"Pass" }, - { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" }, - { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" }, - { NCoderPropID::kAlgorithm, VT_UI4, L"a" }, - { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" }, - { NCoderPropID::kNumThreads, VT_UI4, L"mt" } -}; - -bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, - NCOM::CPropVariant &destProp) -{ - if (varType == srcProp.vt) - { - destProp = srcProp; - return true; - } - if (varType == VT_UI1) - { - if(srcProp.vt == VT_UI4) - { - UInt32 value = srcProp.ulVal; - if (value > 0xFF) - return false; - destProp = Byte(value); - return true; - } - } - return false; -} - -const int kNumNameToPropIDItems = sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); - -int FindPropIdFromStringName(const UString &name) -{ - for (int i = 0; i < kNumNameToPropIDItems; i++) - if (name.CompareNoCase(g_NameToPropID[i].Name) == 0) - return i; - return -1; -} - HRESULT CHandler::SetCompressionMethod( CCompressionMethodMode &methodMode, CCompressionMethodMode &headerMethod) @@ -210,28 +85,28 @@ HRESULT CHandler::SetCompressionMethod( COneMethodInfo oneMethodInfo; oneMethodInfo.MethodName = kLZMAMethodName; { - CProperty property; - property.PropID = NCoderPropID::kMatchFinder; + CProp property; + property.Id = NCoderPropID::kMatchFinder; property.Value = kLzmaMatchFinderForHeaders; - oneMethodInfo.CoderProperties.Add(property); + oneMethodInfo.Properties.Add(property); } { - CProperty property; - property.PropID = NCoderPropID::kAlgorithm; + CProp property; + property.Id = NCoderPropID::kAlgorithm; property.Value = kAlgorithmForHeaders; - oneMethodInfo.CoderProperties.Add(property); + oneMethodInfo.Properties.Add(property); } { - CProperty property; - property.PropID = NCoderPropID::kNumFastBytes; + CProp property; + property.Id = NCoderPropID::kNumFastBytes; property.Value = UInt32(kNumFastBytesForHeaders); - oneMethodInfo.CoderProperties.Add(property); + oneMethodInfo.Properties.Add(property); } { - CProperty property; - property.PropID = NCoderPropID::kDictionarySize; + CProp property; + property.Id = NCoderPropID::kDictionarySize; property.Value = UInt32(kDictionaryForHeaders); - oneMethodInfo.CoderProperties.Add(property); + oneMethodInfo.Properties.Add(property); } headerMethodInfoVector.Add(oneMethodInfo); HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector @@ -244,21 +119,6 @@ HRESULT CHandler::SetCompressionMethod( return S_OK; } -static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID, - const NWindows::NCOM::CPropVariant &value) -{ - int j; - for (j = 0; j < oneMethodInfo.CoderProperties.Size(); j++) - if (oneMethodInfo.CoderProperties[j].PropID == propID) - break; - if (j != oneMethodInfo.CoderProperties.Size()) - return; - CProperty property; - property.PropID = propID; - property.Value = value; - oneMethodInfo.CoderProperties.Add(property); -} - HRESULT CHandler::SetCompressionMethod( CCompressionMethodMode &methodMode, CObjectVector<COneMethodInfo> &methodsInfo @@ -280,113 +140,31 @@ HRESULT CHandler::SetCompressionMethod( for(int i = 0; i < methodsInfo.Size(); i++) { COneMethodInfo &oneMethodInfo = methodsInfo[i]; - if (oneMethodInfo.MethodName.IsEmpty()) - oneMethodInfo.MethodName = kDefaultMethodName; - - if (!IsCopyMethod(oneMethodInfo.MethodName)) - needSolid = true; - - if (IsLZMAMethod(oneMethodInfo.MethodName)) - { - UInt32 dicSize = - (level >= 9 ? kLzmaDicSizeX9 : - (level >= 7 ? kLzmaDicSizeX7 : - (level >= 5 ? kLzmaDicSizeX5 : - (level >= 3 ? kLzmaDicSizeX3 : - kLzmaDicSizeX1)))); - - UInt32 algorithm = - (level >= 5 ? kLzmaAlgorithmX5 : - kLzmaAlgorithmX1); - - UInt32 fastBytes = - (level >= 7 ? kLzmaFastBytesX7 : - kLzmaFastBytesX1); - - const wchar_t *matchFinder = - (level >= 5 ? kLzmaMatchFinderX5 : - kLzmaMatchFinderX1); - - SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); - SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algorithm); - SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); - SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder); - #ifdef COMPRESS_MT - SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); - #endif - } - else if (IsDeflateMethod(oneMethodInfo.MethodName)) - { - UInt32 fastBytes = - (level >= 9 ? kDeflateFastBytesX9 : - (level >= 7 ? kDeflateFastBytesX7 : - kDeflateFastBytesX1)); - - UInt32 numPasses = - (level >= 9 ? kDeflatePassesX9 : - (level >= 7 ? kDeflatePassesX7 : - kDeflatePassesX1)); - UInt32 algo = - (level >= 5 ? kDeflateAlgoX5 : - kDeflateAlgoX1); - - SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo); - SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); - SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); - } - else if (IsBZip2Method(oneMethodInfo.MethodName)) - { - UInt32 numPasses = - (level >= 9 ? kBZip2NumPassesX9 : - (level >= 7 ? kBZip2NumPassesX7 : - kBZip2NumPassesX1)); - - UInt32 dicSize = - (level >= 5 ? kBZip2DicSizeX5 : - (level >= 3 ? kBZip2DicSizeX3 : - kBZip2DicSizeX1)); - - SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); - SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); + SetCompressionMethod2(oneMethodInfo #ifdef COMPRESS_MT - SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); + , numThreads #endif - } - else if (IsPpmdMethod(oneMethodInfo.MethodName)) - { - UInt32 useMemSize = - (level >= 9 ? kPpmdMemSizeX9 : - (level >= 7 ? kPpmdMemSizeX7 : - (level >= 5 ? kPpmdMemSizeX5 : - kPpmdMemSizeX1))); - - UInt32 order = - (level >= 9 ? kPpmdOrderX9 : - (level >= 7 ? kPpmdOrderX7 : - (level >= 5 ? kPpmdOrderX5 : - kPpmdOrderX1))); - - SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize); - SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order); - } + ); + if (!IsCopyMethod(oneMethodInfo.MethodName)) + needSolid = true; CMethodFull methodFull; if (!FindMethod( EXTERNAL_CODECS_VARS - oneMethodInfo.MethodName, methodFull.MethodID, methodFull.NumInStreams, methodFull.NumOutStreams)) + oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams)) return E_INVALIDARG; - methodFull.CoderProperties = oneMethodInfo.CoderProperties; + methodFull.Properties = oneMethodInfo.Properties; methodMode.Methods.Add(methodFull); if (!_numSolidBytesDefined) { - for (int j = 0; j < methodFull.CoderProperties.Size(); j++) + for (int j = 0; j < methodFull.Properties.Size(); j++) { - const CProperty &prop = methodFull.CoderProperties[j]; - if ((prop.PropID == NCoderPropID::kDictionarySize || - prop.PropID == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4) + const CProp &prop = methodFull.Properties[j]; + if ((prop.Id == NCoderPropID::kDictionarySize || + prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4) { _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7; const UInt64 kMinSize = (1 << 24); @@ -652,198 +430,11 @@ static HRESULT GetBindInfo(UString &srcString, CBind &bind) return S_OK; } -static void SplitParams(const UString &srcString, UStringVector &subStrings) -{ - subStrings.Clear(); - UString name; - int len = srcString.Length(); - if (len == 0) - return; - for (int i = 0; i < len; i++) - { - wchar_t c = srcString[i]; - if (c == L':') - { - subStrings.Add(name); - name.Empty(); - } - else - name += c; - } - subStrings.Add(name); -} - -static void SplitParam(const UString ¶m, UString &name, UString &value) -{ - int eqPos = param.Find(L'='); - if (eqPos >= 0) - { - name = param.Left(eqPos); - value = param.Mid(eqPos + 1); - return; - } - for(int i = 0; i < param.Length(); i++) - { - wchar_t c = param[i]; - if (c >= L'0' && c <= L'9') - { - name = param.Left(i); - value = param.Mid(i); - return; - } - } - name = param; -} - -HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value) -{ - CProperty property; - if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0) - { - UInt32 dicSize; - RINOK(ParsePropDictionaryValue(value, dicSize)); - if (name.CompareNoCase(L"D") == 0) - property.PropID = NCoderPropID::kDictionarySize; - else - property.PropID = NCoderPropID::kUsedMemorySize; - property.Value = dicSize; - oneMethodInfo.CoderProperties.Add(property); - } - else - { - int index = FindPropIdFromStringName(name); - if (index < 0) - return E_INVALIDARG; - - const CNameToPropID &nameToPropID = g_NameToPropID[index]; - property.PropID = nameToPropID.PropID; - - NCOM::CPropVariant propValue; - - - if (nameToPropID.VarType == VT_BSTR) - propValue = value; - else - { - UInt32 number; - if (ParseStringToUInt32(value, number) == value.Length()) - propValue = number; - else - propValue = value; - } - - if (!ConvertProperty(propValue, nameToPropID.VarType, property.Value)) - return E_INVALIDARG; - - oneMethodInfo.CoderProperties.Add(property); - } - return S_OK; -} - -HRESULT CHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString) -{ - UStringVector params; - SplitParams(srcString, params); - if (params.Size() > 0) - oneMethodInfo.MethodName = params[0]; - for (int i = 1; i < params.Size(); i++) - { - const UString ¶m = params[i]; - UString name, value; - SplitParam(param, name, value); - RINOK(SetParam(oneMethodInfo, name, value)); - } - return S_OK; -} - -HRESULT CHandler::SetSolidSettings(const UString &s) -{ - UString s2 = s; - s2.MakeUpper(); - if (s2.IsEmpty() || s2.Compare(L"ON") == 0) - { - InitSolid(); - return S_OK; - } - if (s2.Compare(L"OFF") == 0) - { - _numSolidFiles = 1; - return S_OK; - } - for (int i = 0; i < s2.Length();) - { - const wchar_t *start = ((const wchar_t *)s2) + i; - const wchar_t *end; - UInt64 v = ConvertStringToUInt64(start, &end); - if (start == end) - { - if (s2[i++] != 'E') - return E_INVALIDARG; - _solidExtension = true; - continue; - } - i += (int)(end - start); - if (i == s2.Length()) - return E_INVALIDARG; - wchar_t c = s2[i++]; - switch(c) - { - case 'F': - if (v < 1) - v = 1; - _numSolidFiles = v; - break; - case 'B': - _numSolidBytes = v; - _numSolidBytesDefined = true; - break; - case 'K': - _numSolidBytes = (v << 10); - _numSolidBytesDefined = true; - break; - case 'M': - _numSolidBytes = (v << 20); - _numSolidBytesDefined = true; - break; - case 'G': - _numSolidBytes = (v << 30); - _numSolidBytesDefined = true; - break; - default: - return E_INVALIDARG; - } - } - return S_OK; -} - -HRESULT CHandler::SetSolidSettings(const PROPVARIANT &value) -{ - switch(value.vt) - { - case VT_EMPTY: - InitSolid(); - return S_OK; - case VT_BSTR: - return SetSolidSettings(value.bstrVal); - default: - return E_INVALIDARG; - } -} - STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) { COM_TRY_BEGIN - _methods.Clear(); _binds.Clear(); - Init(); - #ifdef COMPRESS_MT - const UInt32 numProcessors = NSystem::GetNumberOfProcessors(); - #endif - - UInt32 mainDicSize = 0xFFFFFFFF; - UInt32 mainDicMethodIndex = 0xFFFFFFFF; - - UInt32 minNumber = 0; + BeforeSetProperty(); for (int i = 0; i < numProperties; i++) { @@ -854,14 +445,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v const PROPVARIANT &value = values[i]; - if (name[0] == 'X') - { - name.Delete(0); - _level = 9; - RINOK(ParsePropValue(name, value, _level)); - continue; - } - if (name[0] == 'B') { name.Delete(0); @@ -871,142 +454,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v continue; } - if (name[0] == L'S') - { - name.Delete(0); - if (name.IsEmpty()) - { - RINOK(SetSolidSettings(value)); - } - else - { - RINOK(SetSolidSettings(name)); - } - continue; - } - - - UInt32 number; - int index = ParseStringToUInt32(name, number); - UString realName = name.Mid(index); - if (index == 0) - { - if(name.Left(2).CompareNoCase(L"MT") == 0) - { - #ifdef COMPRESS_MT - RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads)); - #endif - continue; - } - else if (name.CompareNoCase(L"RSFX") == 0) - { - RINOK(SetBoolProperty(_removeSfxBlock, value)); - continue; - } - else if (name.CompareNoCase(L"F") == 0) - { - RINOK(SetBoolProperty(_autoFilter, value)); - continue; - } - else if (name.CompareNoCase(L"HC") == 0) - { - RINOK(SetBoolProperty(_compressHeaders, value)); - continue; - } - else if (name.CompareNoCase(L"HCF") == 0) - { - bool compressHeadersFull = true; - RINOK(SetBoolProperty(compressHeadersFull, value)); - if (!compressHeadersFull) - return E_INVALIDARG; - continue; - } - else if (name.CompareNoCase(L"HE") == 0) - { - RINOK(SetBoolProperty(_encryptHeaders, value)); - continue; - } - else if (name.CompareNoCase(L"TM") == 0) - { - RINOK(SetBoolProperty(WriteModified, value)); - continue; - } - else if (name.CompareNoCase(L"TC") == 0) - { - RINOK(SetBoolProperty(WriteCreated, value)); - continue; - } - else if (name.CompareNoCase(L"TA") == 0) - { - RINOK(SetBoolProperty(WriteAccessed, value)); - continue; - } - else if (name.CompareNoCase(L"V") == 0) - { - RINOK(SetBoolProperty(_volumeMode, value)); - continue; - } - number = 0; - } - if (number > 10000) - return E_FAIL; - if (number < minNumber) - return E_INVALIDARG; - number -= minNumber; - for(int j = _methods.Size(); j <= (int)number; j++) - { - COneMethodInfo oneMethodInfo; - _methods.Add(oneMethodInfo); - } - - COneMethodInfo &oneMethodInfo = _methods[number]; - - if (realName.Length() == 0) - { - if (value.vt != VT_BSTR) - return E_INVALIDARG; - - // oneMethodInfo.MethodName = UnicodeStringToMultiByte(UString(value.bstrVal)); - RINOK(SetParams(oneMethodInfo, value.bstrVal)); - } - else - { - CProperty property; - if (realName.Left(1).CompareNoCase(L"D") == 0) - { - UInt32 dicSize; - RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize)); - property.PropID = NCoderPropID::kDictionarySize; - property.Value = dicSize; - oneMethodInfo.CoderProperties.Add(property); - if (number <= mainDicMethodIndex) - mainDicSize = dicSize; - } - else if (realName.Left(3).CompareNoCase(L"MEM") == 0) - { - UInt32 dicSize; - RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize)); - property.PropID = NCoderPropID::kUsedMemorySize; - property.Value = dicSize; - oneMethodInfo.CoderProperties.Add(property); - if (number <= mainDicMethodIndex) - mainDicSize = dicSize; - } - else - { - int index = FindPropIdFromStringName(realName); - if (index < 0) - return E_INVALIDARG; - - const CNameToPropID &nameToPropID = g_NameToPropID[index]; - property.PropID = nameToPropID.PropID; - - if (!ConvertProperty(value, nameToPropID.VarType, property.Value)) - return E_INVALIDARG; - - oneMethodInfo.CoderProperties.Add(property); - } - } + RINOK(SetProperty(name, value)); } return S_OK; diff --git a/CPP/7zip/Archive/7z/7zHeader.cpp b/CPP/7zip/Archive/7z/7zHeader.cpp index cff4d121..425231fc 100755 --- a/CPP/7zip/Archive/7z/7zHeader.cpp +++ b/CPP/7zip/Archive/7z/7zHeader.cpp @@ -7,12 +7,20 @@ namespace NArchive { namespace N7z { Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C}; +#ifdef _7Z_VOL Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; +#endif class SignatureInitializer { public: - SignatureInitializer() { kSignature[0]--; kFinishSignature[0]--;}; + SignatureInitializer() + { + kSignature[0]--; + #ifdef _7Z_VOL + kFinishSignature[0]--; + #endif + }; } g_SignatureInitializer; }} diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp index d1ad9da8..c9150898 100755 --- a/CPP/7zip/Archive/7z/7zIn.cpp +++ b/CPP/7zip/Archive/7z/7zIn.cpp @@ -12,7 +12,9 @@ extern "C" } // define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader -// #define FORMAT_7Z_RECOVERY +#ifndef _SFX +#define FORMAT_7Z_RECOVERY +#endif namespace NArchive { namespace N7z { @@ -1268,13 +1270,13 @@ HRESULT CInArchive::ReadDatabase( return S_FALSE; nextHeaderSize = realProcessedSize - i; nextHeaderOffset = cur2 - cur + i; - nextHeaderCRC = CCRC::CalculateDigest(buf + i, (size_t)nextHeaderSize); + nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); RINOK(_stream->Seek(cur, STREAM_SEEK_SET, &_position)); } #endif #ifdef FORMAT_7Z_RECOVERY - crcFromArchive = crc.GetDigest(); + crcFromArchive = CRC_GET_DIGEST(crc); #endif #ifdef _7Z_VOL diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h index cad88dc1..388f19d3 100755 --- a/CPP/7zip/Archive/7z/7zItem.h +++ b/CPP/7zip/Archive/7z/7zItem.h @@ -4,7 +4,7 @@ #define __7Z_ITEM_H #include "../../../Common/Buffer.h" -#include "../../../Common/String.h" +#include "../../../Common/MyString.h" #include "../../Common/MethodId.h" #include "7zHeader.h" diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp index 2399f652..a00cdf5c 100755 --- a/CPP/7zip/Archive/7z/7zOut.cpp +++ b/CPP/7zip/Archive/7z/7zOut.cpp @@ -151,7 +151,7 @@ HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) { if (!Stream) return E_FAIL; - WriteSignature(); + RINOK(WriteSignature()); RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos)); } return S_OK; diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp index 2b197adb..59e7c4fc 100755 --- a/CPP/7zip/Archive/7z/7zUpdate.cpp +++ b/CPP/7zip/Archive/7z/7zUpdate.cpp @@ -357,7 +357,7 @@ static const UInt64 k_BCJ2 = 0x0303011B; static bool GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult) { - methodResult.MethodID = methodID; + methodResult.Id = methodID; methodResult.NumInStreams = numInStreams; methodResult.NumOutStreams = 1; return true; @@ -376,28 +376,28 @@ static bool MakeExeMethod(const CCompressionMethodMode &method, if (!GetMethodFull(k_LZMA, 1, methodFull)) return false; { - CProperty property; - property.PropID = NCoderPropID::kAlgorithm; + CProp property; + property.Id = NCoderPropID::kAlgorithm; property.Value = kAlgorithmForBCJ2_LZMA; - methodFull.CoderProperties.Add(property); + methodFull.Properties.Add(property); } { - CProperty property; - property.PropID = NCoderPropID::kMatchFinder; + CProp property; + property.Id = NCoderPropID::kMatchFinder; property.Value = kMatchFinderForBCJ2_LZMA; - methodFull.CoderProperties.Add(property); + methodFull.Properties.Add(property); } { - CProperty property; - property.PropID = NCoderPropID::kDictionarySize; + CProp property; + property.Id = NCoderPropID::kDictionarySize; property.Value = kDictionaryForBCJ2_LZMA; - methodFull.CoderProperties.Add(property); + methodFull.Properties.Add(property); } { - CProperty property; - property.PropID = NCoderPropID::kNumFastBytes; + CProp property; + property.Id = NCoderPropID::kNumFastBytes; property.Value = kNumFastBytesForBCJ2_LZMA; - methodFull.CoderProperties.Add(property); + methodFull.Properties.Add(property); } exeMethod.Methods.Add(methodFull); diff --git a/CPP/7zip/Archive/7z/makefile b/CPP/7zip/Archive/7z/makefile index 03ef4e46..1a72da0e 100755 --- a/CPP/7zip/Archive/7z/makefile +++ b/CPP/7zip/Archive/7z/makefile @@ -31,10 +31,10 @@ COMMON_OBJS = \ $O\CRC.obj \ $O\IntToString.obj \ $O\NewHandler.obj \ - $O\String.obj \ + $O\MyString.obj \ $O\StringConvert.obj \ $O\StringToInt.obj \ - $O\Vector.obj \ + $O\MyVector.obj \ WIN_OBJS = \ $O\DLL.obj \ @@ -42,7 +42,8 @@ WIN_OBJS = \ $O\FileFind.obj \ $O\FileIO.obj \ $O\PropVariant.obj \ - $O\Synchronization.obj + $O\Synchronization.obj \ + $O\System.obj \ 7ZIP_COMMON_OBJS = \ $O\CreateCoder.obj \ @@ -51,16 +52,19 @@ WIN_OBJS = \ $O\LimitedStreams.obj \ $O\LockedStream.obj \ $O\MethodId.obj \ + $O\MethodProps.obj \ $O\OutBuffer.obj \ $O\ProgressUtils.obj \ $O\StreamBinder.obj \ $O\StreamObjects.obj \ $O\StreamUtils.obj \ + $O\VirtThread.obj \ AR_COMMON_OBJS = \ $O\CoderMixer2.obj \ $O\CoderMixer2MT.obj \ $O\CrossThreadProgress.obj \ + $O\HandlerOut.obj \ $O\InStreamWithCRC.obj \ $O\ItemNameUtils.obj \ $O\MultiStream.obj \ @@ -69,6 +73,7 @@ AR_COMMON_OBJS = \ C_OBJS = \ $O\Alloc.obj \ + $O\Threads.obj \ !include "../../Crc2.mak" diff --git a/CPP/7zip/Archive/Arj/ArjItem.h b/CPP/7zip/Archive/Arj/ArjItem.h index d48fe38d..a0112107 100755 --- a/CPP/7zip/Archive/Arj/ArjItem.h +++ b/CPP/7zip/Archive/Arj/ArjItem.h @@ -4,7 +4,7 @@ #define __ARCHIVE_ARJ_ITEM_H #include "Common/Types.h" -#include "Common/String.h" +#include "Common/MyString.h" #include "ArjHeader.h" namespace NArchive { diff --git a/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp b/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp index 38797c33..134d4124 100755 --- a/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp +++ b/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp @@ -6,7 +6,6 @@ #include "BZip2Update.h" #include "Common/Defs.h" -#include "Common/String.h" #include "Windows/PropVariant.h" diff --git a/CPP/7zip/Archive/Cab/CabItem.h b/CPP/7zip/Archive/Cab/CabItem.h index 21327eca..8b41fe69 100755 --- a/CPP/7zip/Archive/Cab/CabItem.h +++ b/CPP/7zip/Archive/Cab/CabItem.h @@ -4,7 +4,7 @@ #define __ARCHIVE_CAB_ITEM_H #include "Common/Types.h" -#include "Common/String.h" +#include "Common/MyString.h" #include "CabHeader.h" namespace NArchive { diff --git a/CPP/7zip/Archive/Chm/ChmIn.h b/CPP/7zip/Archive/Chm/ChmIn.h index ebf3c4be..e677c618 100755 --- a/CPP/7zip/Archive/Chm/ChmIn.h +++ b/CPP/7zip/Archive/Chm/ChmIn.h @@ -3,7 +3,7 @@ #ifndef __ARCHIVE_CHM_IN_H #define __ARCHIVE_CHM_IN_H -#include "Common/String.h" +#include "Common/MyString.h" #include "Common/Buffer.h" #include "../../IStream.h" #include "../../Common/InBuffer.h" diff --git a/CPP/7zip/Archive/Common/CoderMixer.cpp b/CPP/7zip/Archive/Common/CoderMixer.cpp new file mode 100755 index 00000000..db626fe1 --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixer.cpp @@ -0,0 +1,19 @@ +// CoderMixer.cpp + +#include "StdAfx.h" + +#include "CoderMixer.h" + +namespace NCoderMixer { + +void CCoderInfo::SetCoderInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + InSizeAssigned = (inSize != 0); + if (InSizeAssigned) + InSizeValue = *inSize; + OutSizeAssigned = (outSize != 0); + if (OutSizeAssigned) + OutSizeValue = *outSize; +} + +} diff --git a/CPP/7zip/Archive/Common/CoderMixer.h b/CPP/7zip/Archive/Common/CoderMixer.h new file mode 100755 index 00000000..6379dd80 --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixer.h @@ -0,0 +1,32 @@ +// CoderMixer.h + +#ifndef __CODER_MIXER_H +#define __CODER_MIXER_H + +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" + +namespace NCoderMixer { + +struct CCoderInfo +{ + CMyComPtr<ICompressCoder> Coder; + CMyComPtr<ISequentialInStream> InStream; + CMyComPtr<ISequentialOutStream> OutStream; + CMyComPtr<ICompressProgressInfo> Progress; + + UInt64 InSizeValue; + UInt64 OutSizeValue; + bool InSizeAssigned; + bool OutSizeAssigned; + + void ReInit() + { + InSizeAssigned = OutSizeAssigned = false; + } + + void SetCoderInfo(const UInt64 *inSize, const UInt64 *outSize); +}; + +} +#endif diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp index 8f46e985..d11e9e60 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2.cpp @@ -4,7 +4,7 @@ #include "CoderMixer2.h" -namespace NCoderMixer2 { +namespace NCoderMixer { CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo): _srcBindInfo(srcBindInfo) @@ -81,7 +81,7 @@ void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo) destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]); } -CCoderInfo::CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams): +CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams): NumInStreams(numInStreams), NumOutStreams(numOutStreams) { @@ -111,7 +111,7 @@ static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, } } -void CCoderInfo::SetCoderInfo(const UInt64 **inSizes, +void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes) { SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h index 597a7b60..be68c680 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2.h +++ b/CPP/7zip/Archive/Common/CoderMixer2.h @@ -3,12 +3,12 @@ #ifndef __CODER_MIXER2_H #define __CODER_MIXER2_H -#include "../../../Common/Vector.h" +#include "../../../Common/MyVector.h" #include "../../../Common/Types.h" #include "../../../Common/MyCom.h" #include "../../ICoder.h" -namespace NCoderMixer2 { +namespace NCoderMixer { struct CBindPair { @@ -127,7 +127,7 @@ struct CBindInfo class CBindReverseConverter { UInt32 _numSrcOutStreams; - NCoderMixer2::CBindInfo _srcBindInfo; + NCoderMixer::CBindInfo _srcBindInfo; CRecordVector<UInt32> _srcInToDestOutMap; CRecordVector<UInt32> _srcOutToDestInMap; CRecordVector<UInt32> _destInToSrcOutMap; @@ -135,11 +135,11 @@ public: UInt32 NumSrcInStreams; CRecordVector<UInt32> DestOutToSrcInMap; - CBindReverseConverter(const NCoderMixer2::CBindInfo &srcBindInfo); - void CreateReverseBindInfo(NCoderMixer2::CBindInfo &destBindInfo); + CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo); + void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo); }; -struct CCoderInfo +struct CCoderInfo2 { CMyComPtr<ICompressCoder> Coder; CMyComPtr<ICompressCoder2> Coder2; @@ -151,8 +151,14 @@ struct CCoderInfo CRecordVector<const UInt64 *> InSizePointers; CRecordVector<const UInt64 *> OutSizePointers; - CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams); + CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams); void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes); + + HRESULT QueryInterface(REFGUID iid, void** pp) const + { + IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2; + return p->QueryInterface(iid, pp); + } }; class CCoderMixer2 diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp index 8a37a10d..bff689dd 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @@ -3,16 +3,11 @@ #include "StdAfx.h" #include "CoderMixer2MT.h" -#include "CrossThreadProgress.h" -using namespace NWindows; -using namespace NSynchronization; +namespace NCoderMixer { -namespace NCoderMixer2 { - -CThreadCoderInfo::CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams): - ExitEvent(NULL), - CCoderInfo(numInStreams, numOutStreams) +CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams): + CCoderInfo2(numInStreams, numOutStreams) { InStreams.Reserve(NumInStreams); InStreamPointers.Reserve(NumInStreams); @@ -20,62 +15,38 @@ CThreadCoderInfo::CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams): OutStreamPointers.Reserve(NumOutStreams); } -class CCoderInfoFlusher2 +void CCoder2::Execute() { Code(NULL); } + +void CCoder2::Code(ICompressProgressInfo *progress) { - CThreadCoderInfo *m_CoderInfo; -public: - CCoderInfoFlusher2(CThreadCoderInfo *coderInfo): m_CoderInfo(coderInfo) {} - ~CCoderInfoFlusher2() + InStreamPointers.Clear(); + OutStreamPointers.Clear(); + UInt32 i; + for (i = 0; i < NumInStreams; i++) { - int i; - for (i = 0; i < m_CoderInfo->InStreams.Size(); i++) - m_CoderInfo->InStreams[i].Release(); - for (i = 0; i < m_CoderInfo->OutStreams.Size(); i++) - m_CoderInfo->OutStreams[i].Release(); - m_CoderInfo->CompressionCompletedEvent.Set(); + if (InSizePointers[i] != NULL) + InSizePointers[i] = &InSizes[i]; + InStreamPointers.Add(InStreams[i]); } -}; - -bool CThreadCoderInfo::WaitAndCode() -{ - HANDLE events[2] = { ExitEvent, CompressEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - return false; - + for (i = 0; i < NumOutStreams; i++) { - InStreamPointers.Clear(); - OutStreamPointers.Clear(); - UInt32 i; - for (i = 0; i < NumInStreams; i++) - { - if (InSizePointers[i] != NULL) - InSizePointers[i] = &InSizes[i]; - InStreamPointers.Add(InStreams[i]); - } - for (i = 0; i < NumOutStreams; i++) - { - if (OutSizePointers[i] != NULL) - OutSizePointers[i] = &OutSizes[i]; - OutStreamPointers.Add(OutStreams[i]); - } - CCoderInfoFlusher2 coderInfoFlusher(this); - if (Coder) - Result = Coder->Code(InStreamPointers[0], - OutStreamPointers[0], - InSizePointers[0], - OutSizePointers[0], - Progress); - else - Result = Coder2->Code(&InStreamPointers.Front(), - &InSizePointers.Front(), - NumInStreams, - &OutStreamPointers.Front(), - &OutSizePointers.Front(), - NumOutStreams, - Progress); + if (OutSizePointers[i] != NULL) + OutSizePointers[i] = &OutSizes[i]; + OutStreamPointers.Add(OutStreams[i]); + } + if (Coder) + Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], + InSizePointers[0], OutSizePointers[0], progress); + else + Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams, + &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress); + { + int i; + for (i = 0; i < InStreams.Size(); i++) + InStreams[i].Release(); + for (i = 0; i < OutStreams.Size(); i++) + OutStreams[i].Release(); } - return true; } static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, @@ -99,54 +70,15 @@ static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, } -void CThreadCoderInfo::SetCoderInfo(const UInt64 **inSizes, - const UInt64 **outSizes, ICompressProgressInfo *progress) +void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes) { - Progress = progress; SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); } -static THREAD_FUNC_DECL CoderThread(void *threadCoderInfo) -{ - for (;;) - { - if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode()) - return 0; - } -} - ////////////////////////////////////// // CCoderMixer2MT -static THREAD_FUNC_DECL MainCoderThread(void *threadCoderInfo) -{ - for (;;) - { - if (!((CCoderMixer2MT *)threadCoderInfo)->MyCode()) - return 0; - } -} - -CCoderMixer2MT::CCoderMixer2MT() -{ - if (CreateEvents() != S_OK) - throw 271824; - if (_mainThread.Create(MainCoderThread, this) != S_OK) - throw 271825; -} - -CCoderMixer2MT::~CCoderMixer2MT() -{ - _exitEvent.Set(); - _mainThread.Wait(); - for(int i = 0; i < _threads.Size(); i++) - { - _threads[i].Wait(); - _threads[i].Close(); - } -} - HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo) { _bindInfo = bindInfo; @@ -161,48 +93,23 @@ HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo) void CCoderMixer2MT::AddCoderCommon() { - int index = _coderInfoVector.Size(); - const CCoderStreamsInfo &CoderStreamsInfo = _bindInfo.Coders[index]; - - CThreadCoderInfo threadCoderInfo(CoderStreamsInfo.NumInStreams, - CoderStreamsInfo.NumOutStreams); - _coderInfoVector.Add(threadCoderInfo); - CThreadCoderInfo *tci = &_coderInfoVector.Back(); - tci->CreateEvents(); - tci->ExitEvent = _exitEvent; - - NWindows::CThread newThread; - _threads.Add(newThread); - if (_threads.Back().Create(CoderThread, tci) != S_OK) - throw 271824; + const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()]; + CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams); + _coders.Add(threadCoderInfo); } void CCoderMixer2MT::AddCoder(ICompressCoder *coder) { AddCoderCommon(); - _coderInfoVector.Back().Coder = coder; + _coders.Back().Coder = coder; } void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder) { AddCoderCommon(); - _coderInfoVector.Back().Coder2 = coder; + _coders.Back().Coder2 = coder; } -/* -void CCoderMixer2MT::FinishAddingCoders() -{ - for(int i = 0; i < _coderInfoVector.Size(); i++) - { - DWORD id; - HANDLE newThread = ::CreateThread(NULL, 0, CoderThread, - &_coderInfoVector[i], 0, &id); - if (newThread == 0) - throw 271824; - _threads.Add(newThread); - } -} -*/ void CCoderMixer2MT::ReInit() { @@ -211,17 +118,16 @@ void CCoderMixer2MT::ReInit() } -STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams, - ISequentialOutStream **outStreams) +HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams) { /* - if (_coderInfoVector.Size() != _bindInfo.Coders.Size()) + if (_coders.Size() != _bindInfo.Coders.Size()) throw 0; */ int i; - for(i = 0; i < _coderInfoVector.Size(); i++) + for(i = 0; i < _coders.Size(); i++) { - CThreadCoderInfo &coderInfo = _coderInfoVector[i]; + CCoder2 &coderInfo = _coders[i]; const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i]; coderInfo.InStreams.Clear(); UInt32 j; @@ -241,45 +147,26 @@ STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams, _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex); _streamBinders[i].CreateStreams( - &_coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex], - &_coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex]); + &_coders[inCoderIndex].InStreams[inCoderStreamIndex], + &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]); } for(i = 0; i < _bindInfo.InStreams.Size(); i++) { UInt32 inCoderIndex, inCoderStreamIndex; _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex); - _coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i]; + _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i]; } for(i = 0; i < _bindInfo.OutStreams.Size(); i++) { UInt32 outCoderIndex, outCoderStreamIndex; _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex); - _coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i]; + _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i]; } return S_OK; } - -bool CCoderMixer2MT::MyCode() -{ - HANDLE events[2] = { _exitEvent, _startCompressingEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - return false; - - int i; - for(i = 0; i < _coderInfoVector.Size(); i++) - _coderInfoVector[i].CompressEvent.Set(); - for (i = 0; i < _coderInfoVector.Size(); i++) - _coderInfoVector[i].CompressionCompletedEvent.Lock(); - - _compressingFinishedEvent.Set(); - return true; -} - - STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, const UInt64 ** /* inSizes */, UInt32 numInStreams, @@ -294,56 +181,48 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, Init(inStreams, outStreams); - _compressingFinishedEvent.Reset(); // ? - - CCrossThreadProgress *progressSpec = new CCrossThreadProgress; - CMyComPtr<ICompressProgressInfo> crossProgress = progressSpec; - RINOK(progressSpec->Create()); - progressSpec->Init(); - _coderInfoVector[_progressCoderIndex].Progress = crossProgress; + int i; + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + { + RINOK(_coders[i].Create()); + } + + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + _coders[i].Start(); - _startCompressingEvent.Set(); + _coders[_progressCoderIndex].Code(progress); + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + _coders[i].WaitFinish(); - for (;;) + for (i = 0; i < _coders.Size(); i++) { - HANDLE events[2] = {_compressingFinishedEvent, progressSpec->ProgressEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - break; - if (progress != NULL) - progressSpec->Result = progress->SetRatioInfo(progressSpec->InSize, - progressSpec->OutSize); - else - progressSpec->Result = S_OK; - progressSpec->WaitEvent.Set(); + HRESULT result = _coders[i].Result; + if (result == E_ABORT) + return result; } - - int i; - for(i = 0; i < _coderInfoVector.Size(); i++) + for (i = 0; i < _coders.Size(); i++) { - HRESULT result = _coderInfoVector[i].Result; + HRESULT result = _coders[i].Result; if (result == S_FALSE) return result; } - for(i = 0; i < _coderInfoVector.Size(); i++) + for (i = 0; i < _coders.Size(); i++) { - HRESULT result = _coderInfoVector[i].Result; + HRESULT result = _coders[i].Result; if (result != S_OK && result != E_FAIL) return result; } - for(i = 0; i < _coderInfoVector.Size(); i++) + for (i = 0; i < _coders.Size(); i++) { - HRESULT result = _coderInfoVector[i].Result; + HRESULT result = _coders[i].Result; if (result != S_OK) return result; } return S_OK; } -UInt64 CCoderMixer2MT::GetWriteProcessedSize(UInt32 binderIndex) const -{ - return _streamBinders[binderIndex].ProcessedSize; -} - } diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.h b/CPP/7zip/Archive/Common/CoderMixer2MT.h index 67c0c8a5..3cd3282b 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.h +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.h @@ -5,73 +5,55 @@ #include "CoderMixer2.h" #include "../../../Common/MyCom.h" -#include "../../../Windows/Thread.h" #include "../../Common/StreamBinder.h" +#include "../../Common/VirtThread.h" -namespace NCoderMixer2 { +namespace NCoderMixer { -// CreateEvents(); -// { -// SetCoderInfo() -// Init Streams -// set CompressEvent() -// wait CompressionCompletedEvent -// } - -struct CThreadCoderInfo: public CCoderInfo +struct CCoder2: public CCoderInfo2, public CVirtThread { - NWindows::NSynchronization::CAutoResetEvent CompressEvent; - HANDLE ExitEvent; - NWindows::NSynchronization::CAutoResetEvent CompressionCompletedEvent; - + HRESULT Result; CObjectVector< CMyComPtr<ISequentialInStream> > InStreams; CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams; - CRecordVector<ISequentialInStream *> InStreamPointers; - CRecordVector<ISequentialOutStream *> OutStreamPointers; - - CMyComPtr<ICompressProgressInfo> Progress; // CMyComPtr - HRESULT Result; + CRecordVector<ISequentialInStream*> InStreamPointers; + CRecordVector<ISequentialOutStream*> OutStreamPointers; - CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams); - void SetCoderInfo(const UInt64 **inSizes, - const UInt64 **outSizes, ICompressProgressInfo *progress); - bool WaitAndCode(); - HRes CreateEvents() - { - RINOK(CompressEvent.CreateIfNotCreated()); - return CompressionCompletedEvent.CreateIfNotCreated(); - } + CCoder2(UInt32 numInStreams, UInt32 numOutStreams); + void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes); + virtual void Execute(); + void Code(ICompressProgressInfo *progress); }; -// SetBindInfo() -// for each coder -// { -// AddCoder[2]() -// } -// -// for each file -// { -// ReInit() -// for each coder -// { -// SetCoderInfo -// } -// SetProgressIndex(UInt32 coderIndex); -// Code -// } - +/* + SetBindInfo() + for each coder + AddCoder[2]() + SetProgressIndex(UInt32 coderIndex); + + for each file + { + ReInit() + for each coder + SetCoderInfo + Code + } +*/ class CCoderMixer2MT: public ICompressCoder2, public CCoderMixer2, public CMyUnknownImp { - MY_UNKNOWN_IMP + CBindInfo _bindInfo; + CObjectVector<CStreamBinder> _streamBinders; + int _progressCoderIndex; + void AddCoderCommon(); + HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams); public: - STDMETHOD(Init)(ISequentialInStream **inStreams, - ISequentialOutStream **outStreams); + CObjectVector<CCoder2> _coders; + MY_UNKNOWN_IMP STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, @@ -81,50 +63,17 @@ public: UInt32 numOutStreams, ICompressProgressInfo *progress); - - CCoderMixer2MT(); - ~CCoderMixer2MT(); - void AddCoderCommon(); + HRESULT SetBindInfo(const CBindInfo &bindInfo); void AddCoder(ICompressCoder *coder); void AddCoder2(ICompressCoder2 *coder); + void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; } void ReInit(); void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) - { _coderInfoVector[coderIndex].SetCoderInfo(inSizes, outSizes, NULL); } - void SetProgressCoderIndex(UInt32 coderIndex) - { _progressCoderIndex = coderIndex; } - - - UInt64 GetWriteProcessedSize(UInt32 binderIndex) const; - - - bool MyCode(); - -private: - CBindInfo _bindInfo; - CObjectVector<CStreamBinder> _streamBinders; - CObjectVector<CThreadCoderInfo> _coderInfoVector; - CRecordVector<NWindows::CThread> _threads; - NWindows::CThread _mainThread; - - NWindows::NSynchronization::CAutoResetEvent _startCompressingEvent; - NWindows::NSynchronization::CAutoResetEvent _compressingFinishedEvent; - - NWindows::NSynchronization::CManualResetEvent _exitEvent; - UInt32 _progressCoderIndex; - - HRes CreateEvents() - { - RINOK(_startCompressingEvent.CreateIfNotCreated()); - RINOK(_compressingFinishedEvent.CreateIfNotCreated()); - return _exitEvent.CreateIfNotCreated(); - } - -public: - HRESULT SetBindInfo(const CBindInfo &bindInfo); - + { _coders[coderIndex].SetCoderInfo(inSizes, outSizes); } + UInt64 GetWriteProcessedSize(UInt32 binderIndex) const + { return _streamBinders[binderIndex].ProcessedSize; } }; } #endif - diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.cpp b/CPP/7zip/Archive/Common/CoderMixerMT.cpp new file mode 100755 index 00000000..ad6e12d8 --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixerMT.cpp @@ -0,0 +1,97 @@ +// CoderMixerMT.cpp + +#include "StdAfx.h" + +#include "CoderMixerMT.h" + +namespace NCoderMixer { + +void CCoder::Execute() { Code(NULL); } + +void CCoder::Code(ICompressProgressInfo *progress) +{ + Result = Coder->Code(InStream, OutStream, + InSizeAssigned ? &InSizeValue : NULL, + OutSizeAssigned ? &OutSizeValue : NULL, + progress); + InStream.Release(); + OutStream.Release(); +} + +void CCoderMixerMT::AddCoder(ICompressCoder *coder) +{ + _coders.Add(CCoder()); + _coders.Back().Coder = coder; +} + +void CCoderMixerMT::ReInit() +{ + for(int i = 0; i < _coders.Size(); i++) + _coders[i].ReInit(); +} + +STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, + ICompressProgressInfo *progress) +{ + _coders.Front().InStream = inStream; + int i; + _coders.Back().OutStream = outStream; + + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + { + RINOK(_coders[i].Create()); + } + + while (_streamBinders.Size() + 1 < _coders.Size()) + { + _streamBinders.Add(CStreamBinder()); + int i = _streamBinders.Size() - 1; + CStreamBinder &sb = _streamBinders.Back(); + RINOK(sb.CreateEvents()); + sb.CreateStreams(&_coders[i + 1].InStream, &_coders[i].OutStream); + } + + for(i = 0; i < _streamBinders.Size(); i++) + _streamBinders[i].ReInit(); + + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + _coders[i].Start(); + + _coders[_progressCoderIndex].Code(progress); + + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + _coders[i].WaitFinish(); + + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result == E_ABORT) + return result; + } + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result == S_FALSE) + return result; + } + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result != S_OK && result != E_FAIL) + return result; + } + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result != S_OK) + return result; + } + return S_OK; +} + +} diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.h b/CPP/7zip/Archive/Common/CoderMixerMT.h new file mode 100755 index 00000000..a2250e8a --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixerMT.h @@ -0,0 +1,68 @@ +// CoderMixerMT.h + +#ifndef __CODER_MIXER_MT_H +#define __CODER_MIXER_MT_H + +#include "../../../Common/Vector.h" +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" +#include "../../Common/StreamBinder.h" +#include "../../Common/VirtThread.h" +#include "CoderMixer.h" + +namespace NCoderMixer { + +struct CCoder: public CCoderInfo, public CVirtThread +{ + HRESULT Result; + + virtual void Execute(); + void Code(ICompressProgressInfo *progress); +}; + +/* + for each coder + AddCoder() + SetProgressIndex(UInt32 coderIndex); + + for each file + { + ReInit() + for each coder + SetCoderInfo + Code + } +*/ + + +class CCoderMixerMT: + public ICompressCoder, + public CMyUnknownImp +{ + CObjectVector<CStreamBinder> _streamBinders; + int _progressCoderIndex; + +public: + CObjectVector<CCoder> _coders; + MY_UNKNOWN_IMP + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + void AddCoder(ICompressCoder *coder); + void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; } + + void ReInit(); + void SetCoderInfo(UInt32 coderIndex, const UInt64 *inSize, const UInt64 *outSize) + { _coders[coderIndex].SetCoderInfo(inSize, outSize); } + + /* + UInt64 GetWriteProcessedSize(UInt32 binderIndex) const + { return _streamBinders[binderIndex].ProcessedSize; } + */ +}; + +} +#endif diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp new file mode 100755 index 00000000..7c214c3c --- /dev/null +++ b/CPP/7zip/Archive/Common/HandlerOut.cpp @@ -0,0 +1,609 @@ +// HandlerOutCommon.cpp + +#include "StdAfx.h" + +#include "HandlerOut.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Common/StringToInt.h" +#include "../../ICoder.h" +#include "../Common/ParseProperties.h" + +#ifdef COMPRESS_MT +#include "../../../Windows/System.h" +#endif + +using namespace NWindows; + +namespace NArchive { + +static const wchar_t *kCopyMethod = L"Copy"; +static const wchar_t *kLZMAMethodName = L"LZMA"; +static const wchar_t *kLZMA2MethodName = L"LZMA2"; +static const wchar_t *kBZip2MethodName = L"BZip2"; +static const wchar_t *kPpmdMethodName = L"PPMd"; +static const wchar_t *kDeflateMethodName = L"Deflate"; +static const wchar_t *kDeflate64MethodName = L"Deflate64"; + +static const wchar_t *kLzmaMatchFinderX1 = L"HC4"; +static const wchar_t *kLzmaMatchFinderX5 = L"BT4"; + +static const UInt32 kLzmaAlgoX1 = 0; +static const UInt32 kLzmaAlgoX5 = 1; + +static const UInt32 kLzmaDicSizeX1 = 1 << 16; +static const UInt32 kLzmaDicSizeX3 = 1 << 20; +static const UInt32 kLzmaDicSizeX5 = 1 << 24; +static const UInt32 kLzmaDicSizeX7 = 1 << 25; +static const UInt32 kLzmaDicSizeX9 = 1 << 26; + +static const UInt32 kLzmaFastBytesX1 = 32; +static const UInt32 kLzmaFastBytesX7 = 64; + +static const UInt32 kPpmdMemSizeX1 = (1 << 22); +static const UInt32 kPpmdMemSizeX5 = (1 << 24); +static const UInt32 kPpmdMemSizeX7 = (1 << 26); +static const UInt32 kPpmdMemSizeX9 = (192 << 20); + +static const UInt32 kPpmdOrderX1 = 4; +static const UInt32 kPpmdOrderX5 = 6; +static const UInt32 kPpmdOrderX7 = 16; +static const UInt32 kPpmdOrderX9 = 32; + +static const UInt32 kDeflateAlgoX1 = 0; +static const UInt32 kDeflateAlgoX5 = 1; + +static const UInt32 kDeflateFastBytesX1 = 32; +static const UInt32 kDeflateFastBytesX7 = 64; +static const UInt32 kDeflateFastBytesX9 = 128; + +static const UInt32 kDeflatePassesX1 = 1; +static const UInt32 kDeflatePassesX7 = 3; +static const UInt32 kDeflatePassesX9 = 10; + +static const UInt32 kBZip2NumPassesX1 = 1; +static const UInt32 kBZip2NumPassesX7 = 2; +static const UInt32 kBZip2NumPassesX9 = 7; + +static const UInt32 kBZip2DicSizeX1 = 100000; +static const UInt32 kBZip2DicSizeX3 = 500000; +static const UInt32 kBZip2DicSizeX5 = 900000; + +static const wchar_t *kDefaultMethodName = kLZMAMethodName; + +static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2"; +static const UInt32 kDictionaryForHeaders = 1 << 20; +static const UInt32 kNumFastBytesForHeaders = 273; +static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5; + +static bool AreEqual(const UString &methodName, const wchar_t *s) + { return (methodName.CompareNoCase(s) == 0); } + +static inline bool IsLZMAMethod(const UString &methodName) +{ + return + AreEqual(methodName, kLZMAMethodName) || + AreEqual(methodName, kLZMA2MethodName); +} + +static inline bool IsBZip2Method(const UString &methodName) + { return AreEqual(methodName, kBZip2MethodName); } + +static inline bool IsPpmdMethod(const UString &methodName) + { return AreEqual(methodName, kPpmdMethodName); } + +static inline bool IsDeflateMethod(const UString &methodName) +{ + return + AreEqual(methodName, kDeflateMethodName) || + AreEqual(methodName, kDeflate64MethodName); +} + +struct CNameToPropID +{ + PROPID PropID; + VARTYPE VarType; + const wchar_t *Name; +}; + +CNameToPropID g_NameToPropID[] = +{ + { NCoderPropID::kOrder, VT_UI4, L"O" }, + { NCoderPropID::kPosStateBits, VT_UI4, L"PB" }, + { NCoderPropID::kLitContextBits, VT_UI4, L"LC" }, + { NCoderPropID::kLitPosBits, VT_UI4, L"LP" }, + { NCoderPropID::kEndMarker, VT_BOOL, L"eos" }, + + { NCoderPropID::kNumPasses, VT_UI4, L"Pass" }, + { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" }, + { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" }, + { NCoderPropID::kAlgorithm, VT_UI4, L"a" }, + { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" }, + { NCoderPropID::kNumThreads, VT_UI4, L"mt" } +}; + +static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp) +{ + if (varType == srcProp.vt) + { + destProp = srcProp; + return true; + } + if (varType == VT_UI1) + { + if (srcProp.vt == VT_UI4) + { + UInt32 value = srcProp.ulVal; + if (value > 0xFF) + return false; + destProp = (Byte)value; + return true; + } + } + else if (varType == VT_BOOL) + { + bool res; + if (SetBoolProperty(res, srcProp) != S_OK) + return false; + destProp = res; + return true; + } + return false; +} + +static int FindPropIdFromStringName(const UString &name) +{ + for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++) + if (name.CompareNoCase(g_NameToPropID[i].Name) == 0) + return i; + return -1; +} + +static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID, + const NWindows::NCOM::CPropVariant &value) +{ + for (int j = 0; j < oneMethodInfo.Properties.Size(); j++) + if (oneMethodInfo.Properties[j].Id == propID) + return; + CProp property; + property.Id = propID; + property.Value = value; + oneMethodInfo.Properties.Add(property); +} + +void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo + #ifdef COMPRESS_MT + , UInt32 numThreads + #endif + ) +{ + UInt32 level = _level; + if (oneMethodInfo.MethodName.IsEmpty()) + oneMethodInfo.MethodName = kDefaultMethodName; + + if (IsLZMAMethod(oneMethodInfo.MethodName)) + { + UInt32 dicSize = + (level >= 9 ? kLzmaDicSizeX9 : + (level >= 7 ? kLzmaDicSizeX7 : + (level >= 5 ? kLzmaDicSizeX5 : + (level >= 3 ? kLzmaDicSizeX3 : + kLzmaDicSizeX1)))); + + UInt32 algo = + (level >= 5 ? kLzmaAlgoX5 : + kLzmaAlgoX1); + + UInt32 fastBytes = + (level >= 7 ? kLzmaFastBytesX7 : + kLzmaFastBytesX1); + + const wchar_t *matchFinder = + (level >= 5 ? kLzmaMatchFinderX5 : + kLzmaMatchFinderX1); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder); + #ifdef COMPRESS_MT + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); + #endif + } + else if (IsDeflateMethod(oneMethodInfo.MethodName)) + { + UInt32 fastBytes = + (level >= 9 ? kDeflateFastBytesX9 : + (level >= 7 ? kDeflateFastBytesX7 : + kDeflateFastBytesX1)); + + UInt32 numPasses = + (level >= 9 ? kDeflatePassesX9 : + (level >= 7 ? kDeflatePassesX7 : + kDeflatePassesX1)); + + UInt32 algo = + (level >= 5 ? kDeflateAlgoX5 : + kDeflateAlgoX1); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); + } + else if (IsBZip2Method(oneMethodInfo.MethodName)) + { + UInt32 numPasses = + (level >= 9 ? kBZip2NumPassesX9 : + (level >= 7 ? kBZip2NumPassesX7 : + kBZip2NumPassesX1)); + + UInt32 dicSize = + (level >= 5 ? kBZip2DicSizeX5 : + (level >= 3 ? kBZip2DicSizeX3 : + kBZip2DicSizeX1)); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); + #ifdef COMPRESS_MT + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); + #endif + } + else if (IsPpmdMethod(oneMethodInfo.MethodName)) + { + UInt32 useMemSize = + (level >= 9 ? kPpmdMemSizeX9 : + (level >= 7 ? kPpmdMemSizeX7 : + (level >= 5 ? kPpmdMemSizeX5 : + kPpmdMemSizeX1))); + + UInt32 order = + (level >= 9 ? kPpmdOrderX9 : + (level >= 7 ? kPpmdOrderX7 : + (level >= 5 ? kPpmdOrderX5 : + kPpmdOrderX1))); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order); + } +} + +static void SplitParams(const UString &srcString, UStringVector &subStrings) +{ + subStrings.Clear(); + UString name; + int len = srcString.Length(); + if (len == 0) + return; + for (int i = 0; i < len; i++) + { + wchar_t c = srcString[i]; + if (c == L':') + { + subStrings.Add(name); + name.Empty(); + } + else + name += c; + } + subStrings.Add(name); +} + +static void SplitParam(const UString ¶m, UString &name, UString &value) +{ + int eqPos = param.Find(L'='); + if (eqPos >= 0) + { + name = param.Left(eqPos); + value = param.Mid(eqPos + 1); + return; + } + for(int i = 0; i < param.Length(); i++) + { + wchar_t c = param[i]; + if (c >= L'0' && c <= L'9') + { + name = param.Left(i); + value = param.Mid(i); + return; + } + } + name = param; +} + +HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value) +{ + CProp property; + if ( + name.CompareNoCase(L"D") == 0 || + name.CompareNoCase(L"MEM") == 0) + { + UInt32 dicSize; + RINOK(ParsePropDictionaryValue(value, dicSize)); + if (name.CompareNoCase(L"D") == 0) + property.Id = NCoderPropID::kDictionarySize; + else + property.Id = NCoderPropID::kUsedMemorySize; + property.Value = dicSize; + oneMethodInfo.Properties.Add(property); + } + else + { + int index = FindPropIdFromStringName(name); + if (index < 0) + return E_INVALIDARG; + + const CNameToPropID &nameToPropID = g_NameToPropID[index]; + property.Id = nameToPropID.PropID; + + NCOM::CPropVariant propValue; + + if (nameToPropID.VarType == VT_BSTR) + propValue = value; + else if (nameToPropID.VarType == VT_BOOL) + { + bool res; + if (!StringToBool(value, res)) + return E_INVALIDARG; + propValue = res; + } + else + { + UInt32 number; + if (ParseStringToUInt32(value, number) == value.Length()) + propValue = number; + else + propValue = value; + } + + if (!ConvertProperty(propValue, nameToPropID.VarType, property.Value)) + return E_INVALIDARG; + + oneMethodInfo.Properties.Add(property); + } + return S_OK; +} + +HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString) +{ + UStringVector params; + SplitParams(srcString, params); + if (params.Size() > 0) + oneMethodInfo.MethodName = params[0]; + for (int i = 1; i < params.Size(); i++) + { + const UString ¶m = params[i]; + UString name, value; + SplitParam(param, name, value); + RINOK(SetParam(oneMethodInfo, name, value)); + } + return S_OK; +} + +HRESULT COutHandler::SetSolidSettings(const UString &s) +{ + bool res; + if (StringToBool(s, res)) + { + if (res) + InitSolid(); + else + _numSolidFiles = 1; + return S_OK; + } + UString s2 = s; + s2.MakeUpper(); + for (int i = 0; i < s2.Length();) + { + const wchar_t *start = ((const wchar_t *)s2) + i; + const wchar_t *end; + UInt64 v = ConvertStringToUInt64(start, &end); + if (start == end) + { + if (s2[i++] != 'E') + return E_INVALIDARG; + _solidExtension = true; + continue; + } + i += (int)(end - start); + if (i == s2.Length()) + return E_INVALIDARG; + wchar_t c = s2[i++]; + switch(c) + { + case 'F': + if (v < 1) + v = 1; + _numSolidFiles = v; + break; + case 'B': + _numSolidBytes = v; + _numSolidBytesDefined = true; + break; + case 'K': + _numSolidBytes = (v << 10); + _numSolidBytesDefined = true; + break; + case 'M': + _numSolidBytes = (v << 20); + _numSolidBytesDefined = true; + break; + case 'G': + _numSolidBytes = (v << 30); + _numSolidBytesDefined = true; + break; + default: + return E_INVALIDARG; + } + } + return S_OK; +} + +HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value) +{ + switch(value.vt) + { + case VT_EMPTY: + InitSolid(); + return S_OK; + case VT_BSTR: + return SetSolidSettings(value.bstrVal); + default: + return E_INVALIDARG; + } +} + +void COutHandler::Init() +{ + _removeSfxBlock = false; + _compressHeaders = true; + _encryptHeaders = false; + + WriteModified = true; + WriteCreated = false; + WriteAccessed = false; + + #ifdef COMPRESS_MT + _numThreads = NWindows::NSystem::GetNumberOfProcessors(); + #endif + + _level = 5; + _autoFilter = true; + _volumeMode = false; + InitSolid(); +} + +void COutHandler::BeforeSetProperty() +{ + Init(); + #ifdef COMPRESS_MT + numProcessors = NSystem::GetNumberOfProcessors(); + #endif + + mainDicSize = 0xFFFFFFFF; + mainDicMethodIndex = 0xFFFFFFFF; + minNumber = 0; +} + +HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) +{ + UString name = nameSpec; + name.MakeUpper(); + if (name.IsEmpty()) + return E_INVALIDARG; + + if (name[0] == 'X') + { + name.Delete(0); + _level = 9; + return ParsePropValue(name, value, _level); + } + + if (name[0] == L'S') + { + name.Delete(0); + if (name.IsEmpty()) + return SetSolidSettings(value); + if (value.vt != VT_EMPTY) + return E_INVALIDARG; + return SetSolidSettings(name); + } + + UInt32 number; + int index = ParseStringToUInt32(name, number); + UString realName = name.Mid(index); + if (index == 0) + { + if(name.Left(2).CompareNoCase(L"MT") == 0) + { + #ifdef COMPRESS_MT + RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads)); + #endif + return S_OK; + } + if (name.CompareNoCase(L"RSFX") == 0) + return SetBoolProperty(_removeSfxBlock, value); + if (name.CompareNoCase(L"F") == 0) + return SetBoolProperty(_autoFilter, value); + if (name.CompareNoCase(L"HC") == 0) + return SetBoolProperty(_compressHeaders, value); + if (name.CompareNoCase(L"HCF") == 0) + { + bool compressHeadersFull = true; + RINOK(SetBoolProperty(compressHeadersFull, value)); + if (!compressHeadersFull) + return E_INVALIDARG; + return S_OK; + } + if (name.CompareNoCase(L"HE") == 0) + return SetBoolProperty(_encryptHeaders, value); + if (name.CompareNoCase(L"TM") == 0) + return SetBoolProperty(WriteModified, value); + if (name.CompareNoCase(L"TC") == 0) + return SetBoolProperty(WriteCreated, value); + if (name.CompareNoCase(L"TA") == 0) + return SetBoolProperty(WriteAccessed, value); + if (name.CompareNoCase(L"V") == 0) + return SetBoolProperty(_volumeMode, value); + number = 0; + } + if (number > 10000) + return E_FAIL; + if (number < minNumber) + return E_INVALIDARG; + number -= minNumber; + for(int j = _methods.Size(); j <= (int)number; j++) + { + COneMethodInfo oneMethodInfo; + _methods.Add(oneMethodInfo); + } + + COneMethodInfo &oneMethodInfo = _methods[number]; + + if (realName.Length() == 0) + { + if (value.vt != VT_BSTR) + return E_INVALIDARG; + + RINOK(SetParams(oneMethodInfo, value.bstrVal)); + } + else + { + CProp property; + if (realName.Left(1).CompareNoCase(L"D") == 0) + { + UInt32 dicSize; + RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize)); + property.Id = NCoderPropID::kDictionarySize; + property.Value = dicSize; + oneMethodInfo.Properties.Add(property); + if (number <= mainDicMethodIndex) + mainDicSize = dicSize; + } + else if (realName.Left(3).CompareNoCase(L"MEM") == 0) + { + UInt32 dicSize; + RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize)); + property.Id = NCoderPropID::kUsedMemorySize; + property.Value = dicSize; + oneMethodInfo.Properties.Add(property); + if (number <= mainDicMethodIndex) + mainDicSize = dicSize; + } + else + { + int index = FindPropIdFromStringName(realName); + if (index < 0) + return E_INVALIDARG; + + const CNameToPropID &nameToPropID = g_NameToPropID[index]; + property.Id = nameToPropID.PropID; + + if (!ConvertProperty(value, nameToPropID.VarType, property.Value)) + return E_INVALIDARG; + + oneMethodInfo.Properties.Add(property); + } + } + return S_OK; +} + +} diff --git a/CPP/7zip/Archive/Common/HandlerOut.h b/CPP/7zip/Archive/Common/HandlerOut.h new file mode 100755 index 00000000..eded0786 --- /dev/null +++ b/CPP/7zip/Archive/Common/HandlerOut.h @@ -0,0 +1,84 @@ +// HandlerOut.h + +#ifndef __HANDLER_OUT_H +#define __HANDLER_OUT_H + +#include "../../Common/MethodProps.h" +#include "../../Common/CreateCoder.h" + +namespace NArchive { + +struct COneMethodInfo +{ + CObjectVector<CProp> Properties; + UString MethodName; +}; + +class COutHandler +{ +public: + HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); + + HRESULT SetSolidSettings(const UString &s); + HRESULT SetSolidSettings(const PROPVARIANT &value); + + #ifdef COMPRESS_MT + UInt32 _numThreads; + #endif + + CObjectVector<COneMethodInfo> _methods; + bool _removeSfxBlock; + + UInt64 _numSolidFiles; + UInt64 _numSolidBytes; + bool _numSolidBytesDefined; + bool _solidExtension; + + bool _compressHeaders; + bool _encryptHeaders; + + bool WriteModified; + bool WriteCreated; + bool WriteAccessed; + + bool _autoFilter; + UInt32 _level; + + bool _volumeMode; + + HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value); + HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString); + + void SetCompressionMethod2(COneMethodInfo &oneMethodInfo + #ifdef COMPRESS_MT + , UInt32 numThreads + #endif + ); + + void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); } + void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); } + void InitSolid() + { + InitSolidFiles(); + InitSolidSize(); + _solidExtension = false; + _numSolidBytesDefined = false; + } + + void Init(); + + COutHandler() { Init(); } + + void BeforeSetProperty(); + + UInt32 minNumber; + UInt32 numProcessors; + UInt32 mainDicSize; + UInt32 mainDicMethodIndex; + + DECL_EXTERNAL_CODECS_VARS +}; + +} + +#endif diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.h b/CPP/7zip/Archive/Common/ItemNameUtils.h index 63a01563..5eafacb1 100755 --- a/CPP/7zip/Archive/Common/ItemNameUtils.h +++ b/CPP/7zip/Archive/Common/ItemNameUtils.h @@ -3,7 +3,7 @@ #ifndef __ARCHIVE_ITEMNAMEUTILS_H #define __ARCHIVE_ITEMNAMEUTILS_H -#include "../../../Common/String.h" +#include "../../../Common/MyString.h" namespace NArchive { namespace NItemName { diff --git a/CPP/7zip/Archive/Common/MultiStream.h b/CPP/7zip/Archive/Common/MultiStream.h index 5a7cc687..b0fe41d6 100755 --- a/CPP/7zip/Archive/Common/MultiStream.h +++ b/CPP/7zip/Archive/Common/MultiStream.h @@ -4,7 +4,7 @@ #define __MULTISTREAM_H #include "../../../Common/MyCom.h" -#include "../../../Common/Vector.h" +#include "../../../Common/MyVector.h" #include "../../Archive/IArchive.h" class CMultiStream: diff --git a/CPP/7zip/Archive/Common/ParseProperties.cpp b/CPP/7zip/Archive/Common/ParseProperties.cpp index 9866d900..f0d4e29c 100755 --- a/CPP/7zip/Archive/Common/ParseProperties.cpp +++ b/CPP/7zip/Archive/Common/ParseProperties.cpp @@ -97,34 +97,37 @@ HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, U return ParsePropDictionaryValue(name, resValue); } +bool StringToBool(const UString &s, bool &res) +{ + if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0) + { + res = true; + return true; + } + if (s.CompareNoCase(L"OFF") == 0) + { + res = false; + return true; + } + return false; +} + HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value) { switch(value.vt) { case VT_EMPTY: dest = true; - break; + return S_OK; /* case VT_UI4: dest = (value.ulVal != 0); break; */ case VT_BSTR: - { - UString valueString = value.bstrVal; - valueString.MakeUpper(); - if (valueString.Compare(L"ON") == 0) - dest = true; - else if (valueString.Compare(L"OFF") == 0) - dest = false; - else - return E_INVALIDARG; - break; - } - default: - return E_INVALIDARG; + return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG; } - return S_OK; + return E_INVALIDARG; } int ParseStringToUInt32(const UString &srcString, UInt32 &number) diff --git a/CPP/7zip/Archive/Common/ParseProperties.h b/CPP/7zip/Archive/Common/ParseProperties.h index e6db316b..6f80f634 100755 --- a/CPP/7zip/Archive/Common/ParseProperties.h +++ b/CPP/7zip/Archive/Common/ParseProperties.h @@ -3,13 +3,14 @@ #ifndef __PARSEPROPERTIES_H #define __PARSEPROPERTIES_H -#include "Common/String.h" +#include "Common/MyString.h" #include "Common/Types.h" HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize); HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); +bool StringToBool(const UString &s, bool &res); HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value); int ParseStringToUInt32(const UString &srcString, UInt32 &number); HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads); diff --git a/CPP/7zip/Archive/Cpio/CpioItem.h b/CPP/7zip/Archive/Cpio/CpioItem.h index 0eb2a0b4..cee8b5b3 100755 --- a/CPP/7zip/Archive/Cpio/CpioItem.h +++ b/CPP/7zip/Archive/Cpio/CpioItem.h @@ -6,7 +6,7 @@ #include <sys/stat.h> #include "Common/Types.h" -#include "Common/String.h" +#include "Common/MyString.h" #include "CpioHeader.h" namespace NArchive { diff --git a/CPP/7zip/Archive/Deb/DebItem.h b/CPP/7zip/Archive/Deb/DebItem.h index f587f3f5..86e6740d 100755 --- a/CPP/7zip/Archive/Deb/DebItem.h +++ b/CPP/7zip/Archive/Deb/DebItem.h @@ -4,7 +4,7 @@ #define __ARCHIVE_DEB_ITEMINFO_H #include "Common/Types.h" -#include "Common/String.h" +#include "Common/MyString.h" #include "DebHeader.h" namespace NArchive { diff --git a/CPP/7zip/Archive/GZip/GZipItem.h b/CPP/7zip/Archive/GZip/GZipItem.h index 7006dfb3..cd5e59f0 100755 --- a/CPP/7zip/Archive/GZip/GZipItem.h +++ b/CPP/7zip/Archive/GZip/GZipItem.h @@ -4,7 +4,7 @@ #define __ARCHIVE_GZIP_ITEM_H #include "Common/Types.h" -#include "Common/String.h" +#include "Common/MyString.h" #include "Common/Buffer.h" namespace NArchive { diff --git a/CPP/7zip/Archive/Iso/IsoItem.h b/CPP/7zip/Archive/Iso/IsoItem.h index 14024d8d..e899d616 100755 --- a/CPP/7zip/Archive/Iso/IsoItem.h +++ b/CPP/7zip/Archive/Iso/IsoItem.h @@ -4,7 +4,7 @@ #define __ARCHIVE_ISO_ITEM_H #include "Common/Types.h" -#include "Common/String.h" +#include "Common/MyString.h" #include "Common/Buffer.h" #include "IsoHeader.h" diff --git a/CPP/7zip/Archive/Lzh/LzhItem.h b/CPP/7zip/Archive/Lzh/LzhItem.h index 66d4ed75..d0ba25e2 100755 --- a/CPP/7zip/Archive/Lzh/LzhItem.h +++ b/CPP/7zip/Archive/Lzh/LzhItem.h @@ -4,7 +4,7 @@ #define __ARCHIVE_LZH_ITEM_H #include "Common/Types.h" -#include "Common/String.h" +#include "Common/MyString.h" #include "Common/Buffer.h" #include "LzhHeader.h" diff --git a/CPP/7zip/Archive/Rar/RarIn.h b/CPP/7zip/Archive/Rar/RarIn.h index 83a4d193..9cb66512 100755 --- a/CPP/7zip/Archive/Rar/RarIn.h +++ b/CPP/7zip/Archive/Rar/RarIn.h @@ -4,7 +4,6 @@ #define __ARCHIVE_RAR_IN_H #include "Common/DynamicBuffer.h" -#include "Common/Exception.h" #include "Common/MyCom.h" #include "../../IStream.h" #include "../../ICoder.h" diff --git a/CPP/7zip/Archive/Rar/RarItem.h b/CPP/7zip/Archive/Rar/RarItem.h index 85050a42..5ab8a46e 100755 --- a/CPP/7zip/Archive/Rar/RarItem.h +++ b/CPP/7zip/Archive/Rar/RarItem.h @@ -4,7 +4,7 @@ #define __ARCHIVE_RAR_ITEM_H #include "Common/Types.h" -#include "Common/String.h" +#include "Common/MyString.h" namespace NArchive{ namespace NRar{ diff --git a/CPP/7zip/Archive/Split/SplitHandler.h b/CPP/7zip/Archive/Split/SplitHandler.h index a98dc0a6..65071cfd 100755 --- a/CPP/7zip/Archive/Split/SplitHandler.h +++ b/CPP/7zip/Archive/Split/SplitHandler.h @@ -4,7 +4,7 @@ #define __SPLIT_HANDLER_H #include "Common/MyCom.h" -#include "Common/String.h" +#include "Common/MyString.h" #include "../IArchive.h" namespace NArchive { diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp index 9c2cd006..f2c83caf 100755 --- a/CPP/7zip/Archive/Tar/TarHandler.cpp +++ b/CPP/7zip/Archive/Tar/TarHandler.cpp @@ -113,8 +113,22 @@ STDMETHODIMP CHandler::Open(IInStream *stream, } } if (_items.Size() == 0) - return S_FALSE; - + { + CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; + if (!openArchiveCallback) + return S_FALSE; + openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); + if (!openVolumeCallback) + return S_FALSE; + NCOM::CPropVariant propVariant; + RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); + if (propVariant.vt != VT_BSTR) + return S_FALSE; + UString baseName = propVariant.bstrVal; + baseName = baseName.Right(4); + if (baseName.CompareNoCase(L".tar") != 0) + return S_FALSE; + } _inStream = stream; } /* diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h index 71fff7ba..10b57cd0 100755 --- a/CPP/7zip/Archive/Tar/TarItem.h +++ b/CPP/7zip/Archive/Tar/TarItem.h @@ -6,7 +6,7 @@ #include <time.h> #include "Common/Types.h" -#include "Common/String.h" +#include "Common/MyString.h" #include "../Common/ItemNameUtils.h" #include "TarHeader.h" diff --git a/CPP/7zip/Archive/Tar/TarUpdate.h b/CPP/7zip/Archive/Tar/TarUpdate.h index 92f5cebb..67d671f5 100755 --- a/CPP/7zip/Archive/Tar/TarUpdate.h +++ b/CPP/7zip/Archive/Tar/TarUpdate.h @@ -3,10 +3,6 @@ #ifndef __TAR_UPDATE_H #define __TAR_UPDATE_H -#include "Common/Vector.h" -#include "Common/Types.h" -#include "Common/String.h" - #include "../IArchive.h" #include "TarItem.h" diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h index 650d4f35..37f22f77 100755 --- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h +++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h @@ -3,8 +3,7 @@ #ifndef __ZIP_COMPRESSIONMETHOD_H #define __ZIP_COMPRESSIONMETHOD_H -#include "Common/Vector.h" -#include "Common/String.h" +#include "Common/MyString.h" namespace NArchive { namespace NZip { diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp index 0ccd3727..453c37a3 100755 --- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp @@ -16,6 +16,7 @@ #include "../Common/ItemNameUtils.h" #include "../Common/ParseProperties.h" #include "../../Crypto/WzAES/WzAES.h" +#include "../../Common/OutBuffer.h" using namespace NWindows; using namespace NCOM; @@ -60,10 +61,15 @@ static bool IsAsciiString(const UString &s) return true; } +#define COM_TRY_BEGIN2 try { +#define COM_TRY_END2 } \ +catch(const CSystemException &e) { return e.ErrorCode; } \ +catch(...) { return E_OUTOFMEMORY; } + STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) { - COM_TRY_BEGIN + COM_TRY_BEGIN2 CObjectVector<CUpdateItem> updateItems; for(UInt32 i = 0; i < numItems; i++) { @@ -276,7 +282,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt EXTERNAL_CODECS_VARS m_Items, updateItems, outStream, m_ArchiveIsOpen ? &m_Archive : NULL, &options, updateCallback); - COM_TRY_END + COM_TRY_END2 } STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp index 7c5ecbfb..bb45d1d1 100755 --- a/CPP/7zip/Archive/Zip/ZipIn.cpp +++ b/CPP/7zip/Archive/Zip/ZipIn.cpp @@ -341,11 +341,14 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item) RINOK(ReadLocalItem(localItem)); if (item.Flags != localItem.Flags) { - if ((item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflated || - (item.Flags & 0x7FFC) != (localItem.Flags & 0x7FFC)) && - ((item.CompressionMethod != NFileHeader::NCompressionMethod::kStored || - (item.Flags & 0x7FFF) != (localItem.Flags & 0x7FFF)) - )) + if ( + (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflated || + (item.Flags & 0x7FF9) != (localItem.Flags & 0x7FF9)) && + (item.CompressionMethod != NFileHeader::NCompressionMethod::kStored || + (item.Flags & 0x7FFF) != (localItem.Flags & 0x7FFF)) && + (item.CompressionMethod != NFileHeader::NCompressionMethod::kImploded || + (item.Flags & 0x7FFF) != (localItem.Flags & 0x7FFF)) + ) return S_FALSE; } diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h index 765bfd85..4a7a47f1 100755 --- a/CPP/7zip/Archive/Zip/ZipItem.h +++ b/CPP/7zip/Archive/Zip/ZipItem.h @@ -4,7 +4,7 @@ #define __ARCHIVE_ZIP_ITEM_H #include "Common/Types.h" -#include "Common/String.h" +#include "Common/MyString.h" #include "Common/Buffer.h" #include "ZipHeader.h" diff --git a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp index 1f108235..d5e6895e 100755 --- a/CPP/7zip/Archive/Zip/ZipOut.cpp +++ b/CPP/7zip/Archive/Zip/ZipOut.cpp @@ -12,7 +12,11 @@ namespace NZip { void COutArchive::Create(IOutStream *outStream) { + if (!m_OutBuffer.Create(1 << 16)) + throw CSystemException(E_OUTOFMEMORY); m_Stream = outStream; + m_OutBuffer.SetStream(outStream); + m_OutBuffer.Init(); m_BasePosition = 0; } @@ -47,11 +51,7 @@ void COutArchive::PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPa void COutArchive::WriteBytes(const void *buffer, UInt32 size) { - UInt32 processedSize; - if(WriteStream(m_Stream, buffer, size, &processedSize) != S_OK) - throw 0; - if(processedSize != size) - throw 0; + m_OutBuffer.WriteBytes(buffer, size); m_BasePosition += size; } @@ -101,9 +101,16 @@ void COutArchive::WriteExtra(const CExtraBlock &extra) } } -HRESULT COutArchive::WriteLocalHeader(const CLocalItem &item) +void COutArchive::SeekTo(UInt64 offset) { - m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); + HRESULT res = m_Stream->Seek(offset, STREAM_SEEK_SET, NULL); + if (res != S_OK) + throw CSystemException(res); +} + +void COutArchive::WriteLocalHeader(const CLocalItem &item) +{ + SeekTo(m_BasePosition); bool isZip64 = m_IsZip64 || item.PackSize >= 0xFFFFFFFF || item.UnPackSize >= 0xFFFFFFFF; @@ -120,7 +127,7 @@ HRESULT COutArchive::WriteLocalHeader(const CLocalItem &item) { UInt16 localExtraSize = (UInt16)((isZip64 ? (4 + 16): 0) + item.LocalExtra.GetSize()); if (localExtraSize > m_ExtraSize) - return E_FAIL; + throw CSystemException(E_FAIL); } WriteUInt16((UInt16)m_ExtraSize); // test it; WriteBytes((const char *)item.Name, item.Name.Length()); @@ -140,14 +147,13 @@ HRESULT COutArchive::WriteLocalHeader(const CLocalItem &item) for (; extraPos < m_ExtraSize; extraPos++) WriteByte(0); + m_OutBuffer.FlushWithCheck(); MoveBasePosition(item.PackSize); - return m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); + SeekTo(m_BasePosition); } void COutArchive::WriteCentralHeader(const CItem &item) { - m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); - bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF; bool isPack64 = item.PackSize >= 0xFFFFFFFF; bool isPosition64 = item.LocalHeaderPosition >= 0xFFFFFFFF; @@ -193,7 +199,7 @@ void COutArchive::WriteCentralHeader(const CItem &item) void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment) { - m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); + SeekTo(m_BasePosition); UInt64 cdOffset = GetCurrentPosition(); for(int i = 0; i < items.Size(); i++) @@ -234,6 +240,7 @@ void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByte WriteUInt16(commentSize); if (commentSize > 0) WriteBytes((const Byte *)comment, commentSize); + m_OutBuffer.FlushWithCheck(); } void COutArchive::CreateStreamForCompressing(IOutStream **outStream) @@ -246,7 +253,7 @@ void COutArchive::CreateStreamForCompressing(IOutStream **outStream) void COutArchive::SeekToPackedDataPosition() { - m_Stream->Seek(m_BasePosition + m_LocalFileHeaderSize, STREAM_SEEK_SET, NULL); + SeekTo(m_BasePosition + m_LocalFileHeaderSize); } void COutArchive::CreateStreamForCopying(ISequentialOutStream **outStream) diff --git a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h index e08c306e..24bc83a1 100755 --- a/CPP/7zip/Archive/Zip/ZipOut.h +++ b/CPP/7zip/Archive/Zip/ZipOut.h @@ -6,15 +6,19 @@ #include "Common/MyCom.h" #include "../../IStream.h" +#include "../../Common/OutBuffer.h" #include "ZipItem.h" namespace NArchive { namespace NZip { +// can throw CSystemException and COutBufferException + class COutArchive { CMyComPtr<IOutStream> m_Stream; + COutBuffer m_OutBuffer; UInt64 m_BasePosition; UInt32 m_LocalFileHeaderSize; @@ -30,6 +34,7 @@ class COutArchive void WriteExtraHeader(const CItem &item); void WriteCentralHeader(const CItem &item); void WriteExtra(const CExtraBlock &extra); + void SeekTo(UInt64 offset); public: void Create(IOutStream *outStream); void MoveBasePosition(UInt64 distanceToMove); @@ -37,7 +42,7 @@ public: void PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64, bool aesEncryption); void PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize, bool aesEncryption); void PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize, bool aesEncryption); - HRESULT WriteLocalHeader(const CLocalItem &item); + void WriteLocalHeader(const CLocalItem &item); void WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment); diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp index 8caa1409..27284953 100755 --- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp +++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp @@ -282,12 +282,12 @@ static HRESULT UpdateItemOldData(COutArchive &archive, return S_OK; } -static HRESULT WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options, +static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options, const CUpdateItem &updateItem, CItemEx &item) { SetFileHeader(archive, *options, updateItem, item); archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode); - return archive.WriteLocalHeader(item); + archive.WriteLocalHeader(item); } static HRESULT Update2St( @@ -330,7 +330,7 @@ static HRESULT Update2St( bool isDirectory = ((updateItem.NewProperties) ? updateItem.IsDirectory : item.IsDirectory()); if (isDirectory) { - RINOK(WriteDirHeader(archive, options, updateItem, item)); + WriteDirHeader(archive, options, updateItem, item); } else { @@ -355,7 +355,7 @@ static HRESULT Update2St( EXTERNAL_CODECS_LOC_VARS fileInStream, outStream, compressProgress, compressingResult)); SetItemInfoFromCompressingResult(compressingResult, options->IsAesMode, options->AesKeyMode, item); - RINOK(archive.WriteLocalHeader(item)); + archive.WriteLocalHeader(item); RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); complexity += item.UnPackSize; } @@ -611,7 +611,7 @@ static HRESULT Update2( bool isDirectory = ((updateItem.NewProperties) ? updateItem.IsDirectory : item.IsDirectory()); if (isDirectory) { - RINOK(WriteDirHeader(archive, options, updateItem, item)); + WriteDirHeader(archive, options, updateItem, item); } else { @@ -632,7 +632,7 @@ static HRESULT Update2( SetItemInfoFromCompressingResult(memRef.CompressingResult, options->IsAesMode, options->AesKeyMode, item); SetFileHeader(archive, *options, updateItem, item); - RINOK(archive.WriteLocalHeader(item)); + archive.WriteLocalHeader(item); complexity += item.UnPackSize; // RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); memRef.FreeOpt(&memManager); @@ -666,7 +666,7 @@ static HRESULT Update2( SetItemInfoFromCompressingResult(threadInfo.CompressingResult, options->IsAesMode, options->AesKeyMode, item); SetFileHeader(archive, *options, updateItem, item); - RINOK(archive.WriteLocalHeader(item)); + archive.WriteLocalHeader(item); complexity += item.UnPackSize; } else diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.h b/CPP/7zip/Archive/Zip/ZipUpdate.h index 8b03cfa3..168eedd6 100755 --- a/CPP/7zip/Archive/Zip/ZipUpdate.h +++ b/CPP/7zip/Archive/Zip/ZipUpdate.h @@ -3,9 +3,6 @@ #ifndef __ZIP_UPDATE_H #define __ZIP_UPDATE_H -#include "Common/Vector.h" -#include "Common/Types.h" - #include "../../ICoder.h" #include "../IArchive.h" |