diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Common')
42 files changed, 3718 insertions, 1265 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp b/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp index a77b67e8664..346774e5d04 100644 --- a/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp @@ -1,4 +1,4 @@ -// CWrappers.h +// CWrappers.c #include "StdAfx.h" @@ -8,43 +8,74 @@ #include "StreamUtils.h" +SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw() +{ + switch (res) + { + case S_OK: return SZ_OK; + case E_OUTOFMEMORY: return SZ_ERROR_MEM; + case E_INVALIDARG: return SZ_ERROR_PARAM; + case E_ABORT: return SZ_ERROR_PROGRESS; + case S_FALSE: return SZ_ERROR_DATA; + case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED; + } + return defaultRes; +} + + +HRESULT SResToHRESULT(SRes res) throw() +{ + switch (res) + { + case SZ_OK: return S_OK; + + case SZ_ERROR_DATA: + case SZ_ERROR_CRC: + case SZ_ERROR_INPUT_EOF: + return S_FALSE; + + case SZ_ERROR_MEM: return E_OUTOFMEMORY; + case SZ_ERROR_PARAM: return E_INVALIDARG; + case SZ_ERROR_PROGRESS: return E_ABORT; + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; + // case SZ_ERROR_OUTPUT_EOF: + // case SZ_ERROR_READ: + // case SZ_ERROR_WRITE: + // case SZ_ERROR_THREAD: + // case SZ_ERROR_ARCHIVE: + // case SZ_ERROR_NO_ARCHIVE: + // return E_FAIL; + } + if (res < 0) + return res; + return E_FAIL; +} + + #define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1) #define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x) -static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw() + +static SRes CompressProgress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) throw() { - CCompressProgressWrap *p = (CCompressProgressWrap *)pp; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CCompressProgressWrap) p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize)); - return (SRes)p->Res; + return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS); } -CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw() +void CCompressProgressWrap::Init(ICompressProgressInfo *progress) throw() { - p.Progress = CompressProgress; + vt.Progress = CompressProgress; Progress = progress; Res = SZ_OK; } static const UInt32 kStreamStepSize = (UInt32)1 << 31; -SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) +static SRes MyRead(ISeqInStreamPtr pp, void *data, size_t *size) throw() { - switch (res) - { - case S_OK: return SZ_OK; - case E_OUTOFMEMORY: return SZ_ERROR_MEM; - case E_INVALIDARG: return SZ_ERROR_PARAM; - case E_ABORT: return SZ_ERROR_PROGRESS; - case S_FALSE: return SZ_ERROR_DATA; - case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED; - } - return defaultRes; -} - -static SRes MyRead(void *object, void *data, size_t *size) throw() -{ - CSeqInStreamWrap *p = (CSeqInStreamWrap *)object; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqInStreamWrap) UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); p->Res = (p->Stream->Read(data, curSize, &curSize)); *size = curSize; @@ -54,9 +85,9 @@ static SRes MyRead(void *object, void *data, size_t *size) throw() return HRESULT_To_SRes(p->Res, SZ_ERROR_READ); } -static size_t MyWrite(void *object, const void *data, size_t size) throw() +static size_t MyWrite(ISeqOutStreamPtr pp, const void *data, size_t size) throw() { - CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqOutStreamWrap) if (p->Stream) { p->Res = WriteStream(p->Stream, data, size); @@ -69,49 +100,41 @@ static size_t MyWrite(void *object, const void *data, size_t size) throw() return size; } -CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw() + +void CSeqInStreamWrap::Init(ISequentialInStream *stream) throw() { - p.Read = MyRead; + vt.Read = MyRead; Stream = stream; Processed = 0; + Res = S_OK; } -CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw() +void CSeqOutStreamWrap::Init(ISequentialOutStream *stream) throw() { - p.Write = MyWrite; + vt.Write = MyWrite; Stream = stream; Res = SZ_OK; Processed = 0; } -HRESULT SResToHRESULT(SRes res) throw() -{ - switch (res) - { - case SZ_OK: return S_OK; - case SZ_ERROR_MEM: return E_OUTOFMEMORY; - case SZ_ERROR_PARAM: return E_INVALIDARG; - case SZ_ERROR_PROGRESS: return E_ABORT; - case SZ_ERROR_DATA: return S_FALSE; - case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; - } - return E_FAIL; -} -static SRes InStreamWrap_Read(void *pp, void *data, size_t *size) throw() +static SRes InStreamWrap_Read(ISeekInStreamPtr pp, void *data, size_t *size) throw() { - CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeekInStreamWrap) UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); p->Res = p->Stream->Read(data, curSize, &curSize); *size = curSize; return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; } -static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw() +static SRes InStreamWrap_Seek(ISeekInStreamPtr pp, Int64 *offset, ESzSeek origin) throw() { - CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeekInStreamWrap) UInt32 moveMethod; - switch (origin) + /* we need (int)origin to eliminate the clang warning: + default label in switch which covers all enumeration values + [-Wcovered-switch-default */ + switch ((int)origin) { case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break; case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break; @@ -124,11 +147,11 @@ static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw() return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; } -CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw() +void CSeekInStreamWrap::Init(IInStream *stream) throw() { Stream = stream; - p.Read = InStreamWrap_Read; - p.Seek = InStreamWrap_Seek; + vt.Read = InStreamWrap_Read; + vt.Seek = InStreamWrap_Seek; Res = S_OK; } @@ -138,27 +161,27 @@ CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw() void CByteInBufWrap::Free() throw() { ::MidFree(Buf); - Buf = 0; + Buf = NULL; } bool CByteInBufWrap::Alloc(UInt32 size) throw() { - if (Buf == 0 || size != Size) + if (!Buf || size != Size) { Free(); Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size); Size = size; } - return (Buf != 0); + return (Buf != NULL); } Byte CByteInBufWrap::ReadByteFromNewBlock() throw() { - if (Res == S_OK) + if (!Extra && Res == S_OK) { UInt32 avail; - Processed += (Cur - Buf); Res = Stream->Read(Buf, Size, &avail); + Processed += (size_t)(Cur - Buf); Cur = Buf; Lim = Buf + avail; if (avail != 0) @@ -168,55 +191,106 @@ Byte CByteInBufWrap::ReadByteFromNewBlock() throw() return 0; } -static Byte Wrap_ReadByte(void *pp) throw() +// #pragma GCC diagnostic ignored "-Winvalid-offsetof" + +static Byte Wrap_ReadByte(IByteInPtr pp) throw() { - CByteInBufWrap *p = (CByteInBufWrap *)pp; + CByteInBufWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteInBufWrap, vt); + // Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInBufWrap) if (p->Cur != p->Lim) return *p->Cur++; return p->ReadByteFromNewBlock(); } -CByteInBufWrap::CByteInBufWrap(): Buf(0) +CByteInBufWrap::CByteInBufWrap() throw(): Buf(NULL) +{ + vt.Read = Wrap_ReadByte; +} + + + +/* ---------- CByteOutBufWrap ---------- */ + +/* +void CLookToSequentialWrap::Free() throw() { - p.Read = Wrap_ReadByte; + ::MidFree(BufBase); + BufBase = NULL; } +bool CLookToSequentialWrap::Alloc(UInt32 size) throw() +{ + if (!BufBase || size != Size) + { + Free(); + BufBase = (Byte *)::MidAlloc((size_t)size); + Size = size; + } + return (BufBase != NULL); +} +*/ + +/* +EXTERN_C_BEGIN + +void CLookToSequentialWrap_Look(ILookInSeqStreamPtr pp) +{ + CLookToSequentialWrap *p = (CLookToSequentialWrap *)pp->Obj; + + if (p->Extra || p->Res != S_OK) + return; + { + UInt32 avail; + p->Res = p->Stream->Read(p->BufBase, p->Size, &avail); + p->Processed += avail; + pp->Buf = p->BufBase; + pp->Limit = pp->Buf + avail; + if (avail == 0) + p->Extra = true; + } +} + +EXTERN_C_END +*/ + /* ---------- CByteOutBufWrap ---------- */ void CByteOutBufWrap::Free() throw() { ::MidFree(Buf); - Buf = 0; + Buf = NULL; } bool CByteOutBufWrap::Alloc(size_t size) throw() { - if (Buf == 0 || size != Size) + if (!Buf || size != Size) { Free(); Buf = (Byte *)::MidAlloc(size); Size = size; } - return (Buf != 0); + return (Buf != NULL); } HRESULT CByteOutBufWrap::Flush() throw() { if (Res == S_OK) { - size_t size = (Cur - Buf); + const size_t size = (size_t)(Cur - Buf); Res = WriteStream(Stream, Buf, size); if (Res == S_OK) Processed += size; - Cur = Buf; + // else throw 11; } + Cur = Buf; // reset pointer for later Wrap_WriteByte() return Res; } -static void Wrap_WriteByte(void *pp, Byte b) throw() +static void Wrap_WriteByte(IByteOutPtr pp, Byte b) throw() { - CByteOutBufWrap *p = (CByteOutBufWrap *)pp; + CByteOutBufWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteOutBufWrap, vt); + // Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteOutBufWrap) Byte *dest = p->Cur; *dest = b; p->Cur = ++dest; @@ -224,7 +298,57 @@ static void Wrap_WriteByte(void *pp, Byte b) throw() p->Flush(); } -CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0) +CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(NULL), Size(0) +{ + vt.Write = Wrap_WriteByte; +} + + +/* ---------- CLookOutWrap ---------- */ + +/* +void CLookOutWrap::Free() throw() +{ + ::MidFree(Buf); + Buf = NULL; +} + +bool CLookOutWrap::Alloc(size_t size) throw() +{ + if (!Buf || size != Size) + { + Free(); + Buf = (Byte *)::MidAlloc(size); + Size = size; + } + return (Buf != NULL); +} + +static size_t LookOutWrap_GetOutBuf(ILookOutStreamPtr pp, void **buf) throw() +{ + CLookOutWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt); + *buf = p->Buf; + return p->Size; +} + +static size_t LookOutWrap_Write(ILookOutStreamPtr pp, size_t size) throw() +{ + CLookOutWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt); + if (p->Res == S_OK && size != 0) + { + p->Res = WriteStream(p->Stream, p->Buf, size); + if (p->Res == S_OK) + { + p->Processed += size; + return size; + } + } + return 0; +} + +CLookOutWrap::CLookOutWrap() throw(): Buf(NULL), Size(0) { - p.Write = Wrap_WriteByte; + vt.GetOutBuf = LookOutWrap_GetOutBuf; + vt.Write = LookOutWrap_Write; } +*/ diff --git a/3rdparty/lzma/CPP/7zip/Common/CWrappers.h b/3rdparty/lzma/CPP/7zip/Common/CWrappers.h index acadc170edc..6c10a5c2562 100644 --- a/3rdparty/lzma/CPP/7zip/Common/CWrappers.h +++ b/3rdparty/lzma/CPP/7zip/Common/CWrappers.h @@ -1,54 +1,59 @@ // CWrappers.h -#ifndef __C_WRAPPERS_H -#define __C_WRAPPERS_H +#ifndef ZIP7_INC_C_WRAPPERS_H +#define ZIP7_INC_C_WRAPPERS_H #include "../ICoder.h" #include "../../Common/MyCom.h" +SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw(); +HRESULT SResToHRESULT(SRes res) throw(); + struct CCompressProgressWrap { - ICompressProgress p; + ICompressProgress vt; ICompressProgressInfo *Progress; HRESULT Res; - CCompressProgressWrap(ICompressProgressInfo *progress) throw(); + void Init(ICompressProgressInfo *progress) throw(); }; + struct CSeqInStreamWrap { - ISeqInStream p; + ISeqInStream vt; ISequentialInStream *Stream; HRESULT Res; UInt64 Processed; - CSeqInStreamWrap(ISequentialInStream *stream) throw(); + void Init(ISequentialInStream *stream) throw(); }; + struct CSeekInStreamWrap { - ISeekInStream p; + ISeekInStream vt; IInStream *Stream; HRESULT Res; - CSeekInStreamWrap(IInStream *stream) throw(); + void Init(IInStream *stream) throw(); }; + struct CSeqOutStreamWrap { - ISeqOutStream p; + ISeqOutStream vt; ISequentialOutStream *Stream; HRESULT Res; UInt64 Processed; - CSeqOutStreamWrap(ISequentialOutStream *stream) throw(); + void Init(ISequentialOutStream *stream) throw(); }; -HRESULT SResToHRESULT(SRes res) throw(); struct CByteInBufWrap { - IByteIn p; + IByteIn vt; const Byte *Cur; const Byte *Lim; Byte *Buf; @@ -58,7 +63,7 @@ struct CByteInBufWrap bool Extra; HRESULT Res; - CByteInBufWrap(); + CByteInBufWrap() throw(); ~CByteInBufWrap() { Free(); } void Free() throw(); bool Alloc(UInt32 size) throw(); @@ -69,7 +74,40 @@ struct CByteInBufWrap Extra = false; Res = S_OK; } - UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + UInt64 GetProcessed() const { return Processed + (size_t)(Cur - Buf); } + Byte ReadByteFromNewBlock() throw(); + Byte ReadByte() + { + if (Cur != Lim) + return *Cur++; + return ReadByteFromNewBlock(); + } +}; + + +/* +struct CLookToSequentialWrap +{ + Byte *BufBase; + UInt32 Size; + ISequentialInStream *Stream; + UInt64 Processed; + bool Extra; + HRESULT Res; + + CLookToSequentialWrap(): BufBase(NULL) {} + ~CLookToSequentialWrap() { Free(); } + void Free() throw(); + bool Alloc(UInt32 size) throw(); + void Init() + { + // Lim = Cur = Buf; + Processed = 0; + Extra = false; + Res = S_OK; + } + // UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + Byte ReadByteFromNewBlock() throw(); Byte ReadByte() { @@ -79,9 +117,16 @@ struct CByteInBufWrap } }; +EXTERN_C_BEGIN +// void CLookToSequentialWrap_Look(ILookInSeqStream *pp); +EXTERN_C_END +*/ + + + struct CByteOutBufWrap { - IByteOut p; + IByteOut vt; Byte *Cur; const Byte *Lim; Byte *Buf; @@ -101,7 +146,7 @@ struct CByteOutBufWrap Processed = 0; Res = S_OK; } - UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + UInt64 GetProcessed() const { return Processed + (size_t)(Cur - Buf); } HRESULT Flush() throw(); void WriteByte(Byte b) { @@ -111,4 +156,27 @@ struct CByteOutBufWrap } }; + +/* +struct CLookOutWrap +{ + ILookOutStream vt; + Byte *Buf; + size_t Size; + ISequentialOutStream *Stream; + UInt64 Processed; + HRESULT Res; + + CLookOutWrap() throw(); + ~CLookOutWrap() { Free(); } + void Free() throw(); + bool Alloc(size_t size) throw(); + void Init() + { + Processed = 0; + Res = S_OK; + } +}; +*/ + #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp index 75074ad891f..bf7b04e441c 100644 --- a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp @@ -11,19 +11,23 @@ #include "RegisterCodec.h" static const unsigned kNumCodecsMax = 64; +extern +unsigned g_NumCodecs; unsigned g_NumCodecs = 0; +extern +const CCodecInfo *g_Codecs[]; const CCodecInfo *g_Codecs[kNumCodecsMax]; // We use g_ExternalCodecs in other stages. +#ifdef Z7_EXTERNAL_CODECS /* -#ifdef EXTERNAL_CODECS extern CExternalCodecs g_ExternalCodecs; #define CHECK_GLOBAL_CODECS \ - if (!__externalCodecs || !__externalCodecs->IsSet()) __externalCodecs = &g_ExternalCodecs; -#endif + if (!_externalCodecs || !_externalCodecs->IsSet()) _externalCodecs = &g_ExternalCodecs; */ - #define CHECK_GLOBAL_CODECS +#endif + void RegisterCodec(const CCodecInfo *codecInfo) throw() { @@ -32,7 +36,11 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw() } static const unsigned kNumHashersMax = 16; +extern +unsigned g_NumHashers; unsigned g_NumHashers = 0; +extern +const CHasherInfo *g_Hashers[]; const CHasherInfo *g_Hashers[kNumHashersMax]; void RegisterHasher(const CHasherInfo *hashInfo) throw() @@ -42,12 +50,12 @@ void RegisterHasher(const CHasherInfo *hashInfo) throw() } -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res) { NWindows::NCOM::CPropVariant prop; - RINOK(codecsInfo->GetProperty(index, propID, &prop)); + RINOK(codecsInfo->GetProperty(index, propID, &prop)) if (prop.vt == VT_EMPTY) res = 1; else if (prop.vt == VT_UI4) @@ -60,7 +68,7 @@ static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res) { NWindows::NCOM::CPropVariant prop; - RINOK(codecsInfo->GetProperty(index, propID, &prop)); + RINOK(codecsInfo->GetProperty(index, propID, &prop)) if (prop.vt == VT_EMPTY) res = true; else if (prop.vt == VT_BOOL) @@ -81,13 +89,13 @@ HRESULT CExternalCodecs::Load() UString s; UInt32 num; - RINOK(GetCodecs->GetNumMethods(&num)); + RINOK(GetCodecs->GetNumMethods(&num)) for (UInt32 i = 0; i < num; i++) { NWindows::NCOM::CPropVariant prop; - RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop)); + RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop)) if (prop.vt != VT_UI8) continue; // old Interface info.Id = prop.uhVal.QuadPart; @@ -95,21 +103,22 @@ HRESULT CExternalCodecs::Load() prop.Clear(); info.Name.Empty(); - RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop)); + RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop)) if (prop.vt == VT_BSTR) info.Name.SetFromWStr_if_Ascii(prop.bstrVal); else if (prop.vt != VT_EMPTY) continue; - RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kPackStreams, info.NumStreams)); + RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kPackStreams, info.NumStreams)) { UInt32 numUnpackStreams = 1; - RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kUnpackStreams, numUnpackStreams)); + RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kUnpackStreams, numUnpackStreams)) if (numUnpackStreams != 1) continue; } - RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)); - RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)); + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)) + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)) + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kIsFilter, info.IsFilter)) Codecs.Add(info); } @@ -124,7 +133,7 @@ HRESULT CExternalCodecs::Load() { NWindows::NCOM::CPropVariant prop; - RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop)); + RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop)) if (prop.vt != VT_UI8) continue; info.Id = prop.uhVal.QuadPart; @@ -132,7 +141,7 @@ HRESULT CExternalCodecs::Load() prop.Clear(); info.Name.Empty(); - RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop)); + RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop)) if (prop.vt == VT_BSTR) info.Name.SetFromWStr_if_Ascii(prop.bstrVal); else if (prop.vt != VT_EMPTY) @@ -148,44 +157,82 @@ HRESULT CExternalCodecs::Load() #endif -bool FindMethod( +int FindMethod_Index( DECL_EXTERNAL_CODECS_LOC_VARS const AString &name, - CMethodId &methodId, UInt32 &numStreams) + bool encode, + CMethodId &methodId, + UInt32 &numStreams, + bool &isFilter) { unsigned i; for (i = 0; i < g_NumCodecs; i++) { const CCodecInfo &codec = *g_Codecs[i]; - if (StringsAreEqualNoCase_Ascii(name, codec.Name)) + if ((encode ? codec.CreateEncoder : codec.CreateDecoder) + && StringsAreEqualNoCase_Ascii(name, codec.Name)) { methodId = codec.Id; numStreams = codec.NumStreams; - return true; + isFilter = codec.IsFilter; + return (int)i; } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; - if (StringsAreEqualNoCase_Ascii(name, codec.Name)) + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; + if ((encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned) + && StringsAreEqualNoCase_Ascii(name, codec.Name)) { methodId = codec.Id; numStreams = codec.NumStreams; - return true; + isFilter = codec.IsFilter; + return (int)(g_NumCodecs + i); } } #endif - return false; + return -1; } + +static int FindMethod_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode) +{ + unsigned i; + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if (codec.Id == methodId && (encode ? codec.CreateEncoder : codec.CreateDecoder)) + return (int)i; + } + + #ifdef Z7_EXTERNAL_CODECS + + CHECK_GLOBAL_CODECS + + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) + { + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; + if (codec.Id == methodId && (encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned)) + return (int)(g_NumCodecs + i); + } + + #endif + + return -1; +} + + bool FindMethod( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, @@ -204,14 +251,14 @@ bool FindMethod( } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; if (methodId == codec.Id) { name = codec.Name; @@ -240,14 +287,14 @@ bool FindHashMethod( } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) { - const CHasherInfoEx &codec = __externalCodecs->Hashers[i]; + const CHasherInfoEx &codec = _externalCodecs->Hashers[i]; if (StringsAreEqualNoCase_Ascii(name, codec.Name)) { methodId = codec.Id; @@ -269,20 +316,22 @@ void GetHashMethods( for (i = 0; i < g_NumHashers; i++) methods[i] = (*g_Hashers[i]).Id; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) - methods.Add(__externalCodecs->Hashers[i].Id); + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) + methods.Add(_externalCodecs->Hashers[i].Id); #endif } -HRESULT CreateCoder( + + +HRESULT CreateCoder_Index( DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, bool encode, + unsigned i, bool encode, CMyComPtr<ICompressFilter> &filter, CCreatedCoder &cod) { @@ -290,11 +339,10 @@ HRESULT CreateCoder( cod.IsFilter = false; cod.NumStreams = 1; - unsigned i; - for (i = 0; i < g_NumCodecs; i++) + if (i < g_NumCodecs) { const CCodecInfo &codec = *g_Codecs[i]; - if (codec.Id == methodId) + // if (codec.Id == methodId) { if (encode) { @@ -319,17 +367,18 @@ HRESULT CreateCoder( } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) + if (_externalCodecs) { + i -= g_NumCodecs; cod.IsExternal = true; - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) + if (i < _externalCodecs->Codecs.Size()) { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; - if (codec.Id == methodId) + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; + // if (codec.Id == methodId) { if (encode) { @@ -337,15 +386,15 @@ HRESULT CreateCoder( { if (codec.NumStreams == 1) { - HRESULT res = __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&cod.Coder); + const HRESULT res = _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&cod.Coder); if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE) return res; if (cod.Coder) return res; - return __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter); + return _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter); } cod.NumStreams = codec.NumStreams; - return __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); + return _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); } } else @@ -353,15 +402,15 @@ HRESULT CreateCoder( { if (codec.NumStreams == 1) { - HRESULT res = __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&cod.Coder); + const HRESULT res = _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&cod.Coder); if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE) return res; if (cod.Coder) return res; - return __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter); + return _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter); } cod.NumStreams = codec.NumStreams; - return __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); + return _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); } } } @@ -371,13 +420,50 @@ HRESULT CreateCoder( return S_OK; } -HRESULT CreateCoder( + +HRESULT CreateCoder_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + unsigned index, bool encode, + CCreatedCoder &cod) +{ + CMyComPtr<ICompressFilter> filter; + const HRESULT res = CreateCoder_Index( + EXTERNAL_CODECS_LOC_VARS + index, encode, + filter, cod); + + if (filter) + { + cod.IsFilter = true; + CFilterCoder *coderSpec = new CFilterCoder(encode); + cod.Coder = coderSpec; + coderSpec->Filter = filter; + } + + return res; +} + + +HRESULT CreateCoder_Id( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode, + CMyComPtr<ICompressFilter> &filter, + CCreatedCoder &cod) +{ + const int index = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS methodId, encode); + if (index < 0) + return S_OK; + return CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)index, encode, filter, cod); +} + + +HRESULT CreateCoder_Id( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, bool encode, CCreatedCoder &cod) { CMyComPtr<ICompressFilter> filter; - HRESULT res = CreateCoder( + const HRESULT res = CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS methodId, encode, filter, cod); @@ -393,13 +479,14 @@ HRESULT CreateCoder( return res; } -HRESULT CreateCoder( + +HRESULT CreateCoder_Id( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, bool encode, CMyComPtr<ICompressCoder> &coder) { CCreatedCoder cod; - HRESULT res = CreateCoder( + const HRESULT res = CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS methodId, encode, cod); @@ -413,7 +500,7 @@ HRESULT CreateFilter( CMyComPtr<ICompressFilter> &filter) { CCreatedCoder cod; - return CreateCoder( + return CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS methodId, encode, filter, cod); @@ -440,18 +527,18 @@ HRESULT CreateHasher( } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (!hasher && __externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) + if (!hasher && _externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) { - const CHasherInfoEx &codec = __externalCodecs->Hashers[i]; + const CHasherInfoEx &codec = _externalCodecs->Hashers[i]; if (codec.Id == methodId) { name = codec.Name; - return __externalCodecs->GetHashers->CreateHasher((UInt32)i, &hasher); + return _externalCodecs->GetHashers->CreateHasher((UInt32)i, &hasher); } } diff --git a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h index f06064b6a6f..709fe83c1d7 100644 --- a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h +++ b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h @@ -1,7 +1,7 @@ // CreateCoder.h -#ifndef __CREATE_CODER_H -#define __CREATE_CODER_H +#ifndef ZIP7_INC_CREATE_CODER_H +#define ZIP7_INC_CREATE_CODER_H #include "../../Common/MyCom.h" #include "../../Common/MyString.h" @@ -11,10 +11,10 @@ #include "MethodId.h" /* - if EXTERNAL_CODECS is not defined, the code supports only codecs that + if Z7_EXTERNAL_CODECS is not defined, the code supports only codecs that are statically linked at compile-time and link-time. - if EXTERNAL_CODECS is defined, the code supports also codecs from another + if Z7_EXTERNAL_CODECS is defined, the code supports also codecs from another executable modules, that can be linked dynamically at run-time: - EXE module can use codecs from external DLL files. - DLL module can use codecs from external EXE and DLL files. @@ -26,7 +26,7 @@ 2) External codecs */ -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS struct CCodecInfoEx { @@ -35,8 +35,9 @@ struct CCodecInfoEx UInt32 NumStreams; bool EncoderIsAssigned; bool DecoderIsAssigned; + bool IsFilter; // it's unused - CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {} + CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false), IsFilter(false) {} }; struct CHasherInfoEx @@ -45,13 +46,17 @@ struct CHasherInfoEx AString Name; }; -#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo, -#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo) -#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo); -#define IMPL_ISetCompressCodecsInfo2(x) \ -STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \ - COM_TRY_BEGIN __externalCodecs.GetCodecs = compressCodecsInfo; return __externalCodecs.Load(); COM_TRY_END } -#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler) +#define Z7_PUBLIC_ISetCompressCodecsInfo_IFEC \ + public ISetCompressCodecsInfo, +#define Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC \ + Z7_COM_QI_ENTRY(ISetCompressCodecsInfo) +#define DECL_ISetCompressCodecsInfo \ + Z7_COM7F_IMP(SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) +#define IMPL_ISetCompressCodecsInfo2(cls) \ + Z7_COM7F_IMF(cls::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) \ + { COM_TRY_BEGIN _externalCodecs.GetCodecs = compressCodecsInfo; \ + return _externalCodecs.Load(); COM_TRY_END } +#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler) struct CExternalCodecs { @@ -82,26 +87,27 @@ struct CExternalCodecs extern CExternalCodecs g_ExternalCodecs; -#define EXTERNAL_CODECS_VARS2 (__externalCodecs.IsSet() ? &__externalCodecs : &g_ExternalCodecs) -#define EXTERNAL_CODECS_VARS2_L (&__externalCodecs) +#define EXTERNAL_CODECS_VARS2 (_externalCodecs.IsSet() ? &_externalCodecs : &g_ExternalCodecs) +#define EXTERNAL_CODECS_VARS2_L (&_externalCodecs) #define EXTERNAL_CODECS_VARS2_G (&g_ExternalCodecs) -#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs __externalCodecs; +#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs _externalCodecs; #define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2, #define EXTERNAL_CODECS_VARS_L EXTERNAL_CODECS_VARS2_L, #define EXTERNAL_CODECS_VARS_G EXTERNAL_CODECS_VARS2_G, -#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *__externalCodecs -#define EXTERNAL_CODECS_LOC_VARS2 __externalCodecs +#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *_externalCodecs +#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2, +#define DECL_EXTERNAL_CODECS_LOC_VARS_DECL DECL_EXTERNAL_CODECS_LOC_VARS2; -#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2, -#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2, +#define EXTERNAL_CODECS_LOC_VARS2 _externalCodecs +#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2, #else -#define PUBLIC_ISetCompressCodecsInfo -#define QUERY_ENTRY_ISetCompressCodecsInfo +#define Z7_PUBLIC_ISetCompressCodecsInfo_IFEC +#define Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC #define DECL_ISetCompressCodecsInfo #define IMPL_ISetCompressCodecsInfo #define EXTERNAL_CODECS_VARS2 @@ -110,19 +116,20 @@ extern CExternalCodecs g_ExternalCodecs; #define EXTERNAL_CODECS_VARS_L #define EXTERNAL_CODECS_VARS_G #define DECL_EXTERNAL_CODECS_LOC_VARS2 -#define EXTERNAL_CODECS_LOC_VARS2 #define DECL_EXTERNAL_CODECS_LOC_VARS +#define DECL_EXTERNAL_CODECS_LOC_VARS_DECL +#define EXTERNAL_CODECS_LOC_VARS2 #define EXTERNAL_CODECS_LOC_VARS #endif - - - -bool FindMethod( +int FindMethod_Index( DECL_EXTERNAL_CODECS_LOC_VARS const AString &name, - CMethodId &methodId, UInt32 &numStreams); + bool encode, + CMethodId &methodId, + UInt32 &numStreams, + bool &isFilter); bool FindMethod( DECL_EXTERNAL_CODECS_LOC_VARS @@ -152,18 +159,29 @@ struct CCreatedCoder }; -HRESULT CreateCoder( +HRESULT CreateCoder_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + unsigned codecIndex, bool encode, + CMyComPtr<ICompressFilter> &filter, + CCreatedCoder &cod); + +HRESULT CreateCoder_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + unsigned index, bool encode, + CCreatedCoder &cod); + +HRESULT CreateCoder_Id( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, bool encode, CMyComPtr<ICompressFilter> &filter, CCreatedCoder &cod); -HRESULT CreateCoder( +HRESULT CreateCoder_Id( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, bool encode, CCreatedCoder &cod); -HRESULT CreateCoder( +HRESULT CreateCoder_Id( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, bool encode, CMyComPtr<ICompressCoder> &coder); diff --git a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp index d186e599333..1ebfd72bb93 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp @@ -2,9 +2,6 @@ #include "StdAfx.h" -#include "../../Common/Defs.h" -#include "../../Common/IntToString.h" - #include "../../Windows/FileFind.h" #include "FilePathAutoRename.h" @@ -14,10 +11,8 @@ using namespace NWindows; static bool MakeAutoName(const FString &name, const FString &extension, UInt32 value, FString &path) { - char temp[16]; - ConvertUInt32ToString(value, temp); path = name; - path.AddAscii(temp); + path.Add_UInt32(value); path += extension; return NFile::NFind::DoesFileOrDirExist(path); } @@ -31,10 +26,10 @@ bool AutoRenamePath(FString &path) FString extension; if (dotPos > slashPos + 1) { - name.DeleteFrom(dotPos); - extension = path.Ptr(dotPos); + name.DeleteFrom((unsigned)dotPos); + extension = path.Ptr((unsigned)dotPos); } - name += FTEXT('_'); + name += '_'; FString temp; diff --git a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h index 7b576591c9a..ac36882312d 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h +++ b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h @@ -1,7 +1,7 @@ // FilePathAutoRename.h -#ifndef __FILE_PATH_AUTO_RENAME_H -#define __FILE_PATH_AUTO_RENAME_H +#ifndef ZIP7_INC_FILE_PATH_AUTO_RENAME_H +#define ZIP7_INC_FILE_PATH_AUTO_RENAME_H #include "../../Common/MyString.h" diff --git a/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp b/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp index f3a322fc9be..429863630ed 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp @@ -2,42 +2,71 @@ #include "StdAfx.h" +// #include <stdio.h> + #ifndef _WIN32 #include <fcntl.h> #include <unistd.h> #include <errno.h> +#include <grp.h> +#include <pwd.h> + +// for major()/minor(): +#include <sys/types.h> +#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) +#else +#ifndef major +#include <sys/sysmacros.h> #endif +#endif + +#endif // _WIN32 + +#include "../../Windows/FileFind.h" -#ifdef SUPPORT_DEVICE_FILE +#ifdef Z7_DEVICE_FILE #include "../../../C/Alloc.h" #include "../../Common/Defs.h" #endif +#include "../PropID.h" + #include "FileStreams.h" -static inline HRESULT ConvertBoolToHRESULT(bool result) +static inline HRESULT GetLastError_HRESULT() { - #ifdef _WIN32 - if (result) - return S_OK; DWORD lastError = ::GetLastError(); if (lastError == 0) return E_FAIL; return HRESULT_FROM_WIN32(lastError); - #else - return result ? S_OK: E_FAIL; - #endif } +static inline HRESULT ConvertBoolToHRESULT(bool result) +{ + if (result) + return S_OK; + return GetLastError_HRESULT(); +} + +#ifdef Z7_DEVICE_FILE static const UInt32 kClusterSize = 1 << 18; +#endif + CInFileStream::CInFileStream(): - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE VirtPos(0), PhyPos(0), - Buf(0), + Buf(NULL), BufSize(0), - #endif + #endif + #ifndef _WIN32 + _uid(0), + _gid(0), + StoreOwnerId(false), + StoreOwnerName(false), + #endif + _info_WasLoaded(false), SupportHardLinks(false), Callback(NULL), CallbackRef(0) @@ -46,19 +75,19 @@ CInFileStream::CInFileStream(): CInFileStream::~CInFileStream() { - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE MidFree(Buf); #endif if (Callback) - Callback->InFileStream_On_Destroy(CallbackRef); + Callback->InFileStream_On_Destroy(this, CallbackRef); } -STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE if (processedSize) *processedSize = 0; if (size == 0) @@ -69,7 +98,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) { if (VirtPos >= File.Size) return VirtPos == File.Size ? S_OK : E_FAIL; - UInt64 rem = File.Size - VirtPos; + const UInt64 rem = File.Size - VirtPos; if (size > rem) size = (UInt32)rem; } @@ -77,13 +106,13 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) { const UInt32 mask = kClusterSize - 1; const UInt64 mask2 = ~(UInt64)mask; - UInt64 alignedPos = VirtPos & mask2; + const UInt64 alignedPos = VirtPos & mask2; if (BufSize > 0 && BufStartPos == alignedPos) { - UInt32 pos = (UInt32)VirtPos & mask; + const UInt32 pos = (UInt32)VirtPos & mask; if (pos >= BufSize) return S_OK; - UInt32 rem = MyMin(BufSize - pos, size); + const UInt32 rem = MyMin(BufSize - pos, size); memcpy(data, Buf + pos, rem); VirtPos += rem; if (processedSize) @@ -92,7 +121,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) } bool useBuf = false; - if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 ) + if ((VirtPos & mask) != 0 || ((size_t)(ptrdiff_t)data & mask) != 0 ) useBuf = true; else { @@ -111,7 +140,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) if (alignedPos != PhyPos) { UInt64 realNewPosition; - bool result = File.Seek(alignedPos, FILE_BEGIN, realNewPosition); + const bool result = File.Seek((Int64)alignedPos, FILE_BEGIN, realNewPosition); if (!result) return ConvertBoolToHRESULT(result); PhyPos = realNewPosition; @@ -128,7 +157,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) if (!Buf) return E_OUTOFMEMORY; } - bool result = File.Read1(Buf, readSize, BufSize); + const bool result = File.Read1(Buf, readSize, BufSize); if (!result) return ConvertBoolToHRESULT(result); @@ -140,7 +169,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) if (VirtPos != PhyPos) { UInt64 realNewPosition; - bool result = File.Seek(VirtPos, FILE_BEGIN, realNewPosition); + bool result = File.Seek((Int64)VirtPos, FILE_BEGIN, realNewPosition); if (!result) return ConvertBoolToHRESULT(result); PhyPos = VirtPos = realNewPosition; @@ -149,11 +178,11 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) #endif UInt32 realProcessedSize; - bool result = File.ReadPart(data, size, realProcessedSize); + const bool result = File.ReadPart(data, size, realProcessedSize); if (processedSize) *processedSize = realProcessedSize; - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE VirtPos += realProcessedSize; PhyPos += realProcessedSize; #endif @@ -161,37 +190,31 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) if (result) return S_OK; + #else // Z7_FILE_STREAMS_USE_WIN_FILE + + if (processedSize) + *processedSize = 0; + const ssize_t res = File.read_part(data, (size_t)size); + if (res != -1) { - DWORD error = ::GetLastError(); + if (processedSize) + *processedSize = (UInt32)res; + return S_OK; + } + #endif // Z7_FILE_STREAMS_USE_WIN_FILE + { + const DWORD error = ::GetLastError(); if (Callback) return Callback->InFileStream_On_Error(CallbackRef, error); if (error == 0) return E_FAIL; - return HRESULT_FROM_WIN32(error); } - - #else - - if (processedSize) - *processedSize = 0; - ssize_t res = File.Read(data, (size_t)size); - if (res == -1) - { - if (Callback) - return Callback->InFileStream_On_Error(CallbackRef, E_FAIL); - return E_FAIL; - } - if (processedSize) - *processedSize = (UInt32)res; - return S_OK; - - #endif } #ifdef UNDER_CE -STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { size_t s2 = fread(data, 1, size, stdin); int error = ferror(stdin); @@ -202,7 +225,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi return E_FAIL; } #else -STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { #ifdef _WIN32 @@ -228,7 +251,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi } while (res < 0 && (errno == EINTR)); if (res == -1) - return E_FAIL; + return GetLastError_HRESULT(); if (processedSize) *processedSize = (UInt32)res; return S_OK; @@ -238,14 +261,14 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi #endif -STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { if (seekOrigin >= 3) return STG_E_INVALIDFUNCTION; - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END)) { switch (seekOrigin) @@ -257,29 +280,40 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - VirtPos = offset; + VirtPos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } #endif - UInt64 realNewPosition; - bool result = File.Seek(offset, seekOrigin, realNewPosition); + UInt64 realNewPosition = 0; + const bool result = File.Seek(offset, seekOrigin, realNewPosition); + const HRESULT hres = ConvertBoolToHRESULT(result); + + /* 21.07: new File.Seek() in 21.07 already returns correct (realNewPosition) + in case of error. So we don't need additional code below */ + // if (!result) { realNewPosition = 0; File.GetPosition(realNewPosition); } - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE PhyPos = VirtPos = realNewPosition; #endif if (newPosition) *newPosition = realNewPosition; - return ConvertBoolToHRESULT(result); + + return hres; #else - off_t res = File.Seek((off_t)offset, seekOrigin); + const off_t res = File.seek((off_t)offset, (int)seekOrigin); if (res == -1) - return E_FAIL; + { + const HRESULT hres = GetLastError_HRESULT(); + if (newPosition) + *newPosition = (UInt64)File.seekToCur(); + return hres; + } if (newPosition) *newPosition = (UInt64)res; return S_OK; @@ -287,17 +321,25 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos #endif } -STDMETHODIMP CInFileStream::GetSize(UInt64 *size) +Z7_COM7F_IMF(CInFileStream::GetSize(UInt64 *size)) { return ConvertBoolToHRESULT(File.GetLength(*size)); } -#ifdef USE_WIN_FILE +#ifdef Z7_FILE_STREAMS_USE_WIN_FILE -STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) +Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) { + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const BY_HANDLE_FILE_INFORMATION &info = _info; + /* BY_HANDLE_FILE_INFORMATION info; - if (File.GetFileInformation(&info)) + if (!File.GetFileInformation(&info)) + return GetLastError_HRESULT(); + */ { if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; if (cTime) *cTime = info.ftCreationTime; @@ -306,13 +348,20 @@ STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aT if (attrib) *attrib = info.dwFileAttributes; return S_OK; } - return GetLastError(); } -STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props) +Z7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props)) { + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const BY_HANDLE_FILE_INFORMATION &info = _info; + /* BY_HANDLE_FILE_INFORMATION info; - if (File.GetFileInformation(&info)) + if (!File.GetFileInformation(&info)) + return GetLastError_HRESULT(); + */ { props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; props->VolID = info.dwVolumeSerialNumber; @@ -325,11 +374,300 @@ STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props) props->MTime = info.ftLastWriteTime; return S_OK; } - return GetLastError(); +} + +Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + + if (!_info_WasLoaded) + return S_OK; + + NWindows::NCOM::CPropVariant prop; + + #ifdef Z7_DEVICE_FILE + if (File.IsDeviceFile) + { + switch (propID) + { + case kpidSize: + if (File.SizeDefined) + prop = File.Size; + break; + // case kpidAttrib: prop = (UInt32)0; break; + case kpidPosixAttrib: + { + prop = (UInt32)NWindows::NFile::NFind::NAttributes:: + Get_PosixMode_From_WinAttrib(0); + /* GNU TAR by default can't extract file with MY_LIN_S_IFBLK attribute + so we don't use MY_LIN_S_IFBLK here */ + // prop = (UInt32)(MY_LIN_S_IFBLK | 0600); // for debug + break; + } + /* + case kpidDeviceMajor: + prop = (UInt32)8; // id for SCSI type device (sda) + break; + case kpidDeviceMinor: + prop = (UInt32)0; + break; + */ + } + } + else + #endif + { + switch (propID) + { + case kpidSize: + { + const UInt64 size = (((UInt64)_info.nFileSizeHigh) << 32) + _info.nFileSizeLow; + prop = size; + break; + } + case kpidAttrib: prop = (UInt32)_info.dwFileAttributes; break; + case kpidCTime: PropVariant_SetFrom_FiTime(prop, _info.ftCreationTime); break; + case kpidATime: PropVariant_SetFrom_FiTime(prop, _info.ftLastAccessTime); break; + case kpidMTime: PropVariant_SetFrom_FiTime(prop, _info.ftLastWriteTime); break; + case kpidPosixAttrib: + prop = (UInt32)NWindows::NFile::NFind::NAttributes:: + Get_PosixMode_From_WinAttrib(_info.dwFileAttributes); + // | (UInt32)(1 << 21); // for debug + break; + } + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CInFileStream::ReloadProps()) +{ + #ifdef Z7_DEVICE_FILE + if (File.IsDeviceFile) + { + memset(&_info, 0, sizeof(_info)); + if (File.SizeDefined) + { + _info.nFileSizeHigh = (DWORD)(File.Size >> 32); + _info.nFileSizeLow = (DWORD)(File.Size); + } + _info.nNumberOfLinks = 1; + _info_WasLoaded = true; + return S_OK; + } + #endif + _info_WasLoaded = File.GetFileInformation(&_info); + if (!_info_WasLoaded) + return GetLastError_HRESULT(); + return S_OK; +} + + +#elif !defined(_WIN32) + +Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const struct stat &st = _info; + /* + struct stat st; + if (File.my_fstat(&st) != 0) + return GetLastError_HRESULT(); + */ + + if (size) *size = (UInt64)st.st_size; + if (cTime) FiTime_To_FILETIME (ST_CTIME(st), *cTime); + if (aTime) FiTime_To_FILETIME (ST_ATIME(st), *aTime); + if (mTime) FiTime_To_FILETIME (ST_MTIME(st), *mTime); + if (attrib) *attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); + + return S_OK; +} + +// #include <stdio.h> + +Z7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const struct stat &st = _info; + /* + struct stat st; + if (File.my_fstat(&st) != 0) + return GetLastError_HRESULT(); + */ + + props->Size = (UInt64)st.st_size; + /* + dev_t stat::st_dev: + GCC:Linux long unsigned int : __dev_t + Mac: int + */ + props->VolID = (UInt64)(Int64)st.st_dev; + props->FileID_Low = st.st_ino; + props->FileID_High = 0; + props->NumLinks = (UInt32)st.st_nlink; // we reduce to UInt32 from (nlink_t) that is (unsigned long) + props->Attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); + + FiTime_To_FILETIME (ST_CTIME(st), props->CTime); + FiTime_To_FILETIME (ST_ATIME(st), props->ATime); + FiTime_To_FILETIME (ST_MTIME(st), props->MTime); + + /* + printf("\nGetProps2() NumLinks=%d = st_dev=%d st_ino = %d\n" + , (unsigned)(props->NumLinks) + , (unsigned)(st.st_dev) + , (unsigned)(st.st_ino) + ); + */ + + return S_OK; +} + +Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + + if (!_info_WasLoaded) + return S_OK; + + const struct stat &st = _info; + + NWindows::NCOM::CPropVariant prop; + { + switch (propID) + { + case kpidSize: prop = (UInt64)st.st_size; break; + case kpidAttrib: + prop = (UInt32)NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); + break; + case kpidCTime: PropVariant_SetFrom_FiTime(prop, ST_CTIME(st)); break; + case kpidATime: PropVariant_SetFrom_FiTime(prop, ST_ATIME(st)); break; + case kpidMTime: PropVariant_SetFrom_FiTime(prop, ST_MTIME(st)); break; + case kpidPosixAttrib: prop = (UInt32)st.st_mode; break; + + #if defined(__APPLE__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #endif + + case kpidDeviceMajor: + { + // printf("\nst.st_rdev = %d\n", st.st_rdev); + if (S_ISCHR(st.st_mode) || + S_ISBLK(st.st_mode)) + prop = (UInt32)(major(st.st_rdev)); // + 1000); + // prop = (UInt32)12345678; // for debug + break; + } + + case kpidDeviceMinor: + if (S_ISCHR(st.st_mode) || + S_ISBLK(st.st_mode)) + prop = (UInt32)(minor(st.st_rdev)); // + 100); + // prop = (UInt32)(st.st_rdev); // for debug + // printf("\nst.st_rdev = %d\n", st.st_rdev); + // prop = (UInt32)123456789; // for debug + break; + + #if defined(__APPLE__) + #pragma GCC diagnostic pop + #endif + + /* + case kpidDevice: + if (S_ISCHR(st.st_mode) || + S_ISBLK(st.st_mode)) + prop = (UInt64)(st.st_rdev); + break; + */ + + case kpidUserId: + { + if (StoreOwnerId) + prop = (UInt32)st.st_uid; + break; + } + case kpidGroupId: + { + if (StoreOwnerId) + prop = (UInt32)st.st_gid; + break; + } + case kpidUser: + { + if (StoreOwnerName) + { + const uid_t uid = st.st_uid; + { + if (!OwnerName.IsEmpty() && _uid == uid) + prop = OwnerName; + else + { + const passwd *pw = getpwuid(uid); + if (pw) + { + // we can use utf-8 here. + // prop = pw->pw_name; + } + } + } + } + break; + } + case kpidGroup: + { + if (StoreOwnerName) + { + const uid_t gid = st.st_gid; + { + if (!OwnerGroup.IsEmpty() && _gid == gid) + prop = OwnerGroup; + else + { + const group *gr = getgrgid(gid); + if (gr) + { + // we can use utf-8 here. + // prop = gr->gr_name; + } + } + } + } + break; + } + } + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CInFileStream::ReloadProps()) +{ + _info_WasLoaded = (File.my_fstat(&_info) == 0); + if (!_info_WasLoaded) + return GetLastError_HRESULT(); + return S_OK; } #endif + + + ////////////////////////// // COutFileStream @@ -338,12 +676,12 @@ HRESULT COutFileStream::Close() return ConvertBoolToHRESULT(File.Close()); } -STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE UInt32 realProcessedSize; - bool result = File.Write(data, size, realProcessedSize); + const bool result = File.Write(data, size, realProcessedSize); ProcessedSize += realProcessedSize; if (processedSize) *processedSize = realProcessedSize; @@ -353,35 +691,36 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces if (processedSize) *processedSize = 0; - ssize_t res = File.Write(data, (size_t)size); - if (res == -1) - return E_FAIL; + size_t realProcessedSize; + const ssize_t res = File.write_full(data, (size_t)size, realProcessedSize); + ProcessedSize += realProcessedSize; if (processedSize) - *processedSize = (UInt32)res; - ProcessedSize += res; + *processedSize = (UInt32)realProcessedSize; + if (res == -1) + return GetLastError_HRESULT(); return S_OK; #endif } -STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { if (seekOrigin >= 3) return STG_E_INVALIDFUNCTION; - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - UInt64 realNewPosition; - bool result = File.Seek(offset, seekOrigin, realNewPosition); + UInt64 realNewPosition = 0; + const bool result = File.Seek(offset, seekOrigin, realNewPosition); if (newPosition) *newPosition = realNewPosition; return ConvertBoolToHRESULT(result); #else - off_t res = File.Seek((off_t)offset, seekOrigin); + const off_t res = File.seek((off_t)offset, (int)seekOrigin); if (res == -1) - return E_FAIL; + return GetLastError_HRESULT(); if (newPosition) *newPosition = (UInt64)res; return S_OK; @@ -389,23 +728,9 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo #endif } -STDMETHODIMP COutFileStream::SetSize(UInt64 newSize) +Z7_COM7F_IMF(COutFileStream::SetSize(UInt64 newSize)) { - #ifdef USE_WIN_FILE - - UInt64 currentPos; - if (!File.Seek(0, FILE_CURRENT, currentPos)) - return E_FAIL; - bool result = File.SetLength(newSize); - UInt64 currentPos2; - result = result && File.Seek(currentPos, currentPos2); - return result ? S_OK : E_FAIL; - - #else - - return E_FAIL; - - #endif + return ConvertBoolToHRESULT(File.SetLength_KeepPosition(newSize)); } HRESULT COutFileStream::GetSize(UInt64 *size) @@ -415,7 +740,7 @@ HRESULT COutFileStream::GetSize(UInt64 *size) #ifdef UNDER_CE -STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { size_t s2 = fwrite(data, 1, size, stdout); if (processedSize) @@ -425,7 +750,7 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro #else -STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -462,7 +787,7 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro while (res < 0 && (errno == EINTR)); if (res == -1) - return E_FAIL; + return GetLastError_HRESULT(); _size += (size_t)res; if (processedSize) diff --git a/3rdparty/lzma/CPP/7zip/Common/FileStreams.h b/3rdparty/lzma/CPP/7zip/Common/FileStreams.h index ef2986fdd88..7e1b086b139 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FileStreams.h +++ b/3rdparty/lzma/CPP/7zip/Common/FileStreams.h @@ -1,50 +1,75 @@ // FileStreams.h -#ifndef __FILE_STREAMS_H -#define __FILE_STREAMS_H +#ifndef ZIP7_INC_FILE_STREAMS_H +#define ZIP7_INC_FILE_STREAMS_H #ifdef _WIN32 -#define USE_WIN_FILE +#define Z7_FILE_STREAMS_USE_WIN_FILE #endif +#include "../../Common/MyCom.h" #include "../../Common/MyString.h" -#ifdef USE_WIN_FILE #include "../../Windows/FileIO.h" -#else -#include "../../Common/C_FileIO.h" -#endif - -#include "../../Common/MyCom.h" #include "../IStream.h" -#ifdef _WIN32 -typedef UINT_PTR My_UINT_PTR; -#else -typedef UINT My_UINT_PTR; -#endif +#include "UniqBlocks.h" -struct IInFileStream_Callback + +class CInFileStream; + +Z7_PURE_INTERFACES_BEGIN +DECLARE_INTERFACE(IInFileStream_Callback) { - virtual HRESULT InFileStream_On_Error(My_UINT_PTR val, DWORD error) = 0; - virtual void InFileStream_On_Destroy(My_UINT_PTR val) = 0; + virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error) = 0; + virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) = 0; }; - -class CInFileStream: +Z7_PURE_INTERFACES_END + + +/* +Z7_CLASS_IMP_COM_5( + CInFileStream + , IInStream + , IStreamGetSize + , IStreamGetProps + , IStreamGetProps2 + , IStreamGetProp +) +*/ +Z7_class_final(CInFileStream) : public IInStream, public IStreamGetSize, - #ifdef USE_WIN_FILE public IStreamGetProps, public IStreamGetProps2, - #endif + public IStreamGetProp, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_5( + IInStream, + IStreamGetSize, + IStreamGetProps, + IStreamGetProps2, + IStreamGetProp) + + Z7_IFACE_COM7_IMP(ISequentialInStream) + Z7_IFACE_COM7_IMP(IInStream) +public: + Z7_IFACE_COM7_IMP(IStreamGetSize) +private: + Z7_IFACE_COM7_IMP(IStreamGetProps) public: - #ifdef USE_WIN_FILE + Z7_IFACE_COM7_IMP(IStreamGetProps2) + Z7_IFACE_COM7_IMP(IStreamGetProp) + +private: NWindows::NFile::NIO::CInFile File; +public: + + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE UInt64 VirtPos; UInt64 PhyPos; UInt64 BufStartPos; @@ -52,70 +77,68 @@ public: UInt32 BufSize; #endif - #else - NC::NFile::NIO::CInFile File; #endif + #ifdef _WIN32 + BY_HANDLE_FILE_INFORMATION _info; + #else + struct stat _info; + UInt32 _uid; + UInt32 _gid; + UString OwnerName; + UString OwnerGroup; + bool StoreOwnerId; + bool StoreOwnerName; + #endif + + bool _info_WasLoaded; bool SupportHardLinks; - IInFileStream_Callback *Callback; - My_UINT_PTR CallbackRef; - - virtual ~CInFileStream(); + UINT_PTR CallbackRef; CInFileStream(); + ~CInFileStream(); + + void Set_PreserveATime(bool v) + { + File.PreserveATime = v; + } + + bool GetLength(UInt64 &length) const throw() + { + return File.GetLength(length); + } bool Open(CFSTR fileName) { + _info_WasLoaded = false; return File.Open(fileName); } bool OpenShared(CFSTR fileName, bool shareForWrite) { + _info_WasLoaded = false; return File.OpenShared(fileName, shareForWrite); } - - MY_QUERYINTERFACE_BEGIN2(IInStream) - MY_QUERYINTERFACE_ENTRY(IStreamGetSize) - #ifdef USE_WIN_FILE - MY_QUERYINTERFACE_ENTRY(IStreamGetProps) - MY_QUERYINTERFACE_ENTRY(IStreamGetProps2) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - STDMETHOD(GetSize)(UInt64 *size); - #ifdef USE_WIN_FILE - STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib); - STDMETHOD(GetProps2)(CStreamFileProps *props); - #endif }; -class CStdInFileStream: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - virtual ~CStdInFileStream() {} - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +Z7_CLASS_IMP_NOQIB_1( + CStdInFileStream + , ISequentialInStream +) }; -class COutFileStream: - public IOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + COutFileStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) public: - #ifdef USE_WIN_FILE + NWindows::NFile::NIO::COutFile File; - #else - NC::NFile::NIO::COutFile File; - #endif - virtual ~COutFileStream() {} + bool Create(CFSTR fileName, bool createAlways) { ProcessedSize = 0; @@ -131,36 +154,33 @@ public: UInt64 ProcessedSize; - #ifdef USE_WIN_FILE - bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) + bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) { return File.SetTime(cTime, aTime, mTime); } - bool SetMTime(const FILETIME *mTime) { return File.SetMTime(mTime); } - #endif + bool SetMTime(const CFiTime *mTime) { return File.SetMTime(mTime); } - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); + bool SeekToBegin_bool() + { + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE + return File.SeekToBegin(); + #else + return File.seekToBegin() == 0; + #endif + } HRESULT GetSize(UInt64 *size); }; -class CStdOutFileStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_NOQIB_1( + CStdOutFileStream + , ISequentialOutStream +) UInt64 _size; public: - MY_UNKNOWN_IMP - UInt64 GetSize() const { return _size; } CStdOutFileStream(): _size(0) {} - virtual ~CStdOutFileStream() {} - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp index 4f3ae4e7dcf..8d7e0dccfe5 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp @@ -2,11 +2,30 @@ #include "StdAfx.h" +// #include <stdio.h> + #include "../../Common/Defs.h" #include "FilterCoder.h" #include "StreamUtils.h" +#ifdef _WIN32 + #define alignedMidBuffer_Alloc g_MidAlloc +#else + #define alignedMidBuffer_Alloc g_AlignedAlloc +#endif + +CAlignedMidBuffer::~CAlignedMidBuffer() +{ + ISzAlloc_Free(&alignedMidBuffer_Alloc, _buf); +} + +void CAlignedMidBuffer::AllocAligned(size_t size) +{ + ISzAlloc_Free(&alignedMidBuffer_Alloc, _buf); + _buf = (Byte *)ISzAlloc_Alloc(&alignedMidBuffer_Alloc, size); +} + /* AES filters need 16-bytes alignment for HARDWARE-AES instructions. So we call IFilter::Filter(, size), where (size != 16 * N) only for last data block. @@ -16,13 +35,17 @@ Some filters (BCJ and others) don't process data at the end of stream in some cases. So the encoder and decoder write such last bytes without change. + + Most filters process all data, if we send aligned size to filter. + But BCJ filter can process up 4 bytes less than sent size. + And ARMT filter can process 2 bytes less than sent size. */ -static const UInt32 kBufSize = 1 << 20; +static const UInt32 kBufSize = 1 << 21; -STDMETHODIMP CFilterCoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; } -STDMETHODIMP CFilterCoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; } +Z7_COM7F_IMF(CFilterCoder::SetInBufSize(UInt32 , UInt32 size)) { _inBufSize = size; return S_OK; } +Z7_COM7F_IMF(CFilterCoder::SetOutBufSize(UInt32 , UInt32 size)) { _outBufSize = size; return S_OK; } HRESULT CFilterCoder::Alloc() { @@ -34,9 +57,10 @@ HRESULT CFilterCoder::Alloc() size &= ~(UInt32)(kMinSize - 1); if (size < kMinSize) size = kMinSize; + // size = (1 << 12); // + 117; // for debug if (!_buf || _bufSize != size) { - AllocAlignedMask(size, 16 - 1); + AllocAligned(size); if (!_buf) return E_OUTOFMEMORY; _bufSize = size; @@ -46,7 +70,7 @@ HRESULT CFilterCoder::Alloc() HRESULT CFilterCoder::Init_and_Alloc() { - RINOK(Filter->Init()); + RINOK(Filter->Init()) return Alloc(); } @@ -55,78 +79,198 @@ CFilterCoder::CFilterCoder(bool encodeMode): _inBufSize(kBufSize), _outBufSize(kBufSize), _encodeMode(encodeMode), - _outSizeIsDefined(false), + _outSize_Defined(false), _outSize(0), _nowPos64(0) {} -CFilterCoder::~CFilterCoder() -{ -} -STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) { - RINOK(Init_and_Alloc()); - + RINOK(Init_and_Alloc()) + + /* + It's expected that BCJ/ARMT filter can process up to 4 bytes less + than sent data size. For such BCJ/ARMT cases with non-filtered data we: + - write some filtered data to output stream + - move non-written data (filtered and non-filtered data) to start of buffer + - read more new data from input stream to position after end of non-filtered data + - call Filter() for concatenated data in buffer. + + For all cases, even for cases with partial filtering (BCJ/ARMT), + we try to keep real/virtual alignment for all operations + (memmove, Read(), Filter(), Write()). + We use (kAlignSize=64) alignmnent that is larger than (16-bytes) + required for AES filter alignment. + + AES-CBC uses 16-bytes blocks, that is simple case for processing here, + if we call Filter() for aligned size for all calls except of last call (last block). + And now there are no filters that use blocks with non-power2 size, + but we try to support such non-power2 filters too here at Code(). + */ + + UInt64 prev = 0; UInt64 nowPos64 = 0; bool inputFinished = false; - UInt32 pos = 0; + UInt32 readPos = 0; + UInt32 filterPos = 0; while (!outSize || nowPos64 < *outSize) { - UInt32 endPos = pos; - + HRESULT hres = S_OK; if (!inputFinished) { - size_t processedSize = _bufSize - pos; - RINOK(ReadStream(inStream, _buf + pos, &processedSize)); - endPos = pos + (UInt32)processedSize; - inputFinished = (endPos != _bufSize); + size_t processedSize = _bufSize - readPos; + /* for AES filters we need at least max(16, kAlignSize) bytes in buffer. + But we try to read full buffer to reduce the number of Filter() and Write() calls. + */ + hres = ReadStream(inStream, _buf + readPos, &processedSize); + readPos += (UInt32)processedSize; + inputFinished = (readPos != _bufSize); + if (hres != S_OK) + { + // do we need to stop encoding after reading error? + // if (_encodeMode) return hres; + inputFinished = true; + } } - pos = Filter->Filter(_buf, endPos); - - if (pos > endPos) + if (readPos == 0) + return hres; + + /* we set (needMoreInput = true), if it's block-filter (like AES-CBC) + that needs more data for current block filtering: + We read full input buffer with Read(), and _bufSize is aligned, + So the possible cases when we set (needMoreInput = true) are: + 1) decode : filter needs more data after the end of input stream. + another cases are possible for non-power2-block-filter, + because buffer size is not aligned for filter_non_power2_block_size: + 2) decode/encode : filter needs more data from non-finished input stream + 3) encode : filter needs more space for zeros after the end of input stream + */ + bool needMoreInput = false; + + while (readPos != filterPos) { - // AES - if (!inputFinished || pos > _bufSize) - return E_FAIL; - if (!_encodeMode) - return S_FALSE; - - do - _buf[endPos] = 0; - while (++endPos != pos); - - if (pos != Filter->Filter(_buf, pos)) - return E_FAIL; + /* Filter() is allowed to process part of data. + Here we use the loop to filter as max as possible. + when we call Filter(data, size): + if (size < 16), AES-CTR filter uses internal 16-byte buffer. + new (since v23.00) AES-CTR filter allows (size < 16) for non-last block, + but it will work less efficiently than calls with aligned (size). + We still support old (before v23.00) AES-CTR filters here. + We have aligned (size) for AES-CTR, if it's not last block. + We have aligned (readPos) for any filter, if (!inputFinished). + We also meet the requirements for (data) pointer in Filter() call: + { + (virtual_stream_offset % aligment_size) == (data_ptr % aligment_size) + (aligment_size == 2^N) + (aligment_size >= 16) + } + */ + const UInt32 cur = Filter->Filter(_buf + filterPos, readPos - filterPos); + if (cur == 0) + break; + const UInt32 f = filterPos + cur; + if (cur > readPos - filterPos) + { + // AES-CBC + if (hres != S_OK) + break; + + if (!_encodeMode + || cur > _bufSize - filterPos + || !inputFinished) + { + /* (cur > _bufSize - filterPos) is unexpected for AES filter, if _bufSize is multiply of 16. + But we support this case, if some future filter will use block with non-power2-size. + */ + needMoreInput = true; + break; + } + + /* (_encodeMode && inputFinished). + We add zero bytes as pad in current block after the end of read data. */ + Byte *buf = _buf; + do + buf[readPos] = 0; + while (++readPos != f); + // (readPos) now is (size_of_real_input_data + size_of_zero_pad) + if (cur != Filter->Filter(buf + filterPos, cur)) + return E_FAIL; + } + filterPos = f; } - if (endPos == 0) - return S_OK; + UInt32 size = filterPos; + if (hres == S_OK) + { + /* If we need more Read() or Filter() calls, then we need to Write() + some data and move unwritten data to get additional space in buffer. + We try to keep alignment for data moves, Read(), Filter() and Write() calls. + */ + const UInt32 kAlignSize = 1 << 6; + const UInt32 alignedFiltered = filterPos & ~(kAlignSize - 1); + if (inputFinished) + { + if (!needMoreInput) + size = readPos; // for risc/bcj filters in last block we write data after filterPos. + else if (_encodeMode) + size = alignedFiltered; // for non-power2-block-encode-filter + } + else + size = alignedFiltered; + } - UInt32 size = (pos != 0 ? pos : endPos); - if (outSize) { - UInt64 remSize = *outSize - nowPos64; - if (size > remSize) - size = (UInt32)remSize; + UInt32 writeSize = size; + if (outSize) + { + const UInt64 rem = *outSize - nowPos64; + if (writeSize > rem) + writeSize = (UInt32)rem; + } + RINOK(WriteStream(outStream, _buf, writeSize)) + nowPos64 += writeSize; } - - RINOK(WriteStream(outStream, _buf, size)); - nowPos64 += size; - if (pos == 0) - return S_OK; + if (hres != S_OK) + return hres; - if (progress) - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); + if (inputFinished) + { + if (readPos == size) + return hres; + if (!_encodeMode) + { + // block-decode-filter (AES-CBS) has non-full last block + // we don't want unaligned data move for more iterations with this error case. + return S_FALSE; + } + } - UInt32 i = 0; - while (pos < endPos) - _buf[i++] = _buf[pos++]; - pos = i; + if (size == 0) + { + // it's unexpected that we have no any move in this iteration. + return E_FAIL; + } + // if (size != 0) + { + if (filterPos < size) + return E_FAIL; // filterPos = 0; else + filterPos -= size; + readPos -= size; + if (readPos != 0) + memmove(_buf, _buf + size, readPos); + } + // printf("\nnowPos64=%x, readPos=%x, filterPos=%x\n", (unsigned)nowPos64, (unsigned)readPos, (unsigned)filterPos); + + if (progress && (nowPos64 - prev) >= (1 << 22)) + { + prev = nowPos64; + RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)) + } } return S_OK; @@ -136,13 +280,13 @@ STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStr // ---------- Write to Filter ---------- -STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CFilterCoder::SetOutStream(ISequentialOutStream *outStream)) { _outStream = outStream; return S_OK; } -STDMETHODIMP CFilterCoder::ReleaseOutStream() +Z7_COM7F_IMF(CFilterCoder::ReleaseOutStream()) { _outStream.Release(); return S_OK; @@ -153,9 +297,9 @@ HRESULT CFilterCoder::Flush2() while (_convSize != 0) { UInt32 num = _convSize; - if (_outSizeIsDefined) + if (_outSize_Defined) { - UInt64 rem = _outSize - _nowPos64; + const UInt64 rem = _outSize - _nowPos64; if (num > rem) num = (UInt32)rem; if (num == 0) @@ -163,21 +307,23 @@ HRESULT CFilterCoder::Flush2() } UInt32 processed = 0; - HRESULT res = _outStream->Write(_buf + _convPos, num, &processed); + const HRESULT res = _outStream->Write(_buf + _convPos, num, &processed); if (processed == 0) return res != S_OK ? res : E_FAIL; _convPos += processed; _convSize -= processed; _nowPos64 += processed; - RINOK(res); + RINOK(res) } - if (_convPos != 0) + const UInt32 convPos = _convPos; + if (convPos != 0) { - UInt32 num = _bufPos - _convPos; + const UInt32 num = _bufPos - convPos; + Byte *buf = _buf; for (UInt32 i = 0; i < num; i++) - _buf[i] = _buf[_convPos + i]; + buf[i] = buf[convPos + i]; _bufPos = num; _convPos = 0; } @@ -185,14 +331,14 @@ HRESULT CFilterCoder::Flush2() return S_OK; } -STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; while (size != 0) { - RINOK(Flush2()); + RINOK(Flush2()) // _convSize is 0 // _convPos is 0 @@ -227,20 +373,22 @@ STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processe return S_OK; } -STDMETHODIMP CFilterCoder::OutStreamFinish() +Z7_COM7F_IMF(CFilterCoder::OutStreamFinish()) { for (;;) { - RINOK(Flush2()); + RINOK(Flush2()) if (_bufPos == 0) break; - _convSize = Filter->Filter(_buf, _bufPos); - if (_convSize == 0) - _convSize = _bufPos; - else if (_convSize > _bufPos) + const UInt32 convSize = Filter->Filter(_buf, _bufPos); + _convSize = convSize; + UInt32 bufPos = _bufPos; + if (convSize == 0) + _convSize = bufPos; + else if (convSize > bufPos) { // AES - if (_convSize > _bufSize) + if (convSize > _bufSize) { _convSize = 0; return E_FAIL; @@ -250,9 +398,11 @@ STDMETHODIMP CFilterCoder::OutStreamFinish() _convSize = 0; return S_FALSE; } - for (; _bufPos < _convSize; _bufPos++) - _buf[_bufPos] = 0; - _convSize = Filter->Filter(_buf, _bufPos); + Byte *buf = _buf; + for (; bufPos < convSize; bufPos++) + buf[bufPos] = 0; + _bufPos = bufPos; + _convSize = Filter->Filter(_buf, bufPos); if (_convSize != _bufPos) return E_FAIL; } @@ -267,7 +417,7 @@ STDMETHODIMP CFilterCoder::OutStreamFinish() // ---------- Init functions ---------- -STDMETHODIMP CFilterCoder::InitEncoder() +Z7_COM7F_IMF(CFilterCoder::InitEncoder()) { InitSpecVars(); return Init_and_Alloc(); @@ -279,33 +429,33 @@ HRESULT CFilterCoder::Init_NoSubFilterInit() return Alloc(); } -STDMETHODIMP CFilterCoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CFilterCoder::SetOutStreamSize(const UInt64 *outSize)) { InitSpecVars(); if (outSize) { _outSize = *outSize; - _outSizeIsDefined = true; + _outSize_Defined = true; } return Init_and_Alloc(); } // ---------- Read from Filter ---------- -STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream) +Z7_COM7F_IMF(CFilterCoder::SetInStream(ISequentialInStream *inStream)) { _inStream = inStream; return S_OK; } -STDMETHODIMP CFilterCoder::ReleaseInStream() +Z7_COM7F_IMF(CFilterCoder::ReleaseInStream()) { _inStream.Release(); return S_OK; } -STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -316,9 +466,9 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) { if (size > _convSize) size = _convSize; - if (_outSizeIsDefined) + if (_outSize_Defined) { - UInt64 rem = _outSize - _nowPos64; + const UInt64 rem = _outSize - _nowPos64; if (size > rem) size = (UInt32)rem; } @@ -331,46 +481,51 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) break; } - if (_convPos != 0) + const UInt32 convPos = _convPos; + if (convPos != 0) { - UInt32 num = _bufPos - _convPos; + const UInt32 num = _bufPos - convPos; + Byte *buf = _buf; for (UInt32 i = 0; i < num; i++) - _buf[i] = _buf[_convPos + i]; + buf[i] = buf[convPos + i]; _bufPos = num; _convPos = 0; } { size_t readSize = _bufSize - _bufPos; - HRESULT res = ReadStream(_inStream, _buf + _bufPos, &readSize); + const HRESULT res = ReadStream(_inStream, _buf + _bufPos, &readSize); _bufPos += (UInt32)readSize; - RINOK(res); + RINOK(res) } - _convSize = Filter->Filter(_buf, _bufPos); + const UInt32 convSize = Filter->Filter(_buf, _bufPos); + _convSize = convSize; - if (_convSize == 0) + UInt32 bufPos = _bufPos; + + if (convSize == 0) { - if (_bufPos == 0) + if (bufPos == 0) break; // BCJ - _convSize = _bufPos; + _convSize = bufPos; continue; } - if (_convSize > _bufPos) + if (convSize > bufPos) { // AES - if (_convSize > _bufSize) + if (convSize > _bufSize) return E_FAIL; if (!_encodeMode) return S_FALSE; - + Byte *buf = _buf; do - _buf[_bufPos] = 0; - while (++_bufPos != _convSize); - - _convSize = Filter->Filter(_buf, _convSize); + buf[bufPos] = 0; + while (++bufPos != convSize); + _bufPos = bufPos; + _convSize = Filter->Filter(_buf, convSize); if (_convSize != _bufPos) return E_FAIL; } @@ -380,39 +535,43 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) } -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO -STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size) - { return _SetPassword->CryptoSetPassword(data, size); } +Z7_COM7F_IMF(CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)) + { return _setPassword->CryptoSetPassword(data, size); } -STDMETHODIMP CFilterCoder::SetKey(const Byte *data, UInt32 size) - { return _CryptoProperties->SetKey(data, size); } +Z7_COM7F_IMF(CFilterCoder::SetKey(const Byte *data, UInt32 size)) + { return _cryptoProperties->SetKey(data, size); } -STDMETHODIMP CFilterCoder::SetInitVector(const Byte *data, UInt32 size) - { return _CryptoProperties->SetInitVector(data, size); } +Z7_COM7F_IMF(CFilterCoder::SetInitVector(const Byte *data, UInt32 size)) + { return _cryptoProperties->SetInitVector(data, size); } #endif -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY + +Z7_COM7F_IMF(CFilterCoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties)) + { return _setCoderProperties->SetCoderProperties(propIDs, properties, numProperties); } -STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *properties, UInt32 numProperties) - { return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties); } +Z7_COM7F_IMF(CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)) + { return _writeCoderProperties->WriteCoderProperties(outStream); } -STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream) - { return _WriteCoderProperties->WriteCoderProperties(outStream); } +Z7_COM7F_IMF(CFilterCoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties)) + { return _setCoderPropertiesOpt->SetCoderPropertiesOpt(propIDs, properties, numProperties); } /* -STDMETHODIMP CFilterCoder::ResetSalt() - { return _CryptoResetSalt->ResetSalt(); } +Z7_COM7F_IMF(CFilterCoder::ResetSalt() + { return _cryptoResetSalt->ResetSalt(); } */ -STDMETHODIMP CFilterCoder::ResetInitVector() - { return _CryptoResetInitVector->ResetInitVector(); } +Z7_COM7F_IMF(CFilterCoder::ResetInitVector()) + { return _cryptoResetInitVector->ResetInitVector(); } #endif -STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size) - { return _SetDecoderProperties2->SetDecoderProperties2(data, size); } +Z7_COM7F_IMF(CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)) + { return _setDecoderProperties2->SetDecoderProperties2(data, size); } diff --git a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h index 224ff2ca459..3a588fd5228 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h +++ b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h @@ -1,62 +1,33 @@ // FilterCoder.h -#ifndef __FILTER_CODER_H -#define __FILTER_CODER_H +#ifndef ZIP7_INC_FILTER_CODER_H +#define ZIP7_INC_FILTER_CODER_H #include "../../../C/Alloc.h" #include "../../Common/MyCom.h" #include "../ICoder.h" -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO #include "../IPassword.h" #endif -#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \ +#define Z7_COM_QI_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \ { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ *outObject = (void *)(i *)this; } struct CAlignedMidBuffer { - #ifdef _WIN32 - Byte *_buf; CAlignedMidBuffer(): _buf(NULL) {} - ~CAlignedMidBuffer() { ::MidFree(_buf); } - - void AllocAlignedMask(size_t size, size_t) - { - ::MidFree(_buf); - _buf = (Byte *)::MidAlloc(size); - } - - #else - - Byte *_bufBase; - Byte *_buf; - - CAlignedMidBuffer(): _bufBase(NULL), _buf(NULL) {} - ~CAlignedMidBuffer() { ::MidFree(_bufBase); } - - void AllocAlignedMask(size_t size, size_t alignMask) - { - ::MidFree(_bufBase); - _buf = NULL; - _bufBase = (Byte *)::MidAlloc(size + alignMask); - - if (_bufBase) - { - // _buf = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask); - _buf = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask); - } - } - - #endif + ~CAlignedMidBuffer(); + void AllocAligned(size_t size); }; -class CFilterCoder: + +class CFilterCoder Z7_final : public ICompressCoder, public ICompressSetOutStreamSize, @@ -71,14 +42,15 @@ class CFilterCoder: public ICompressSetBufSize, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO public ICryptoSetPassword, public ICryptoProperties, #endif - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY public ICompressSetCoderProperties, public ICompressWriteCoderProperties, + public ICompressSetCoderPropertiesOpt, // public ICryptoResetSalt, public ICryptoResetInitVector, #endif @@ -92,7 +64,7 @@ class CFilterCoder: UInt32 _outBufSize; bool _encodeMode; - bool _outSizeIsDefined; + bool _outSize_Defined; UInt64 _outSize; UInt64 _nowPos64; @@ -108,7 +80,7 @@ class CFilterCoder: _convPos = 0; _convSize = 0; - _outSizeIsDefined = false; + _outSize_Defined = false; _outSize = 0; _nowPos64 = 0; } @@ -117,108 +89,111 @@ class CFilterCoder: HRESULT Init_and_Alloc(); HRESULT Flush2(); - #ifndef _NO_CRYPTO - CMyComPtr<ICryptoSetPassword> _SetPassword; - CMyComPtr<ICryptoProperties> _CryptoProperties; + #ifndef Z7_NO_CRYPTO + CMyComPtr<ICryptoSetPassword> _setPassword; + CMyComPtr<ICryptoProperties> _cryptoProperties; #endif - #ifndef EXTRACT_ONLY - CMyComPtr<ICompressSetCoderProperties> _SetCoderProperties; - CMyComPtr<ICompressWriteCoderProperties> _WriteCoderProperties; - // CMyComPtr<ICryptoResetSalt> _CryptoResetSalt; - CMyComPtr<ICryptoResetInitVector> _CryptoResetInitVector; + #ifndef Z7_EXTRACT_ONLY + CMyComPtr<ICompressSetCoderProperties> _setCoderProperties; + CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties; + CMyComPtr<ICompressSetCoderPropertiesOpt> _setCoderPropertiesOpt; + // CMyComPtr<ICryptoResetSalt> _cryptoResetSalt; + CMyComPtr<ICryptoResetInitVector> _cryptoResetInitVector; #endif - CMyComPtr<ICompressSetDecoderProperties2> _SetDecoderProperties2; + CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties2; public: CMyComPtr<ICompressFilter> Filter; CFilterCoder(bool encodeMode); - ~CFilterCoder(); - class C_InStream_Releaser + struct C_InStream_Releaser { - public: CFilterCoder *FilterCoder; C_InStream_Releaser(): FilterCoder(NULL) {} ~C_InStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); } }; - class C_OutStream_Releaser + struct C_OutStream_Releaser { - public: CFilterCoder *FilterCoder; C_OutStream_Releaser(): FilterCoder(NULL) {} ~C_OutStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); } }; - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) + struct C_Filter_Releaser + { + CFilterCoder *FilterCoder; + C_Filter_Releaser(): FilterCoder(NULL) {} + ~C_Filter_Releaser() { if (FilterCoder) FilterCoder->Filter.Release(); } + }; + +private: + Z7_COM_QI_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ICompressInitEncoder) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ICompressInitEncoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ISequentialInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream) - MY_QUERYINTERFACE_ENTRY(ISequentialOutStream) - MY_QUERYINTERFACE_ENTRY(IOutStreamFinish) + Z7_COM_QI_ENTRY(ICompressSetOutStream) + Z7_COM_QI_ENTRY(ISequentialOutStream) + Z7_COM_QI_ENTRY(IOutStreamFinish) - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) + Z7_COM_QI_ENTRY(ICompressSetBufSize) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _SetPassword) - MY_QUERYINTERFACE_ENTRY_AG(ICryptoProperties, Filter, _CryptoProperties) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword) + Z7_COM_QI_ENTRY_AG(ICryptoProperties, Filter, _cryptoProperties) #endif - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties) - MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _WriteCoderProperties) - // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt) - MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY_AG(ICompressSetCoderProperties, Filter, _setCoderProperties) + Z7_COM_QI_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties) + Z7_COM_QI_ENTRY_AG(ICompressSetCoderPropertiesOpt, Filter, _setCoderPropertiesOpt) + // Z7_COM_QI_ENTRY_AG(ICryptoResetSalt, Filter, _cryptoResetSalt) + Z7_COM_QI_ENTRY_AG(ICryptoResetInitVector, Filter, _cryptoResetInitVector) #endif - MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _SetDecoderProperties2) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE + Z7_COM_QI_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties2) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE +public: + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressInitEncoder) + Z7_IFACE_COM7_IMP(ICompressSetInStream) +private: + Z7_IFACE_COM7_IMP(ISequentialInStream) +public: + Z7_IFACE_COM7_IMP(ICompressSetOutStream) +private: + Z7_IFACE_COM7_IMP(ISequentialOutStream) +public: + Z7_IFACE_COM7_IMP(IOutStreamFinish) +private: - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - STDMETHOD(InitEncoder)(); - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); - STDMETHOD(ReleaseOutStream)(); - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(OutStreamFinish)(); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); + Z7_IFACE_COM7_IMP(ICompressSetBufSize) - #ifndef _NO_CRYPTO - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); - - STDMETHOD(SetKey)(const Byte *data, UInt32 size); - STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoSetPassword) + Z7_IFACE_COM7_IMP(ICryptoProperties) #endif - #ifndef EXTRACT_ONLY - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, - const PROPVARIANT *properties, UInt32 numProperties); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - // STDMETHOD(ResetSalt)(); - STDMETHOD(ResetInitVector)(); + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + Z7_IFACE_COM7_IMP(ICompressWriteCoderProperties) + Z7_IFACE_COM7_IMP(ICompressSetCoderPropertiesOpt) + // Z7_IFACE_COM7_IMP(ICryptoResetSalt) + Z7_IFACE_COM7_IMP(ICryptoResetInitVector) #endif - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - +public: + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) HRESULT Init_NoSubFilterInit(); }; diff --git a/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp b/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp index 133d95b3885..b0f222c2621 100644 --- a/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp @@ -7,10 +7,10 @@ #include "InBuffer.h" CInBufferBase::CInBufferBase() throw(): - _buf(0), - _bufLim(0), - _bufBase(0), - _stream(0), + _buf(NULL), + _bufLim(NULL), + _bufBase(NULL), + _stream(NULL), _processedSize(0), _bufSize(0), _wasFinished(false), @@ -22,18 +22,18 @@ bool CInBuffer::Create(size_t bufSize) throw() const unsigned kMinBlockSize = 1; if (bufSize < kMinBlockSize) bufSize = kMinBlockSize; - if (_bufBase != 0 && _bufSize == bufSize) + if (_bufBase != NULL && _bufSize == bufSize) return true; Free(); _bufSize = bufSize; _bufBase = (Byte *)::MidAlloc(bufSize); - return (_bufBase != 0); + return (_bufBase != NULL); } void CInBuffer::Free() throw() { ::MidFree(_bufBase); - _bufBase = 0; + _bufBase = NULL; } void CInBufferBase::Init() throw() @@ -42,7 +42,7 @@ void CInBufferBase::Init() throw() _buf = _bufBase; _bufLim = _buf; _wasFinished = false; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS ErrorCode = S_OK; #endif NumExtraBytes = 0; @@ -50,19 +50,19 @@ void CInBufferBase::Init() throw() bool CInBufferBase::ReadBlock() { - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS if (ErrorCode != S_OK) return false; #endif if (_wasFinished) return false; - _processedSize += (_buf - _bufBase); + _processedSize += (size_t)(_buf - _bufBase); _buf = _bufBase; _bufLim = _bufBase; UInt32 processed; // FIX_ME: we can improve it to support (_bufSize >= (1 << 32)) - HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed); - #ifdef _NO_EXCEPTIONS + const HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed); + #ifdef Z7_NO_EXCEPTIONS ErrorCode = result; #else if (result != S_OK) @@ -77,7 +77,8 @@ bool CInBufferBase::ReadByte_FromNewBlock(Byte &b) { if (!ReadBlock()) { - NumExtraBytes++; + // 22.00: we don't increment (NumExtraBytes) here + // NumExtraBytes++; b = 0xFF; return false; } @@ -97,6 +98,33 @@ Byte CInBufferBase::ReadByte_FromNewBlock() size_t CInBufferBase::ReadBytes(Byte *buf, size_t size) { + size_t num = 0; + for (;;) + { + const size_t rem = (size_t)(_bufLim - _buf); + if (size <= rem) + { + if (size != 0) + { + memcpy(buf, _buf, size); + _buf += size; + num += size; + } + return num; + } + if (rem != 0) + { + memcpy(buf, _buf, rem); + _buf += rem; + buf += rem; + num += rem; + size -= rem; + } + if (!ReadBlock()) + return num; + } + + /* if ((size_t)(_bufLim - _buf) >= size) { const Byte *src = _buf; @@ -113,6 +141,7 @@ size_t CInBufferBase::ReadBytes(Byte *buf, size_t size) buf[i] = *_buf++; } return size; + */ } size_t CInBufferBase::Skip(size_t size) @@ -120,7 +149,7 @@ size_t CInBufferBase::Skip(size_t size) size_t processed = 0; for (;;) { - size_t rem = (_bufLim - _buf); + const size_t rem = (size_t)(_bufLim - _buf); if (rem >= size) { _buf += size; diff --git a/3rdparty/lzma/CPP/7zip/Common/InBuffer.h b/3rdparty/lzma/CPP/7zip/Common/InBuffer.h index 4b8662bb9d5..3aaf797a589 100644 --- a/3rdparty/lzma/CPP/7zip/Common/InBuffer.h +++ b/3rdparty/lzma/CPP/7zip/Common/InBuffer.h @@ -1,12 +1,12 @@ // InBuffer.h -#ifndef __IN_BUFFER_H -#define __IN_BUFFER_H +#ifndef ZIP7_INC_IN_BUFFER_H +#define ZIP7_INC_IN_BUFFER_H #include "../../Common/MyException.h" #include "../IStream.h" -#ifndef _NO_EXCEPTIONS +#ifndef Z7_NO_EXCEPTIONS struct CInBufferException: public CSystemException { CInBufferException(HRESULT errorCode): CSystemException(errorCode) {} @@ -31,15 +31,23 @@ protected: Byte ReadByte_FromNewBlock(); public: - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS HRESULT ErrorCode; #endif UInt32 NumExtraBytes; CInBufferBase() throw(); - UInt64 GetStreamSize() const { return _processedSize + (_buf - _bufBase); } - UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (_buf - _bufBase); } + // the size of portion of data in real stream that was already read from this object + // it doesn't include unused data in buffer + // it doesn't include virtual Extra bytes after the end of real stream data + UInt64 GetStreamSize() const { return _processedSize + (size_t)(_buf - _bufBase); } + + // the size of virtual data that was read from this object + // it doesn't include unused data in buffers + // it includes any virtual Extra bytes after the end of real data + UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (size_t)(_buf - _bufBase); } + bool WasFinished() const { return _wasFinished; } void SetStream(ISequentialInStream *stream) { _stream = stream; } @@ -52,14 +60,15 @@ public: _buf = buf + pos; _bufLim = buf + end; _wasFinished = false; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS ErrorCode = S_OK; #endif NumExtraBytes = 0; } void Init() throw(); - + + Z7_FORCE_INLINE bool ReadByte(Byte &b) { if (_buf >= _bufLim) @@ -67,7 +76,17 @@ public: b = *_buf++; return true; } + + Z7_FORCE_INLINE + bool ReadByte_FromBuf(Byte &b) + { + if (_buf >= _bufLim) + return false; + b = *_buf++; + return true; + } + Z7_FORCE_INLINE Byte ReadByte() { if (_buf >= _bufLim) diff --git a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp index 85d6a1aa921..3f7272ef820 100644 --- a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp @@ -2,126 +2,236 @@ #include "StdAfx.h" -#include "../../../C/7zCrc.h" - -#include "../../Common/Defs.h" +#include "../../../C/Alloc.h" #include "InOutTempBuffer.h" + #include "StreamUtils.h" -using namespace NWindows; -using namespace NFile; -using namespace NDir; +#ifdef USE_InOutTempBuffer_FILE + +#include "../../../C/7zCrc.h" + +#define kTempFilePrefixString FTEXT("7zt") +/* + Total buffer size limit, if we use temp file scheme: + 32-bit: 16 MiB = 1 MiB * 16 buffers + 64-bit: 4 GiB = 1 MiB * 4096 buffers +*/ +static const size_t kNumBufsMax = (size_t)1 << (sizeof(size_t) * 2 - 4); -static const size_t kTempBufSize = (1 << 20); +#endif -static CFSTR kTempFilePrefixString = FTEXT("7zt"); +static const size_t kBufSize = (size_t)1 << 20; -CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { } -void CInOutTempBuffer::Create() +CInOutTempBuffer::CInOutTempBuffer(): + _size(0), + _bufs(NULL), + _numBufs(0), + _numFilled(0) { - if (!_buf) - _buf = new Byte[kTempBufSize]; + #ifdef USE_InOutTempBuffer_FILE + _tempFile_Created = false; + _useMemOnly = false; + _crc = CRC_INIT_VAL; + #endif } CInOutTempBuffer::~CInOutTempBuffer() { - delete []_buf; + for (size_t i = 0; i < _numBufs; i++) + MyFree(_bufs[i]); + MyFree(_bufs); } -void CInOutTempBuffer::InitWriting() -{ - _bufPos = 0; - _tempFileCreated = false; - _size = 0; - _crc = CRC_INIT_VAL; -} -bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size) +void *CInOutTempBuffer::GetBuf(size_t index) { - if (size == 0) - return true; - if (!_tempFileCreated) + if (index >= _numBufs) + { + const size_t num = (_numBufs == 0 ? 16 : _numBufs * 2); + void **p = (void **)MyRealloc(_bufs, num * sizeof(void *)); + if (!p) + return NULL; + _bufs = p; + memset(p + _numBufs, 0, (num - _numBufs) * sizeof(void *)); + _numBufs = num; + } + + void *buf = _bufs[index]; + if (!buf) { - if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile)) - return false; - _tempFileCreated = true; + buf = MyAlloc(kBufSize); + if (buf) + _bufs[index] = buf; } - UInt32 processed; - if (!_outFile.Write(data, size, processed)) - return false; - _crc = CrcUpdate(_crc, data, processed); - _size += processed; - return (processed == size); + return buf; } -bool CInOutTempBuffer::Write(const void *data, UInt32 size) + +HRESULT CInOutTempBuffer::Write_HRESULT(const void *data, UInt32 size) { if (size == 0) - return true; - size_t cur = kTempBufSize - _bufPos; - if (cur != 0) + return S_OK; + + #ifdef USE_InOutTempBuffer_FILE + if (!_tempFile_Created) + #endif + for (;;) // loop for additional attemp to allocate memory after file creation error { - if (cur > size) - cur = size; - memcpy(_buf + _bufPos, data, cur); - _crc = CrcUpdate(_crc, data, cur); - _bufPos += cur; - _size += cur; - size -= (UInt32)cur; - data = ((const Byte *)data) + cur; + #ifdef USE_InOutTempBuffer_FILE + bool allocError = false; + #endif + + for (;;) // loop for writing to buffers + { + const size_t index = (size_t)(_size / kBufSize); + + #ifdef USE_InOutTempBuffer_FILE + if (index >= kNumBufsMax && !_useMemOnly) + break; + #endif + + void *buf = GetBuf(index); + if (!buf) + { + #ifdef USE_InOutTempBuffer_FILE + if (!_useMemOnly) + { + allocError = true; + break; + } + #endif + return E_OUTOFMEMORY; + } + + const size_t offset = (size_t)(_size) & (kBufSize - 1); + size_t cur = kBufSize - offset; + if (cur > size) + cur = size; + memcpy((Byte *)buf + offset, data, cur); + _size += cur; + if (index >= _numFilled) + _numFilled = index + 1; + data = (const void *)((const Byte *)data + cur); + size -= (UInt32)cur; + if (size == 0) + return S_OK; + } + + #ifdef USE_InOutTempBuffer_FILE + #ifndef _WIN32 + _outFile.mode_for_Create = 0600; // only owner will have the rights to access this file + #endif + if (_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile)) + { + _tempFile_Created = true; + break; + } + _useMemOnly = true; + if (allocError) + return GetLastError_noZero_HRESULT(); + #endif } - return WriteToFile(data, size); + + #ifdef USE_InOutTempBuffer_FILE + if (!_outFile.WriteFull(data, size)) + return GetLastError_noZero_HRESULT(); + _crc = CrcUpdate(_crc, data, size); + _size += size; + return S_OK; + #endif } + HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) { - if (!_outFile.Close()) - return E_FAIL; + UInt64 rem = _size; + // if (rem == 0) return S_OK; - UInt64 size = 0; - UInt32 crc = CRC_INIT_VAL; + const size_t numFilled = _numFilled; + _numFilled = 0; - if (_bufPos != 0) + for (size_t i = 0; i < numFilled; i++) { - RINOK(WriteStream(stream, _buf, _bufPos)); - crc = CrcUpdate(crc, _buf, _bufPos); - size += _bufPos; - } - - if (_tempFileCreated) - { - NIO::CInFile inFile; - if (!inFile.Open(_tempFile.GetPath())) + if (rem == 0) return E_FAIL; - while (size < _size) + size_t cur = kBufSize; + if (cur > rem) + cur = (size_t)rem; + RINOK(WriteStream(stream, _bufs[i], cur)) + rem -= cur; + #ifdef USE_InOutTempBuffer_FILE + // we will use _bufs[0] later for writing from temp file + if (i != 0 || !_tempFile_Created) + #endif { - UInt32 processed; - if (!inFile.ReadPart(_buf, kTempBufSize, processed)) - return E_FAIL; - if (processed == 0) - break; - RINOK(WriteStream(stream, _buf, processed)); - crc = CrcUpdate(crc, _buf, processed); - size += processed; + MyFree(_bufs[i]); + _bufs[i] = NULL; } } - - return (_crc == crc && size == _size) ? S_OK : E_FAIL; -} -/* -STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed) -{ - if (!_buf->Write(data, size)) - { - if (processed) - *processed = 0; + + #ifdef USE_InOutTempBuffer_FILE + + if (rem == 0) + return _tempFile_Created ? E_FAIL : S_OK; + + if (!_tempFile_Created) return E_FAIL; + + if (!_outFile.Close()) + return GetLastError_noZero_HRESULT(); + + HRESULT hres; + void *buf = GetBuf(0); // index + if (!buf) + hres = E_OUTOFMEMORY; + else + { + NWindows::NFile::NIO::CInFile inFile; + if (!inFile.Open(_tempFile.GetPath())) + hres = GetLastError_noZero_HRESULT(); + else + { + UInt32 crc = CRC_INIT_VAL; + for (;;) + { + size_t processed; + if (!inFile.ReadFull(buf, kBufSize, processed)) + { + hres = GetLastError_noZero_HRESULT(); + break; + } + if (processed == 0) + { + // we compare crc without CRC_GET_DIGEST + hres = (_crc == crc ? S_OK : E_FAIL); + break; + } + size_t n = processed; + if (n > rem) + n = (size_t)rem; + hres = WriteStream(stream, buf, n); + if (hres != S_OK) + break; + crc = CrcUpdate(crc, buf, n); + rem -= n; + if (n != processed) + { + hres = E_FAIL; + break; + } + } + } } - if (processed) - *processed = size; - return S_OK; + + // _tempFile.DisableDeleting(); // for debug + _tempFile.Remove(); + RINOK(hres) + + #endif + + return rem == 0 ? S_OK : E_FAIL; } -*/ diff --git a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h index 204a105f1de..345c3863c40 100644 --- a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h +++ b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h @@ -1,48 +1,45 @@ // InOutTempBuffer.h -#ifndef __IN_OUT_TEMP_BUFFER_H -#define __IN_OUT_TEMP_BUFFER_H +#ifndef ZIP7_INC_IN_OUT_TEMP_BUFFER_H +#define ZIP7_INC_IN_OUT_TEMP_BUFFER_H -#include "../../Common/MyCom.h" +// #ifdef _WIN32 +#define USE_InOutTempBuffer_FILE +// #endif + +#ifdef USE_InOutTempBuffer_FILE #include "../../Windows/FileDir.h" +#endif #include "../IStream.h" class CInOutTempBuffer { - NWindows::NFile::NDir::CTempFile _tempFile; - NWindows::NFile::NIO::COutFile _outFile; - Byte *_buf; - size_t _bufPos; UInt64 _size; + void **_bufs; + size_t _numBufs; + size_t _numFilled; + + #ifdef USE_InOutTempBuffer_FILE + + bool _tempFile_Created; + bool _useMemOnly; UInt32 _crc; - bool _tempFileCreated; + // COutFile object must be declared after CTempFile object for correct destructor order + NWindows::NFile::NDir::CTempFile _tempFile; + NWindows::NFile::NIO::COutFile _outFile; + + #endif + + void *GetBuf(size_t index); - bool WriteToFile(const void *data, UInt32 size); + Z7_CLASS_NO_COPY(CInOutTempBuffer) public: CInOutTempBuffer(); ~CInOutTempBuffer(); - void Create(); - - void InitWriting(); - bool Write(const void *data, UInt32 size); - + HRESULT Write_HRESULT(const void *data, UInt32 size); HRESULT WriteToStream(ISequentialOutStream *stream); UInt64 GetDataSize() const { return _size; } }; -/* -class CSequentialOutTempBufferImp: - public ISequentialOutStream, - public CMyUnknownImp -{ - CInOutTempBuffer *_buf; -public: - void Init(CInOutTempBuffer *buffer) { _buf = buffer; } - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; -*/ - #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp index 8e032561662..664cd0c4b5c 100644 --- a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp @@ -6,7 +6,7 @@ #include "LimitedStreams.h" -STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize = 0; { @@ -27,7 +27,7 @@ STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *p return result; } -STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -46,7 +46,7 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } HRESULT res = _stream->Read(data, size, &size); if (processedSize) @@ -56,7 +56,7 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi return res; } -STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -67,7 +67,7 @@ STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *new } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; return S_OK; @@ -75,17 +75,17 @@ STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *new HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream) { - *resStream = 0; + *resStream = NULL; CLimitedInStream *streamSpec = new CLimitedInStream; CMyComPtr<ISequentialInStream> streamTemp = streamSpec; streamSpec->SetStream(inStream); - RINOK(streamSpec->InitAndSeek(pos, size)); + RINOK(streamSpec->InitAndSeek(pos, size)) streamSpec->SeekToStart(); *resStream = streamTemp.Detach(); return S_OK; } -STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -110,12 +110,12 @@ STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSi if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } _curRem = blockSize - offsetInBlock; - for (int i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++) + for (unsigned i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++) _curRem += (UInt32)1 << BlockSizeLog; } @@ -130,7 +130,7 @@ STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSi return res; } -STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -143,56 +143,82 @@ STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *new return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; if (_virtPos != (UInt64)offset) _curRem = 0; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } -STDMETHODIMP CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; - if (_virtPos >= Extents.Back().Virt) + const UInt64 virt = _virtPos; + if (virt >= Extents.Back().Virt) return S_OK; if (size == 0) return S_OK; - unsigned left = 0, right = Extents.Size() - 1; - for (;;) + unsigned left = _prevExtentIndex; + if (virt < Extents[left].Virt || + virt >= Extents[left + 1].Virt) { - unsigned mid = (left + right) / 2; - if (mid == left) - break; - if (_virtPos < Extents[mid].Virt) - right = mid; - else - left = mid; + left = 0; + unsigned right = Extents.Size() - 1; + for (;;) + { + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + if (mid == left) + break; + if (virt < Extents[mid].Virt) + right = mid; + else + left = mid; + } + _prevExtentIndex = left; } - const CSeekExtent &extent = Extents[left]; - UInt64 phyPos = extent.Phy + (_virtPos - extent.Virt); - if (_needStartSeek || _phyPos != phyPos) { - _needStartSeek = false; - _phyPos = phyPos; - RINOK(SeekToPhys()); + const UInt64 rem = Extents[left + 1].Virt - virt; + if (size > rem) + size = (UInt32)rem; } - UInt64 rem = Extents[left + 1].Virt - _virtPos; - if (size > rem) - size = (UInt32)rem; + const CSeekExtent &extent = Extents[left]; - HRESULT res = Stream->Read(data, size, &size); - _phyPos += size; + if (extent.Is_ZeroFill()) + { + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } + + { + const UInt64 phy = extent.Phy + (virt - extent.Virt); + if (_phyPos != phy) + { + _phyPos = (UInt64)0 - 1; // we don't trust seek_pos in case of error + RINOK(InStream_SeekSet(Stream, phy)) + _phyPos = phy; + } + } + + const HRESULT res = Stream->Read(data, size, &size); _virtPos += size; + if (res == S_OK) + _phyPos += size; + else + _phyPos = (UInt64)0 - 1; // we don't trust seek_pos in case of error if (processedSize) *processedSize = size; return res; } -STDMETHODIMP CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) + +Z7_COM7F_IMF(CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -203,14 +229,14 @@ STDMETHODIMP CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; return S_OK; } -STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (processedSize) @@ -237,7 +263,7 @@ STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, U } -STDMETHODIMP CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 cur; HRESULT res = Stream->Read(data, size, &cur); @@ -247,7 +273,7 @@ STDMETHODIMP CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize) return res; } -STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -256,7 +282,7 @@ STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos case STREAM_SEEK_END: { UInt64 pos = 0; - RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos)); + RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos)) if (pos < Offset) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; _virtPos = pos - Offset; @@ -268,13 +294,13 @@ STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; - return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(Stream, Offset + _virtPos); } -STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -303,7 +329,7 @@ STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *proce if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } res = _stream->Read(data, size, &size); _physPos += size; @@ -314,7 +340,7 @@ STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *proce return res; } -STDMETHODIMP CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -325,13 +351,13 @@ STDMETHODIMP CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt6 } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; return S_OK; } -STDMETHODIMP CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { UInt32 cur; HRESULT res = Stream->Write(data, size, &cur); @@ -343,7 +369,7 @@ STDMETHODIMP CTailOutStream::Write(const void *data, UInt32 size, UInt32 *proces return res; } -STDMETHODIMP CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -354,13 +380,13 @@ STDMETHODIMP CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; - return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL); + return Stream->Seek((Int64)(Offset + _virtPos), STREAM_SEEK_SET, NULL); } -STDMETHODIMP CTailOutStream::SetSize(UInt64 newSize) +Z7_COM7F_IMF(CTailOutStream::SetSize(UInt64 newSize)) { _virtSize = newSize; return Stream->SetSize(Offset + newSize); diff --git a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h index fb1ac3cd6bd..69fcdcdb0e5 100644 --- a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h +++ b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h @@ -1,17 +1,19 @@ // LimitedStreams.h -#ifndef __LIMITED_STREAMS_H -#define __LIMITED_STREAMS_H +#ifndef ZIP7_INC_LIMITED_STREAMS_H +#define ZIP7_INC_LIMITED_STREAMS_H #include "../../Common/MyBuffer.h" #include "../../Common/MyCom.h" #include "../../Common/MyVector.h" #include "../IStream.h" -class CLimitedSequentialInStream: - public ISequentialInStream, - public CMyUnknownImp -{ +#include "StreamUtils.h" + +Z7_CLASS_IMP_COM_1( + CLimitedSequentialInStream + , ISequentialInStream +) CMyComPtr<ISequentialInStream> _stream; UInt64 _size; UInt64 _pos; @@ -25,26 +27,22 @@ public: _pos = 0; _wasFinished = false; } - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); UInt64 GetSize() const { return _pos; } UInt64 GetRem() const { return _size - _pos; } bool WasFinished() const { return _wasFinished; } }; -class CLimitedInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CLimitedInStream +) CMyComPtr<IInStream> _stream; UInt64 _virtPos; UInt64 _physPos; UInt64 _size; UInt64 _startOffset; - HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } + HRESULT SeekToPhys() { return InStream_SeekSet(_stream, _physPos); } public: void SetStream(IInStream *stream) { _stream = stream; } HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) @@ -55,21 +53,15 @@ public: _size = size; return SeekToPhys(); } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } }; HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream); -class CClusterInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CClusterInStream +) UInt64 _virtPos; UInt64 _physPos; UInt32 _curRem; @@ -80,7 +72,7 @@ public: CRecordVector<UInt32> Vector; UInt64 StartOffset; - HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } + HRESULT SeekToPhys() { return InStream_SeekSet(Stream, _physPos); } HRESULT InitAndSeek() { @@ -94,57 +86,52 @@ public: } return S_OK; } +}; - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; + +const UInt64 k_SeekExtent_Phy_Type_ZeroFill = (UInt64)(Int64)-1; struct CSeekExtent { - UInt64 Phy; UInt64 Virt; -}; + UInt64 Phy; -class CExtentsStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _phyPos; - UInt64 _virtPos; - bool _needStartSeek; + void SetAs_ZeroFill() { Phy = k_SeekExtent_Phy_Type_ZeroFill; } + bool Is_ZeroFill() const { return Phy == k_SeekExtent_Phy_Type_ZeroFill; } +}; - HRESULT SeekToPhys() { return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); } +Z7_CLASS_IMP_IInStream( + CExtentsStream +) + UInt64 _virtPos; + UInt64 _phyPos; + unsigned _prevExtentIndex; public: CMyComPtr<IInStream> Stream; CRecordVector<CSeekExtent> Extents; - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); void ReleaseStream() { Stream.Release(); } - void Init() { _virtPos = 0; - _phyPos = 0; - _needStartSeek = true; + _phyPos = (UInt64)0 - 1; // we need Seek() for Stream + _prevExtentIndex = 0; } }; -class CLimitedSequentialOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + + +Z7_CLASS_IMP_COM_1( + CLimitedSequentialOutStream + , ISequentialOutStream +) CMyComPtr<ISequentialOutStream> _stream; UInt64 _size; bool _overflow; bool _overflowIsAllowed; public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init(UInt64 size, bool overflowIsAllowed = false) @@ -158,10 +145,9 @@ public: }; -class CTailInStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream( + CTailInStream +) UInt64 _virtPos; public: CMyComPtr<IInStream> Stream; @@ -171,19 +157,13 @@ public: { _virtPos = 0; } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - HRESULT SeekToStart() { return Stream->Seek(Offset, STREAM_SEEK_SET, NULL); } + HRESULT SeekToStart() { return InStream_SeekSet(Stream, Offset); } }; -class CLimitedCachedInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CLimitedCachedInStream +) CMyComPtr<IInStream> _stream; UInt64 _virtPos; UInt64 _physPos; @@ -194,8 +174,7 @@ class CLimitedCachedInStream: size_t _cacheSize; size_t _cachePhyPos; - - HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } + HRESULT SeekToPhys() { return InStream_SeekSet(_stream, _physPos); } public: CByteBuffer Buffer; @@ -216,37 +195,27 @@ public: return SeekToPhys(); } - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } }; -class CTailOutStream: + +class CTailOutStream Z7_final : public IOutStream, public CMyUnknownImp { + Z7_IFACES_IMP_UNK_2(ISequentialOutStream, IOutStream) + UInt64 _virtPos; UInt64 _virtSize; public: CMyComPtr<IOutStream> Stream; UInt64 Offset; - virtual ~CTailOutStream() {} - - MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStream) - void Init() { _virtPos = 0; _virtSize = 0; } - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/LockedStream.h b/3rdparty/lzma/CPP/7zip/Common/LockedStream.h index efebf197553..99ee8055c6e 100644 --- a/3rdparty/lzma/CPP/7zip/Common/LockedStream.h +++ b/3rdparty/lzma/CPP/7zip/Common/LockedStream.h @@ -1,6 +1,6 @@ // LockedStream.h -#ifndef __LOCKED_STREAM_H -#define __LOCKED_STREAM_H +#ifndef ZIP7_INC_LOCKED_STREAM_H +#define ZIP7_INC_LOCKED_STREAM_H #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/MethodId.h b/3rdparty/lzma/CPP/7zip/Common/MethodId.h index 28b615fcd3e..19b1f10d5fa 100644 --- a/3rdparty/lzma/CPP/7zip/Common/MethodId.h +++ b/3rdparty/lzma/CPP/7zip/Common/MethodId.h @@ -1,7 +1,7 @@ // MethodId.h -#ifndef __7Z_METHOD_ID_H -#define __7Z_METHOD_ID_H +#ifndef ZIP7_INC_7Z_METHOD_ID_H +#define ZIP7_INC_7Z_METHOD_ID_H #include "../../Common/MyTypes.h" diff --git a/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp b/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp index 09f7b29cc24..fe60f610064 100644 --- a/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp @@ -8,9 +8,39 @@ using namespace NWindows; -bool StringToBool(const UString &s, bool &res) +UInt64 Calc_From_Val_Percents(UInt64 val, UInt64 percents) { - if (s.IsEmpty() || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON")) + // if (percents == 0) return 0; + const UInt64 q = percents / 100; + const UInt32 r = (UInt32)(percents % 100); + UInt64 res = 0; + + if (q != 0) + { + if (val > (UInt64)(Int64)-1 / q) + return (UInt64)(Int64)-1; + res = val * q; + } + + if (r != 0) + { + UInt64 v2; + if (val <= (UInt64)(Int64)-1 / r) + v2 = val * r / 100; + else + v2 = val / 100 * r; + res += v2; + if (res < v2) + return (UInt64)(Int64)-1; + } + + return res; +} + + +bool StringToBool(const wchar_t *s, bool &res) +{ + if (s[0] == 0 || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON")) { res = true; return true; @@ -42,10 +72,18 @@ unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number) return (unsigned)(end - start); } +static unsigned ParseStringToUInt64(const UString &srcString, UInt64 &number) +{ + const wchar_t *start = srcString; + const wchar_t *end; + number = ConvertStringToUInt64(start, &end); + return (unsigned)(end - start); +} + HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) { // =VT_UI4 - // =VT_EMPTY + // =VT_EMPTY : it doesn't change (resValue), and returns S_OK // {stringUInt32}=VT_EMPTY if (prop.vt == VT_UI4) @@ -66,66 +104,151 @@ HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 & return S_OK; } -HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads) + + +HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force) { + force = false; + UString s; if (name.IsEmpty()) { - switch (prop.vt) + if (prop.vt == VT_UI4) + { + numThreads = prop.ulVal; + force = true; + return S_OK; + } + bool val; + HRESULT res = PROPVARIANT_to_bool(prop, val); + if (res == S_OK) { - case VT_UI4: - numThreads = prop.ulVal; - break; - default: + if (!val) { - bool val; - RINOK(PROPVARIANT_to_bool(prop, val)); - numThreads = (val ? defaultNumThreads : 1); - break; + numThreads = 1; + force = true; } + // force = true; for debug + // "(VT_BOOL = VARIANT_TRUE)" set "force = false" and doesn't change numThreads + return S_OK; } - return S_OK; + if (prop.vt != VT_BSTR) + return res; + s.SetFromBstr(prop.bstrVal); + if (s.IsEmpty()) + return E_INVALIDARG; } - if (prop.vt != VT_EMPTY) + else + { + if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + s = name; + } + + s.MakeLower_Ascii(); + const wchar_t *start = s; + UInt32 v = numThreads; + + /* we force up, if threads number specified + only `d` will force it down */ + bool force_loc = true; + for (;;) + { + const wchar_t c = *start; + if (!c) + break; + if (c == 'd') + { + force_loc = false; // force down + start++; + continue; + } + if (c == 'u') + { + force_loc = true; // force up + start++; + continue; + } + bool isPercent = false; + if (c == 'p') + { + isPercent = true; + start++; + } + const wchar_t *end; + v = ConvertStringToUInt32(start, &end); + if (end == start) + return E_INVALIDARG; + if (isPercent) + v = numThreads * v / 100; + start = end; + } + + numThreads = v; + force = force_loc; + return S_OK; +} + + + +static HRESULT SetLogSizeProp(UInt64 number, NCOM::CPropVariant &destProp) +{ + if (number >= 64) return E_INVALIDARG; - return ParsePropToUInt32(name, prop, numThreads); + UInt32 val32; + if (number < 32) + val32 = (UInt32)1 << (unsigned)number; + /* + else if (number == 32 && reduce_4GB_to_32bits) + val32 = (UInt32)(Int32)-1; + */ + else + { + destProp = (UInt64)((UInt64)1 << (unsigned)number); + return S_OK; + } + destProp = (UInt32)val32; + return S_OK; } static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp) { + /* if (reduce_4GB_to_32bits) we can reduce (4 GiB) property to (4 GiB - 1). + to fit the value to UInt32 for clients that do not support 64-bit values */ + const wchar_t *end; - UInt32 number = ConvertStringToUInt32(s, &end); - unsigned numDigits = (unsigned)(end - s); + const UInt64 number = ConvertStringToUInt64(s, &end); + const unsigned numDigits = (unsigned)(end - s.Ptr()); if (numDigits == 0 || s.Len() > numDigits + 1) return E_INVALIDARG; if (s.Len() == numDigits) - { - if (number >= 64) - return E_INVALIDARG; - if (number < 32) - destProp = (UInt32)((UInt32)1 << (unsigned)number); - else - destProp = (UInt64)((UInt64)1 << (unsigned)number); - return S_OK; - } + return SetLogSizeProp(number, destProp); unsigned numBits; switch (MyCharLower_Ascii(s[numDigits])) { - case 'b': destProp = number; return S_OK; + case 'b': numBits = 0; break; case 'k': numBits = 10; break; case 'm': numBits = 20; break; case 'g': numBits = 30; break; default: return E_INVALIDARG; } - if (number < ((UInt32)1 << (32 - numBits))) - destProp = (UInt32)(number << numBits); + const UInt64 range4g = ((UInt64)1 << (32 - numBits)); + if (number < range4g) + destProp = (UInt32)((UInt32)number << numBits); + /* + else if (number == range4g && reduce_4GB_to_32bits) + destProp = (UInt32)(Int32)-1; + */ + else if (numBits == 0) + destProp = (UInt64)number; + else if (number >= ((UInt64)1 << (64 - numBits))) + return E_INVALIDARG; else destProp = (UInt64)((UInt64)number << numBits); - return S_OK; } @@ -133,28 +256,32 @@ static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp) static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp) { if (prop.vt == VT_UI4) + return SetLogSizeProp(prop.ulVal, destProp); + + if (prop.vt == VT_BSTR) { - UInt32 v = prop.ulVal; - if (v >= 64) - return E_INVALIDARG; - if (v < 32) - destProp = (UInt32)((UInt32)1 << (unsigned)v); - else - destProp = (UInt64)((UInt64)1 << (unsigned)v); - return S_OK; + UString s; + s = prop.bstrVal; + return StringToDictSize(s, destProp); } - if (prop.vt == VT_BSTR) - return StringToDictSize(prop.bstrVal, destProp); return E_INVALIDARG; } -void CProps::AddProp32(PROPID propid, UInt32 level) +void CProps::AddProp32(PROPID propid, UInt32 val) +{ + CProp &prop = Props.AddNew(); + prop.IsOptional = true; + prop.Id = propid; + prop.Value = (UInt32)val; +} + +void CProps::AddPropBool(PROPID propid, bool val) { CProp &prop = Props.AddNew(); prop.IsOptional = true; prop.Id = propid; - prop.Value = (UInt32)level; + prop.Value = val; } class CCoderProps @@ -164,10 +291,12 @@ class CCoderProps unsigned _numProps; unsigned _numPropsMax; public: - CCoderProps(unsigned numPropsMax) + CCoderProps(unsigned numPropsMax): + _propIDs(NULL), + _props(NULL), + _numProps(0), + _numPropsMax(numPropsMax) { - _numPropsMax = numPropsMax; - _numProps = 0; _propIDs = new PROPID[numPropsMax]; _props = new NCOM::CPropVariant[numPropsMax]; } @@ -194,7 +323,15 @@ void CCoderProps::AddProp(const CProp &prop) HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const { - CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0)); + return SetCoderProps_DSReduce_Aff(scp, dataSizeReduce, NULL); +} + +HRESULT CProps::SetCoderProps_DSReduce_Aff( + ICompressSetCoderProperties *scp, + const UInt64 *dataSizeReduce, + const UInt64 *affinity) const +{ + CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0) + (affinity ? 1 : 0) ); FOR_VECTOR (i, Props) coderProps.AddProp(Props[i]); if (dataSizeReduce) @@ -204,27 +341,34 @@ HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *da prop.Value = *dataSizeReduce; coderProps.AddProp(prop); } + if (affinity) + { + CProp prop; + prop.Id = NCoderPropID::kAffinity; + prop.Value = *affinity; + coderProps.AddProp(prop); + } return coderProps.SetProps(scp); } int CMethodProps::FindProp(PROPID id) const { - for (int i = Props.Size() - 1; i >= 0; i--) - if (Props[i].Id == id) - return i; + for (unsigned i = Props.Size(); i != 0;) + if (Props[--i].Id == id) + return (int)i; return -1; } -int CMethodProps::GetLevel() const +unsigned CMethodProps::GetLevel() const { int i = FindProp(NCoderPropID::kLevel); if (i < 0) return 5; - if (Props[i].Value.vt != VT_UI4) + if (Props[(unsigned)i].Value.vt != VT_UI4) return 9; - UInt32 level = Props[i].Value.ulVal; - return level > 9 ? 9 : (int)level; + UInt32 level = Props[(unsigned)i].Value.ulVal; + return level > 9 ? 9 : (unsigned)level; } struct CNameToPropID @@ -233,13 +377,16 @@ struct CNameToPropID const char *Name; }; + +// the following are related to NCoderPropID::EEnum values +// NCoderPropID::k_NUM_DEFINED static const CNameToPropID g_NameToPropID[] = { { VT_UI4, "" }, { VT_UI4, "d" }, { VT_UI4, "mem" }, { VT_UI4, "o" }, - { VT_UI4, "c" }, + { VT_UI8, "c" }, { VT_UI4, "pb" }, { VT_UI4, "lc" }, { VT_UI4, "lp" }, @@ -251,14 +398,61 @@ static const CNameToPropID g_NameToPropID[] = { VT_UI4, "mt" }, { VT_BOOL, "eos" }, { VT_UI4, "x" }, - { VT_UI4, "reduceSize" } + { VT_UI8, "reduce" }, + { VT_UI8, "expect" }, + { VT_UI8, "cc" }, // "cc" in v23, "b" in v22.01 + { VT_UI4, "check" }, + { VT_BSTR, "filter" }, + { VT_UI8, "memuse" }, + { VT_UI8, "aff" }, + { VT_UI4, "offset" }, + { VT_UI4, "zhb" } + /* + , + // { VT_UI4, "zhc" }, + // { VT_UI4, "zhd" }, + // { VT_UI4, "zcb" }, + { VT_UI4, "dc" }, + { VT_UI4, "zx" }, + { VT_UI4, "zf" }, + { VT_UI4, "zmml" }, + { VT_UI4, "zov" }, + { VT_BOOL, "zmfr" }, + { VT_BOOL, "zle" }, // long enable + // { VT_UI4, "zldb" }, + { VT_UI4, "zld" }, + { VT_UI4, "zlhb" }, + { VT_UI4, "zlmml" }, + { VT_UI4, "zlbb" }, + { VT_UI4, "zlhrb" }, + { VT_BOOL, "zwus" }, + { VT_BOOL, "zshp" }, + { VT_BOOL, "zshs" }, + { VT_BOOL, "zshe" }, + { VT_BOOL, "zshg" }, + { VT_UI4, "zpsm" } + */ + // { VT_UI4, "mcb" }, // mc log version + // { VT_UI4, "ztlen" }, // fb ? }; +/* +#if defined(static_assert) || (defined(__cplusplus) && __cplusplus >= 200410L) || (defined(_MSC_VER) && _MSC_VER >= 1600) + +#if (defined(__cplusplus) && __cplusplus < 201103L) \ + && defined(__clang__) && __clang_major__ >= 4 +#pragma GCC diagnostic ignored "-Wc11-extensions" +#endif + static_assert(Z7_ARRAY_SIZE(g_NameToPropID) == NCoderPropID::k_NUM_DEFINED, + "g_NameToPropID doesn't match NCoderPropID enum"); +#endif +*/ + static int FindPropIdExact(const UString &name) { - for (unsigned i = 0; i < ARRAY_SIZE(g_NameToPropID); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NameToPropID); i++) if (StringsAreEqualNoCase_Ascii(name, g_NameToPropID[i].Name)) - return i; + return (int)i; return -1; } @@ -269,6 +463,13 @@ static bool ConvertProperty(const PROPVARIANT &srcProp, VARTYPE varType, NCOM::C destProp = srcProp; return true; } + + if (varType == VT_UI8 && srcProp.vt == VT_UI4) + { + destProp = (UInt64)srcProp.ulVal; + return true; + } + if (varType == VT_BOOL) { bool res; @@ -311,8 +512,8 @@ static void SplitParam(const UString ¶m, UString &name, UString &value) int eqPos = param.Find(L'='); if (eqPos >= 0) { - name.SetFrom(param, eqPos); - value = param.Ptr(eqPos + 1); + name.SetFrom(param, (unsigned)eqPos); + value = param.Ptr((unsigned)(eqPos + 1)); return; } unsigned i; @@ -333,7 +534,12 @@ static bool IsLogSizeProp(PROPID propid) case NCoderPropID::kDictionarySize: case NCoderPropID::kUsedMemorySize: case NCoderPropID::kBlockSize: - case NCoderPropID::kReduceSize: + case NCoderPropID::kBlockSize2: + /* + case NCoderPropID::kChainSize: + case NCoderPropID::kLdmWindowSize: + */ + // case NCoderPropID::kReduceSize: return true; } return false; @@ -343,14 +549,19 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value) { int index = FindPropIdExact(name); if (index < 0) - return E_INVALIDARG; + { + // 'b' was used as NCoderPropID::kBlockSize2 before v23 + if (!name.IsEqualTo_Ascii_NoCase("b") || value.Find(L':') >= 0) + return E_INVALIDARG; + index = NCoderPropID::kBlockSize2; + } const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index]; CProp prop; - prop.Id = index; + prop.Id = (unsigned)index; if (IsLogSizeProp(prop.Id)) { - RINOK(StringToDictSize(value, prop.Value)); + RINOK(StringToDictSize(value, prop.Value)) } else { @@ -366,9 +577,22 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value) } else if (!value.IsEmpty()) { - UInt32 number; - if (ParseStringToUInt32(value, number) == value.Len()) - propValue = number; + if (nameToPropID.VarType == VT_UI4) + { + UInt32 number; + if (ParseStringToUInt32(value, number) == value.Len()) + propValue = number; + else + propValue = value; + } + else if (nameToPropID.VarType == VT_UI8) + { + UInt64 number; + if (ParseStringToUInt64(value, number) == value.Len()) + propValue = number; + else + propValue = value; + } else propValue = value; } @@ -388,7 +612,7 @@ HRESULT CMethodProps::ParseParamsFromString(const UString &srcString) const UString ¶m = params[i]; UString name, value; SplitParam(param, name, value); - RINOK(SetParam(name, value)); + RINOK(SetParam(name, value)) } return S_OK; } @@ -409,16 +633,16 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const } // {realName}=value - int index = FindPropIdExact(realName); + const int index = FindPropIdExact(realName); if (index < 0) return E_INVALIDARG; const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index]; CProp prop; - prop.Id = index; + prop.Id = (unsigned)index; if (IsLogSizeProp(prop.Id)) { - RINOK(PROPVARIANT_to_DictSize(value, prop.Value)); + RINOK(PROPVARIANT_to_DictSize(value, prop.Value)) } else { @@ -429,6 +653,59 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const return S_OK; } + +static UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads) +{ + UInt32 hs = dict - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + if (hs >= (1 << 24)) + hs >>= 1; + hs |= (1 << 16) - 1; + // if (numHashBytes >= 5) + if (!isBt) + hs |= (256 << 10) - 1; + hs++; + UInt64 size1 = (UInt64)hs * 4; + size1 += (UInt64)dict * 4; + if (isBt) + size1 += (UInt64)dict * 4; + size1 += (2 << 20); + + if (numThreads > 1 && isBt) + size1 += (2 << 20) + (4 << 20); + return size1; +} + +static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28; + +UInt64 CMethodProps::Get_Lzma_MemUsage(bool addSlidingWindowSize) const +{ + const UInt64 dicSize = Get_Lzma_DicSize(); + const bool isBt = Get_Lzma_MatchFinder_IsBt(); + const UInt32 dict32 = (dicSize >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dicSize); + const UInt32 numThreads = Get_Lzma_NumThreads(); + UInt64 size = GetMemoryUsage_LZMA(dict32, isBt, numThreads); + + if (addSlidingWindowSize) + { + const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16); + UInt64 blockSize = (UInt64)dict32 + (1 << 16) + + (numThreads > 1 ? (1 << 20) : 0); + blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)); + if (blockSize >= kBlockSizeMax) + blockSize = kBlockSizeMax; + size += blockSize; + } + return size; +} + + + + HRESULT COneMethodInfo::ParseMethodFromString(const UString &s) { MethodName.Empty(); @@ -436,14 +713,14 @@ HRESULT COneMethodInfo::ParseMethodFromString(const UString &s) { UString temp = s; if (splitPos >= 0) - temp.DeleteFrom(splitPos); + temp.DeleteFrom((unsigned)splitPos); if (!temp.IsAscii()) return E_INVALIDARG; MethodName.SetFromWStr_if_Ascii(temp); } if (splitPos < 0) return S_OK; - PropsString = s.Ptr(splitPos + 1); + PropsString = s.Ptr((unsigned)(splitPos + 1)); return ParseParamsFromString(PropsString); } @@ -454,5 +731,7 @@ HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, cons // -m{N}=method if (value.vt != VT_BSTR) return E_INVALIDARG; - return ParseMethodFromString(value.bstrVal); + UString s; + s = value.bstrVal; + return ParseMethodFromString(s); } diff --git a/3rdparty/lzma/CPP/7zip/Common/MethodProps.h b/3rdparty/lzma/CPP/7zip/Common/MethodProps.h index 765e425df6d..3c332d6af48 100644 --- a/3rdparty/lzma/CPP/7zip/Common/MethodProps.h +++ b/3rdparty/lzma/CPP/7zip/Common/MethodProps.h @@ -1,20 +1,49 @@ // MethodProps.h -#ifndef __7Z_METHOD_PROPS_H -#define __7Z_METHOD_PROPS_H +#ifndef ZIP7_INC_7Z_METHOD_PROPS_H +#define ZIP7_INC_7Z_METHOD_PROPS_H #include "../../Common/MyString.h" +#include "../../Common/Defs.h" + +#include "../../Windows/Defs.h" #include "../../Windows/PropVariant.h" #include "../ICoder.h" -bool StringToBool(const UString &s, bool &res); +// UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads); + +inline UInt64 Calc_From_Val_Percents_Less100(UInt64 val, UInt64 percents) +{ + if (percents == 0) + return 0; + if (val <= (UInt64)(Int64)-1 / percents) + return val * percents / 100; + return val / 100 * percents; +} + +UInt64 Calc_From_Val_Percents(UInt64 val, UInt64 percents); + +bool StringToBool(const wchar_t *s, bool &res); HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest); unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number); + +/* +if (name.IsEmpty() && prop.vt == VT_EMPTY), it doesn't change (resValue) and returns S_OK. + So you must set (resValue) for default value before calling */ HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); -HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads); +/* input: (numThreads = the_number_of_processors) */ +HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force); + +inline HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 numCPUs, UInt32 &numThreads) +{ + bool forced = false; + numThreads = numCPUs; + return ParseMtProp2(name, prop, numThreads, forced); +} + struct CProp { @@ -38,7 +67,9 @@ struct CProps return false; } - void AddProp32(PROPID propid, UInt32 level); + void AddProp32(PROPID propid, UInt32 val); + + void AddPropBool(PROPID propid, bool val); void AddProp_Ascii(PROPID propid, const char *s) { @@ -48,33 +79,45 @@ struct CProps prop.Value = s; } - HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const; + HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce = NULL) const; + HRESULT SetCoderProps_DSReduce_Aff(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce, const UInt64 *affinity) const; }; class CMethodProps: public CProps { HRESULT SetParam(const UString &name, const UString &value); public: - int GetLevel() const; + unsigned GetLevel() const; int Get_NumThreads() const { - int i = FindProp(NCoderPropID::kNumThreads); + const int i = FindProp(NCoderPropID::kNumThreads); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return (int)Props[i].Value.ulVal; + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return (int)val.ulVal; + } return -1; } - bool Get_DicSize(UInt32 &res) const + bool Get_DicSize(UInt64 &res) const { res = 0; - int i = FindProp(NCoderPropID::kDictionarySize); + const int i = FindProp(NCoderPropID::kDictionarySize); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + { + res = val.ulVal; + return true; + } + if (val.vt == VT_UI8) { - res = Props[i].Value.ulVal; + res = val.uhVal.QuadPart; return true; } + } return false; } @@ -84,19 +127,50 @@ public: { int i = FindProp(NCoderPropID::kAlgorithm); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return Props[i].Value.ulVal; + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return val.ulVal; + } return GetLevel() >= 5 ? 1 : 0; } - UInt32 Get_Lzma_DicSize() const + UInt64 Get_Lzma_DicSize() const + { + UInt64 v; + if (Get_DicSize(v)) + return v; + const unsigned level = GetLevel(); + const UInt32 dictSize = + ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : + ( level <= 6 ? ((UInt32)1 << (level + 19)) : + ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) + ))); + return dictSize; + } + + bool Get_Lzma_MatchFinder_IsBt() const { - int i = FindProp(NCoderPropID::kDictionarySize); + const int i = FindProp(NCoderPropID::kMatchFinder); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return Props[i].Value.ulVal; - int level = GetLevel(); - return level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)); + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_BSTR) + return ((val.bstrVal[0] | 0x20) != 'h'); // check for "hc" + } + return GetLevel() >= 5; + } + + bool Get_Lzma_Eos() const + { + const int i = FindProp(NCoderPropID::kEndMarker); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_BOOL) + return VARIANT_BOOLToBool(val.boolVal); + } + return false; } bool Are_Lzma_Model_Props_Defined() const @@ -107,18 +181,68 @@ public: return false; } - UInt32 Get_Lzma_NumThreads(bool &fixedNumber) const + UInt32 Get_Lzma_NumThreads() const { - fixedNumber = false; + if (Get_Lzma_Algo() == 0) + return 1; int numThreads = Get_NumThreads(); if (numThreads >= 0) - { - fixedNumber = true; return numThreads < 2 ? 1 : 2; + return 2; + } + + UInt64 Get_Lzma_MemUsage(bool addSlidingWindowSize) const; + + /* returns -1, if numThreads is unknown */ + int Get_Xz_NumThreads(UInt32 &lzmaThreads) const + { + lzmaThreads = 1; + int numThreads = Get_NumThreads(); + if (numThreads >= 0 && numThreads <= 1) + return 1; + if (Get_Lzma_Algo() != 0) + lzmaThreads = 2; + return numThreads; + } + + UInt64 GetProp_BlockSize(PROPID id) const + { + const int i = FindProp(id); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) { return val.ulVal; } + if (val.vt == VT_UI8) { return val.uhVal.QuadPart; } } - return Get_Lzma_Algo() == 0 ? 1 : 2; + return 0; } + UInt64 Get_Xz_BlockSize() const + { + { + UInt64 blockSize1 = GetProp_BlockSize(NCoderPropID::kBlockSize); + UInt64 blockSize2 = GetProp_BlockSize(NCoderPropID::kBlockSize2); + UInt64 minSize = MyMin(blockSize1, blockSize2); + if (minSize != 0) + return minSize; + UInt64 maxSize = MyMax(blockSize1, blockSize2); + if (maxSize != 0) + return maxSize; + } + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + const UInt64 dictSize = Get_Lzma_DicSize(); + /* lzma2 code uses fake 4 GiB to calculate ChunkSize. So we do same */ + UInt64 blockSize = (UInt64)dictSize << 2; + if (blockSize < kMinSize) blockSize = kMinSize; + if (blockSize > kMaxSize) blockSize = kMaxSize; + if (blockSize < dictSize) blockSize = dictSize; + blockSize += (kMinSize - 1); + blockSize &= ~(UInt64)(kMinSize - 1); + return blockSize; + } + + UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const { fixedNumber = false; @@ -127,37 +251,47 @@ public: { fixedNumber = true; if (numThreads < 1) return 1; - if (numThreads > 64) return 64; - return numThreads; + const unsigned kNumBZip2ThreadsMax = 64; + if ((unsigned)numThreads > kNumBZip2ThreadsMax) return kNumBZip2ThreadsMax; + return (unsigned)numThreads; } return 1; } UInt32 Get_BZip2_BlockSize() const { - int i = FindProp(NCoderPropID::kDictionarySize); + const int i = FindProp(NCoderPropID::kDictionarySize); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) { - UInt32 blockSize = Props[i].Value.ulVal; + UInt32 blockSize = val.ulVal; const UInt32 kDicSizeMin = 100000; const UInt32 kDicSizeMax = 900000; if (blockSize < kDicSizeMin) blockSize = kDicSizeMin; if (blockSize > kDicSizeMax) blockSize = kDicSizeMax; return blockSize; } - int level = GetLevel(); + } + const unsigned level = GetLevel(); return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1)); } - UInt32 Get_Ppmd_MemSize() const + UInt64 Get_Ppmd_MemSize() const { - int i = FindProp(NCoderPropID::kUsedMemorySize); + const int i = FindProp(NCoderPropID::kUsedMemorySize); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return Props[i].Value.ulVal; - int level = GetLevel(); - return level >= 9 ? (192 << 20) : ((UInt32)1 << (level + 19)); + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return val.ulVal; + if (val.vt == VT_UI8) + return val.uhVal.QuadPart; + } + const unsigned level = GetLevel(); + const UInt32 mem = (UInt32)1 << (level + 19); + return mem; } void AddProp_Level(UInt32 level) @@ -170,6 +304,23 @@ public: AddProp32(NCoderPropID::kNumThreads, numThreads); } + void AddProp_EndMarker_if_NotFound(bool eos) + { + if (FindProp(NCoderPropID::kEndMarker) < 0) + AddPropBool(NCoderPropID::kEndMarker, eos); + } + + void AddProp_BlockSize2(UInt64 blockSize2) + { + if (FindProp(NCoderPropID::kBlockSize2) < 0) + { + CProp &prop = Props.AddNew(); + prop.IsOptional = true; + prop.Id = NCoderPropID::kBlockSize2; + prop.Value = blockSize2; + } + } + HRESULT ParseParamsFromString(const UString &srcString); HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value); }; diff --git a/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.cpp b/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.cpp new file mode 100644 index 00000000000..8efb977fdba --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.cpp @@ -0,0 +1,849 @@ +// MultiOutStream.cpp + +#include "StdAfx.h" + +// #define DEBUG_VOLUMES + +#ifdef DEBUG_VOLUMES +#include <stdio.h> + #define PRF(x) x; +#else + #define PRF(x) +#endif + +#include "../../Common/ComTry.h" + +#include "../../Windows/FileDir.h" +#include "../../Windows/FileFind.h" +#include "../../Windows/System.h" + +#include "MultiOutStream.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static const unsigned k_NumVols_MAX = k_VectorSizeMax - 1; + // 2; // for debug + +/* +#define UPDATE_HRES(hres, x) \ + { const HRESULT res2 = (x); if (hres == SZ_OK) hres = res2; } +*/ + +HRESULT CMultiOutStream::Destruct() +{ + COM_TRY_BEGIN + HRESULT hres = S_OK; + HRESULT hres3 = S_OK; + + while (!Streams.IsEmpty()) + { + try + { + HRESULT hres2; + if (NeedDelete) + { + /* we could call OptReOpen_and_SetSize() to test that we try to delete correct file, + but we cannot guarantee that (RealSize) will be correct after Write() or another failures. + And we still want to delete files even for such cases. + So we don't check for OptReOpen_and_SetSize() here: */ + // if (OptReOpen_and_SetSize(Streams.Size() - 1, 0) == S_OK) + hres2 = CloseStream_and_DeleteFile(Streams.Size() - 1); + } + else + { + hres2 = CloseStream(Streams.Size() - 1); + } + if (hres == S_OK) + hres = hres2; + } + catch(...) + { + hres3 = E_OUTOFMEMORY; + } + + { + /* Stream was released in CloseStream_*() above already, and it was removed from linked list + it's some unexpected case, if Stream is still attached here. + So the following code is optional: */ + CVolStream &s = Streams.Back(); + if (s.Stream) + { + if (hres3 == S_OK) + hres3 = E_FAIL; + s.Stream.Detach(); + /* it will be not failure, even if we call RemoveFromLinkedList() + twice for same CVolStream in this Destruct() function */ + RemoveFromLinkedList(Streams.Size() - 1); + } + } + Streams.DeleteBack(); + // Delete_LastStream_Records(); + } + + if (hres == S_OK) + hres = hres3; + if (hres == S_OK && NumListItems != 0) + hres = E_FAIL; + return hres; + COM_TRY_END +} + + +CMultiOutStream::~CMultiOutStream() +{ + // we try to avoid exception in destructors + Destruct(); +} + + +void CMultiOutStream::Init(const CRecordVector<UInt64> &sizes) +{ + Streams.Clear(); + InitLinkedList(); + Sizes = sizes; + NeedDelete = true; + MTime_Defined = false; + FinalVol_WasReopen = false; + NumOpenFiles_AllowedMax = NSystem::Get_File_OPEN_MAX_Reduced_for_3_tasks(); + + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + _absLimit = (UInt64)(Int64)-1; + + _restrict_Begin = 0; + _restrict_End = (UInt64)(Int64)-1; + _restrict_Global = 0; + + UInt64 sum = 0; + unsigned i = 0; + for (i = 0; i < Sizes.Size(); i++) + { + if (i >= k_NumVols_MAX) + { + _absLimit = sum; + break; + } + const UInt64 size = Sizes[i]; + const UInt64 next = sum + size; + if (next < sum) + break; + sum = next; + } + + // if (Sizes.IsEmpty()) throw "no volume sizes"; + const UInt64 size = Sizes.Back(); + if (size == 0) + throw "zero size last volume"; + + if (i == Sizes.Size()) + if ((_absLimit - sum) / size >= (k_NumVols_MAX - i)) + _absLimit = sum + (k_NumVols_MAX - i) * size; +} + + +/* IsRestricted(): + we must call only if volume is full (s.RealSize==VolSize) or finished. + the function doesn't use VolSize and it uses s.RealSize instead. + it returns true : if stream is restricted, and we can't close that stream + it returns false : if there is no restriction, and we can close that stream + Note: (RealSize == 0) (empty volume) on restriction bounds are supposed as non-restricted +*/ +bool CMultiOutStream::IsRestricted(const CVolStream &s) const +{ + if (s.Start < _restrict_Global) + return true; + if (_restrict_Begin == _restrict_End) + return false; + if (_restrict_Begin <= s.Start) + return _restrict_End > s.Start; + return _restrict_Begin < s.Start + s.RealSize; +} + +/* +// this function check also _length and volSize +bool CMultiOutStream::IsRestricted_for_Close(unsigned index) const +{ + const CVolStream &s = Streams[index]; + if (_length <= s.Start) // we don't close streams after the end, because we still can write them later + return true; + // (_length > s.Start) + const UInt64 volSize = GetVolSize_for_Stream(index); + if (volSize == 0) + return IsRestricted_Empty(s); + if (_length - s.Start < volSize) + return true; + return IsRestricted(s); +} +*/ + +FString CMultiOutStream::GetFilePath(unsigned index) +{ + FString name; + name.Add_UInt32(index + 1); + while (name.Len() < 3) + name.InsertAtFront(FTEXT('0')); + name.Insert(0, Prefix); + return name; +} + + +// we close stream, but we still keep item in Streams[] vector +HRESULT CMultiOutStream::CloseStream(unsigned index) +{ + CVolStream &s = Streams[index]; + if (s.Stream) + { + RINOK(s.StreamSpec->Close()) + // the following two commands must be called together: + s.Stream.Release(); + RemoveFromLinkedList(index); + } + return S_OK; +} + + +// we close stream and delete file, but we still keep item in Streams[] vector +HRESULT CMultiOutStream::CloseStream_and_DeleteFile(unsigned index) +{ + PRF(printf("\n====== %u, CloseStream_AndDelete \n", index)); + RINOK(CloseStream(index)) + FString path = GetFilePath(index); + path += Streams[index].Postfix; + // we can checki that file exist + // if (NFind::DoesFileExist_Raw(path)) + if (!DeleteFileAlways(path)) + return GetLastError_noZero_HRESULT(); + return S_OK; +} + + +HRESULT CMultiOutStream::CloseStream_and_FinalRename(unsigned index) +{ + PRF(printf("\n====== %u, CloseStream_and_FinalRename \n", index)); + CVolStream &s = Streams[index]; + // HRESULT res = S_OK; + bool mtime_WasSet = false; + if (MTime_Defined && s.Stream) + { + if (s.StreamSpec->SetMTime(&MTime)) + mtime_WasSet = true; + // else res = GetLastError_noZero_HRESULT(); + } + + RINOK(CloseStream(index)) + if (s.Postfix.IsEmpty()) // if Postfix is empty, the path is already final + return S_OK; + const FString path = GetFilePath(index); + FString tempPath = path; + tempPath += s.Postfix; + + if (MTime_Defined && !mtime_WasSet) + { + if (!SetDirTime(tempPath, NULL, NULL, &MTime)) + { + // res = GetLastError_noZero_HRESULT(); + } + } + if (!MyMoveFile(tempPath, path)) + return GetLastError_noZero_HRESULT(); + /* we clear CVolStream::Postfix. So we will not use Temp path + anymore for this stream, and we will work only with final path */ + s.Postfix.Empty(); + // we can ignore set_mtime error or we can return it + return S_OK; + // return res; +} + + +HRESULT CMultiOutStream::PrepareToOpenNew() +{ + if (NumListItems < NumOpenFiles_AllowedMax) + return S_OK; + /* when we create zip archive: in most cases we need only starting + data of restricted region for rewriting zip's local header. + So here we close latest created volume (from Head), and we try to + keep oldest volumes that will be used for header rewriting later. */ + const int index = Head; + if (index == -1) + return E_FAIL; + PRF(printf("\n== %u, PrepareToOpenNew::CloseStream, NumListItems =%u \n", index, NumListItems)); + /* we don't expect non-restricted stream here in normal cases (if _restrict_Global was not changed). + if there was non-restricted stream, it should be closed before */ + // if (!IsRestricted_for_Close(index)) return CloseStream_and_FinalRename(index); + return CloseStream((unsigned)index); +} + + +HRESULT CMultiOutStream::CreateNewStream(UInt64 newSize) +{ + PRF(printf("\n== %u, CreateNewStream, size =%u \n", Streams.Size(), (unsigned)newSize)); + + if (Streams.Size() >= k_NumVols_MAX) + return E_INVALIDARG; // E_OUTOFMEMORY + + RINOK(PrepareToOpenNew()) + CVolStream s; + s.StreamSpec = new COutFileStream; + s.Stream = s.StreamSpec; + const FString path = GetFilePath(Streams.Size()); + + if (NFind::DoesFileExist_Raw(path)) + return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); + if (!CreateTempFile2(path, false, s.Postfix, &s.StreamSpec->File)) + return GetLastError_noZero_HRESULT(); + + s.Start = GetGlobalOffset_for_NewStream(); + s.Pos = 0; + s.RealSize = 0; + + const unsigned index = Streams.Add(s); + InsertToLinkedList(index); + + if (newSize != 0) + return s.SetSize2(newSize); + return S_OK; +} + + +HRESULT CMultiOutStream::CreateStreams_If_Required(unsigned streamIndex) +{ + // UInt64 lastStreamSize = 0; + for (;;) + { + const unsigned numStreamsBefore = Streams.Size(); + if (streamIndex < numStreamsBefore) + return S_OK; + UInt64 newSize; + if (streamIndex == numStreamsBefore) + { + // it's final volume that will be used for real writing. + /* SetSize(_offsetPos) is not required, + because the file Size will be set later by calling Seek() with Write() */ + newSize = 0; // lastStreamSize; + } + else + { + // it's intermediate volume. So we need full volume size + newSize = GetVolSize_for_Stream(numStreamsBefore); + } + + RINOK(CreateNewStream(newSize)) + + // optional check + if (numStreamsBefore + 1 != Streams.Size()) return E_FAIL; + + if (streamIndex != numStreamsBefore) + { + // it's intermediate volume. So we can close it, if it's non-restricted + bool isRestricted; + { + const CVolStream &s = Streams[numStreamsBefore]; + if (newSize == 0) + isRestricted = IsRestricted_Empty(s); + else + isRestricted = IsRestricted(s); + } + if (!isRestricted) + { + RINOK(CloseStream_and_FinalRename(numStreamsBefore)) + } + } + } +} + + +HRESULT CMultiOutStream::ReOpenStream(unsigned streamIndex) +{ + PRF(printf("\n====== %u, ReOpenStream \n", streamIndex)); + RINOK(PrepareToOpenNew()) + CVolStream &s = Streams[streamIndex]; + + FString path = GetFilePath(streamIndex); + path += s.Postfix; + + s.StreamSpec = new COutFileStream; + s.Stream = s.StreamSpec; + s.Pos = 0; + + HRESULT hres; + if (s.StreamSpec->Open(path, OPEN_EXISTING)) + { + if (s.Postfix.IsEmpty()) + { + /* it's unexpected case that we open finished volume. + It can mean that the code for restriction is incorrect */ + FinalVol_WasReopen = true; + } + UInt64 realSize = 0; + hres = s.StreamSpec->GetSize(&realSize); + if (hres == S_OK) + { + if (realSize == s.RealSize) + { + InsertToLinkedList(streamIndex); + return S_OK; + } + // file size was changed between Close() and ReOpen() + // we must release Stream to be consistent with linked list + hres = E_FAIL; + } + } + else + hres = GetLastError_noZero_HRESULT(); + s.Stream.Release(); + s.StreamSpec = NULL; + return hres; +} + + +/* Sets size of stream, if new size is not equal to old size (RealSize). + If stream was closed and size change is required, it reopens the stream. */ + +HRESULT CMultiOutStream::OptReOpen_and_SetSize(unsigned index, UInt64 size) +{ + CVolStream &s = Streams[index]; + if (size == s.RealSize) + return S_OK; + if (!s.Stream) + { + RINOK(ReOpenStream(index)) + } + PRF(printf("\n== %u, OptReOpen_and_SetSize, size =%u RealSize = %u\n", index, (unsigned)size, (unsigned)s.RealSize)); + // comment it to debug tail after data + return s.SetSize2(size); +} + + +/* +call Normalize_finalMode(false), if _length was changed. + for all streams starting after _length: + - it sets zero size + - it still keeps file open + Note: after _length reducing with CMultiOutStream::SetSize() we can + have very big number of empty streams at the end of Streams[] list. + And Normalize_finalMode() will runs all these empty streams of Streams[] vector. + So it can be ineffective, if we call Normalize_finalMode() many + times after big reducing of (_length). + +call Normalize_finalMode(true) to set final presentations of all streams + for all streams starting after _length: + - it sets zero size + - it removes file + - it removes CVolStream object from Streams[] vector + +Note: we don't remove zero sized first volume, if (_length == 0) +*/ + +HRESULT CMultiOutStream::Normalize_finalMode(bool finalMode) +{ + PRF(printf("\n== Normalize_finalMode: _length =%d \n", (unsigned)_length)); + + unsigned i = Streams.Size(); + + UInt64 offset = 0; + + /* At first we normalize (reduce or increase) the sizes of all existing + streams in Streams[] that can be affected by changed _length. + And we remove tailing zero-size streams, if (finalMode == true) */ + while (i != 0) + { + offset = Streams[--i].Start; // it's last item in Streams[] + // we don't want to remove first volume + if (offset < _length || i == 0) + { + const UInt64 volSize = GetVolSize_for_Stream(i); + UInt64 size = _length - offset; // (size != 0) here + if (size > volSize) + size = volSize; + RINOK(OptReOpen_and_SetSize(i, size)) + if (_length - offset <= volSize) + return S_OK; + // _length - offset > volSize + offset += volSize; + // _length > offset + break; + // UPDATE_HRES(res, OptReOpen_and_SetSize(i, size)); + } + + /* we Set Size of stream to zero even for (finalMode==true), although + that stream will be deleted in next commands */ + // UPDATE_HRES(res, OptReOpen_and_SetSize(i, 0)); + RINOK(OptReOpen_and_SetSize(i, 0)) + if (finalMode) + { + RINOK(CloseStream_and_DeleteFile(i)) + /* CVolStream::Stream was released above already, and it was + removed from linked list. So we don't need to update linked list + structure, when we delete last item in Streams[] */ + Streams.DeleteBack(); + // Delete_LastStream_Records(); + } + } + + /* now we create new zero-filled streams to cover all data up to _length */ + + if (_length == 0) + return S_OK; + + // (offset) is start offset of next stream after existing Streams[] + + for (;;) + { + // _length > offset + const UInt64 volSize = GetVolSize_for_Stream(Streams.Size()); + UInt64 size = _length - offset; // (size != 0) here + if (size > volSize) + size = volSize; + RINOK(CreateNewStream(size)) + if (_length - offset <= volSize) + return S_OK; + // _length - offset > volSize) + offset += volSize; + // _length > offset + } +} + + +HRESULT CMultiOutStream::FinalFlush_and_CloseFiles(unsigned &numTotalVolumesRes) +{ + // at first we remove unused zero-sized streams after _length + HRESULT res = Normalize_finalMode(true); + numTotalVolumesRes = Streams.Size(); + FOR_VECTOR (i, Streams) + { + const HRESULT res2 = CloseStream_and_FinalRename(i); + if (res == S_OK) + res = res2; + } + if (NumListItems != 0 && res == S_OK) + res = E_FAIL; + return res; +} + + +bool CMultiOutStream::SetMTime_Final(const CFiTime &mTime) +{ + // we will set mtime only if new value differs from previous + if (!FinalVol_WasReopen && MTime_Defined && Compare_FiTime(&MTime, &mTime) == 0) + return true; + bool res = true; + FOR_VECTOR (i, Streams) + { + CVolStream &s = Streams[i]; + if (s.Stream) + { + if (!s.StreamSpec->SetMTime(&mTime)) + res = false; + } + else + { + if (!SetDirTime(GetFilePath(i), NULL, NULL, &mTime)) + res = false; + } + } + return res; +} + + +Z7_COM7F_IMF(CMultiOutStream::SetSize(UInt64 newSize)) +{ + COM_TRY_BEGIN + if ((Int64)newSize < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if (newSize > _absLimit) + { + /* big seek value was sent to SetSize() or to Seek()+Write(). + It can mean one of two situations: + 1) some incorrect code called it with big seek value. + 2) volume size was small, and we have too big number of volumes + */ + /* in Windows SetEndOfFile() can return: + ERROR_NEGATIVE_SEEK: for >= (1 << 63) + ERROR_INVALID_PARAMETER: for > (16 TiB - 64 KiB) + ERROR_DISK_FULL: for <= (16 TiB - 64 KiB) + */ + // return E_FAIL; + // return E_OUTOFMEMORY; + return E_INVALIDARG; + } + + if (newSize > _length) + { + // we don't expect such case. So we just define global restriction */ + _restrict_Global = newSize; + } + else if (newSize < _restrict_Global) + _restrict_Global = newSize; + + PRF(printf("\n== SetSize, size =%u \n", (unsigned)newSize)); + + _length = newSize; + return Normalize_finalMode(false); + + COM_TRY_END +} + + +Z7_COM7F_IMF(CMultiOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + COM_TRY_BEGIN + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + + if (_absPos > _length) + { + // it create data only up to _absPos. + // but we still can need additional new streams, if _absPos at range of volume + RINOK(SetSize(_absPos)) + } + + while (size != 0) + { + UInt64 volSize; + { + if (_streamIndex < Sizes.Size() - 1) + { + volSize = Sizes[_streamIndex]; + if (_offsetPos >= volSize) + { + _offsetPos -= volSize; + _streamIndex++; + continue; + } + } + else + { + volSize = Sizes[Sizes.Size() - 1]; + if (_offsetPos >= volSize) + { + const UInt64 v = _offsetPos / volSize; + if (v >= ((UInt32)(Int32)-1) - _streamIndex) + return E_INVALIDARG; + // throw 202208; + _streamIndex += (unsigned)v; + _offsetPos -= (unsigned)v * volSize; + } + if (_streamIndex >= k_NumVols_MAX) + return E_INVALIDARG; + } + } + + // (_offsetPos < volSize) here + + /* we can need to create one or more streams here, + vol_size for some streams is allowed to be 0. + Also we close some new created streams, if they are non-restricted */ + // file Size will be set later by calling Seek() with Write() + + /* the case (_absPos > _length) was processed above with SetSize(_absPos), + so here it's expected. that we can create optional zero-size streams and then _streamIndex */ + RINOK(CreateStreams_If_Required(_streamIndex)) + + CVolStream &s = Streams[_streamIndex]; + + PRF(printf("\n%d, == Write : Pos = %u, RealSize = %u size =%u \n", + _streamIndex, (unsigned)s.Pos, (unsigned)s.RealSize, size)); + + if (!s.Stream) + { + RINOK(ReOpenStream(_streamIndex)) + } + if (_offsetPos != s.Pos) + { + RINOK(s.Stream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL)) + s.Pos = _offsetPos; + } + + UInt32 curSize = size; + { + const UInt64 rem = volSize - _offsetPos; + if (curSize > rem) + curSize = (UInt32)rem; + } + // curSize != 0 + UInt32 realProcessed = 0; + + HRESULT hres = s.Stream->Write(data, curSize, &realProcessed); + + data = (const void *)((const Byte *)data + realProcessed); + size -= realProcessed; + s.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_length < _absPos) + _length = _absPos; + if (s.RealSize < _offsetPos) + s.RealSize = _offsetPos; + if (processedSize) + *processedSize += realProcessed; + + if (s.Pos == volSize) + { + bool isRestricted; + if (volSize == 0) + isRestricted = IsRestricted_Empty(s); + else + isRestricted = IsRestricted(s); + if (!isRestricted) + { + const HRESULT res2 = CloseStream_and_FinalRename(_streamIndex); + if (hres == S_OK) + hres = res2; + } + _streamIndex++; + _offsetPos = 0; + } + + RINOK(hres) + if (realProcessed == 0 && curSize != 0) + return E_FAIL; + // break; + } + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CMultiOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + PRF(printf("\n-- Seek seekOrigin=%u Seek =%u\n", seekOrigin, (unsigned)offset)); + + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _absPos; break; + case STREAM_SEEK_END: offset += _length; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if ((UInt64)offset != _absPos) + { + _absPos = (UInt64)offset; + _offsetPos = (UInt64)offset; + _streamIndex = 0; + } + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + +// result value will be saturated to (UInt32)(Int32)-1 + +unsigned CMultiOutStream::GetStreamIndex_for_Offset(UInt64 offset, UInt64 &relOffset) const +{ + const unsigned last = Sizes.Size() - 1; + for (unsigned i = 0; i < last; i++) + { + const UInt64 size = Sizes[i]; + if (offset < size) + { + relOffset = offset; + return i; + } + offset -= size; + } + const UInt64 size = Sizes[last]; + const UInt64 v = offset / size; + if (v >= ((UInt32)(Int32)-1) - last) + return (UInt32)(Int32)-1; // saturation + relOffset = offset - (unsigned)v * size; + return last + (unsigned)(v); +} + + +Z7_COM7F_IMF(CMultiOutStream::SetRestriction(UInt64 begin, UInt64 end)) +{ + COM_TRY_BEGIN + + // begin = end = 0; // for debug + + PRF(printf("\n==================== CMultiOutStream::SetRestriction %u, %u\n", (unsigned)begin, (unsigned)end)); + if (begin > end) + { + // these value are FAILED values. + return E_FAIL; + // return E_INVALIDARG; + /* + // or we can ignore error with 3 ways: no change, non-restricted, saturation: + end = begin; // non-restricted + end = (UInt64)(Int64)-1; // saturation: + return S_OK; + */ + } + UInt64 b = _restrict_Begin; + UInt64 e = _restrict_End; + _restrict_Begin = begin; + _restrict_End = end; + + if (b == e) // if there were no restriction before + return S_OK; // no work to derestrict now. + + /* [b, e) is previous restricted region. So all volumes that + intersect that [b, e) region are candidats for derestriction */ + + if (begin != end) // if there is new non-empty restricted region + { + /* Now we will try to reduce or change (b) and (e) bounds + to reduce main loop that checks volumes for derestriction. + We still use one big derestriction region in main loop, although + in some cases we could have two smaller derestriction regions. + Also usually restriction region cannot move back from previous start position, + so (b <= begin) is expected here for normal cases */ + if (b == begin) // if same low bounds + b = end; // we need to derestrict only after the end of new restricted region + if (e == end) // if same high bounds + e = begin; // we need to derestrict only before the begin of new restricted region + } + + if (b > e) // || b == (UInt64)(Int64)-1 + return S_OK; + + /* Here we close finished volumes that are not restricted anymore. + We close (low number) volumes at first. */ + + UInt64 offset; + unsigned index = GetStreamIndex_for_Offset(b, offset); + + for (; index < Streams.Size(); index++) + { + { + const CVolStream &s = Streams[index]; + if (_length <= s.Start) + break; // we don't close streams after _length + // (_length > s.Start) + const UInt64 volSize = GetVolSize_for_Stream(index); + if (volSize == 0) + { + if (e < s.Start) + break; + // we don't close empty stream, if next byte [s.Start, s.Start] is restricted + if (IsRestricted_Empty(s)) + continue; + } + else + { + if (e <= s.Start) + break; + // we don't close non full streams + if (_length - s.Start < volSize) + break; + // (volSize == s.RealSize) is expected here. So no need to check it + // if (volSize != s.RealSize) break; + if (IsRestricted(s)) + continue; + } + } + RINOK(CloseStream_and_FinalRename(index)) + } + + return S_OK; + COM_TRY_END +} diff --git a/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.h b/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.h new file mode 100644 index 00000000000..2fb78112ec3 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.h @@ -0,0 +1,160 @@ +// MultiOutStream.h + +#ifndef ZIP7_INC_MULTI_OUT_STREAM_H +#define ZIP7_INC_MULTI_OUT_STREAM_H + +#include "FileStreams.h" + +Z7_CLASS_IMP_COM_2( + CMultiOutStream + , IOutStream + , IStreamSetRestriction +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + Z7_CLASS_NO_COPY(CMultiOutStream) + + struct CVolStream + { + COutFileStream *StreamSpec; + CMyComPtr<IOutStream> Stream; + UInt64 Start; // start pos of current Stream in global stream + UInt64 Pos; // pos in current Stream + UInt64 RealSize; + int Next; // next older + int Prev; // prev newer + AString Postfix; + + HRESULT SetSize2(UInt64 size) + { + const HRESULT res = Stream->SetSize(size); + if (res == SZ_OK) + RealSize = size; + return res; + } + }; + + unsigned _streamIndex; // (_streamIndex >= Stream.Size()) is allowed in some internal code + UInt64 _offsetPos; // offset relative to Streams[_streamIndex] volume. (_offsetPos >= volSize is allowed) + UInt64 _absPos; + UInt64 _length; // virtual Length + UInt64 _absLimit; + + CObjectVector<CVolStream> Streams; + CRecordVector<UInt64> Sizes; + + UInt64 _restrict_Begin; + UInt64 _restrict_End; + UInt64 _restrict_Global; + + unsigned NumOpenFiles_AllowedMax; + + // ----- Double Linked List ----- + + unsigned NumListItems; + int Head; // newest + int Tail; // oldest + + void InitLinkedList() + { + Head = -1; + Tail = -1; + NumListItems = 0; + } + + void InsertToLinkedList(unsigned index) + { + { + CVolStream &node = Streams[index]; + node.Next = Head; + node.Prev = -1; + } + if (Head != -1) + Streams[(unsigned)Head].Prev = (int)index; + else + { + // if (Tail != -1) throw 1; + Tail = (int)index; + } + Head = (int)index; + NumListItems++; + } + + void RemoveFromLinkedList(unsigned index) + { + CVolStream &s = Streams[index]; + if (s.Next != -1) Streams[(unsigned)s.Next].Prev = s.Prev; else Tail = s.Prev; + if (s.Prev != -1) Streams[(unsigned)s.Prev].Next = s.Next; else Head = s.Next; + s.Next = -1; // optional + s.Prev = -1; // optional + NumListItems--; + } + + /* + void Delete_LastStream_Records() + { + if (Streams.Back().Stream) + RemoveFromLinkedList(Streams.Size() - 1); + Streams.DeleteBack(); + } + */ + + UInt64 GetVolSize_for_Stream(unsigned i) const + { + const unsigned last = Sizes.Size() - 1; + return Sizes[i < last ? i : last]; + } + UInt64 GetGlobalOffset_for_NewStream() const + { + return Streams.Size() == 0 ? 0: + Streams.Back().Start + + GetVolSize_for_Stream(Streams.Size() - 1); + } + unsigned GetStreamIndex_for_Offset(UInt64 offset, UInt64 &relOffset) const; + bool IsRestricted(const CVolStream &s) const; + bool IsRestricted_Empty(const CVolStream &s) const + { + // (s) must be stream that has (VolSize == 0). + // we treat empty stream as restricted, if next byte is restricted. + if (s.Start < _restrict_Global) + return true; + return + (_restrict_Begin != _restrict_End) + && (_restrict_Begin <= s.Start) + && (_restrict_Begin == s.Start || _restrict_End > s.Start); + } + // bool IsRestricted_for_Close(unsigned index) const; + FString GetFilePath(unsigned index); + + HRESULT CloseStream(unsigned index); + HRESULT CloseStream_and_DeleteFile(unsigned index); + HRESULT CloseStream_and_FinalRename(unsigned index); + + HRESULT PrepareToOpenNew(); + HRESULT CreateNewStream(UInt64 newSize); + HRESULT CreateStreams_If_Required(unsigned streamIndex); + HRESULT ReOpenStream(unsigned streamIndex); + HRESULT OptReOpen_and_SetSize(unsigned index, UInt64 size); + + HRESULT Normalize_finalMode(bool finalMode); +public: + FString Prefix; + CFiTime MTime; + bool MTime_Defined; + bool FinalVol_WasReopen; + bool NeedDelete; + + CMultiOutStream() {} + ~CMultiOutStream(); + void Init(const CRecordVector<UInt64> &sizes); + bool SetMTime_Final(const CFiTime &mTime); + UInt64 GetSize() const { return _length; } + /* it makes final flushing, closes open files and renames to final name if required + but it still keeps Streams array of all closed files. + So we still can delete all files later, if required */ + HRESULT FinalFlush_and_CloseFiles(unsigned &numTotalVolumesRes); + // Destruct object without exceptions + HRESULT Destruct(); +}; + +#endif diff --git a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp index 368d39b6514..a6b005e4ff6 100644 --- a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp @@ -2,38 +2,36 @@ #include "StdAfx.h" -#include "../../Common/Defs.h" - #include "OffsetStream.h" HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset) { _offset = offset; _stream = stream; - return _stream->Seek(offset, STREAM_SEEK_SET, NULL); + return _stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL); } -STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { return _stream->Write(data, size, processedSize); } -STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { - UInt64 absoluteNewPosition; if (seekOrigin == STREAM_SEEK_SET) { if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; offset += _offset; } - HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); + UInt64 absoluteNewPosition = 0; // =0 for gcc-10 + const HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); if (newPosition) *newPosition = absoluteNewPosition - _offset; return result; } -STDMETHODIMP COffsetOutStream::SetSize(UInt64 newSize) +Z7_COM7F_IMF(COffsetOutStream::SetSize(UInt64 newSize)) { return _stream->SetSize(_offset + newSize); } diff --git a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h index 9074a24e031..9bd554cc8b6 100644 --- a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h +++ b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h @@ -1,26 +1,22 @@ // OffsetStream.h -#ifndef __OFFSET_STREAM_H -#define __OFFSET_STREAM_H +#ifndef ZIP7_INC_OFFSET_STREAM_H +#define ZIP7_INC_OFFSET_STREAM_H #include "../../Common/MyCom.h" #include "../IStream.h" -class COffsetOutStream: - public IOutStream, - public CMyUnknownImp -{ - UInt64 _offset; +Z7_CLASS_IMP_NOQIB_1( + COffsetOutStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + CMyComPtr<IOutStream> _stream; + UInt64 _offset; public: HRESULT Init(IOutStream *stream, UInt64 offset); - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp index 4ba34a053b1..197b3767efb 100644 --- a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp @@ -11,18 +11,18 @@ bool COutBuffer::Create(UInt32 bufSize) throw() const UInt32 kMinBlockSize = 1; if (bufSize < kMinBlockSize) bufSize = kMinBlockSize; - if (_buf != 0 && _bufSize == bufSize) + if (_buf && _bufSize == bufSize) return true; Free(); _bufSize = bufSize; _buf = (Byte *)::MidAlloc(bufSize); - return (_buf != 0); + return (_buf != NULL); } void COutBuffer::Free() throw() { ::MidFree(_buf); - _buf = 0; + _buf = NULL; } void COutBuffer::Init() throw() @@ -32,7 +32,7 @@ void COutBuffer::Init() throw() _pos = 0; _processedSize = 0; _overDict = false; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS ErrorCode = S_OK; #endif } @@ -51,17 +51,17 @@ HRESULT COutBuffer::FlushPart() throw() // _streamPos < _bufSize UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos); HRESULT result = S_OK; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS result = ErrorCode; #endif - if (_buf2 != 0) + if (_buf2) { memcpy(_buf2, _buf + _streamPos, size); _buf2 += size; } - if (_stream != 0 - #ifdef _NO_EXCEPTIONS + if (_stream + #ifdef Z7_NO_EXCEPTIONS && (ErrorCode == S_OK) #endif ) @@ -85,14 +85,14 @@ HRESULT COutBuffer::FlushPart() throw() HRESULT COutBuffer::Flush() throw() { - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS if (ErrorCode != S_OK) return ErrorCode; #endif while (_streamPos != _pos) { - HRESULT result = FlushPart(); + const HRESULT result = FlushPart(); if (result != S_OK) return result; } @@ -101,8 +101,8 @@ HRESULT COutBuffer::Flush() throw() void COutBuffer::FlushWithCheck() { - HRESULT result = Flush(); - #ifdef _NO_EXCEPTIONS + const HRESULT result = Flush(); + #ifdef Z7_NO_EXCEPTIONS ErrorCode = result; #else if (result != S_OK) diff --git a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h index 3bdfb87c592..cef7d502dfe 100644 --- a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h +++ b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h @@ -1,13 +1,13 @@ // OutBuffer.h -#ifndef __OUT_BUFFER_H -#define __OUT_BUFFER_H +#ifndef ZIP7_INC_OUT_BUFFER_H +#define ZIP7_INC_OUT_BUFFER_H #include "../IStream.h" #include "../../Common/MyCom.h" #include "../../Common/MyException.h" -#ifndef _NO_EXCEPTIONS +#ifndef Z7_NO_EXCEPTIONS struct COutBufferException: public CSystemException { COutBufferException(HRESULT errorCode): CSystemException(errorCode) {} @@ -29,11 +29,11 @@ protected: HRESULT FlushPart() throw(); public: - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS HRESULT ErrorCode; #endif - COutBuffer(): _buf(0), _pos(0), _stream(0), _buf2(0) {} + COutBuffer(): _buf(NULL), _pos(0), _stream(NULL), _buf2(NULL) {} ~COutBuffer() { Free(); } bool Create(UInt32 bufSize) throw(); @@ -47,8 +47,11 @@ public: void WriteByte(Byte b) { - _buf[_pos++] = b; - if (_pos == _limitPos) + UInt32 pos = _pos; + _buf[pos] = b; + pos++; + _pos = pos; + if (pos == _limitPos) FlushWithCheck(); } void WriteBytes(const void *data, size_t size) diff --git a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp index 41385ccb1cc..fb81f29b568 100644 --- a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp @@ -5,11 +5,11 @@ #include "ProgressUtils.h" CLocalProgress::CLocalProgress(): + SendRatio(true), + SendProgress(true), ProgressOffset(0), InSize(0), - OutSize(0), - SendRatio(true), - SendProgress(true) + OutSize(0) {} void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) @@ -20,7 +20,7 @@ void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) _inSizeIsMain = inSizeIsMain; } -STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { UInt64 inSize2 = InSize; UInt64 outSize2 = OutSize; @@ -32,7 +32,7 @@ STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *ou if (SendRatio && _ratioProgress) { - RINOK(_ratioProgress->SetRatioInfo(&inSize2, &outSize2)); + RINOK(_ratioProgress->SetRatioInfo(&inSize2, &outSize2)) } if (SendProgress) diff --git a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h index e94265ba715..dad5fccfa2c 100644 --- a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h +++ b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h @@ -1,35 +1,33 @@ // ProgressUtils.h -#ifndef __PROGRESS_UTILS_H -#define __PROGRESS_UTILS_H +#ifndef ZIP7_INC_PROGRESS_UTILS_H +#define ZIP7_INC_PROGRESS_UTILS_H #include "../../Common/MyCom.h" #include "../ICoder.h" #include "../IProgress.h" -class CLocalProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CLocalProgress + , ICompressProgressInfo +) +public: + bool SendRatio; + bool SendProgress; +private: + bool _inSizeIsMain; CMyComPtr<IProgress> _progress; CMyComPtr<ICompressProgressInfo> _ratioProgress; - bool _inSizeIsMain; public: UInt64 ProgressOffset; UInt64 InSize; UInt64 OutSize; - bool SendRatio; - bool SendProgress; CLocalProgress(); void Init(IProgress *progress, bool inSizeIsMain); HRESULT SetCur(); - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/PropId.cpp b/3rdparty/lzma/CPP/7zip/Common/PropId.cpp index 11d20d55753..6117b0e21b6 100644 --- a/3rdparty/lzma/CPP/7zip/Common/PropId.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/PropId.cpp @@ -104,5 +104,14 @@ const Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED] = VT_UI8, VT_BOOL, VT_BSTR, - VT_BSTR + VT_BSTR, + VT_BSTR, + VT_BOOL, + VT_FILETIME, // kpidChangeTime + VT_UI4, + VT_UI4, + VT_UI4, + VT_UI4, + VT_UI4, + VT_UI4 // kpidDevMinor }; diff --git a/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h b/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h index 3421ba1b164..55c1483f2e4 100644 --- a/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h +++ b/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h @@ -1,13 +1,13 @@ // RegisterArc.h -#ifndef __REGISTER_ARC_H -#define __REGISTER_ARC_H +#ifndef ZIP7_INC_REGISTER_ARC_H +#define ZIP7_INC_REGISTER_ARC_H #include "../Archive/IArchive.h" struct CArcInfo { - UInt16 Flags; + UInt32 Flags; Byte Id; Byte SignatureSize; UInt16 SignatureOffset; @@ -17,6 +17,8 @@ struct CArcInfo const char *Ext; const char *AddExt; + UInt32 TimeFlags; + Func_CreateInArchive CreateInArchive; Func_CreateOutArchive CreateOutArchive; Func_IsArc IsArc; @@ -32,29 +34,29 @@ void RegisterArc(const CArcInfo *arcInfo) throw(); #define IMP_CreateArcIn IMP_CreateArcIn_2(CHandler()) -#ifdef EXTRACT_ONLY +#ifdef Z7_EXTRACT_ONLY #define IMP_CreateArcOut #define CreateArcOut NULL #else #define IMP_CreateArcOut static IOutArchive *CreateArcOut() { return new CHandler(); } #endif -#define REGISTER_ARC_V(n, e, ae, id, sigSize, sig, offs, flags, crIn, crOut, isArc) \ - static const CArcInfo g_ArcInfo = { flags, id, sigSize, offs, sig, n, e, ae, crIn, crOut, isArc } ; \ +#define REGISTER_ARC_V(n, e, ae, id, sigSize, sig, offs, flags, tf, crIn, crOut, isArc) \ + static const CArcInfo g_ArcInfo = { flags, id, sigSize, offs, sig, n, e, ae, tf, crIn, crOut, isArc } ; \ -#define REGISTER_ARC_R(n, e, ae, id, sigSize, sig, offs, flags, crIn, crOut, isArc) \ - REGISTER_ARC_V(n, e, ae, id, sigSize, sig, offs, flags, crIn, crOut, isArc) \ +#define REGISTER_ARC_R(n, e, ae, id, sigSize, sig, offs, flags, tf, crIn, crOut, isArc) \ + REGISTER_ARC_V (n, e, ae, id, sigSize, sig, offs, flags, tf, crIn, crOut, isArc) \ struct CRegisterArc { CRegisterArc() { RegisterArc(&g_ArcInfo); }}; \ static CRegisterArc g_RegisterArc; #define REGISTER_ARC_I_CLS(cls, n, e, ae, id, sig, offs, flags, isArc) \ IMP_CreateArcIn_2(cls) \ - REGISTER_ARC_R(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, NULL, isArc) + REGISTER_ARC_R(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, 0, CreateArc, NULL, isArc) #define REGISTER_ARC_I_CLS_NO_SIG(cls, n, e, ae, id, offs, flags, isArc) \ IMP_CreateArcIn_2(cls) \ - REGISTER_ARC_R(n, e, ae, id, 0, NULL, offs, flags, CreateArc, NULL, isArc) + REGISTER_ARC_R(n, e, ae, id, 0, NULL, offs, flags, 0, CreateArc, NULL, isArc) #define REGISTER_ARC_I(n, e, ae, id, sig, offs, flags, isArc) \ REGISTER_ARC_I_CLS(CHandler(), n, e, ae, id, sig, offs, flags, isArc) @@ -63,15 +65,15 @@ void RegisterArc(const CArcInfo *arcInfo) throw(); REGISTER_ARC_I_CLS_NO_SIG(CHandler(), n, e, ae, id, offs, flags, isArc) -#define REGISTER_ARC_IO(n, e, ae, id, sig, offs, flags, isArc) \ +#define REGISTER_ARC_IO(n, e, ae, id, sig, offs, flags, tf, isArc) \ IMP_CreateArcIn \ IMP_CreateArcOut \ - REGISTER_ARC_R(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, CreateArcOut, isArc) + REGISTER_ARC_R(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, tf, CreateArc, CreateArcOut, isArc) -#define REGISTER_ARC_IO_DECREMENT_SIG(n, e, ae, id, sig, offs, flags, isArc) \ +#define REGISTER_ARC_IO_DECREMENT_SIG(n, e, ae, id, sig, offs, flags, tf, isArc) \ IMP_CreateArcIn \ IMP_CreateArcOut \ - REGISTER_ARC_V(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, CreateArcOut, isArc) \ + REGISTER_ARC_V(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, tf, CreateArc, CreateArcOut, isArc) \ struct CRegisterArcDecSig { CRegisterArcDecSig() { sig[0]--; RegisterArc(&g_ArcInfo); }}; \ static CRegisterArcDecSig g_RegisterArc; diff --git a/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h b/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h index 7ddb7604b9a..cf94998ac7d 100644 --- a/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h +++ b/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h @@ -1,7 +1,7 @@ // RegisterCodec.h -#ifndef __REGISTER_CODEC_H -#define __REGISTER_CODEC_H +#ifndef ZIP7_INC_REGISTER_CODEC_H +#define ZIP7_INC_REGISTER_CODEC_H #include "../Common/MethodId.h" @@ -26,29 +26,29 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw(); #define REGISTER_CODEC_CREATE(name, cls) REGISTER_CODEC_CREATE_2(name, cls, ICompressCoder) #define REGISTER_CODEC_NAME(x) CRegisterCodec ## x -#define REGISTER_CODEC_VAR static const CCodecInfo g_CodecInfo = +#define REGISTER_CODEC_VAR(x) static const CCodecInfo g_CodecInfo_ ## x = #define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \ - REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \ - static REGISTER_CODEC_NAME(x) g_RegisterCodec; + REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo_ ## x); }}; \ + static REGISTER_CODEC_NAME(x) g_RegisterCodec_ ## x; #define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x #define REGISTER_CODECS_VAR static const CCodecInfo g_CodecsInfo[] = #define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \ - REGISTER_CODECS_NAME(x)() { for (unsigned i = 0; i < ARRAY_SIZE(g_CodecsInfo); i++) \ + REGISTER_CODECS_NAME(x)() { for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_CodecsInfo); i++) \ RegisterCodec(&g_CodecsInfo[i]); }}; \ static REGISTER_CODECS_NAME(x) g_RegisterCodecs; #define REGISTER_CODEC_2(x, crDec, crEnc, id, name) \ - REGISTER_CODEC_VAR \ + REGISTER_CODEC_VAR(x) \ { crDec, crEnc, id, name, 1, false }; \ REGISTER_CODEC(x) -#ifdef EXTRACT_ONLY +#ifdef Z7_EXTRACT_ONLY #define REGISTER_CODEC_E(x, clsDec, clsEnc, id, name) \ REGISTER_CODEC_CREATE(CreateDec, clsDec) \ REGISTER_CODEC_2(x, CreateDec, NULL, id, name) @@ -67,19 +67,19 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw(); { crDec, crEnc, id, name, 1, true } #define REGISTER_FILTER(x, crDec, crEnc, id, name) \ - REGISTER_CODEC_VAR \ + REGISTER_CODEC_VAR(x) \ REGISTER_FILTER_ITEM(crDec, crEnc, id, name); \ REGISTER_CODEC(x) -#ifdef EXTRACT_ONLY +#ifdef Z7_EXTRACT_ONLY #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \ - REGISTER_FILTER_CREATE(CreateDec, clsDec) \ - REGISTER_FILTER(x, CreateDec, NULL, id, name) + REGISTER_FILTER_CREATE(x ## _CreateDec, clsDec) \ + REGISTER_FILTER(x, x ## _CreateDec, NULL, id, name) #else #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \ - REGISTER_FILTER_CREATE(CreateDec, clsDec) \ - REGISTER_FILTER_CREATE(CreateEnc, clsEnc) \ - REGISTER_FILTER(x, CreateDec, CreateEnc, id, name) + REGISTER_FILTER_CREATE(x ## _CreateDec, clsDec) \ + REGISTER_FILTER_CREATE(x ## _CreateEnc, clsEnc) \ + REGISTER_FILTER(x, x ## _CreateDec, x ## _CreateEnc, id, name) #endif @@ -97,7 +97,7 @@ void RegisterHasher(const CHasherInfo *hasher) throw(); #define REGISTER_HASHER_NAME(x) CRegHasher_ ## x #define REGISTER_HASHER(cls, id, name, size) \ - STDMETHODIMP_(UInt32) cls::GetDigestSize() throw() { return size; } \ + Z7_COM7F_IMF2(UInt32, cls::GetDigestSize()) { return size; } \ static IHasher *CreateHasherSpec() { return new cls(); } \ static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, size }; \ struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \ diff --git a/3rdparty/lzma/CPP/7zip/Common/StdAfx.h b/3rdparty/lzma/CPP/7zip/Common/StdAfx.h index 1cbd7feaeec..80866550d1f 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Common/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp index 435440c6649..38334af9638 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp @@ -6,50 +6,48 @@ #include "StreamBinder.h" -class CBinderInStream: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CBinderInStream + , ISequentialInStream +) CStreamBinder *_binder; public: - MY_UNKNOWN_IMP1(ISequentialInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - ~CBinderInStream() { _binder->CloseRead(); } + ~CBinderInStream() { _binder->CloseRead_CallOnce(); } CBinderInStream(CStreamBinder *binder): _binder(binder) {} }; -STDMETHODIMP CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { return _binder->Read(data, size, processedSize); } -class CBinderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CBinderOutStream + , ISequentialOutStream +) CStreamBinder *_binder; public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); ~CBinderOutStream() { _binder->CloseWrite(); } CBinderOutStream(CStreamBinder *binder): _binder(binder) {} }; -STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { return _binder->Write(data, size, processedSize); } - -WRes CStreamBinder::CreateEvents() +static HRESULT Event_Create_or_Reset(NWindows::NSynchronization::CAutoResetEvent &event) { - RINOK(_canWrite_Event.Create()); - RINOK(_canRead_Event.Create()); - return _readingWasClosed_Event.Create(); + const WRes wres = event.CreateIfNotCreated_Reset(); + return HRESULT_FROM_WIN32(wres); } -void CStreamBinder::ReInit() +HRESULT CStreamBinder::Create_ReInit() { - _canWrite_Event.Reset(); - _canRead_Event.Reset(); - _readingWasClosed_Event.Reset(); + RINOK(Event_Create_or_Reset(_canRead_Event)) + // RINOK(Event_Create_or_Reset(_canWrite_Event)) + + // _canWrite_Semaphore.Close(); + // we need at least 3 items of maxCount: 1 for normal unlock in Read(), 2 items for unlock in CloseRead_CallOnce() + _canWrite_Semaphore.OptCreateInit(0, 3); // _readingWasClosed = false; _readingWasClosed2 = false; @@ -59,27 +57,14 @@ void CStreamBinder::ReInit() _buf = NULL; ProcessedSize = 0; // WritingWasCut = false; + return S_OK; } -void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream) +void CStreamBinder::CreateStreams2(CMyComPtr<ISequentialInStream> &inStream, CMyComPtr<ISequentialOutStream> &outStream) { - // _readingWasClosed = false; - _readingWasClosed2 = false; - - _waitWrite = true; - _bufSize = 0; - _buf = NULL; - ProcessedSize = 0; - // WritingWasCut = false; - - CBinderInStream *inStreamSpec = new CBinderInStream(this); - CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); - *inStream = inStreamLoc.Detach(); - - CBinderOutStream *outStreamSpec = new CBinderOutStream(this); - CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec); - *outStream = outStreamLoc.Detach(); + inStream = new CBinderInStream(this); + outStream = new CBinderOutStream(this); } // (_canRead_Event && _bufSize == 0) means that stream is finished. @@ -92,7 +77,9 @@ HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) { if (_waitWrite) { - RINOK(_canRead_Event.Lock()); + WRes wres = _canRead_Event.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); _waitWrite = false; } if (size > _bufSize) @@ -105,17 +92,25 @@ HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) if (processedSize) *processedSize = size; _bufSize -= size; + + /* + if (_bufSize == 0), then we have read whole buffer + we have two ways here: + - if we check (_bufSize == 0) here, we unlock Write only after full data Reading - it reduces the number of syncs + - if we don't check (_bufSize == 0) here, we unlock Write after partial data Reading + */ if (_bufSize == 0) { _waitWrite = true; - _canRead_Event.Reset(); - _canWrite_Event.Set(); + // _canWrite_Event.Set(); + _canWrite_Semaphore.Release(); } } } return S_OK; } + HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) { if (processedSize) @@ -135,20 +130,20 @@ HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSiz _readingWasClosed2 = true; */ - HANDLE events[2] = { _canWrite_Event, _readingWasClosed_Event }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult >= WAIT_OBJECT_0 + 2) - return E_FAIL; + _canWrite_Semaphore.Lock(); + // _bufSize : is remain size that was not read size -= _bufSize; + + // size : is size of data that was read if (size != 0) { + // if some data was read, then we report that size and return if (processedSize) *processedSize = size; return S_OK; } - // if (waitResult == WAIT_OBJECT_0 + 1) - _readingWasClosed2 = true; + _readingWasClosed2 = true; } // WritingWasCut = true; diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h index 12088a94586..c0a70793c4b 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h +++ b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h @@ -1,52 +1,70 @@ // StreamBinder.h -#ifndef __STREAM_BINDER_H -#define __STREAM_BINDER_H +#ifndef ZIP7_INC_STREAM_BINDER_H +#define ZIP7_INC_STREAM_BINDER_H #include "../../Windows/Synchronization.h" #include "../IStream.h" /* -We don't use probably UNSAFE version: -reader thread: +We can use one from two code versions here: with Event or with Semaphore to unlock Writer thread +The difference for cases where Reading must be closed before Writing closing + +1) Event Version: _canWrite_Event + We call _canWrite_Event.Set() without waiting _canRead_Event in CloseRead() function. + The writer thread can get (_readingWasClosed) status in one from two iterations. + It's ambiguity of processing flow. But probably it's SAFE to use, if Event functions provide memory barriers. + reader thread: _canWrite_Event.Set(); - _readingWasClosed = true + _readingWasClosed = true; _canWrite_Event.Set(); -writer thread: + writer thread: _canWrite_Event.Wait() if (_readingWasClosed) -Can second call of _canWrite_Event.Set() be executed without memory barrier, if event is already set? + +2) Semaphore Version: _canWrite_Semaphore + writer thread always will detect closing of reading in latest iteration after all data processing iterations */ class CStreamBinder { - NWindows::NSynchronization::CAutoResetEvent _canWrite_Event; - NWindows::NSynchronization::CManualResetEvent _canRead_Event; - NWindows::NSynchronization::CManualResetEvent _readingWasClosed_Event; + NWindows::NSynchronization::CAutoResetEvent _canRead_Event; + // NWindows::NSynchronization::CAutoResetEvent _canWrite_Event; + NWindows::NSynchronization::CSemaphore _canWrite_Semaphore; - // bool _readingWasClosed; - bool _readingWasClosed2; + // bool _readingWasClosed; // set it in reader thread and check it in write thread + bool _readingWasClosed2; // use it in writer thread // bool WritingWasCut; - bool _waitWrite; + bool _waitWrite; // use it in reader thread UInt32 _bufSize; const void *_buf; public: - UInt64 ProcessedSize; + UInt64 ProcessedSize; // the size that was read by reader thread - WRes CreateEvents(); - void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream); + void CreateStreams2(CMyComPtr<ISequentialInStream> &inStream, CMyComPtr<ISequentialOutStream> &outStream); - void ReInit(); + HRESULT Create_ReInit(); HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize); - void CloseRead() + void CloseRead_CallOnce() { - _readingWasClosed_Event.Set(); - // _readingWasClosed = true; - // _canWrite_Event.Set(); + // call it only once: for example, in destructor + + /* + _readingWasClosed = true; + _canWrite_Event.Set(); + */ + + /* + We must relase Semaphore only once !!! + we must release at least 2 items of Semaphore: + one item to unlock partial Write(), if Read() have read some items + then additional item to stop writing (_bufSize will be 0) + */ + _canWrite_Semaphore.Release(2); } void CloseWrite() diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp index 8136716d66f..b54f4237359 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp @@ -2,13 +2,11 @@ #include "StdAfx.h" -#include <stdlib.h> - #include "../../../C/Alloc.h" #include "StreamObjects.h" -STDMETHODIMP CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -26,7 +24,7 @@ STDMETHODIMP CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSiz return S_OK; } -STDMETHODIMP CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -37,13 +35,13 @@ STDMETHODIMP CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newP } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; + _pos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } -STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -61,7 +59,7 @@ STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize) return S_OK; } -STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -72,9 +70,9 @@ STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosi } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; + _pos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } @@ -99,8 +97,8 @@ void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequential void CByteDynBuffer::Free() throw() { - free(_buf); - _buf = 0; + MyFree(_buf); + _buf = NULL; _capacity = 0; } @@ -108,15 +106,10 @@ bool CByteDynBuffer::EnsureCapacity(size_t cap) throw() { if (cap <= _capacity) return true; - size_t delta; - if (_capacity > 64) - delta = _capacity / 4; - else if (_capacity > 8) - delta = 16; - else - delta = 4; - cap = MyMax(_capacity + delta, cap); - Byte *buf = (Byte *)realloc(_buf, cap); + const size_t cap2 = _capacity + _capacity / 4; + if (cap < cap2) + cap = cap2; + Byte *buf = (Byte *)MyRealloc(_buf, cap); if (!buf) return false; _buf = buf; @@ -139,7 +132,7 @@ void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const dest.CopyFrom((const Byte *)_buffer, _size); } -STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -155,7 +148,7 @@ STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *p return S_OK; } -STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { size_t rem = _size - _pos; if (rem > size) @@ -170,7 +163,7 @@ STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *p return (rem != 0 || size == 0) ? S_OK : E_FAIL; } -STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize; HRESULT result = _stream->Write(data, size, &realProcessedSize); @@ -185,9 +178,9 @@ static const UInt64 kEmptyTag = (UInt64)(Int64)-1; void CCachedInStream::Free() throw() { MyFree(_tags); - _tags = 0; + _tags = NULL; MidFree(_data); - _data = 0; + _data = NULL; } bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw() @@ -196,19 +189,19 @@ bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw( if (sizeLog >= sizeof(size_t) * 8) return false; size_t dataSize = (size_t)1 << sizeLog; - if (_data == 0 || dataSize != _dataSize) + if (!_data || dataSize != _dataSize) { MidFree(_data); _data = (Byte *)MidAlloc(dataSize); - if (_data == 0) + if (!_data) return false; _dataSize = dataSize; } - if (_tags == 0 || numBlocksLog != _numBlocksLog) + if (!_tags || numBlocksLog != _numBlocksLog) { MyFree(_tags); _tags = (UInt64 *)MyAlloc(sizeof(UInt64) << numBlocksLog); - if (_tags == 0) + if (!_tags) return false; _numBlocksLog = numBlocksLog; } @@ -220,12 +213,12 @@ void CCachedInStream::Init(UInt64 size) throw() { _size = size; _pos = 0; - size_t numBlocks = (size_t)1 << _numBlocksLog; + const size_t numBlocks = (size_t)1 << _numBlocksLog; for (size_t i = 0; i < numBlocks; i++) _tags[i] = kEmptyTag; } -STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -235,28 +228,39 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz return S_OK; { - UInt64 rem = _size - _pos; + const UInt64 rem = _size - _pos; if (size > rem) size = (UInt32)rem; } while (size != 0) { - UInt64 cacheTag = _pos >> _blockSizeLog; - size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1); + const UInt64 cacheTag = _pos >> _blockSizeLog; + const size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1); Byte *p = _data + (cacheIndex << _blockSizeLog); + if (_tags[cacheIndex] != cacheTag) { - UInt64 remInBlock = _size - (cacheTag << _blockSizeLog); + _tags[cacheIndex] = kEmptyTag; + const UInt64 remInBlock = _size - (cacheTag << _blockSizeLog); size_t blockSize = (size_t)1 << _blockSizeLog; if (blockSize > remInBlock) blockSize = (size_t)remInBlock; - RINOK(ReadBlock(cacheTag, p, blockSize)); + + RINOK(ReadBlock(cacheTag, p, blockSize)) + _tags[cacheIndex] = cacheTag; } - size_t offset = (size_t)_pos & (((size_t)1 << _blockSizeLog) - 1); - UInt32 cur = (UInt32)MyMin(((size_t)1 << _blockSizeLog) - offset, (size_t)size); + + const size_t kBlockSize = (size_t)1 << _blockSizeLog; + const size_t offset = (size_t)_pos & (kBlockSize - 1); + UInt32 cur = size; + const size_t rem = kBlockSize - offset; + if (cur > rem) + cur = (UInt32)rem; + memcpy(data, p + offset, cur); + if (processedSize) *processedSize += cur; data = (void *)((const Byte *)data + cur); @@ -266,8 +270,9 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz return S_OK; } + -STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -278,8 +283,8 @@ STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newP } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; + _pos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h index e20e9bd80de..2c0ebea9d62 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h +++ b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h @@ -1,7 +1,7 @@ // StreamObjects.h -#ifndef __STREAM_OBJECTS_H -#define __STREAM_OBJECTS_H +#ifndef ZIP7_INC_STREAM_OBJECTS_H +#define ZIP7_INC_STREAM_OBJECTS_H #include "../../Common/MyBuffer.h" #include "../../Common/MyCom.h" @@ -9,39 +9,33 @@ #include "../IStream.h" -class CBufferInStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream( + CBufferInStream +) UInt64 _pos; public: CByteBuffer Buf; void Init() { _pos = 0; } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; -struct CReferenceBuf: - public IUnknown, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_0( + CReferenceBuf +) +public: CByteBuffer Buf; - MY_UNKNOWN_IMP }; -class CBufInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CBufInStream +) const Byte *_data; UInt64 _pos; size_t _size; CMyComPtr<IUnknown> _ref; public: - void Init(const Byte *data, size_t size, IUnknown *ref = 0) + void Init(const Byte *data, size_t size, IUnknown *ref = NULL) { _data = data; _size = size; @@ -50,22 +44,24 @@ public: } void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.Size(), ref); } - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + // Seek() is allowed here. So reading order could be changed + bool WasFinished() const { return _pos == _size; } }; + void Create_BufInStream_WithReference(const void *data, size_t size, IUnknown *ref, ISequentialInStream **stream); void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequentialInStream **stream); inline void Create_BufInStream_WithNewBuffer(const CByteBuffer &buf, ISequentialInStream **stream) { Create_BufInStream_WithNewBuffer(buf, buf.Size(), stream); } -class CByteDynBuffer + +class CByteDynBuffer Z7_final { size_t _capacity; Byte *_buf; + Z7_CLASS_NO_COPY(CByteDynBuffer) public: - CByteDynBuffer(): _capacity(0), _buf(0) {}; + CByteDynBuffer(): _capacity(0), _buf(NULL) {} // there is no copy constructor. So don't copy this object. ~CByteDynBuffer() { Free(); } void Free() throw(); @@ -75,10 +71,11 @@ public: bool EnsureCapacity(size_t capacity) throw(); }; -class CDynBufSeqOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CDynBufSeqOutStream + , ISequentialOutStream +) CByteDynBuffer _buffer; size_t _size; public: @@ -89,15 +86,13 @@ public: void CopyToBuffer(CByteBuffer &dest) const; Byte *GetBufPtrForWriting(size_t addSize); void UpdateSize(size_t addSize) { _size += addSize; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -class CBufPtrSeqOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CBufPtrSeqOutStream + , ISequentialOutStream +) Byte *_buffer; size_t _size; size_t _pos; @@ -109,30 +104,28 @@ public: _size = size; } size_t GetPos() const { return _pos; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -class CSequentialOutStreamSizeCount: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CSequentialOutStreamSizeCount + , ISequentialOutStream +) CMyComPtr<ISequentialOutStream> _stream; UInt64 _size; public: void SetStream(ISequentialOutStream *stream) { _stream = stream; } void Init() { _size = 0; } UInt64 GetSize() const { return _size; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; + class CCachedInStream: public IInStream, public CMyUnknownImp { + Z7_IFACES_IMP_UNK_2(ISequentialInStream, IInStream) + UInt64 *_tags; Byte *_data; size_t _dataSize; @@ -143,15 +136,11 @@ class CCachedInStream: protected: virtual HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) = 0; public: - CCachedInStream(): _tags(0), _data(0) {} - virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!! + CCachedInStream(): _tags(NULL), _data(NULL) {} + virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (Release() calls it) !!! void Free() throw(); bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw(); void Init(UInt64 size) throw(); - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp index 1402f420599..24eed36c5bf 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp @@ -2,10 +2,55 @@ #include "StdAfx.h" +#include "../../Common/MyCom.h" + #include "StreamUtils.h" static const UInt32 kBlockSize = ((UInt32)1 << 31); + +HRESULT InStream_SeekToBegin(IInStream *stream) throw() +{ + return InStream_SeekSet(stream, 0); +} + + +HRESULT InStream_AtBegin_GetSize(IInStream *stream, UInt64 &sizeRes) throw() +{ +#ifdef _WIN32 + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, stream) + if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK) + return S_OK; + } +#endif + const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes); + const HRESULT hres2 = InStream_SeekToBegin(stream); + return hres != S_OK ? hres : hres2; +} + + +HRESULT InStream_GetPos_GetSize(IInStream *stream, UInt64 &curPosRes, UInt64 &sizeRes) throw() +{ + RINOK(InStream_GetPos(stream, curPosRes)) +#ifdef _WIN32 + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, stream) + if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK) + return S_OK; + } +#endif + const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes); + const HRESULT hres2 = InStream_SeekSet(stream, curPosRes); + return hres != S_OK ? hres : hres2; +} + + + HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw() { size_t size = *processedSize; @@ -18,7 +63,7 @@ HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSiz *processedSize += processedSizeLoc; data = (void *)((Byte *)data + processedSizeLoc); size -= processedSizeLoc; - RINOK(res); + RINOK(res) if (processedSizeLoc == 0) return S_OK; } @@ -28,14 +73,14 @@ HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSiz HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw() { size_t processedSize = size; - RINOK(ReadStream(stream, data, &processedSize)); + RINOK(ReadStream(stream, data, &processedSize)) return (size == processedSize) ? S_OK : S_FALSE; } HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw() { size_t processedSize = size; - RINOK(ReadStream(stream, data, &processedSize)); + RINOK(ReadStream(stream, data, &processedSize)) return (size == processedSize) ? S_OK : E_FAIL; } @@ -48,7 +93,7 @@ HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) HRESULT res = stream->Write(data, curSize, &processedSizeLoc); data = (const void *)((const Byte *)data + processedSizeLoc); size -= processedSizeLoc; - RINOK(res); + RINOK(res) if (processedSizeLoc == 0) return E_FAIL; } diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h index ae914c004b0..35a62ed3e95 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h +++ b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h @@ -1,10 +1,28 @@ // StreamUtils.h -#ifndef __STREAM_UTILS_H -#define __STREAM_UTILS_H +#ifndef ZIP7_INC_STREAM_UTILS_H +#define ZIP7_INC_STREAM_UTILS_H #include "../IStream.h" +inline HRESULT InStream_SeekSet(IInStream *stream, UInt64 offset) throw() + { return stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL); } +inline HRESULT InStream_GetPos(IInStream *stream, UInt64 &curPosRes) throw() + { return stream->Seek(0, STREAM_SEEK_CUR, &curPosRes); } +inline HRESULT InStream_GetSize_SeekToEnd(IInStream *stream, UInt64 &sizeRes) throw() + { return stream->Seek(0, STREAM_SEEK_END, &sizeRes); } + +HRESULT InStream_SeekToBegin(IInStream *stream) throw(); +HRESULT InStream_AtBegin_GetSize(IInStream *stream, UInt64 &size) throw(); +HRESULT InStream_GetPos_GetSize(IInStream *stream, UInt64 &curPosRes, UInt64 &sizeRes) throw(); + +inline HRESULT InStream_GetSize_SeekToBegin(IInStream *stream, UInt64 &sizeRes) throw() +{ + RINOK(InStream_SeekToBegin(stream)) + return InStream_AtBegin_GetSize(stream, sizeRes); +} + + HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size) throw(); HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw(); HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw(); diff --git a/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp index 8f754e177e8..32dc27626ed 100644 --- a/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp @@ -11,10 +11,10 @@ unsigned CUniqBlocks::AddUniq(const Byte *data, size_t size) unsigned left = 0, right = Sorted.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - unsigned index = Sorted[mid]; + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned index = Sorted[mid]; const CByteBuffer &buf = Bufs[index]; - size_t sizeMid = buf.Size(); + const size_t sizeMid = buf.Size(); if (size < sizeMid) right = mid; else if (size > sizeMid) @@ -23,7 +23,7 @@ unsigned CUniqBlocks::AddUniq(const Byte *data, size_t size) { if (size == 0) return index; - int cmp = memcmp(data, buf, size); + const int cmp = memcmp(data, buf, size); if (cmp == 0) return index; if (cmp < 0) diff --git a/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h index a376024e3df..66c7fa21b8a 100644 --- a/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h +++ b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h @@ -1,11 +1,26 @@ // UniqBlocks.h -#ifndef __UNIQ_BLOCKS_H -#define __UNIQ_BLOCKS_H +#ifndef ZIP7_INC_UNIQ_BLOCKS_H +#define ZIP7_INC_UNIQ_BLOCKS_H -#include "../../Common/MyTypes.h" #include "../../Common/MyBuffer.h" -#include "../../Common/MyVector.h" +#include "../../Common/MyString.h" + +struct C_UInt32_UString_Map +{ + CRecordVector<UInt32> Numbers; + UStringVector Strings; + + void Add_UInt32(const UInt32 n) + { + Numbers.AddToUniqueSorted(n); + } + int Find(const UInt32 n) + { + return Numbers.FindInSorted(n); + } +}; + struct CUniqBlocks { @@ -19,7 +34,7 @@ struct CUniqBlocks bool IsOnlyEmpty() const { - return (Bufs.Size() == 0 || Bufs.Size() == 1 && Bufs[0].Size() == 0); + return (Bufs.Size() == 0 || (Bufs.Size() == 1 && Bufs[0].Size() == 0)); } }; diff --git a/3rdparty/lzma/CPP/7zip/Common/VirtThread.cpp b/3rdparty/lzma/CPP/7zip/Common/VirtThread.cpp index 77e3c1acfd8..3cf7296c26a 100644 --- a/3rdparty/lzma/CPP/7zip/Common/VirtThread.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/VirtThread.cpp @@ -11,7 +11,7 @@ static THREAD_FUNC_DECL CoderThread(void *p) CVirtThread *t = (CVirtThread *)p; t->StartEvent.Lock(); if (t->Exit) - return 0; + return THREAD_FUNC_RET_ZERO; t->Execute(); t->FinishedEvent.Set(); } @@ -19,20 +19,20 @@ static THREAD_FUNC_DECL CoderThread(void *p) WRes CVirtThread::Create() { - RINOK(StartEvent.CreateIfNotCreated()); - RINOK(FinishedEvent.CreateIfNotCreated()); - StartEvent.Reset(); - FinishedEvent.Reset(); + RINOK_WRes(StartEvent.CreateIfNotCreated_Reset()) + RINOK_WRes(FinishedEvent.CreateIfNotCreated_Reset()) + // StartEvent.Reset(); + // FinishedEvent.Reset(); Exit = false; if (Thread.IsCreated()) return S_OK; return Thread.Create(CoderThread, this); } -void CVirtThread::Start() +WRes CVirtThread::Start() { Exit = false; - StartEvent.Set(); + return StartEvent.Set(); } void CVirtThread::WaitThreadFinish() @@ -42,7 +42,6 @@ void CVirtThread::WaitThreadFinish() StartEvent.Set(); if (Thread.IsCreated()) { - Thread.Wait(); - Thread.Close(); + Thread.Wait_Close(); } } diff --git a/3rdparty/lzma/CPP/7zip/Common/VirtThread.h b/3rdparty/lzma/CPP/7zip/Common/VirtThread.h index ebee158ca5b..809b3568985 100644 --- a/3rdparty/lzma/CPP/7zip/Common/VirtThread.h +++ b/3rdparty/lzma/CPP/7zip/Common/VirtThread.h @@ -1,7 +1,7 @@ // VirtThread.h -#ifndef __VIRT_THREAD_H -#define __VIRT_THREAD_H +#ifndef ZIP7_INC_VIRT_THREAD_H +#define ZIP7_INC_VIRT_THREAD_H #include "../../Windows/Synchronization.h" #include "../../Windows/Thread.h" @@ -13,12 +13,12 @@ struct CVirtThread NWindows::CThread Thread; bool Exit; - ~CVirtThread() { WaitThreadFinish(); } + virtual ~CVirtThread() { WaitThreadFinish(); } void WaitThreadFinish(); // call it in destructor of child class ! WRes Create(); - void Start(); + WRes Start(); virtual void Execute() = 0; - void WaitExecuteFinish() { FinishedEvent.Lock(); } + WRes WaitExecuteFinish() { return FinishedEvent.Lock(); } }; #endif |