summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/unix/CPP/7zip/Common
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/unix/CPP/7zip/Common')
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/CWrappers.cpp44
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/CWrappers.h37
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/Common.pri39
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp218
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.h41
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp28
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h10
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FileStreams.cpp318
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FileStreams.h80
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.cpp24
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.h22
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/InBuffer.cpp122
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/InBuffer.h101
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp15
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h4
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp255
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.h142
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/MethodId.cpp27
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/MethodId.h2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/MethodProps.cpp484
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/MethodProps.h178
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.cpp35
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.h25
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.cpp57
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.h37
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/PropId.cpp99
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h67
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h48
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.cpp153
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.h43
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.cpp75
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.h31
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.cpp8
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.h12
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.cpp56
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.h30
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/VirtThread.cpp14
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/VirtThread.h11
39 files changed, 2207 insertions, 787 deletions
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.cpp b/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.cpp
index 358f0b503..a15794e2a 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.cpp
@@ -12,14 +12,14 @@
#define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x)
-static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize)
+static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw()
{
CCompressProgressWrap *p = (CCompressProgressWrap *)pp;
p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize));
return (SRes)p->Res;
}
-CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress)
+CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw()
{
p.Progress = CompressProgress;
Progress = progress;
@@ -30,29 +30,31 @@ static const UInt32 kStreamStepSize = (UInt32)1 << 31;
SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes)
{
- switch(res)
+ 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)
+static SRes MyRead(void *object, void *data, size_t *size) throw()
{
CSeqInStreamWrap *p = (CSeqInStreamWrap *)object;
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
p->Res = (p->Stream->Read(data, curSize, &curSize));
*size = curSize;
+ p->Processed += curSize;
if (p->Res == S_OK)
return SZ_OK;
return HRESULT_To_SRes(p->Res, SZ_ERROR_READ);
}
-static size_t MyWrite(void *object, const void *data, size_t size)
+static size_t MyWrite(void *object, const void *data, size_t size) throw()
{
CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object;
if (p->Stream)
@@ -67,13 +69,14 @@ static size_t MyWrite(void *object, const void *data, size_t size)
return size;
}
-CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream)
+CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw()
{
p.Read = MyRead;
Stream = stream;
+ Processed = 0;
}
-CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream)
+CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw()
{
p.Write = MyWrite;
Stream = stream;
@@ -81,7 +84,7 @@ CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream)
Processed = 0;
}
-HRESULT SResToHRESULT(SRes res)
+HRESULT SResToHRESULT(SRes res) throw()
{
switch(res)
{
@@ -90,11 +93,12 @@ HRESULT SResToHRESULT(SRes res)
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)
+static SRes InStreamWrap_Read(void *pp, void *data, size_t *size) throw()
{
CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
@@ -103,7 +107,7 @@ static SRes InStreamWrap_Read(void *pp, void *data, size_t *size)
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
}
-static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin)
+static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw()
{
CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
UInt32 moveMethod;
@@ -120,7 +124,7 @@ static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin)
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
}
-CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream)
+CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw()
{
Stream = stream;
p.Read = InStreamWrap_Read;
@@ -131,13 +135,13 @@ CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream)
/* ---------- CByteInBufWrap ---------- */
-void CByteInBufWrap::Free()
+void CByteInBufWrap::Free() throw()
{
::MidFree(Buf);
Buf = 0;
}
-bool CByteInBufWrap::Alloc(UInt32 size)
+bool CByteInBufWrap::Alloc(UInt32 size) throw()
{
if (Buf == 0 || size != Size)
{
@@ -148,7 +152,7 @@ bool CByteInBufWrap::Alloc(UInt32 size)
return (Buf != 0);
}
-Byte CByteInBufWrap::ReadByteFromNewBlock()
+Byte CByteInBufWrap::ReadByteFromNewBlock() throw()
{
if (Res == S_OK)
{
@@ -164,7 +168,7 @@ Byte CByteInBufWrap::ReadByteFromNewBlock()
return 0;
}
-static Byte Wrap_ReadByte(void *pp)
+static Byte Wrap_ReadByte(void *pp) throw()
{
CByteInBufWrap *p = (CByteInBufWrap *)pp;
if (p->Cur != p->Lim)
@@ -180,13 +184,13 @@ CByteInBufWrap::CByteInBufWrap(): Buf(0)
/* ---------- CByteOutBufWrap ---------- */
-void CByteOutBufWrap::Free()
+void CByteOutBufWrap::Free() throw()
{
::MidFree(Buf);
Buf = 0;
}
-bool CByteOutBufWrap::Alloc(size_t size)
+bool CByteOutBufWrap::Alloc(size_t size) throw()
{
if (Buf == 0 || size != Size)
{
@@ -197,7 +201,7 @@ bool CByteOutBufWrap::Alloc(size_t size)
return (Buf != 0);
}
-HRESULT CByteOutBufWrap::Flush()
+HRESULT CByteOutBufWrap::Flush() throw()
{
if (Res == S_OK)
{
@@ -210,7 +214,7 @@ HRESULT CByteOutBufWrap::Flush()
return Res;
}
-static void Wrap_WriteByte(void *pp, Byte b)
+static void Wrap_WriteByte(void *pp, Byte b) throw()
{
CByteOutBufWrap *p = (CByteOutBufWrap *)pp;
Byte *dest = p->Cur;
@@ -220,7 +224,7 @@ static void Wrap_WriteByte(void *pp, Byte b)
p->Flush();
}
-CByteOutBufWrap::CByteOutBufWrap(): Buf(0)
+CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0)
{
p.Write = Wrap_WriteByte;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.h b/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.h
index 80a8a1b61..4fe7dea3e 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.h
@@ -11,7 +11,8 @@ struct CCompressProgressWrap
ICompressProgress p;
ICompressProgressInfo *Progress;
HRESULT Res;
- CCompressProgressWrap(ICompressProgressInfo *progress);
+
+ CCompressProgressWrap(ICompressProgressInfo *progress) throw();
};
struct CSeqInStreamWrap
@@ -19,7 +20,9 @@ struct CSeqInStreamWrap
ISeqInStream p;
ISequentialInStream *Stream;
HRESULT Res;
- CSeqInStreamWrap(ISequentialInStream *stream);
+ UInt64 Processed;
+
+ CSeqInStreamWrap(ISequentialInStream *stream) throw();
};
struct CSeekInStreamWrap
@@ -27,7 +30,8 @@ struct CSeekInStreamWrap
ISeekInStream p;
IInStream *Stream;
HRESULT Res;
- CSeekInStreamWrap(IInStream *stream);
+
+ CSeekInStreamWrap(IInStream *stream) throw();
};
struct CSeqOutStreamWrap
@@ -36,10 +40,11 @@ struct CSeqOutStreamWrap
ISequentialOutStream *Stream;
HRESULT Res;
UInt64 Processed;
- CSeqOutStreamWrap(ISequentialOutStream *stream);
+
+ CSeqOutStreamWrap(ISequentialOutStream *stream) throw();
};
-HRESULT SResToHRESULT(SRes res);
+HRESULT SResToHRESULT(SRes res) throw();
struct CByteInBufWrap
{
@@ -52,11 +57,11 @@ struct CByteInBufWrap
UInt64 Processed;
bool Extra;
HRESULT Res;
-
+
CByteInBufWrap();
- ~CByteInBufWrap() { Free(); }
- void Free();
- bool Alloc(UInt32 size);
+ ~CByteInBufWrap() { Free(); }
+ void Free() throw();
+ bool Alloc(UInt32 size) throw();
void Init()
{
Lim = Cur = Buf;
@@ -65,7 +70,7 @@ struct CByteInBufWrap
Res = S_OK;
}
UInt64 GetProcessed() const { return Processed + (Cur - Buf); }
- Byte ReadByteFromNewBlock();
+ Byte ReadByteFromNewBlock() throw();
Byte ReadByte()
{
if (Cur != Lim)
@@ -84,11 +89,11 @@ struct CByteOutBufWrap
ISequentialOutStream *Stream;
UInt64 Processed;
HRESULT Res;
-
- CByteOutBufWrap();
- ~CByteOutBufWrap() { Free(); }
- void Free();
- bool Alloc(size_t size);
+
+ CByteOutBufWrap() throw();
+ ~CByteOutBufWrap() { Free(); }
+ void Free() throw();
+ bool Alloc(size_t size) throw();
void Init()
{
Cur = Buf;
@@ -97,7 +102,7 @@ struct CByteOutBufWrap
Res = S_OK;
}
UInt64 GetProcessed() const { return Processed + (Cur - Buf); }
- HRESULT Flush();
+ HRESULT Flush() throw();
void WriteByte(Byte b)
{
*Cur++ = b;
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/Common.pri b/src/libs/7zip/unix/CPP/7zip/Common/Common.pri
new file mode 100644
index 000000000..a23ad30b1
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Common/Common.pri
@@ -0,0 +1,39 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/Common/CWrappers.h \
+ $$7ZIP_BASE/CPP/7zip/Common/CreateCoder.h \
+ $$7ZIP_BASE/CPP/7zip/Common/FilePathAutoRename.h \
+ $$7ZIP_BASE/CPP/7zip/Common/FileStreams.h \
+ $$7ZIP_BASE/CPP/7zip/Common/FilterCoder.h \
+ $$7ZIP_BASE/CPP/7zip/Common/InBuffer.h \
+ $$7ZIP_BASE/CPP/7zip/Common/InOutTempBuffer.h \
+ $$7ZIP_BASE/CPP/7zip/Common/LimitedStreams.h \
+ $$7ZIP_BASE/CPP/7zip/Common/LockedStream.h \
+ $$7ZIP_BASE/CPP/7zip/Common/MethodId.h \
+ $$7ZIP_BASE/CPP/7zip/Common/MethodProps.h \
+ $$7ZIP_BASE/CPP/7zip/Common/OutBuffer.h \
+ $$7ZIP_BASE/CPP/7zip/Common/ProgressUtils.h \
+ $$7ZIP_BASE/CPP/7zip/Common/RegisterArc.h \
+ $$7ZIP_BASE/CPP/7zip/Common/RegisterCodec.h \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamBinder.h \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamObjects.h \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamUtils.h \
+ $$7ZIP_BASE/CPP/7zip/Common/UniqBlocks.h \
+ $$7ZIP_BASE/CPP/7zip/Common/VirtThread.h
+
+SOURCES += $$7ZIP_BASE/CPP/7zip/Common/CWrappers.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/CreateCoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/FilePathAutoRename.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/FileStreams.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/FilterCoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/InBuffer.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/InOutTempBuffer.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/LimitedStreams.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/LockedStream.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/MethodProps.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/OutBuffer.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/ProgressUtils.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/PropId.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamBinder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamObjects.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamUtils.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/UniqBlocks.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/VirtThread.cpp
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp b/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp
index cc82a0db5..01ccbe12a 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp
@@ -13,12 +13,21 @@
static const unsigned int kNumCodecsMax = 64;
unsigned int g_NumCodecs = 0;
const CCodecInfo *g_Codecs[kNumCodecsMax];
-void RegisterCodec(const CCodecInfo *codecInfo)
+void RegisterCodec(const CCodecInfo *codecInfo) throw()
{
if (g_NumCodecs < kNumCodecsMax)
g_Codecs[g_NumCodecs++] = codecInfo;
}
+static const unsigned int kNumHashersMax = 16;
+unsigned int g_NumHashers = 0;
+const CHasherInfo *g_Hashers[kNumHashersMax];
+void RegisterHasher(const CHasherInfo *hashInfo) throw()
+{
+ if (g_NumHashers < kNumHashersMax)
+ g_Hashers[g_NumHashers++] = hashInfo;
+}
+
#ifdef EXTERNAL_CODECS
static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res)
{
@@ -46,56 +55,74 @@ static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index,
return S_OK;
}
-HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)
+HRESULT CExternalCodecs::LoadCodecs()
{
- UInt32 num;
- RINOK(codecsInfo->GetNumberOfMethods(&num));
- for (UInt32 i = 0; i < num; i++)
+ if (GetCodecs)
{
- CCodecInfoEx info;
- NWindows::NCOM::CPropVariant prop;
- RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));
- // if (prop.vt != VT_BSTR)
- // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
- // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);
- if (prop.vt != VT_UI8)
+ UInt32 num;
+ RINOK(GetCodecs->GetNumberOfMethods(&num));
+ for (UInt32 i = 0; i < num; i++)
{
- continue; // old Interface
- // return E_INVALIDARG;
+ CCodecInfoEx info;
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop));
+ // if (prop.vt != VT_BSTR)
+ // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
+ // memcpy(info.Id.ID, prop.bstrVal, info.Id.IDSize);
+ if (prop.vt != VT_UI8)
+ continue; // old Interface
+ info.Id = prop.uhVal.QuadPart;
+ prop.Clear();
+
+ RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop));
+ if (prop.vt == VT_BSTR)
+ info.Name = prop.bstrVal;
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+
+ RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kInStreams, info.NumInStreams));
+ RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kOutStreams, info.NumOutStreams));
+ RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
+ RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
+
+ Codecs.Add(info);
+ }
+ }
+ if (GetHashers)
+ {
+ UInt32 num = GetHashers->GetNumHashers();
+ for (UInt32 i = 0; i < num; i++)
+ {
+ CHasherInfoEx info;
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop));
+ if (prop.vt != VT_UI8)
+ continue;
+ info.Id = prop.uhVal.QuadPart;
+ prop.Clear();
+
+ RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop));
+ if (prop.vt == VT_BSTR)
+ info.Name = prop.bstrVal;
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+
+ Hashers.Add(info);
}
- info.Id = prop.uhVal.QuadPart;
- prop.Clear();
-
- RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));
- if (prop.vt == VT_BSTR)
- info.Name = prop.bstrVal;
- else if (prop.vt != VT_EMPTY)
- return E_INVALIDARG;;
-
- RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));
- RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));
- RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
- RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
-
- externalCodecs.Add(info);
}
return S_OK;
}
#endif
-bool FindMethod(
- #ifdef EXTERNAL_CODECS
- ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
- #endif
- const UString &name,
- CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
+bool FindMethod(DECL_EXTERNAL_CODECS_LOC_VARS
+ const UString &name, CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
{
UInt32 i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
- if (name.CompareNoCase(codec.Name) == 0)
+ if (name.IsEqualToNoCase(codec.Name))
{
methodId = codec.Id;
numInStreams = codec.NumInStreams;
@@ -104,11 +131,11 @@ bool FindMethod(
}
}
#ifdef EXTERNAL_CODECS
- if (externalCodecs)
- for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ if (__externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++)
{
- const CCodecInfoEx &codec = (*externalCodecs)[i];
- if (codec.Name.CompareNoCase(name) == 0)
+ const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
+ if (codec.Name.IsEqualToNoCase(name))
{
methodId = codec.Id;
numInStreams = codec.NumInStreams;
@@ -120,11 +147,8 @@ bool FindMethod(
return false;
}
-bool FindMethod(
- #ifdef EXTERNAL_CODECS
- ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
- #endif
- CMethodId methodId, UString &name)
+bool FindMethod(DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, UString &name)
{
UInt32 i;
for (i = 0; i < g_NumCodecs; i++)
@@ -137,10 +161,10 @@ bool FindMethod(
}
}
#ifdef EXTERNAL_CODECS
- if (externalCodecs)
- for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ if (__externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++)
{
- const CCodecInfoEx &codec = (*externalCodecs)[i];
+ const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
if (methodId == codec.Id)
{
name = codec.Name;
@@ -151,6 +175,49 @@ bool FindMethod(
return false;
}
+bool FindHashMethod(DECL_EXTERNAL_CODECS_LOC_VARS
+ const UString &name,
+ CMethodId &methodId)
+{
+ UInt32 i;
+ for (i = 0; i < g_NumHashers; i++)
+ {
+ const CHasherInfo &codec = *g_Hashers[i];
+ if (name.IsEqualToNoCase(codec.Name))
+ {
+ methodId = codec.Id;
+ return true;
+ }
+ }
+ #ifdef EXTERNAL_CODECS
+ if (__externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Hashers.Size(); i++)
+ {
+ const CHasherInfoEx &codec = __externalCodecs->Hashers[i];
+ if (codec.Name.IsEqualToNoCase(name))
+ {
+ methodId = codec.Id;
+ return true;
+ }
+ }
+ #endif
+ return false;
+}
+
+void GetHashMethods(DECL_EXTERNAL_CODECS_LOC_VARS
+ CRecordVector<CMethodId> &methods)
+{
+ methods.ClearAndSetSize(g_NumHashers);
+ UInt32 i;
+ for (i = 0; i < g_NumHashers; i++)
+ methods[i] = (*g_Hashers[i]).Id;
+ #ifdef EXTERNAL_CODECS
+ if (__externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Hashers.Size(); i++)
+ methods.Add(__externalCodecs->Hashers[i].Id);
+ #endif
+}
+
HRESULT CreateCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
@@ -159,7 +226,6 @@ HRESULT CreateCoder(
CMyComPtr<ICompressCoder2> &coder2,
bool encode, bool onlyCoder)
{
- bool created = false;
UInt32 i;
for (i = 0; i < g_NumCodecs; i++)
{
@@ -174,7 +240,6 @@ HRESULT CreateCoder(
if (codec.IsFilter) filter = (ICompressFilter *)p;
else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
else coder2 = (ICompressCoder2 *)p;
- created = (p != 0);
break;
}
}
@@ -185,17 +250,16 @@ HRESULT CreateCoder(
if (codec.IsFilter) filter = (ICompressFilter *)p;
else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
else coder2 = (ICompressCoder2 *)p;
- created = (p != 0);
break;
}
}
}
#ifdef EXTERNAL_CODECS
- if (!created && externalCodecs)
- for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ if (!filter && !coder && !coder2 && __externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++)
{
- const CCodecInfoEx &codec = (*externalCodecs)[i];
+ const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
if (codec.Id == methodId)
{
if (encode)
@@ -204,17 +268,17 @@ HRESULT CreateCoder(
{
if (codec.IsSimpleCodec())
{
- HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
+ HRESULT result = __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
return result;
if (!coder)
{
- RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
+ RINOK(__externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
}
}
else
{
- RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
+ RINOK(__externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
}
break;
}
@@ -224,17 +288,17 @@ HRESULT CreateCoder(
{
if (codec.IsSimpleCodec())
{
- HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
+ HRESULT result = __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
return result;
if (!coder)
{
- RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
+ RINOK(__externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
}
}
else
{
- RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));
+ RINOK(__externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));
}
break;
}
@@ -291,3 +355,37 @@ HRESULT CreateFilter(
methodId,
filter, coder, coder2, encode, false);
}
+
+HRESULT CreateHasher(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ UString &name,
+ CMyComPtr<IHasher> &hasher)
+{
+ UInt32 i;
+ for (i = 0; i < g_NumHashers; i++)
+ {
+ const CHasherInfo &codec = *g_Hashers[i];
+ if (codec.Id == methodId)
+ {
+ hasher = (IHasher *)codec.CreateHasher();
+ name = codec.Name;
+ break;
+ }
+ }
+
+ #ifdef EXTERNAL_CODECS
+ if (!hasher && __externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Hashers.Size(); i++)
+ {
+ const CHasherInfoEx &codec = __externalCodecs->Hashers[i];
+ if (codec.Id == methodId)
+ {
+ name = codec.Name;
+ return __externalCodecs->GetHashers->CreateHasher(i, &hasher);
+ }
+ }
+ #endif
+
+ return S_OK;
+}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.h b/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.h
index bf0e96a38..fe1f6ccfe 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.h
@@ -19,27 +19,43 @@ struct CCodecInfoEx
UInt32 NumOutStreams;
bool EncoderIsAssigned;
bool DecoderIsAssigned;
+
bool IsSimpleCodec() const { return NumOutStreams == 1 && NumInStreams == 1; }
CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {}
};
-HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs);
+struct CHasherInfoEx
+{
+ UString Name;
+ CMethodId Id;
+};
#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 _codecsInfo = compressCodecsInfo; return LoadExternalCodecs(_codecsInfo, _externalCodecs); COM_TRY_END }
+ COM_TRY_BEGIN __externalCodecs.GetCodecs = compressCodecsInfo; return __externalCodecs.LoadCodecs(); COM_TRY_END }
#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler)
-#define EXTERNAL_CODECS_VARS2 _codecsInfo, &_externalCodecs
+struct CExternalCodecs
+{
+ CMyComPtr<ICompressCodecsInfo> GetCodecs;
+ CMyComPtr<IHashers> GetHashers;
+
+ CObjectVector<CCodecInfoEx> Codecs;
+ CObjectVector<CHasherInfoEx> Hashers;
+
+ HRESULT LoadCodecs();
+};
+
+#define EXTERNAL_CODECS_VARS2 &__externalCodecs
-#define DECL_EXTERNAL_CODECS_VARS CMyComPtr<ICompressCodecsInfo> _codecsInfo; CObjectVector<CCodecInfoEx> _externalCodecs;
+#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs __externalCodecs;
#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2,
-#define DECL_EXTERNAL_CODECS_LOC_VARS2 ICompressCodecsInfo *codecsInfo, const CObjectVector<CCodecInfoEx> *externalCodecs
-#define EXTERNAL_CODECS_LOC_VARS2 codecsInfo, externalCodecs
+#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *__externalCodecs
+#define EXTERNAL_CODECS_LOC_VARS2 __externalCodecs
#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2,
#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2,
@@ -68,6 +84,13 @@ bool FindMethod(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, UString &name);
+bool FindHashMethod(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const UString &name, CMethodId &methodId);
+
+void GetHashMethods(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CRecordVector<CMethodId> &methods);
HRESULT CreateCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
@@ -95,4 +118,10 @@ HRESULT CreateFilter(
CMyComPtr<ICompressFilter> &filter,
bool encode);
+HRESULT CreateHasher(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ UString &name,
+ CMyComPtr<IHasher> &hacher);
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp b/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp
index 7d6e36f14..958360fac 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp
@@ -2,19 +2,19 @@
#include "StdAfx.h"
-#include "Common/Defs.h"
-#include "Common/IntToString.h"
+#include "../../Common/Defs.h"
+#include "../../Common/IntToString.h"
-#include "Windows/FileFind.h"
+#include "../../Windows/FileFind.h"
#include "FilePathAutoRename.h"
using namespace NWindows;
-static bool MakeAutoName(const UString &name,
- const UString &extension, unsigned value, UString &path)
+static bool MakeAutoName(const FString &name,
+ const FString &extension, unsigned value, FString &path)
{
- wchar_t number[16];
+ FChar number[16];
ConvertUInt32ToString(value, number);
path = name;
path += number;
@@ -22,22 +22,22 @@ static bool MakeAutoName(const UString &name,
return NFile::NFind::DoesFileOrDirExist(path);
}
-bool AutoRenamePath(UString &fullProcessedPath)
+bool AutoRenamePath(FString &fullProcessedPath)
{
- UString path;
- int dotPos = fullProcessedPath.ReverseFind(L'.');
+ FString path;
+ int dotPos = fullProcessedPath.ReverseFind(FTEXT('.'));
- int slashPos = fullProcessedPath.ReverseFind(L'/');
+ int slashPos = fullProcessedPath.ReverseFind(FTEXT('/'));
#ifdef _WIN32
- int slash1Pos = fullProcessedPath.ReverseFind(L'\\');
+ int slash1Pos = fullProcessedPath.ReverseFind(FTEXT('\\'));
slashPos = MyMax(slashPos, slash1Pos);
#endif
- UString name, extension;
+ FString name, extension;
if (dotPos > slashPos && dotPos > 0)
{
- name = fullProcessedPath.Left(dotPos);
- extension = fullProcessedPath.Mid(dotPos);
+ name.SetFrom(fullProcessedPath, dotPos);
+ extension = fullProcessedPath.Ptr(dotPos);
}
else
name = fullProcessedPath;
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h b/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h
index 3ef87f482..7b576591c 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h
@@ -1,10 +1,10 @@
-// Util/FilePathAutoRename.h
+// FilePathAutoRename.h
-#ifndef __FILEPATHAUTORENAME_H
-#define __FILEPATHAUTORENAME_H
+#ifndef __FILE_PATH_AUTO_RENAME_H
+#define __FILE_PATH_AUTO_RENAME_H
-#include "Common/MyString.h"
+#include "../../Common/MyString.h"
-bool AutoRenamePath(UString &fullProcessedPath);
+bool AutoRenamePath(FString &fullProcessedPath);
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.cpp b/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.cpp
index 76ab5ee29..ee1cc54e2 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.cpp
@@ -8,6 +8,11 @@
#include <errno.h>
#endif
+#ifdef SUPPORT_DEVICE_FILE
+#include "../../../C/Alloc.h"
+#include "../../Common/Defs.h"
+#endif
+
#include "FileStreams.h"
static inline HRESULT ConvertBoolToHRESULT(bool result)
@@ -24,86 +29,175 @@ static inline HRESULT ConvertBoolToHRESULT(bool result)
#endif
}
-bool CInFileStream::Open(LPCTSTR fileName)
-{
-#ifdef ENV_UNIX
- return File.Open(fileName,_ignoreSymbolicLink);
-#else
- return File.Open(fileName);
-#endif
-}
+#ifdef SUPPORT_DEVICE_FILE
-#ifdef USE_WIN_FILE
-#ifndef _UNICODE
-bool CInFileStream::Open(LPCWSTR fileName)
+static const UInt32 kClusterSize = 1 << 18;
+CInFileStream::CInFileStream():
+ VirtPos(0),
+ PhyPos(0),
+ Buf(0),
+ BufSize(0),
+ SupportHardLinks(false)
{
-#ifdef ENV_UNIX
- return File.Open(fileName,_ignoreSymbolicLink);
-#else
- return File.Open(fileName);
-#endif
}
-#endif
-#endif
-bool CInFileStream::OpenShared(LPCTSTR fileName, bool shareForWrite)
-{
-#ifdef ENV_UNIX
- return File.Open(fileName,_ignoreSymbolicLink);
-#else
- return File.OpenShared(fileName, shareForWrite);
#endif
-}
-#ifdef USE_WIN_FILE
-#ifndef _UNICODE
-bool CInFileStream::OpenShared(LPCWSTR fileName, bool shareForWrite)
+CInFileStream::~CInFileStream()
{
- return File.OpenShared(fileName, shareForWrite);
+ #ifdef SUPPORT_DEVICE_FILE
+ MidFree(Buf);
+ #endif
}
-#endif
-#endif
STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
#ifdef USE_WIN_FILE
-
+
+ #ifdef SUPPORT_DEVICE_FILE
+ if (processedSize)
+ *processedSize = 0;
+ if (size == 0)
+ return S_OK;
+ if (File.IsDeviceFile)
+ {
+ if (File.SizeDefined)
+ {
+ if (VirtPos >= File.Size)
+ return VirtPos == File.Size ? S_OK : E_FAIL;
+ UInt64 rem = File.Size - VirtPos;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+ for (;;)
+ {
+ const UInt32 mask = kClusterSize - 1;
+ const UInt64 mask2 = ~(UInt64)mask;
+ UInt64 alignedPos = VirtPos & mask2;
+ if (BufSize > 0 && BufStartPos == alignedPos)
+ {
+ UInt32 pos = (UInt32)VirtPos & mask;
+ if (pos >= BufSize)
+ return S_OK;
+ UInt32 rem = MyMin(BufSize - pos, size);
+ memcpy(data, Buf + pos, rem);
+ VirtPos += rem;
+ if (processedSize)
+ *processedSize += rem;
+ return S_OK;
+ }
+
+ bool useBuf = false;
+ if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 )
+ useBuf = true;
+ else
+ {
+ UInt64 end = VirtPos + size;
+ if ((end & mask) != 0)
+ {
+ end &= mask2;
+ if (end <= VirtPos)
+ useBuf = true;
+ else
+ size = (UInt32)(end - VirtPos);
+ }
+ }
+ if (!useBuf)
+ break;
+ if (alignedPos != PhyPos)
+ {
+ UInt64 realNewPosition;
+ bool result = File.Seek(alignedPos, FILE_BEGIN, realNewPosition);
+ if (!result)
+ return ConvertBoolToHRESULT(result);
+ PhyPos = realNewPosition;
+ }
+
+ BufStartPos = alignedPos;
+ UInt32 readSize = kClusterSize;
+ if (File.SizeDefined)
+ readSize = (UInt32)MyMin(File.Size - PhyPos, (UInt64)kClusterSize);
+
+ if (!Buf)
+ {
+ Buf = (Byte *)MidAlloc(kClusterSize);
+ if (!Buf)
+ return E_OUTOFMEMORY;
+ }
+ bool result = File.Read1(Buf, readSize, BufSize);
+ if (!result)
+ return ConvertBoolToHRESULT(result);
+
+ if (BufSize == 0)
+ return S_OK;
+ PhyPos += BufSize;
+ }
+
+ if (VirtPos != PhyPos)
+ {
+ UInt64 realNewPosition;
+ bool result = File.Seek(VirtPos, FILE_BEGIN, realNewPosition);
+ if (!result)
+ return ConvertBoolToHRESULT(result);
+ PhyPos = VirtPos = realNewPosition;
+ }
+ }
+ #endif
+
UInt32 realProcessedSize;
bool result = File.ReadPart(data, size, realProcessedSize);
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
+ #ifdef SUPPORT_DEVICE_FILE
+ VirtPos += realProcessedSize;
+ PhyPos += realProcessedSize;
+ #endif
return ConvertBoolToHRESULT(result);
-
+
#else
-
- if(processedSize != NULL)
+
+ if (processedSize)
*processedSize = 0;
ssize_t res = File.Read(data, (size_t)size);
if (res == -1)
return E_FAIL;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)res;
return S_OK;
#endif
}
-#ifndef _WIN32_WCE
+#ifdef UNDER_CE
+STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ size_t s2 = fread(data, 1, size, stdin);
+ int error = ferror(stdin);
+ if (processedSize)
+ *processedSize = s2;
+ if (s2 <= size && error == 0)
+ return S_OK;
+ return E_FAIL;
+}
+#else
STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
#ifdef _WIN32
- UInt32 realProcessedSize;
- BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE),
- data, size, (DWORD *)&realProcessedSize, NULL);
- if(processedSize != NULL)
+
+ DWORD realProcessedSize;
+ UInt32 sizeTemp = (1 << 20);
+ if (sizeTemp > size)
+ sizeTemp = size;
+ BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL);
+ if (processedSize)
*processedSize = realProcessedSize;
if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
return S_OK;
return ConvertBoolToHRESULT(res != FALSE);
-
+
#else
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
ssize_t res;
do
@@ -113,38 +207,61 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
while (res < 0 && (errno == EINTR));
if (res == -1)
return E_FAIL;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)res;
return S_OK;
-
+
#endif
}
-
+
#endif
-STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
- UInt64 *newPosition)
+STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- if(seekOrigin >= 3)
+ if (seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
#ifdef USE_WIN_FILE
+ #ifdef SUPPORT_DEVICE_FILE
+ if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END))
+ {
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += VirtPos; break;
+ case STREAM_SEEK_END: offset += File.Size; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ VirtPos = offset;
+ if (newPosition)
+ *newPosition = offset;
+ return S_OK;
+ }
+ #endif
+
UInt64 realNewPosition;
bool result = File.Seek(offset, seekOrigin, realNewPosition);
- if(newPosition != NULL)
+
+ #ifdef SUPPORT_DEVICE_FILE
+ PhyPos = VirtPos = realNewPosition;
+ #endif
+
+ if (newPosition)
*newPosition = realNewPosition;
return ConvertBoolToHRESULT(result);
-
+
#else
-
- off_t res = File.Seek(offset, seekOrigin);
+
+ off_t res = File.Seek((off_t)offset, seekOrigin);
if (res == -1)
return E_FAIL;
- if(newPosition != NULL)
+ if (newPosition)
*newPosition = (UInt64)res;
return S_OK;
-
+
#endif
}
@@ -153,6 +270,43 @@ STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
return ConvertBoolToHRESULT(File.GetLength(*size));
}
+#if 0 // FIXME #ifdef USE_WIN_FILE
+
+STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ if (File.GetFileInformation(&info))
+ {
+ if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
+ if (cTime) *cTime = info.ftCreationTime;
+ if (aTime) *aTime = info.ftLastAccessTime;
+ if (mTime) *mTime = info.ftLastWriteTime;
+ if (attrib) *attrib = info.dwFileAttributes;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
+STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ if (File.GetFileInformation(&info))
+ {
+ props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
+ props->VolID = info.dwVolumeSerialNumber;
+ props->FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
+ props->FileID_High = 0;
+ props->NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1;
+ props->Attrib = info.dwFileAttributes;
+ props->CTime = info.ftCreationTime;
+ props->ATime = info.ftLastAccessTime;
+ props->MTime = info.ftLastWriteTime;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
+#endif
//////////////////////////
// COutFileStream
@@ -169,46 +323,46 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
UInt32 realProcessedSize;
bool result = File.WritePart(data, size, realProcessedSize);
ProcessedSize += realProcessedSize;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
return ConvertBoolToHRESULT(result);
-
+
#else
-
- if(processedSize != NULL)
+
+ if (processedSize)
*processedSize = 0;
ssize_t res = File.Write(data, (size_t)size);
if (res == -1)
return E_FAIL;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)res;
ProcessedSize += res;
return S_OK;
-
+
#endif
}
-
+
STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- if(seekOrigin >= 3)
+ if (seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
#ifdef USE_WIN_FILE
UInt64 realNewPosition;
bool result = File.Seek(offset, seekOrigin, realNewPosition);
- if(newPosition != NULL)
+ if (newPosition)
*newPosition = realNewPosition;
return ConvertBoolToHRESULT(result);
-
+
#else
-
- off_t res = File.Seek(offset, seekOrigin);
+
+ off_t res = File.Seek((off_t)offset, seekOrigin);
if (res == -1)
return E_FAIL;
- if(newPosition != NULL)
+ if (newPosition)
*newPosition = (UInt64)res;
return S_OK;
-
+
#endif
}
@@ -216,7 +370,7 @@ STDMETHODIMP COutFileStream::SetSize(UInt64 newSize)
{
#ifdef USE_WIN_FILE
UInt64 currentPos;
- if(!File.Seek(0, FILE_CURRENT, currentPos))
+ if (!File.Seek(0, FILE_CURRENT, currentPos))
return E_FAIL;
bool result = File.SetLength(newSize);
UInt64 currentPos2;
@@ -227,10 +381,18 @@ STDMETHODIMP COutFileStream::SetSize(UInt64 newSize)
#endif
}
-#ifndef _WIN32_WCE
+#ifdef UNDER_CE
+STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ size_t s2 = fwrite(data, 1, size, stdout);
+ if (processedSize)
+ *processedSize = s2;
+ return (s2 == size) ? S_OK : E_FAIL;
+}
+#else
STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
#ifdef _WIN32
@@ -247,13 +409,13 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
size -= realProcessedSize;
data = (const void *)((const Byte *)data + realProcessedSize);
- if(processedSize != NULL)
+ if (processedSize)
*processedSize += realProcessedSize;
}
return ConvertBoolToHRESULT(res != FALSE);
#else
-
+
ssize_t res;
do
{
@@ -262,12 +424,12 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
while (res < 0 && (errno == EINTR));
if (res == -1)
return E_FAIL;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)res;
return S_OK;
-
+
return S_OK;
#endif
}
-
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.h b/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.h
index f70905b56..a80cbad4d 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.h
@@ -1,12 +1,14 @@
// FileStreams.h
-#ifndef __FILESTREAMS_H
-#define __FILESTREAMS_H
+#ifndef __FILE_STREAMS_H
+#define __FILE_STREAMS_H
#if defined(_WIN32) || defined(ENV_UNIX)
#define USE_WIN_FILE
#endif
+#include "../../Common/MyString.h"
+
#ifdef USE_WIN_FILE
#include "../../Windows/FileIO.h"
#else
@@ -14,43 +16,67 @@
#endif
#include "../../Common/MyCom.h"
+
#include "../IStream.h"
class CInFileStream:
public IInStream,
public IStreamGetSize,
+ #if 0 // #ifdef USE_WIN_FILE
+ public IStreamGetProps,
+ public IStreamGetProps2,
+ #endif
public CMyUnknownImp
{
bool _ignoreSymbolicLink;
public:
#ifdef USE_WIN_FILE
NWindows::NFile::NIO::CInFile File;
+
+ #ifdef SUPPORT_DEVICE_FILE
+ UInt64 VirtPos;
+ UInt64 PhyPos;
+ UInt64 BufStartPos;
+ Byte *Buf;
+ UInt32 BufSize;
+ #endif
+
#else
NC::NFile::NIO::CInFile File;
#endif
+
+ bool SupportHardLinks;
+
CInFileStream(bool b=false) { _ignoreSymbolicLink = b; }
- virtual ~CInFileStream() {}
+ virtual ~CInFileStream();
- bool Open(LPCTSTR fileName);
- #ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool Open(LPCWSTR fileName);
- #endif
- #endif
+ bool Open(CFSTR fileName)
+ {
+ return File.Open(fileName,_ignoreSymbolicLink);
+ }
- bool OpenShared(LPCTSTR fileName, bool shareForWrite);
- #ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool OpenShared(LPCWSTR fileName, bool shareForWrite);
- #endif
- #endif
+ bool OpenShared(CFSTR fileName , bool /* shareForWrite */ )
+ {
+ return File.Open(fileName,_ignoreSymbolicLink);
+ }
- MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
+ MY_QUERYINTERFACE_BEGIN2(IInStream)
+ MY_QUERYINTERFACE_ENTRY(IStreamGetSize)
+ #if 0 // #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);
+ #if 0 // #ifdef USE_WIN_FILE
+ STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib);
+ STDMETHOD(GetProps2)(CStreamFileProps *props);
+ #endif
};
class CStdInFileStream:
@@ -68,40 +94,26 @@ class COutFileStream:
public IOutStream,
public CMyUnknownImp
{
+public:
#ifdef USE_WIN_FILE
NWindows::NFile::NIO::COutFile File;
#else
NC::NFile::NIO::COutFile File;
#endif
-public:
virtual ~COutFileStream() {}
- bool Create(LPCTSTR fileName, bool createAlways)
+ bool Create(CFSTR fileName, bool createAlways)
{
ProcessedSize = 0;
return File.Create(fileName, createAlways);
}
- bool Open(LPCTSTR fileName, DWORD creationDisposition)
+ bool Open(CFSTR fileName, DWORD creationDisposition)
{
ProcessedSize = 0;
return File.Open(fileName, creationDisposition);
}
- #ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool Create(LPCWSTR fileName, bool createAlways)
- {
- ProcessedSize = 0;
- return File.Create(fileName, createAlways);
- }
- bool Open(LPCWSTR fileName, DWORD creationDisposition)
- {
- ProcessedSize = 0;
- return File.Open(fileName, creationDisposition);
- }
- #endif
- #endif
HRESULT Close();
-
+
UInt64 ProcessedSize;
#ifdef USE_WIN_FILE
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.cpp b/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.cpp
index 696735278..3a2023b35 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.cpp
@@ -48,10 +48,10 @@ STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStr
while (!_outSizeIsDefined || _nowPos64 < _outSize)
{
size_t processedSize = kBufferSize - bufferPos;
-
+
// Change it: It can be optimized using ReadPart
RINOK(ReadStream(inStream, _buffer + bufferPos, &processedSize));
-
+
UInt32 endPos = bufferPos + (UInt32)processedSize;
bufferPos = Filter->Filter(_buffer, endPos);
@@ -153,10 +153,16 @@ STDMETHODIMP CFilterCoder::Flush()
}
-STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+void CFilterCoder::SetInStream_NoSubFilterInit(ISequentialInStream *inStream)
{
_convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
_inStream = inStream;
+ Init2();
+}
+
+STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+{
+ SetInStream_NoSubFilterInit(inStream);
return Init();
}
@@ -210,10 +216,22 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
}
#ifndef _NO_CRYPTO
+
STDMETHODIMP 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);
+}
+
+STDMETHODIMP CFilterCoder::SetInitVector(const Byte *data, UInt32 size)
+{
+ return _cryptoProperties->SetInitVector(data, size);
+}
+
#endif
#ifndef EXTRACT_ONLY
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.h b/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.h
index 8132a6dd7..2b8f142f5 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.h
@@ -7,9 +7,9 @@
#include "../ICoder.h"
#include "../IPassword.h"
-#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \
-{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
-*outObject = (void *)(i *)this; AddRef(); return S_OK; }
+#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \
+ { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
+ *outObject = (void *)(i *)this; }
class CFilterCoder:
public ICompressCoder,
@@ -21,6 +21,7 @@ class CFilterCoder:
#ifndef _NO_CRYPTO
public ICryptoSetPassword,
+ public ICryptoProperties,
#endif
#ifndef EXTRACT_ONLY
public ICompressSetCoderProperties,
@@ -42,14 +43,20 @@ protected:
UInt64 _outSize;
UInt64 _nowPos64;
- HRESULT Init()
+ void Init2()
{
_nowPos64 = 0;
_outSizeIsDefined = false;
+ }
+
+ HRESULT Init()
+ {
+ Init2();
return Filter->Init();
}
CMyComPtr<ICryptoSetPassword> _setPassword;
+ CMyComPtr<ICryptoProperties> _cryptoProperties;
#ifndef EXTRACT_ONLY
CMyComPtr<ICompressSetCoderProperties> _SetCoderProperties;
CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;
@@ -74,6 +81,7 @@ public:
#ifndef _NO_CRYPTO
MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)
+ MY_QUERYINTERFACE_ENTRY_AG(ICryptoProperties, Filter, _cryptoProperties)
#endif
#ifndef EXTRACT_ONLY
@@ -98,6 +106,9 @@ public:
#ifndef _NO_CRYPTO
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
#endif
#ifndef EXTRACT_ONLY
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
@@ -107,6 +118,9 @@ public:
STDMETHOD(ResetInitVector)();
#endif
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+ void SetInStream_NoSubFilterInit(ISequentialInStream *inStream);
+
};
class CInStreamReleaser
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.cpp b/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.cpp
index ad4f8825e..133d95b38 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.cpp
@@ -6,50 +6,49 @@
#include "InBuffer.h"
-CInBuffer::CInBuffer():
- _buffer(0),
- _bufferLimit(0),
- _bufferBase(0),
+CInBufferBase::CInBufferBase() throw():
+ _buf(0),
+ _bufLim(0),
+ _bufBase(0),
_stream(0),
- _bufferSize(0)
+ _processedSize(0),
+ _bufSize(0),
+ _wasFinished(false),
+ NumExtraBytes(0)
{}
-bool CInBuffer::Create(UInt32 bufferSize)
+bool CInBuffer::Create(size_t bufSize) throw()
{
- const UInt32 kMinBlockSize = 1;
- if (bufferSize < kMinBlockSize)
- bufferSize = kMinBlockSize;
- if (_bufferBase != 0 && _bufferSize == bufferSize)
+ const unsigned kMinBlockSize = 1;
+ if (bufSize < kMinBlockSize)
+ bufSize = kMinBlockSize;
+ if (_bufBase != 0 && _bufSize == bufSize)
return true;
Free();
- _bufferSize = bufferSize;
- _bufferBase = (Byte *)::MidAlloc(bufferSize);
- return (_bufferBase != 0);
+ _bufSize = bufSize;
+ _bufBase = (Byte *)::MidAlloc(bufSize);
+ return (_bufBase != 0);
}
-void CInBuffer::Free()
+void CInBuffer::Free() throw()
{
- ::MidFree(_bufferBase);
- _bufferBase = 0;
+ ::MidFree(_bufBase);
+ _bufBase = 0;
}
-void CInBuffer::SetStream(ISequentialInStream *stream)
-{
- _stream = stream;
-}
-
-void CInBuffer::Init()
+void CInBufferBase::Init() throw()
{
_processedSize = 0;
- _buffer = _bufferBase;
- _bufferLimit = _buffer;
+ _buf = _bufBase;
+ _bufLim = _buf;
_wasFinished = false;
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
+ NumExtraBytes = 0;
}
-bool CInBuffer::ReadBlock()
+bool CInBufferBase::ReadBlock()
{
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
@@ -57,27 +56,80 @@ bool CInBuffer::ReadBlock()
#endif
if (_wasFinished)
return false;
- _processedSize += (_buffer - _bufferBase);
- UInt32 numProcessedBytes;
- HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
+ _processedSize += (_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
ErrorCode = result;
#else
if (result != S_OK)
throw CInBufferException(result);
#endif
- _buffer = _bufferBase;
- _bufferLimit = _buffer + numProcessedBytes;
- _wasFinished = (numProcessedBytes == 0);
- return (!_wasFinished);
+ _bufLim = _buf + processed;
+ _wasFinished = (processed == 0);
+ return !_wasFinished;
}
-Byte CInBuffer::ReadBlock2()
+bool CInBufferBase::ReadByte_FromNewBlock(Byte &b)
{
if (!ReadBlock())
{
- _processedSize++;
+ NumExtraBytes++;
+ b = 0xFF;
+ return false;
+ }
+ b = *_buf++;
+ return true;
+}
+
+Byte CInBufferBase::ReadByte_FromNewBlock()
+{
+ if (!ReadBlock())
+ {
+ NumExtraBytes++;
return 0xFF;
}
- return *_buffer++;
+ return *_buf++;
+}
+
+size_t CInBufferBase::ReadBytes(Byte *buf, size_t size)
+{
+ if ((size_t)(_bufLim - _buf) >= size)
+ {
+ const Byte *src = _buf;
+ for (size_t i = 0; i < size; i++)
+ buf[i] = src[i];
+ _buf += size;
+ return size;
+ }
+ for (size_t i = 0; i < size; i++)
+ {
+ if (_buf >= _bufLim)
+ if (!ReadBlock())
+ return i;
+ buf[i] = *_buf++;
+ }
+ return size;
+}
+
+size_t CInBufferBase::Skip(size_t size)
+{
+ size_t processed = 0;
+ for (;;)
+ {
+ size_t rem = (_bufLim - _buf);
+ if (rem >= size)
+ {
+ _buf += size;
+ return processed + size;
+ }
+ _buf += rem;
+ processed += rem;
+ size -= rem;
+ if (!ReadBlock())
+ return processed;
+ }
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.h b/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.h
index 75625bfd9..dd3c66808 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.h
@@ -1,11 +1,10 @@
// InBuffer.h
-#ifndef __INBUFFER_H
-#define __INBUFFER_H
+#ifndef __IN_BUFFER_H
+#define __IN_BUFFER_H
-#include "../IStream.h"
-#include "../../Common/MyCom.h"
#include "../../Common/MyException.h"
+#include "../IStream.h"
#ifndef _NO_EXCEPTIONS
struct CInBufferException: public CSystemException
@@ -14,68 +13,78 @@ struct CInBufferException: public CSystemException
};
#endif
-class CInBuffer
+class CInBufferBase
{
- Byte *_buffer;
- Byte *_bufferLimit;
- Byte *_bufferBase;
- CMyComPtr<ISequentialInStream> _stream;
+protected:
+ Byte *_buf;
+ Byte *_bufLim;
+ Byte *_bufBase;
+
+ ISequentialInStream *_stream;
UInt64 _processedSize;
- UInt32 _bufferSize;
+ size_t _bufSize; // actually it's number of Bytes for next read. The buf can be larger
+ // only up to 32-bits values now are supported!
bool _wasFinished;
bool ReadBlock();
- Byte ReadBlock2();
+ bool ReadByte_FromNewBlock(Byte &b);
+ Byte ReadByte_FromNewBlock();
public:
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
+ UInt32 NumExtraBytes;
- CInBuffer();
- ~CInBuffer() { Free(); }
+ CInBufferBase() throw();
+
+ UInt64 GetStreamSize() const { return _processedSize + (_buf - _bufBase); }
+ UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (_buf - _bufBase); }
+ bool WasFinished() const { return _wasFinished; }
+
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+
+ void SetBuf(Byte *buf, size_t bufSize, size_t end, size_t pos)
+ {
+ _bufBase = buf;
+ _bufSize = bufSize;
+ _processedSize = 0;
+ _buf = buf + pos;
+ _bufLim = buf + end;
+ _wasFinished = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+ NumExtraBytes = 0;
+ }
- bool Create(UInt32 bufferSize);
- void Free();
-
- void SetStream(ISequentialInStream *stream);
- void Init();
- void ReleaseStream() { _stream.Release(); }
+ void Init() throw();
bool ReadByte(Byte &b)
{
- if (_buffer >= _bufferLimit)
- if (!ReadBlock())
- return false;
- b = *_buffer++;
+ if (_buf >= _bufLim)
+ return ReadByte_FromNewBlock(b);
+ b = *_buf++;
return true;
}
+
Byte ReadByte()
{
- if (_buffer >= _bufferLimit)
- return ReadBlock2();
- return *_buffer++;
- }
- UInt32 ReadBytes(Byte *buf, UInt32 size)
- {
- if ((UInt32)(_bufferLimit - _buffer) >= size)
- {
- for (UInt32 i = 0; i < size; i++)
- buf[i] = _buffer[i];
- _buffer += size;
- return size;
- }
- for (UInt32 i = 0; i < size; i++)
- {
- if (_buffer >= _bufferLimit)
- if (!ReadBlock())
- return i;
- buf[i] = *_buffer++;
- }
- return size;
+ if (_buf >= _bufLim)
+ return ReadByte_FromNewBlock();
+ return *_buf++;
}
- UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
- bool WasFinished() const { return _wasFinished; }
+
+ size_t ReadBytes(Byte *buf, size_t size);
+ size_t Skip(size_t size);
+};
+
+class CInBuffer: public CInBufferBase
+{
+public:
+ ~CInBuffer() { Free(); }
+ bool Create(size_t bufSize) throw(); // only up to 32-bits values now are supported!
+ void Free() throw();
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp b/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp
index dfe8b3d32..be65ba32f 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp
@@ -4,16 +4,18 @@
#include "../../../C/7zCrc.h"
+#include "../../Common/Defs.h"
+
#include "InOutTempBuffer.h"
#include "StreamUtils.h"
using namespace NWindows;
using namespace NFile;
-using namespace NDirectory;
+using namespace NDir;
static const UInt32 kTempBufSize = (1 << 20);
-static LPCTSTR kTempFilePrefixString = TEXT("7zt");
+static CFSTR kTempFilePrefixString = FTEXT("7zt");
CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { }
@@ -42,12 +44,7 @@ bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
return true;
if (!_tempFileCreated)
{
- CSysString tempDirPath;
- if (!MyGetTempPath(tempDirPath))
- return false;
- if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tempFileName) == 0)
- return false;
- if (!_outFile.Create(_tempFileName, true))
+ if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile))
return false;
_tempFileCreated = true;
}
@@ -91,7 +88,7 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
if (_tempFileCreated)
{
NIO::CInFile inFile;
- if (!inFile.Open(_tempFileName))
+ if (!inFile.Open(_tempFile.GetPath()))
return E_FAIL;
while (size < _size)
{
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h b/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h
index 073f95acf..256d72420 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h
@@ -5,17 +5,15 @@
#include "../../Common/MyCom.h"
#include "../../Windows/FileDir.h"
-#include "../../Windows/FileIO.h"
#include "../IStream.h"
class CInOutTempBuffer
{
- NWindows::NFile::NDirectory::CTempFile _tempFile;
+ NWindows::NFile::NDir::CTempFile _tempFile;
NWindows::NFile::NIO::COutFile _outFile;
Byte *_buf;
UInt32 _bufPos;
- CSysString _tempFileName;
bool _tempFileCreated;
UInt64 _size;
UInt32 _crc;
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp b/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp
index 1837e3201..5f20dcda4 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp
@@ -17,17 +17,21 @@ STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *p
if (realProcessedSize == 0)
_wasFinished = true;
}
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
return result;
}
STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (_virtPos >= _size)
- return (_virtPos == _size) ? S_OK: E_FAIL;
+ {
+ // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case.
+ return S_OK;
+ // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF
+ }
UInt64 rem = _size - _virtPos;
if (rem < size)
size = (UInt32)rem;
@@ -38,7 +42,7 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi
RINOK(SeekToPhys());
}
HRESULT res = _stream->Read(data, size, &size);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
_physPos += size;
_virtPos += size;
@@ -47,24 +51,39 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi
STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _virtPos = offset; break;
- case STREAM_SEEK_CUR: _virtPos += offset; break;
- case STREAM_SEEK_END: _virtPos = _size + offset; break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += _size; break;
default: return STG_E_INVALIDFUNCTION;
}
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
if (newPosition)
*newPosition = _virtPos;
return S_OK;
}
+HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream)
+{
+ *resStream = 0;
+ CLimitedInStream *streamSpec = new CLimitedInStream;
+ CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
+ streamSpec->SetStream(inStream);
+ RINOK(streamSpec->InitAndSeek(pos, size));
+ streamSpec->SeekToStart();
+ *resStream = streamTemp.Detach();
+ return S_OK;
+}
+
STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (_virtPos >= Size)
- return (_virtPos == Size) ? S_OK: E_FAIL;
+ return S_OK;
if (_curRem == 0)
{
@@ -88,49 +107,98 @@ STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSi
if (size > _curRem)
size = _curRem;
HRESULT res = Stream->Read(data, size, &size);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
_physPos += size;
_virtPos += size;
_curRem -= size;
return res;
}
-
+
STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- UInt64 newVirtPos = offset;
- switch(seekOrigin)
+ switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
- case STREAM_SEEK_CUR: newVirtPos += _virtPos; break;
- case STREAM_SEEK_END: newVirtPos += Size; break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += Size; break;
default: return STG_E_INVALIDFUNCTION;
}
- if (_virtPos != newVirtPos)
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ if (_virtPos != (UInt64)offset)
_curRem = 0;
- _virtPos = newVirtPos;
+ _virtPos = offset;
if (newPosition)
- *newPosition = newVirtPos;
+ *newPosition = offset;
return S_OK;
}
-HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream)
+STDMETHODIMP CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- *resStream = 0;
- CLimitedInStream *streamSpec = new CLimitedInStream;
- CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
- streamSpec->SetStream(inStream);
- RINOK(streamSpec->InitAndSeek(pos, size));
- streamSpec->SeekToStart();
- *resStream = streamTemp.Detach();
+ if (processedSize)
+ *processedSize = 0;
+ if (_virtPos >= Extents.Back().Virt)
+ return S_OK;
+ if (size == 0)
+ return S_OK;
+
+ unsigned left = 0, right = Extents.Size() - 1;
+ for (;;)
+ {
+ unsigned mid = (left + right) / 2;
+ if (mid == left)
+ break;
+ if (_virtPos < Extents[mid].Virt)
+ right = mid;
+ else
+ left = mid;
+ }
+
+ const CSeekExtent &extent = Extents[left];
+ UInt64 phyPos = extent.Phy + (_virtPos - extent.Virt);
+ if (_needStartSeek || _phyPos != phyPos)
+ {
+ _needStartSeek = false;
+ _phyPos = phyPos;
+ RINOK(SeekToPhys());
+ }
+
+ UInt64 rem = Extents[left + 1].Virt - _virtPos;
+ if (size > rem)
+ size = (UInt32)rem;
+
+ HRESULT res = Stream->Read(data, size, &size);
+ _phyPos += size;
+ _virtPos += size;
+ if (processedSize)
+ *processedSize = size;
+ return res;
+}
+
+STDMETHODIMP CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += Extents.Back().Virt; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
return S_OK;
}
+
STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
HRESULT result = S_OK;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (size > _size)
{
@@ -139,7 +207,7 @@ STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, U
_overflow = true;
if (!_overflowIsAllowed)
return E_FAIL;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
return S_OK;
}
@@ -148,7 +216,134 @@ STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, U
if (_stream)
result = _stream->Write(data, size, &size);
_size -= size;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
return result;
}
+
+
+STDMETHODIMP CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 cur;
+ HRESULT res = Stream->Read(data, size, &cur);
+ if (processedSize)
+ *processedSize = cur;
+ _virtPos += cur;
+ return res;
+}
+
+STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END:
+ {
+ UInt64 pos = 0;
+ RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos));
+ if (pos < Offset)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = pos - Offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return S_OK;
+ }
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL);
+}
+
+STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+ if (_virtPos >= _size)
+ {
+ // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case.
+ return S_OK;
+ // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF
+ }
+ UInt64 rem = _size - _virtPos;
+ if (rem < size)
+ size = (UInt32)rem;
+
+ UInt64 newPos = _startOffset + _virtPos;
+ UInt64 offsetInCache = newPos - _cachePhyPos;
+ HRESULT res = S_OK;
+ if (newPos >= _cachePhyPos &&
+ offsetInCache <= _cacheSize &&
+ size <= _cacheSize - (size_t)offsetInCache)
+ memcpy(data, _cache + (size_t)offsetInCache, size);
+ else
+ {
+ if (newPos != _physPos)
+ {
+ _physPos = newPos;
+ RINOK(SeekToPhys());
+ }
+ res = _stream->Read(data, size, &size);
+ _physPos += size;
+ }
+ if (processedSize)
+ *processedSize = size;
+ _virtPos += size;
+ return res;
+}
+
+STDMETHODIMP CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += _size; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return S_OK;
+}
+
+STDMETHODIMP CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 cur;
+ HRESULT res = Stream->Write(data, size, &cur);
+ if (processedSize)
+ *processedSize = cur;
+ _virtPos += cur;
+ if (_virtSize < _virtPos)
+ _virtSize = _virtPos;
+ return res;
+}
+
+STDMETHODIMP CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += _virtSize; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL);
+}
+
+STDMETHODIMP CTailOutStream::SetSize(UInt64 newSize)
+{
+ _virtSize = newSize;
+ return Stream->SetSize(Offset + newSize);
+}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.h b/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.h
index 2cbe18e48..b14616f3b 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.h
@@ -3,6 +3,7 @@
#ifndef __LIMITED_STREAMS_H
#define __LIMITED_STREAMS_H
+#include "../../Common/MyBuffer.h"
#include "../../Common/MyCom.h"
#include "../../Common/MyVector.h"
#include "../IStream.h"
@@ -24,8 +25,8 @@ public:
_pos = 0;
_wasFinished = false;
}
-
- MY_UNKNOWN_IMP
+
+ MY_UNKNOWN_IMP1(ISequentialInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetSize() const { return _pos; }
@@ -53,8 +54,8 @@ public:
_size = size;
return SeekToPhys();
}
-
- MY_UNKNOWN_IMP1(IInStream)
+
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
@@ -62,6 +63,8 @@ public:
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
@@ -73,7 +76,7 @@ public:
CMyComPtr<IInStream> Stream;
UInt64 StartOffset;
UInt64 Size;
- int BlockSizeLog;
+ unsigned BlockSizeLog;
CRecordVector<UInt32> Vector;
HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
@@ -91,13 +94,44 @@ public:
return S_OK;
}
- MY_UNKNOWN_IMP1(IInStream)
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
-HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream);
+struct CSeekExtent
+{
+ UInt64 Phy;
+ UInt64 Virt;
+};
+
+class CExtentsStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ UInt64 _phyPos;
+ UInt64 _virtPos;
+ bool _needStartSeek;
+
+ HRESULT SeekToPhys() { return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); }
+
+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;
+ }
+};
class CLimitedSequentialOutStream:
public ISequentialOutStream,
@@ -108,7 +142,7 @@ class CLimitedSequentialOutStream:
bool _overflow;
bool _overflowIsAllowed;
public:
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
@@ -122,4 +156,96 @@ public:
UInt64 GetRem() const { return _size; }
};
+
+class CTailInStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ UInt64 _virtPos;
+public:
+ CMyComPtr<IInStream> Stream;
+ UInt64 Offset;
+
+ void Init()
+ {
+ _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); }
+};
+
+class CLimitedCachedInStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<IInStream> _stream;
+ UInt64 _virtPos;
+ UInt64 _physPos;
+ UInt64 _size;
+ UInt64 _startOffset;
+
+ const Byte *_cache;
+ size_t _cacheSize;
+ size_t _cachePhyPos;
+
+
+ HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
+public:
+ CByteBuffer Buffer;
+
+ void SetStream(IInStream *stream) { _stream = stream; }
+ void SetCache(size_t cacheSize, size_t cachePos)
+ {
+ _cache = Buffer;
+ _cacheSize = cacheSize;
+ _cachePhyPos = cachePos;
+ }
+
+ HRESULT InitAndSeek(UInt64 startOffset, UInt64 size)
+ {
+ _startOffset = startOffset;
+ _physPos = startOffset;
+ _virtPos = 0;
+ _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); }
+};
+
+class CTailOutStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ 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/src/libs/7zip/unix/CPP/7zip/Common/MethodId.cpp b/src/libs/7zip/unix/CPP/7zip/Common/MethodId.cpp
deleted file mode 100644
index b797b6857..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Common/MethodId.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// MethodId.cpp
-
-#include "StdAfx.h"
-
-#include "MethodId.h"
-#include "../../Common/MyString.h"
-
-static inline wchar_t GetHex(Byte value)
-{
- return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
-}
-
-UString ConvertMethodIdToString(UInt64 id)
-{
- wchar_t s[32];
- int len = 32;
- s[--len] = 0;
- do
- {
- s[--len] = GetHex((Byte)id & 0xF);
- id >>= 4;
- s[--len] = GetHex((Byte)id & 0xF);
- id >>= 4;
- }
- while (id != 0);
- return s + len;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/MethodId.h b/src/libs/7zip/unix/CPP/7zip/Common/MethodId.h
index 54ebc9f7d..28b615fcd 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/MethodId.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/MethodId.h
@@ -3,7 +3,7 @@
#ifndef __7Z_METHOD_ID_H
#define __7Z_METHOD_ID_H
-#include "../../Common/Types.h"
+#include "../../Common/MyTypes.h"
typedef UInt64 CMethodId;
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.cpp b/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.cpp
index 5836d0f84..ff61995b7 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.cpp
@@ -2,98 +2,440 @@
#include "StdAfx.h"
-#include "../../Common/MyCom.h"
-
-#include "../ICoder.h"
+#include "../../Common/StringToInt.h"
#include "MethodProps.h"
-static const UInt64 k_LZMA = 0x030101;
-static const UInt64 k_LZMA2 = 0x21;
+using namespace NWindows;
+
+bool StringToBool(const UString &s, bool &res)
+{
+ if (s.IsEmpty() || s == L"+" || StringsAreEqualNoCase_Ascii(s, "ON"))
+ {
+ res = true;
+ return true;
+ }
+ if (s == L"-" || StringsAreEqualNoCase_Ascii(s, "OFF"))
+ {
+ res = false;
+ return true;
+ }
+ return false;
+}
+
+HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest)
+{
+ switch (prop.vt)
+ {
+ case VT_EMPTY: dest = true; return S_OK;
+ case VT_BOOL: dest = (prop.boolVal != VARIANT_FALSE); return S_OK;
+ case VT_BSTR: return StringToBool(prop.bstrVal, dest) ? S_OK : E_INVALIDARG;
+ }
+ return E_INVALIDARG;
+}
+
+unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number)
+{
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ number = ConvertStringToUInt32(start, &end);
+ return (unsigned)(end - start);
+}
+
+HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
+{
+ // =VT_UI4
+ // =VT_EMPTY
+ // {stringUInt32}=VT_EMPTY
-HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder)
+ if (prop.vt == VT_UI4)
+ {
+ if (!name.IsEmpty())
+ return E_INVALIDARG;
+ resValue = prop.ulVal;
+ return S_OK;
+ }
+ if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ if (name.IsEmpty())
+ return S_OK;
+ UInt32 v;
+ if (ParseStringToUInt32(name, v) != name.Len())
+ return E_INVALIDARG;
+ resValue = v;
+ return S_OK;
+}
+
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
{
- bool tryReduce = false;
- UInt32 reducedDictionarySize = 1 << 10;
- if (inSizeForReduce != 0 && (method.Id == k_LZMA || method.Id == k_LZMA2))
+ if (name.IsEmpty())
{
- for (;;)
+ switch (prop.vt)
{
- const UInt32 step = (reducedDictionarySize >> 1);
- if (reducedDictionarySize >= *inSizeForReduce)
- {
- tryReduce = true;
+ case VT_UI4:
+ numThreads = prop.ulVal;
break;
- }
- reducedDictionarySize += step;
- if (reducedDictionarySize >= *inSizeForReduce)
+ default:
{
- tryReduce = true;
+ bool val;
+ RINOK(PROPVARIANT_to_bool(prop, val));
+ numThreads = (val ? defaultNumThreads : 1);
break;
}
- if (reducedDictionarySize >= ((UInt32)3 << 30))
- break;
- reducedDictionarySize += step;
}
+ return S_OK;
+ }
+ if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ return ParsePropToUInt32(name, prop, numThreads);
+}
+
+static HRESULT StringToDictSize(const UString &s, UInt32 &dicSize)
+{
+ const wchar_t *end;
+ UInt32 number = ConvertStringToUInt32(s, &end);
+ unsigned numDigits = (unsigned)(end - s);
+ if (numDigits == 0 || s.Len() > numDigits + 1)
+ return E_INVALIDARG;
+ const unsigned kLogDictSizeLimit = 32;
+ if (s.Len() == numDigits)
+ {
+ if (number >= kLogDictSizeLimit)
+ return E_INVALIDARG;
+ dicSize = (UInt32)1 << (unsigned)number;
+ return S_OK;
+ }
+ unsigned numBits;
+ switch (MyCharLower_Ascii(s[numDigits]))
+ {
+ case 'b': dicSize = number; return S_OK;
+ case 'k': numBits = 10; break;
+ case 'm': numBits = 20; break;
+ case 'g': numBits = 30; break;
+ default: return E_INVALIDARG;
+ }
+ if (number >= ((UInt32)1 << (kLogDictSizeLimit - numBits)))
+ return E_INVALIDARG;
+ dicSize = number << numBits;
+ return S_OK;
+}
+
+static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, UInt32 &resValue)
+{
+ if (prop.vt == VT_UI4)
+ {
+ UInt32 v = prop.ulVal;
+ if (v >= 32)
+ return E_INVALIDARG;
+ resValue = (UInt32)1 << v;
+ return S_OK;
+ }
+ if (prop.vt == VT_BSTR)
+ return StringToDictSize(prop.bstrVal, resValue);
+ return E_INVALIDARG;
+}
+
+void CProps::AddProp32(PROPID propid, UInt32 level)
+{
+ CProp prop;
+ prop.IsOptional = true;
+ prop.Id = propid;
+ prop.Value = (UInt32)level;
+ Props.Add(prop);
+}
+
+class CCoderProps
+{
+ PROPID *_propIDs;
+ NCOM::CPropVariant *_props;
+ unsigned _numProps;
+ unsigned _numPropsMax;
+public:
+ CCoderProps(unsigned numPropsMax)
+ {
+ _numPropsMax = numPropsMax;
+ _numProps = 0;
+ _propIDs = new PROPID[numPropsMax];
+ _props = new NCOM::CPropVariant[numPropsMax];
+ }
+ ~CCoderProps()
+ {
+ delete []_propIDs;
+ delete []_props;
+ }
+ void AddProp(const CProp &prop);
+ HRESULT SetProps(ICompressSetCoderProperties *setCoderProperties)
+ {
+ return setCoderProperties->SetCoderProperties(_propIDs, _props, _numProps);
+ }
+};
+
+void CCoderProps::AddProp(const CProp &prop)
+{
+ if (_numProps >= _numPropsMax)
+ throw 1;
+ _propIDs[_numProps] = prop.Id;
+ _props[_numProps] = prop.Value;
+ _numProps++;
+}
+
+HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const
+{
+ CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0));
+ FOR_VECTOR (i, Props)
+ coderProps.AddProp(Props[i]);
+ if (dataSizeReduce)
+ {
+ CProp prop;
+ prop.Id = NCoderPropID::kReduceSize;
+ prop.Value = *dataSizeReduce;
+ 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;
+ return -1;
+}
+
+int CMethodProps::GetLevel() const
+{
+ int i = FindProp(NCoderPropID::kLevel);
+ if (i < 0)
+ return 5;
+ if (Props[i].Value.vt != VT_UI4)
+ return 9;
+ UInt32 level = Props[i].Value.ulVal;
+ return level > 9 ? 9 : (int)level;
+}
+
+struct CNameToPropID
+{
+ VARTYPE VarType;
+ const char *Name;
+};
+
+static const CNameToPropID g_NameToPropID[] =
+{
+ { VT_UI4, "" },
+ { VT_UI4, "d" },
+ { VT_UI4, "mem" },
+ { VT_UI4, "o" },
+ { VT_UI4, "c" },
+ { VT_UI4, "pb" },
+ { VT_UI4, "lc" },
+ { VT_UI4, "lp" },
+ { VT_UI4, "fb" },
+ { VT_BSTR, "mf" },
+ { VT_UI4, "mc" },
+ { VT_UI4, "pass" },
+ { VT_UI4, "a" },
+ { VT_UI4, "mt" },
+ { VT_BOOL, "eos" },
+ { VT_UI4, "x" },
+ { VT_UI4, "reduceSize" }
+};
+
+static int FindPropIdExact(const UString &name)
+{
+ for (unsigned i = 0; i < ARRAY_SIZE(g_NameToPropID); i++)
+ if (StringsAreEqualNoCase_Ascii(name, g_NameToPropID[i].Name))
+ return i;
+ return -1;
+}
+
+static bool ConvertProperty(const PROPVARIANT &srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
+{
+ if (varType == srcProp.vt)
+ {
+ destProp = srcProp;
+ return true;
+ }
+ if (varType == VT_BOOL)
+ {
+ bool res;
+ if (PROPVARIANT_to_bool(srcProp, res) != S_OK)
+ return false;
+ destProp = res;
+ return true;
+ }
+ if (srcProp.vt == VT_EMPTY)
+ {
+ destProp = srcProp;
+ return true;
+ }
+ return false;
+}
+
+static void SplitParams(const UString &srcString, UStringVector &subStrings)
+{
+ subStrings.Clear();
+ UString s;
+ int len = srcString.Len();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L':')
+ {
+ subStrings.Add(s);
+ s.Empty();
+ }
+ else
+ s += c;
+ }
+ subStrings.Add(s);
+}
+
+static void SplitParam(const UString &param, UString &name, UString &value)
+{
+ int eqPos = param.Find(L'=');
+ if (eqPos >= 0)
+ {
+ name.SetFrom(param, eqPos);
+ value = param.Ptr(eqPos + 1);
+ return;
}
+ unsigned i;
+ for (i = 0; i < param.Len(); i++)
+ {
+ wchar_t c = param[i];
+ if (c >= L'0' && c <= L'9')
+ break;
+ }
+ name.SetFrom(param, i);
+ value = param.Ptr(i);
+}
+
+static bool IsLogSizeProp(PROPID propid)
+{
+ switch (propid)
+ {
+ case NCoderPropID::kDictionarySize:
+ case NCoderPropID::kUsedMemorySize:
+ case NCoderPropID::kBlockSize:
+ case NCoderPropID::kReduceSize:
+ return true;
+ }
+ return false;
+}
+HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
+{
+ int index = FindPropIdExact(name);
+ if (index < 0)
+ return E_INVALIDARG;
+ const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ CProp prop;
+ prop.Id = index;
+
+ if (IsLogSizeProp(prop.Id))
{
- int numProps = method.Props.Size();
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
- if (setCoderProperties == NULL)
+ UInt32 dicSize;
+ RINOK(StringToDictSize(value, dicSize));
+ prop.Value = dicSize;
+ }
+ else
+ {
+ NCOM::CPropVariant propValue;
+ if (nameToPropID.VarType == VT_BSTR)
+ propValue = value;
+ else if (nameToPropID.VarType == VT_BOOL)
{
- if (numProps != 0)
+ bool res;
+ if (!StringToBool(value, res))
return E_INVALIDARG;
+ propValue = res;
}
- else
+ else if (!value.IsEmpty())
{
- CRecordVector<PROPID> propIDs;
- NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProps];
- HRESULT res = S_OK;
- try
- {
- for (int i = 0; i < numProps; i++)
- {
- const CProp &prop = method.Props[i];
- propIDs.Add(prop.Id);
- NWindows::NCOM::CPropVariant &value = values[i];
- value = prop.Value;
- // if (tryReduce && prop.Id == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
- if (tryReduce)
- if (prop.Id == NCoderPropID::kDictionarySize)
- if (value.vt == VT_UI4)
- if (reducedDictionarySize < value.ulVal)
- value.ulVal = reducedDictionarySize;
- }
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
- res = setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProps);
- }
- catch(...)
- {
- delete []values;
- throw;
- }
- delete []values;
- RINOK(res);
+ UInt32 number;
+ if (ParseStringToUInt32(value, number) == value.Len())
+ propValue = number;
+ else
+ propValue = value;
}
+ if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value))
+ return E_INVALIDARG;
+ }
+ Props.Add(prop);
+ return S_OK;
+}
+
+HRESULT CMethodProps::ParseParamsFromString(const UString &srcString)
+{
+ UStringVector params;
+ SplitParams(srcString, params);
+ FOR_VECTOR (i, params)
+ {
+ const UString &param = params[i];
+ UString name, value;
+ SplitParam(param, name, value);
+ RINOK(SetParam(name, value));
+ }
+ return S_OK;
+}
+
+HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value)
+{
+ if (realName.Len() == 0)
+ {
+ // [empty]=method
+ return E_INVALIDARG;
}
-
- /*
- CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
- coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
- if (writeCoderProperties != NULL)
- {
- CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
- CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
- outStreamSpec->Init();
- RINOK(writeCoderProperties->WriteCoderProperties(outStream));
- size_t size = outStreamSpec->GetSize();
- filterProps.SetCapacity(size);
- memmove(filterProps, outStreamSpec->GetBuffer(), size);
- }
- */
+ if (value.vt == VT_EMPTY)
+ {
+ // {realName}=[empty]
+ UString name, value;
+ SplitParam(realName, name, value);
+ return SetParam(name, value);
+ }
+
+ // {realName}=value
+ int index = FindPropIdExact(realName);
+ if (index < 0)
+ return E_INVALIDARG;
+ const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ CProp prop;
+ prop.Id = index;
+
+ if (IsLogSizeProp(prop.Id))
+ {
+ UInt32 dicSize;
+ RINOK(PROPVARIANT_to_DictSize(value, dicSize));
+ prop.Value = dicSize;
+ }
+ else
+ {
+ if (!ConvertProperty(value, nameToPropID.VarType, prop.Value))
+ return E_INVALIDARG;
+ }
+ Props.Add(prop);
return S_OK;
}
+HRESULT COneMethodInfo::ParseMethodFromString(const UString &s)
+{
+ int splitPos = s.Find(':');
+ MethodName = s;
+ if (splitPos < 0)
+ return S_OK;
+ MethodName.DeleteFrom(splitPos);
+ return ParseParamsFromString(s.Ptr(splitPos + 1));
+}
+
+HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value)
+{
+ if (!realName.IsEmpty() && !StringsAreEqualNoCase_Ascii(realName, "m"))
+ return ParseParamsFromPROPVARIANT(realName, value);
+ // -m{N}=method
+ if (value.vt != VT_BSTR)
+ return E_INVALIDARG;
+ return ParseMethodFromString(value.bstrVal);
+}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.h b/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.h
index 8127e21ee..39e2ee937 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.h
@@ -3,39 +3,183 @@
#ifndef __7Z_METHOD_PROPS_H
#define __7Z_METHOD_PROPS_H
-#include "../../Common/MyVector.h"
+#include "../../Common/MyString.h"
#include "../../Windows/PropVariant.h"
-#include "MethodId.h"
+#include "../ICoder.h"
+
+bool StringToBool(const UString &s, bool &res);
+HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest);
+unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number);
+HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
+
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
struct CProp
{
PROPID Id;
+ bool IsOptional;
NWindows::NCOM::CPropVariant Value;
+ CProp(): IsOptional(false) {}
};
-struct CMethod
+struct CProps
{
- CMethodId Id;
CObjectVector<CProp> Props;
+
+ void Clear() { Props.Clear(); }
+
+ bool AreThereNonOptionalProps() const
+ {
+ FOR_VECTOR (i, Props)
+ if (!Props[i].IsOptional)
+ return true;
+ return false;
+ }
+
+ void AddProp32(PROPID propid, UInt32 level);
+
+ void AddPropString(PROPID propid, const wchar_t *s)
+ {
+ CProp prop;
+ prop.IsOptional = true;
+ prop.Id = propid;
+ prop.Value = s;
+ Props.Add(prop);
+ }
+
+ HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const;
};
-struct CMethodsMode
+class CMethodProps: public CProps
{
- CObjectVector<CMethod> Methods;
- #ifndef _7ZIP_ST
- UInt32 NumThreads;
- #endif
-
- CMethodsMode()
- #ifndef _7ZIP_ST
- : NumThreads(1)
- #endif
- {}
- bool IsEmpty() const { return Methods.IsEmpty() ; }
+ HRESULT SetParam(const UString &name, const UString &value);
+public:
+ int GetLevel() const;
+ int Get_NumThreads() const
+ {
+ int i = FindProp(NCoderPropID::kNumThreads);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ return (int)Props[i].Value.ulVal;
+ return -1;
+ }
+
+ bool Get_DicSize(UInt32 &res) const
+ {
+ res = 0;
+ int i = FindProp(NCoderPropID::kDictionarySize);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ {
+ res = Props[i].Value.ulVal;
+ return true;
+ }
+ return false;
+ }
+
+ int FindProp(PROPID id) const;
+
+ UInt32 Get_Lzma_Algo() const
+ {
+ int i = FindProp(NCoderPropID::kAlgorithm);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ return Props[i].Value.ulVal;
+ return GetLevel() >= 5 ? 1 : 0;
+ }
+
+ UInt32 Get_Lzma_DicSize() const
+ {
+ int i = FindProp(NCoderPropID::kDictionarySize);
+ 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));
+ }
+
+ UInt32 Get_Lzma_NumThreads(bool &fixedNumber) const
+ {
+ fixedNumber = false;
+ int numThreads = Get_NumThreads();
+ if (numThreads >= 0)
+ {
+ fixedNumber = true;
+ return numThreads < 2 ? 1 : 2;
+ }
+ return Get_Lzma_Algo() == 0 ? 1 : 2;
+ }
+
+ UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const
+ {
+ fixedNumber = false;
+ int numThreads = Get_NumThreads();
+ if (numThreads >= 0)
+ {
+ fixedNumber = true;
+ if (numThreads < 1) return 1;
+ if (numThreads > 64) return 64;
+ return numThreads;
+ }
+ return 1;
+ }
+
+ UInt32 Get_BZip2_BlockSize() const
+ {
+ int i = FindProp(NCoderPropID::kDictionarySize);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ {
+ UInt32 blockSize = Props[i].Value.ulVal;
+ const UInt32 kDicSizeMin = 100000;
+ const UInt32 kDicSizeMax = 900000;
+ if (blockSize < kDicSizeMin) blockSize = kDicSizeMin;
+ if (blockSize > kDicSizeMax) blockSize = kDicSizeMax;
+ return blockSize;
+ }
+ int level = GetLevel();
+ return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1));
+ }
+
+ UInt32 Get_Ppmd_MemSize() 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));
+ }
+
+ void AddLevelProp(UInt32 level)
+ {
+ AddProp32(NCoderPropID::kLevel, level);
+ }
+
+ void AddNumThreadsProp(UInt32 numThreads)
+ {
+ AddProp32(NCoderPropID::kNumThreads, numThreads);
+ }
+
+ HRESULT ParseParamsFromString(const UString &srcString);
+ HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
};
-HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder);
+class COneMethodInfo: public CMethodProps
+{
+public:
+ UString MethodName;
+
+ void Clear()
+ {
+ CMethodProps::Clear();
+ MethodName.Empty();
+ }
+ bool IsEmpty() const { return MethodName.IsEmpty() && Props.IsEmpty(); }
+ HRESULT ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
+ HRESULT ParseMethodFromString(const UString &s);
+};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.cpp b/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.cpp
deleted file mode 100644
index c5e4e6da4..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// OffsetStream.cpp
-
-#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);
-}
-
-STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return _stream->Write(data, size, processedSize);
-}
-
-STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin,
- UInt64 *newPosition)
-{
- UInt64 absoluteNewPosition;
- if (seekOrigin == STREAM_SEEK_SET)
- offset += _offset;
- HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);
- if (newPosition != NULL)
- *newPosition = absoluteNewPosition - _offset;
- return result;
-}
-
-STDMETHODIMP COffsetOutStream::SetSize(UInt64 newSize)
-{
- return _stream->SetSize(_offset + newSize);
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.h b/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.h
deleted file mode 100644
index de9d06dd0..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// OffsetStream.h
-
-#ifndef __OFFSETSTREAM_H
-#define __OFFSETSTREAM_H
-
-#include "Common/MyCom.h"
-#include "../IStream.h"
-
-class COffsetOutStream:
- public IOutStream,
- public CMyUnknownImp
-{
- UInt64 _offset;
- CMyComPtr<IOutStream> _stream;
-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/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.cpp b/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.cpp
index 2e5debd83..4ba34a053 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.cpp
@@ -6,34 +6,29 @@
#include "OutBuffer.h"
-bool COutBuffer::Create(UInt32 bufferSize)
+bool COutBuffer::Create(UInt32 bufSize) throw()
{
const UInt32 kMinBlockSize = 1;
- if (bufferSize < kMinBlockSize)
- bufferSize = kMinBlockSize;
- if (_buffer != 0 && _bufferSize == bufferSize)
+ if (bufSize < kMinBlockSize)
+ bufSize = kMinBlockSize;
+ if (_buf != 0 && _bufSize == bufSize)
return true;
Free();
- _bufferSize = bufferSize;
- _buffer = (Byte *)::MidAlloc(bufferSize);
- return (_buffer != 0);
+ _bufSize = bufSize;
+ _buf = (Byte *)::MidAlloc(bufSize);
+ return (_buf != 0);
}
-void COutBuffer::Free()
+void COutBuffer::Free() throw()
{
- ::MidFree(_buffer);
- _buffer = 0;
+ ::MidFree(_buf);
+ _buf = 0;
}
-void COutBuffer::SetStream(ISequentialOutStream *stream)
-{
- _stream = stream;
-}
-
-void COutBuffer::Init()
+void COutBuffer::Init() throw()
{
_streamPos = 0;
- _limitPos = _bufferSize;
+ _limitPos = _bufSize;
_pos = 0;
_processedSize = 0;
_overDict = false;
@@ -42,27 +37,27 @@ void COutBuffer::Init()
#endif
}
-UInt64 COutBuffer::GetProcessedSize() const
+UInt64 COutBuffer::GetProcessedSize() const throw()
{
UInt64 res = _processedSize + _pos - _streamPos;
if (_streamPos > _pos)
- res += _bufferSize;
+ res += _bufSize;
return res;
}
-HRESULT COutBuffer::FlushPart()
+HRESULT COutBuffer::FlushPart() throw()
{
- // _streamPos < _bufferSize
- UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
+ // _streamPos < _bufSize
+ UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos);
HRESULT result = S_OK;
#ifdef _NO_EXCEPTIONS
result = ErrorCode;
#endif
- if (_buffer2 != 0)
+ if (_buf2 != 0)
{
- memmove(_buffer2, _buffer + _streamPos, size);
- _buffer2 += size;
+ memcpy(_buf2, _buf + _streamPos, size);
+ _buf2 += size;
}
if (_stream != 0
@@ -72,30 +67,30 @@ HRESULT COutBuffer::FlushPart()
)
{
UInt32 processedSize = 0;
- result = _stream->Write(_buffer + _streamPos, size, &processedSize);
+ result = _stream->Write(_buf + _streamPos, size, &processedSize);
size = processedSize;
}
_streamPos += size;
- if (_streamPos == _bufferSize)
+ if (_streamPos == _bufSize)
_streamPos = 0;
- if (_pos == _bufferSize)
+ if (_pos == _bufSize)
{
_overDict = true;
_pos = 0;
}
- _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
+ _limitPos = (_streamPos > _pos) ? _streamPos : _bufSize;
_processedSize += size;
return result;
}
-HRESULT COutBuffer::Flush()
+HRESULT COutBuffer::Flush() throw()
{
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
return ErrorCode;
#endif
- while(_streamPos != _pos)
+ while (_streamPos != _pos)
{
HRESULT result = FlushPart();
if (result != S_OK)
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.h b/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.h
index 62e77caae..0baad3636 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.h
@@ -1,7 +1,7 @@
// OutBuffer.h
-#ifndef __OUTBUFFER_H
-#define __OUTBUFFER_H
+#ifndef __OUT_BUFFER_H
+#define __OUT_BUFFER_H
#include "../IStream.h"
#include "../../Common/MyCom.h"
@@ -17,39 +17,38 @@ struct COutBufferException: public CSystemException
class COutBuffer
{
protected:
- Byte *_buffer;
+ Byte *_buf;
UInt32 _pos;
UInt32 _limitPos;
UInt32 _streamPos;
- UInt32 _bufferSize;
- CMyComPtr<ISequentialOutStream> _stream;
+ UInt32 _bufSize;
+ ISequentialOutStream *_stream;
UInt64 _processedSize;
- Byte *_buffer2;
+ Byte *_buf2;
bool _overDict;
- HRESULT FlushPart();
+ HRESULT FlushPart() throw();
public:
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
- COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
+ COutBuffer(): _buf(0), _pos(0), _stream(0), _buf2(0) {}
~COutBuffer() { Free(); }
-
- bool Create(UInt32 bufferSize);
- void Free();
- void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
- void SetStream(ISequentialOutStream *stream);
- void Init();
- HRESULT Flush();
+ bool Create(UInt32 bufSize) throw();
+ void Free() throw();
+
+ void SetMemStream(Byte *buf) { _buf2 = buf; }
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void Init() throw();
+ HRESULT Flush() throw();
void FlushWithCheck();
- void ReleaseStream() { _stream.Release(); }
void WriteByte(Byte b)
{
- _buffer[_pos++] = b;
- if(_pos == _limitPos)
+ _buf[_pos++] = b;
+ if (_pos == _limitPos)
FlushWithCheck();
}
void WriteBytes(const void *data, size_t size)
@@ -58,7 +57,7 @@ public:
WriteByte(((const Byte *)data)[i]);
}
- UInt64 GetProcessedSize() const;
+ UInt64 GetProcessedSize() const throw();
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp b/src/libs/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp
index f24ff6b6f..bac45c1c2 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp
@@ -1,4 +1,4 @@
-// ProgressUtils.h
+// ProgressUtils.cpp
#include "StdAfx.h"
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/PropId.cpp b/src/libs/7zip/unix/CPP/7zip/Common/PropId.cpp
new file mode 100644
index 000000000..10daef715
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Common/PropId.cpp
@@ -0,0 +1,99 @@
+// PropId.cpp
+
+#include "StdAfx.h"
+
+#include "../PropID.h"
+
+// VARTYPE
+Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED] =
+{
+ VT_EMPTY,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BOOL,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4,
+ VT_FILETIME,
+ VT_FILETIME,
+ VT_FILETIME,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_BOOL,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_UI8,
+ VT_BSTR,
+ VT_UI8,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_BSTR, // or VT_UI8 kpidUnpackVer
+ VT_UI4, // or VT_UI8 kpidVolume
+ VT_BOOL,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4, // kpidChecksum
+ VT_BSTR,
+ VT_UI8,
+ VT_BSTR, // or VT_UI8 kpidId
+ VT_BSTR,
+ VT_BSTR,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR, // kpidNtSecure
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BSTR, // SHA-1
+ VT_BSTR, // SHA-256
+ VT_BSTR,
+ VT_UI8,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_UI8,
+ VT_UI8
+};
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h b/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h
index 305aac1fd..82bd09673 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h
@@ -5,28 +5,69 @@
#include "../Archive/IArchive.h"
-typedef IInArchive * (*CreateInArchiveP)();
-typedef IOutArchive * (*CreateOutArchiveP)();
+#include <mutex>
struct CArcInfo
{
- const wchar_t *Name;
- const wchar_t *Ext;
- const wchar_t *AddExt;
+ const char *Name;
+ const char *Ext;
+ const char *AddExt;
+
Byte ClassId;
- Byte Signature[28]; // FIXME Byte Signature[16]; adding 22 bytes to insure kSignature[0x1A]!= 0 and kSignature[0x1B] != 0
- int SignatureSize;
- bool KeepName;
- CreateInArchiveP CreateInArchive;
- CreateOutArchiveP CreateOutArchive;
+
+ Byte SignatureSize;
+ Byte Signature[20];
+ UInt16 SignatureOffset;
+
+ UInt16 Flags;
+
+ Func_CreateInArchive CreateInArchive;
+ Func_CreateOutArchive CreateOutArchive;
+ Func_IsArc IsArc;
+
+ bool IsMultiSignature() const { return (Flags & NArcInfoFlags::kMultiSignature) != 0; }
+
+ std::once_flag once;
};
-void RegisterArc(const CArcInfo *arcInfo);
+void RegisterArc(const CArcInfo *arcInfo) throw();
#define REGISTER_ARC_NAME(x) CRegister ## x
-#define REGISTER_ARC(x) struct REGISTER_ARC_NAME(x) { \
- REGISTER_ARC_NAME(x)() { RegisterArc(&g_ArcInfo); }}; \
+#define REGISTER_ARC(x) struct REGISTER_ARC_NAME(x) \
+ { \
+ REGISTER_ARC_NAME(x)() \
+ { \
+ std::call_once(g_ArcInfo.once, [] { RegisterArc(&g_ArcInfo); }); \
+ } \
+ }; \
static REGISTER_ARC_NAME(x) g_RegisterArc; \
void registerArc##x() { static REGISTER_ARC_NAME(x) g_RegisterArc; }
+
+#define REGISTER_ARC_DEC_SIG(x) struct REGISTER_ARC_NAME(x) \
+ { \
+ REGISTER_ARC_NAME(x)() { \
+ std::call_once(g_ArcInfo.once, [] { \
+ g_ArcInfo.Signature[0]--; \
+ RegisterArc(&g_ArcInfo); \
+ }); \
+ } \
+ }; \
+ static REGISTER_ARC_NAME(x) g_RegisterArc; \
+ void registerArcDec##x() { static REGISTER_ARC_NAME(x) g_RegisterArc; }
+
+
+#define IMP_CreateArcIn_2(c) \
+ static IInArchive *CreateArc() { return new c; }
+
+#define IMP_CreateArcIn IMP_CreateArcIn_2(CHandler)
+
+#ifdef EXTRACT_ONLY
+ #define IMP_CreateArcOut
+ #define REF_CreateArc_Pair CreateArc, NULL
+#else
+ #define IMP_CreateArcOut static IOutArchive *CreateArcOut() { return new CHandler; }
+ #define REF_CreateArc_Pair CreateArc, CreateArcOut
+#endif
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h b/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h
index d53c4344a..0c6662a6c 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h
@@ -1,9 +1,12 @@
// RegisterCodec.h
-#ifndef __REGISTERCODEC_H
-#define __REGISTERCODEC_H
+#ifndef __REGISTER_CODEC_H
+#define __REGISTER_CODEC_H
#include "../Common/MethodId.h"
+#include "../ICoder.h"
+
+#include <mutex>
typedef void * (*CreateCodecP)();
struct CCodecInfo
@@ -14,21 +17,50 @@ struct CCodecInfo
const wchar_t *Name;
UInt32 NumInStreams;
bool IsFilter;
+ std::once_flag once;
};
-void RegisterCodec(const CCodecInfo *codecInfo);
+void RegisterCodec(const CCodecInfo *codecInfo) throw();
#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x
-#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \
- REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \
+#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) \
+ { \
+ REGISTER_CODEC_NAME(x)() \
+ { \
+ std::call_once(g_CodecInfo.once, [] { RegisterCodec(&g_CodecInfo); }); \
+ } \
+ }; \
static REGISTER_CODEC_NAME(x) g_RegisterCodec; \
void registerCodec##x() { static REGISTER_CODEC_NAME(x) g_RegisterCodecs; }
#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x
-#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \
- REGISTER_CODECS_NAME(x)() { for (int i = 0; i < sizeof(g_CodecsInfo) / sizeof(g_CodecsInfo[0]); i++) \
- RegisterCodec(&g_CodecsInfo[i]); }}; \
+#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) \
+ { \
+ REGISTER_CODECS_NAME(x)() \
+ { \
+ for (unsigned i = 0; i < ARRAY_SIZE(g_CodecsInfo); i++) \
+ std::call_once(g_CodecsInfo[i].once, [&i] { RegisterCodec(&g_CodecsInfo[i]); }); \
+ } \
+ }; \
static REGISTER_CODECS_NAME(x) g_RegisterCodecs; \
void registerCodec##x() { static REGISTER_CODECS_NAME(x) g_RegisterCodecs; }
+
+
+struct CHasherInfo
+{
+ IHasher * (*CreateHasher)();
+ CMethodId Id;
+ const wchar_t *Name;
+ UInt32 DigestSize;
+};
+
+void RegisterHasher(const CHasherInfo *hasher) throw();
+
+#define REGISTER_HASHER_NAME(x) CRegisterHasher ## x
+
+#define REGISTER_HASHER(x) struct REGISTER_HASHER_NAME(x) { \
+ REGISTER_HASHER_NAME(x)() { RegisterHasher(&g_HasherInfo); }}; \
+ static REGISTER_HASHER_NAME(x) g_RegisterHasher;
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.cpp b/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.cpp
index 9dfa3fb75..43feef1ba 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.cpp
@@ -2,151 +2,128 @@
#include "StdAfx.h"
-#include "StreamBinder.h"
-#include "../../Common/Defs.h"
#include "../../Common/MyCom.h"
-using namespace NWindows;
-using namespace NSynchronization;
+#include "StreamBinder.h"
-class CSequentialInStreamForBinder:
+class CBinderInStream:
public ISequentialInStream,
public CMyUnknownImp
{
+ CStreamBinder *_binder;
public:
MY_UNKNOWN_IMP
-
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
-private:
- CStreamBinder *m_StreamBinder;
-public:
- ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); }
- void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+ ~CBinderInStream() { _binder->CloseRead(); }
+ CBinderInStream(CStreamBinder *binder): _binder(binder) {}
};
-STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
- { return m_StreamBinder->Read(data, size, processedSize); }
+STDMETHODIMP CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+ { return _binder->Read(data, size, processedSize); }
-class CSequentialOutStreamForBinder:
+class CBinderOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
+ CStreamBinder *_binder;
public:
MY_UNKNOWN_IMP
-
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
-
-private:
- CStreamBinder *m_StreamBinder;
-public:
- ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); }
- void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+ ~CBinderOutStream() { _binder->CloseWrite(); }
+ CBinderOutStream(CStreamBinder *binder): _binder(binder) {}
};
-STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
- { return m_StreamBinder->Write(data, size, processedSize); }
+STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+ { return _binder->Write(data, size, processedSize); }
-//////////////////////////
-// CStreamBinder
-// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished.
-HRes CStreamBinder::CreateEvents()
+WRes CStreamBinder::CreateEvents()
{
- _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent = new NWindows::NSynchronization::CSynchro();
- _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent->Create();
- RINOK(_allBytesAreWritenEvent.Create(_synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent,true));
- RINOK(_thereAreBytesToReadEvent.Create());
- return _readStreamIsClosedEvent.Create(_synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent);
+ _synchroFor_canWrite_Event_and_readingWasClosed_Event = new NWindows::NSynchronization::CSynchro();
+ _synchroFor_canWrite_Event_and_readingWasClosed_Event->Create();
+ RINOK(_canWrite_Event.Create(_synchroFor_canWrite_Event_and_readingWasClosed_Event,true));
+ // RINOK(_canWrite_Event.Create(true));
+ RINOK(_canRead_Event.Create());
+ return _readingWasClosed_Event.Create(_synchroFor_canWrite_Event_and_readingWasClosed_Event);
}
void CStreamBinder::ReInit()
{
- _thereAreBytesToReadEvent.Reset();
- _readStreamIsClosedEvent.Reset();
+ _waitWrite = true;
+ _canRead_Event.Reset();
+ _readingWasClosed_Event.Reset();
ProcessedSize = 0;
}
-
-void CStreamBinder::CreateStreams(ISequentialInStream **inStream,
- ISequentialOutStream **outStream)
+void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream)
{
- CSequentialInStreamForBinder *inStreamSpec = new
- CSequentialInStreamForBinder;
+ _waitWrite = true;
+ _bufSize = 0;
+ _buf = NULL;
+ ProcessedSize = 0;
+
+ CBinderInStream *inStreamSpec = new CBinderInStream(this);
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
- inStreamSpec->SetBinder(this);
*inStream = inStreamLoc.Detach();
- CSequentialOutStreamForBinder *outStreamSpec = new
- CSequentialOutStreamForBinder;
+ CBinderOutStream *outStreamSpec = new CBinderOutStream(this);
CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
- outStreamSpec->SetBinder(this);
*outStream = outStreamLoc.Detach();
-
- _buffer = NULL;
- _bufferSize= 0;
- ProcessedSize = 0;
}
+// (_canRead_Event && _bufSize == 0) means that stream is finished.
+
HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- UInt32 sizeToRead = size;
- if (size > 0)
+ if (processedSize)
+ *processedSize = 0;
+ if (size != 0)
{
- RINOK(_thereAreBytesToReadEvent.Lock());
- sizeToRead = MyMin(_bufferSize, size);
- if (_bufferSize > 0)
+ if (_waitWrite)
{
- memcpy(data, _buffer, sizeToRead);
- _buffer = ((const Byte *)_buffer) + sizeToRead;
- _bufferSize -= sizeToRead;
- if (_bufferSize == 0)
+ RINOK(_canRead_Event.Lock());
+ _waitWrite = false;
+ }
+ if (size > _bufSize)
+ size = _bufSize;
+ if (size != 0)
+ {
+ memcpy(data, _buf, size);
+ _buf = ((const Byte *)_buf) + size;
+ ProcessedSize += size;
+ if (processedSize)
+ *processedSize = size;
+ _bufSize -= size;
+ if (_bufSize == 0)
{
- _thereAreBytesToReadEvent.Reset();
- _allBytesAreWritenEvent.Set();
+ _waitWrite = true;
+ _canRead_Event.Reset();
+ _canWrite_Event.Set();
}
}
}
- if (processedSize != NULL)
- *processedSize = sizeToRead;
- ProcessedSize += sizeToRead;
return S_OK;
}
-void CStreamBinder::CloseRead()
-{
- _readStreamIsClosedEvent.Set();
-}
-
HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if (size > 0)
+ if (processedSize)
+ *processedSize = 0;
+ if (size != 0)
{
- _buffer = data;
- _bufferSize = size;
- _allBytesAreWritenEvent.Reset();
- _thereAreBytesToReadEvent.Set();
-
- HANDLE events[2];
- events[0] = _allBytesAreWritenEvent;
- events[1] = _readStreamIsClosedEvent;
+ _buf = data;
+ _bufSize = size;
+ _canWrite_Event.Reset();
+ _canRead_Event.Set();
+
+ HANDLE events[2] = { _canWrite_Event, _readingWasClosed_Event };
DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
if (waitResult != WAIT_OBJECT_0 + 0)
- {
- // ReadingWasClosed = true;
return S_FALSE;
- }
- // if(!_allBytesAreWritenEvent.Lock())
- // return E_FAIL;
+ if (processedSize)
+ *processedSize = size;
}
- if (processedSize != NULL)
- *processedSize = size;
return S_OK;
}
-
-void CStreamBinder::CloseWrite()
-{
- // _bufferSize must be = 0
- _thereAreBytesToReadEvent.Set();
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.h b/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.h
index 47743dee2..aba6b8e17 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.h
@@ -1,38 +1,35 @@
// StreamBinder.h
-#ifndef __STREAMBINDER_H
-#define __STREAMBINDER_H
+#ifndef __STREAM_BINDER_H
+#define __STREAM_BINDER_H
-#include "../IStream.h"
#include "../../Windows/Synchronization.h"
+#include "../IStream.h"
+
class CStreamBinder
{
- NWindows::NSynchronization::CManualResetEventWFMO _allBytesAreWritenEvent;
- NWindows::NSynchronization::CManualResetEvent _thereAreBytesToReadEvent;
- NWindows::NSynchronization::CManualResetEventWFMO _readStreamIsClosedEvent;
- NWindows::NSynchronization::CSynchro * _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent;
- UInt32 _bufferSize;
- const void *_buffer;
+ NWindows::NSynchronization::CManualResetEventWFMO _canWrite_Event;
+ NWindows::NSynchronization::CManualResetEvent _canRead_Event;
+ NWindows::NSynchronization::CManualResetEventWFMO _readingWasClosed_Event;
+ NWindows::NSynchronization::CSynchro * _synchroFor_canWrite_Event_and_readingWasClosed_Event;
+ bool _waitWrite;
+ UInt32 _bufSize;
+ const void *_buf;
public:
- // bool ReadingWasClosed;
UInt64 ProcessedSize;
- CStreamBinder() { _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent = 0; }
- ~CStreamBinder() {
- if (_synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent)
- delete _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent;
- _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent = 0;
- }
- HRes CreateEvents();
- void CreateStreams(ISequentialInStream **inStream,
- ISequentialOutStream **outStream);
+ WRes CreateEvents();
+ void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream);
+ void ReInit();
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
- void CloseRead();
-
HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
- void CloseWrite();
- void ReInit();
+ void CloseRead() { _readingWasClosed_Event.Set(); }
+ void CloseWrite()
+ {
+ // _bufSize must be = 0
+ _canRead_Event.Set();
+ }
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.cpp b/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.cpp
index 24253a9ed..7721c3a7e 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include <stdlib.h>
+
#include "../../../C/Alloc.h"
#include "StreamObjects.h"
@@ -12,8 +14,8 @@ STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
*processedSize = 0;
if (size == 0)
return S_OK;
- if (_pos > _size)
- return E_FAIL;
+ if (_pos >= _size)
+ return S_OK;
size_t rem = _size - (size_t)_pos;
if (rem > size)
rem = (size_t)size;
@@ -26,26 +28,51 @@ STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _pos = offset; break;
- case STREAM_SEEK_CUR: _pos += offset; break;
- case STREAM_SEEK_END: _pos = _size + offset; break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _pos; break;
+ case STREAM_SEEK_END: offset += _size; break;
default: return STG_E_INVALIDFUNCTION;
}
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _pos = offset;
if (newPosition)
- *newPosition = _pos;
+ *newPosition = offset;
return S_OK;
}
-void CByteDynBuffer::Free()
+/*
+void Create_BufInStream_WithReference(const void *data, size_t size, ISequentialInStream **stream)
+{
+ CBufInStream *inStreamSpec = new CBufInStream;
+ CMyComPtr<ISequentialInStream> streamTemp = inStreamSpec;
+ inStreamSpec->Init((const Byte *)data, size);
+ *stream = streamTemp.Detach();
+}
+*/
+
+void Create_BufInStream_WithNewBuf(const void *data, size_t size, ISequentialInStream **stream)
+{
+ CReferenceBuf *referenceBuf = new CReferenceBuf;
+ CMyComPtr<IUnknown> ref = referenceBuf;
+ referenceBuf->Buf.CopyFrom((const Byte *)data, size);
+
+ CBufInStream *inStreamSpec = new CBufInStream;
+ CMyComPtr<ISequentialInStream> streamTemp = inStreamSpec;
+ inStreamSpec->Init(referenceBuf);
+ *stream = streamTemp.Detach();
+}
+
+void CByteDynBuffer::Free() throw()
{
free(_buf);
_buf = 0;
_capacity = 0;
}
-bool CByteDynBuffer::EnsureCapacity(size_t cap)
+bool CByteDynBuffer::EnsureCapacity(size_t cap) throw()
{
if (cap <= _capacity)
return true;
@@ -77,8 +104,7 @@ Byte *CDynBufSeqOutStream::GetBufPtrForWriting(size_t addSize)
void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const
{
- dest.SetCapacity(_size);
- memcpy((Byte *)dest, (const Byte *)_buffer, _size);
+ dest.CopyFrom((const Byte *)_buffer, _size);
}
STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
@@ -121,7 +147,7 @@ STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size,
static const UInt64 kEmptyTag = (UInt64)(Int64)-1;
-void CCachedInStream::Free()
+void CCachedInStream::Free() throw()
{
MyFree(_tags);
_tags = 0;
@@ -129,7 +155,7 @@ void CCachedInStream::Free()
_data = 0;
}
-bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog)
+bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw()
{
unsigned sizeLog = blockSizeLog + numBlocksLog;
if (sizeLog >= sizeof(size_t) * 8)
@@ -155,7 +181,7 @@ bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog)
return true;
}
-void CCachedInStream::Init(UInt64 size)
+void CCachedInStream::Init(UInt64 size) throw()
{
_size = size;
_pos = 0;
@@ -170,8 +196,8 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
*processedSize = 0;
if (size == 0)
return S_OK;
- if (_pos > _size)
- return E_FAIL;
+ if (_pos >= _size)
+ return S_OK;
{
UInt64 rem = _size - _pos;
@@ -205,17 +231,20 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
return S_OK;
}
-
+
STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _pos = offset; break;
- case STREAM_SEEK_CUR: _pos = _pos + offset; break;
- case STREAM_SEEK_END: _pos = _size + offset; break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _pos; break;
+ case STREAM_SEEK_END: offset += _size; break;
default: return STG_E_INVALIDFUNCTION;
}
- if (newPosition != 0)
- *newPosition = _pos;
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _pos = offset;
+ if (newPosition)
+ *newPosition = offset;
return S_OK;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.h b/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.h
index 5c8b5e51b..d0c86b566 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.h
@@ -3,8 +3,10 @@
#ifndef __STREAM_OBJECTS_H
#define __STREAM_OBJECTS_H
-#include "../../Common/Buffer.h"
+#include "../../Common/MyBuffer.h"
#include "../../Common/MyCom.h"
+#include "../../Common/MyVector.h"
+
#include "../IStream.h"
struct CReferenceBuf:
@@ -31,13 +33,16 @@ public:
_pos = 0;
_ref = ref;
}
- void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.GetCapacity(), ref); }
+ void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.Size(), ref); }
- MY_UNKNOWN_IMP1(IInStream)
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
+// void Create_BufInStream_WithReference(const void *data, size_t size, ISequentialInStream **stream);
+void Create_BufInStream_WithNewBuf(const void *data, size_t size, ISequentialInStream **stream);
+
class CByteDynBuffer
{
size_t _capacity;
@@ -46,11 +51,11 @@ public:
CByteDynBuffer(): _capacity(0), _buf(0) {};
// there is no copy constructor. So don't copy this object.
~CByteDynBuffer() { Free(); }
- void Free();
- size_t GetCapacity() const { return _capacity; }
- operator Byte*() { return _buf; };
+ void Free() throw();
+ size_t GetCapacity() const { return _capacity; }
+ operator Byte*() const { return _buf; };
operator const Byte*() const { return _buf; };
- bool EnsureCapacity(size_t capacity);
+ bool EnsureCapacity(size_t capacity) throw();
};
class CDynBufSeqOutStream:
@@ -68,7 +73,7 @@ public:
Byte *GetBufPtrForWriting(size_t addSize);
void UpdateSize(size_t addSize) { _size += addSize; }
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -88,7 +93,7 @@ public:
}
size_t GetPos() const { return _pos; }
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -103,7 +108,7 @@ public:
void Init() { _size = 0; }
UInt64 GetSize() const { return _size; }
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -123,9 +128,9 @@ protected:
public:
CCachedInStream(): _tags(0), _data(0) {}
virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!!
- void Free();
- bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog);
- void Init(UInt64 size);
+ 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);
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.cpp b/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.cpp
index 049e4aa17..1402f4205 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.cpp
@@ -6,7 +6,7 @@
static const UInt32 kBlockSize = ((UInt32)1 << 31);
-HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize)
+HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw()
{
size_t size = *processedSize;
*processedSize = 0;
@@ -25,21 +25,21 @@ HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSiz
return S_OK;
}
-HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size)
+HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw()
{
size_t processedSize = size;
RINOK(ReadStream(stream, data, &processedSize));
return (size == processedSize) ? S_OK : S_FALSE;
}
-HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size)
+HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw()
{
size_t processedSize = size;
RINOK(ReadStream(stream, data, &processedSize));
return (size == processedSize) ? S_OK : E_FAIL;
}
-HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size)
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw()
{
while (size != 0)
{
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.h b/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.h
index f1cfd1848..ae914c004 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.h
@@ -1,13 +1,13 @@
// StreamUtils.h
-#ifndef __STREAMUTILS_H
-#define __STREAMUTILS_H
+#ifndef __STREAM_UTILS_H
+#define __STREAM_UTILS_H
#include "../IStream.h"
-HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size);
-HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size);
-HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size);
-HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size);
+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();
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw();
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.cpp b/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.cpp
new file mode 100644
index 000000000..7fcc88f5e
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.cpp
@@ -0,0 +1,56 @@
+// UniqBlocks.cpp
+
+#include "StdAfx.h"
+
+#include "UniqBlocks.h"
+
+int CUniqBlocks::AddUniq(const Byte *data, size_t size)
+{
+ unsigned left = 0, right = Sorted.Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ int index = Sorted[mid];
+ const CByteBuffer &buf = Bufs[index];
+ size_t sizeMid = buf.Size();
+ if (size < sizeMid)
+ right = mid;
+ else if (size > sizeMid)
+ left = mid + 1;
+ else
+ {
+ int cmp = memcmp(data, buf, size);
+ if (cmp == 0)
+ return index;
+ if (cmp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ }
+ int index = Bufs.Size();
+ Sorted.Insert(left, index);
+ CByteBuffer &buf = Bufs.AddNew();
+ buf.CopyFrom(data, size);
+ return index;
+}
+
+UInt64 CUniqBlocks::GetTotalSizeInBytes() const
+{
+ UInt64 size = 0;
+ FOR_VECTOR (i, Bufs)
+ size += Bufs[i].Size();
+ return size;
+}
+
+void CUniqBlocks::GetReverseMap()
+{
+ unsigned num = Sorted.Size();
+ BufIndexToSortedIndex.ClearAndSetSize(num);
+ int *p = &BufIndexToSortedIndex[0];
+ unsigned i;
+ for (i = 0; i < num; i++)
+ p[i] = 0;
+ for (i = 0; i < num; i++)
+ p[Sorted[i]] = i;
+}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.h b/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.h
new file mode 100644
index 000000000..9c08b09f4
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.h
@@ -0,0 +1,30 @@
+// UniqBlocks.h
+
+#ifndef __UNIQ_BLOCKS_H
+#define __UNIQ_BLOCKS_H
+
+#include "../../Common/MyTypes.h"
+#include "../../Common/MyBuffer.h"
+#include "../../Common/MyVector.h"
+
+struct CUniqBlocks
+{
+ CObjectVector<CByteBuffer> Bufs;
+ CIntVector Sorted;
+ CIntVector BufIndexToSortedIndex;
+
+ int AddUniq(const Byte *data, size_t size);
+ UInt64 GetTotalSizeInBytes() const;
+ void GetReverseMap();
+
+ bool IsOnlyEmpty() const
+ {
+ if (Bufs.Size() == 0)
+ return true;
+ if (Bufs.Size() > 1)
+ return false;
+ return Bufs[0].Size() == 0;
+ }
+};
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.cpp b/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.cpp
index cf39bd023..77e3c1acf 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.cpp
@@ -10,7 +10,7 @@ static THREAD_FUNC_DECL CoderThread(void *p)
{
CVirtThread *t = (CVirtThread *)p;
t->StartEvent.Lock();
- if (t->ExitEvent)
+ if (t->Exit)
return 0;
t->Execute();
t->FinishedEvent.Set();
@@ -23,7 +23,7 @@ WRes CVirtThread::Create()
RINOK(FinishedEvent.CreateIfNotCreated());
StartEvent.Reset();
FinishedEvent.Reset();
- ExitEvent = false;
+ Exit = false;
if (Thread.IsCreated())
return S_OK;
return Thread.Create(CoderThread, this);
@@ -31,16 +31,18 @@ WRes CVirtThread::Create()
void CVirtThread::Start()
{
- ExitEvent = false;
+ Exit = false;
StartEvent.Set();
}
-CVirtThread::~CVirtThread()
+void CVirtThread::WaitThreadFinish()
{
- ExitEvent = true;
+ Exit = true;
if (StartEvent.IsCreated())
StartEvent.Set();
if (Thread.IsCreated())
+ {
Thread.Wait();
+ Thread.Close();
+ }
}
-
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.h b/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.h
index f14a1f223..ebee158ca 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.h
@@ -1,7 +1,7 @@
// VirtThread.h
-#ifndef __VIRTTHREAD_H
-#define __VIRTTHREAD_H
+#ifndef __VIRT_THREAD_H
+#define __VIRT_THREAD_H
#include "../../Windows/Synchronization.h"
#include "../../Windows/Thread.h"
@@ -11,13 +11,14 @@ struct CVirtThread
NWindows::NSynchronization::CAutoResetEvent StartEvent;
NWindows::NSynchronization::CAutoResetEvent FinishedEvent;
NWindows::CThread Thread;
- bool ExitEvent;
+ bool Exit;
- ~CVirtThread();
+ ~CVirtThread() { WaitThreadFinish(); }
+ void WaitThreadFinish(); // call it in destructor of child class !
WRes Create();
void Start();
- void WaitFinish() { FinishedEvent.Lock(); }
virtual void Execute() = 0;
+ void WaitExecuteFinish() { FinishedEvent.Lock(); }
};
#endif