diff options
Diffstat (limited to 'src/libs/3rdparty/7zip/unix/CPP/7zip/Common')
39 files changed, 4910 insertions, 0 deletions
diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/CWrappers.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/CWrappers.cpp new file mode 100644 index 000000000..a15794e2a --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/CWrappers.cpp @@ -0,0 +1,230 @@ +// CWrappers.h + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "CWrappers.h" + +#include "StreamUtils.h" + +#define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1) + +#define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x) + +static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw() +{ + 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) throw() +{ + p.Progress = CompressProgress; + Progress = progress; + Res = SZ_OK; +} + +static const UInt32 kStreamStepSize = (UInt32)1 << 31; + +SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) +{ + switch (res) + { + case S_OK: return SZ_OK; + case E_OUTOFMEMORY: return SZ_ERROR_MEM; + case E_INVALIDARG: return SZ_ERROR_PARAM; + case E_ABORT: return SZ_ERROR_PROGRESS; + case S_FALSE: return SZ_ERROR_DATA; + case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED; + } + return defaultRes; +} + +static SRes MyRead(void *object, void *data, size_t *size) throw() +{ + CSeqInStreamWrap *p = (CSeqInStreamWrap *)object; + 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) throw() +{ + CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object; + if (p->Stream) + { + p->Res = WriteStream(p->Stream, data, size); + if (p->Res != 0) + return 0; + } + else + p->Res = S_OK; + p->Processed += size; + return size; +} + +CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw() +{ + p.Read = MyRead; + Stream = stream; + Processed = 0; +} + +CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw() +{ + p.Write = MyWrite; + Stream = stream; + Res = SZ_OK; + Processed = 0; +} + +HRESULT SResToHRESULT(SRes res) throw() +{ + switch(res) + { + case SZ_OK: return S_OK; + case SZ_ERROR_MEM: return E_OUTOFMEMORY; + case SZ_ERROR_PARAM: return E_INVALIDARG; + case SZ_ERROR_PROGRESS: return E_ABORT; + case SZ_ERROR_DATA: return S_FALSE; + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; + } + return E_FAIL; +} + +static SRes InStreamWrap_Read(void *pp, void *data, size_t *size) throw() +{ + CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp; + UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); + p->Res = p->Stream->Read(data, curSize, &curSize); + *size = curSize; + return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; +} + +static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw() +{ + CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp; + UInt32 moveMethod; + switch(origin) + { + case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break; + case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break; + case SZ_SEEK_END: moveMethod = STREAM_SEEK_END; break; + default: return SZ_ERROR_PARAM; + } + UInt64 newPosition; + p->Res = p->Stream->Seek(*offset, moveMethod, &newPosition); + *offset = (Int64)newPosition; + return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; +} + +CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw() +{ + Stream = stream; + p.Read = InStreamWrap_Read; + p.Seek = InStreamWrap_Seek; + Res = S_OK; +} + + +/* ---------- CByteInBufWrap ---------- */ + +void CByteInBufWrap::Free() throw() +{ + ::MidFree(Buf); + Buf = 0; +} + +bool CByteInBufWrap::Alloc(UInt32 size) throw() +{ + if (Buf == 0 || size != Size) + { + Free(); + Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size); + Size = size; + } + return (Buf != 0); +} + +Byte CByteInBufWrap::ReadByteFromNewBlock() throw() +{ + if (Res == S_OK) + { + UInt32 avail; + Processed += (Cur - Buf); + Res = Stream->Read(Buf, Size, &avail); + Cur = Buf; + Lim = Buf + avail; + if (avail != 0) + return *Cur++; + } + Extra = true; + return 0; +} + +static Byte Wrap_ReadByte(void *pp) throw() +{ + CByteInBufWrap *p = (CByteInBufWrap *)pp; + if (p->Cur != p->Lim) + return *p->Cur++; + return p->ReadByteFromNewBlock(); +} + +CByteInBufWrap::CByteInBufWrap(): Buf(0) +{ + p.Read = Wrap_ReadByte; +} + + +/* ---------- CByteOutBufWrap ---------- */ + +void CByteOutBufWrap::Free() throw() +{ + ::MidFree(Buf); + Buf = 0; +} + +bool CByteOutBufWrap::Alloc(size_t size) throw() +{ + if (Buf == 0 || size != Size) + { + Free(); + Buf = (Byte *)::MidAlloc(size); + Size = size; + } + return (Buf != 0); +} + +HRESULT CByteOutBufWrap::Flush() throw() +{ + if (Res == S_OK) + { + size_t size = (Cur - Buf); + Res = WriteStream(Stream, Buf, size); + if (Res == S_OK) + Processed += size; + Cur = Buf; + } + return Res; +} + +static void Wrap_WriteByte(void *pp, Byte b) throw() +{ + CByteOutBufWrap *p = (CByteOutBufWrap *)pp; + Byte *dest = p->Cur; + *dest = b; + p->Cur = ++dest; + if (dest == p->Lim) + p->Flush(); +} + +CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0) +{ + p.Write = Wrap_WriteByte; +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/CWrappers.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/CWrappers.h new file mode 100644 index 000000000..4fe7dea3e --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/CWrappers.h @@ -0,0 +1,114 @@ +// CWrappers.h + +#ifndef __C_WRAPPERS_H +#define __C_WRAPPERS_H + +#include "../ICoder.h" +#include "../../Common/MyCom.h" + +struct CCompressProgressWrap +{ + ICompressProgress p; + ICompressProgressInfo *Progress; + HRESULT Res; + + CCompressProgressWrap(ICompressProgressInfo *progress) throw(); +}; + +struct CSeqInStreamWrap +{ + ISeqInStream p; + ISequentialInStream *Stream; + HRESULT Res; + UInt64 Processed; + + CSeqInStreamWrap(ISequentialInStream *stream) throw(); +}; + +struct CSeekInStreamWrap +{ + ISeekInStream p; + IInStream *Stream; + HRESULT Res; + + CSeekInStreamWrap(IInStream *stream) throw(); +}; + +struct CSeqOutStreamWrap +{ + ISeqOutStream p; + ISequentialOutStream *Stream; + HRESULT Res; + UInt64 Processed; + + CSeqOutStreamWrap(ISequentialOutStream *stream) throw(); +}; + +HRESULT SResToHRESULT(SRes res) throw(); + +struct CByteInBufWrap +{ + IByteIn p; + const Byte *Cur; + const Byte *Lim; + Byte *Buf; + UInt32 Size; + ISequentialInStream *Stream; + UInt64 Processed; + bool Extra; + HRESULT Res; + + CByteInBufWrap(); + ~CByteInBufWrap() { Free(); } + void Free() throw(); + bool Alloc(UInt32 size) throw(); + void Init() + { + Lim = Cur = Buf; + Processed = 0; + Extra = false; + Res = S_OK; + } + UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + Byte ReadByteFromNewBlock() throw(); + Byte ReadByte() + { + if (Cur != Lim) + return *Cur++; + return ReadByteFromNewBlock(); + } +}; + +struct CByteOutBufWrap +{ + IByteOut p; + Byte *Cur; + const Byte *Lim; + Byte *Buf; + size_t Size; + ISequentialOutStream *Stream; + UInt64 Processed; + HRESULT Res; + + CByteOutBufWrap() throw(); + ~CByteOutBufWrap() { Free(); } + void Free() throw(); + bool Alloc(size_t size) throw(); + void Init() + { + Cur = Buf; + Lim = Buf + Size; + Processed = 0; + Res = S_OK; + } + UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + HRESULT Flush() throw(); + void WriteByte(Byte b) + { + *Cur++ = b; + if (Cur == Lim) + Flush(); + } +}; + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/Common.pri b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/Common.pri new file mode 100644 index 000000000..a23ad30b1 --- /dev/null +++ b/src/libs/3rdparty/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/3rdparty/7zip/unix/CPP/7zip/Common/CreateCoder.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/CreateCoder.cpp new file mode 100644 index 000000000..01ccbe12a --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/CreateCoder.cpp @@ -0,0 +1,391 @@ +// CreateCoder.cpp + +#include "StdAfx.h" + +#include "../../Windows/Defs.h" +#include "../../Windows/PropVariant.h" + +#include "CreateCoder.h" + +#include "FilterCoder.h" +#include "RegisterCodec.h" + +static const unsigned int kNumCodecsMax = 64; +unsigned int g_NumCodecs = 0; +const CCodecInfo *g_Codecs[kNumCodecsMax]; +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) +{ + NWindows::NCOM::CPropVariant prop; + RINOK(codecsInfo->GetProperty(index, propID, &prop)); + if (prop.vt == VT_EMPTY) + res = 1; + else if (prop.vt == VT_UI4) + res = prop.ulVal; + else + return E_INVALIDARG; + return S_OK; +} + +static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res) +{ + NWindows::NCOM::CPropVariant prop; + RINOK(codecsInfo->GetProperty(index, propID, &prop)); + if (prop.vt == VT_EMPTY) + res = true; + else if (prop.vt == VT_BOOL) + res = VARIANT_BOOLToBool(prop.boolVal); + else + return E_INVALIDARG; + return S_OK; +} + +HRESULT CExternalCodecs::LoadCodecs() +{ + if (GetCodecs) + { + UInt32 num; + RINOK(GetCodecs->GetNumberOfMethods(&num)); + for (UInt32 i = 0; i < num; i++) + { + 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); + } + } + return S_OK; +} + +#endif + +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.IsEqualToNoCase(codec.Name)) + { + methodId = codec.Id; + numInStreams = codec.NumInStreams; + numOutStreams = 1; + return true; + } + } + #ifdef EXTERNAL_CODECS + if (__externalCodecs) + for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++) + { + const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; + if (codec.Name.IsEqualToNoCase(name)) + { + methodId = codec.Id; + numInStreams = codec.NumInStreams; + numOutStreams = codec.NumOutStreams; + return true; + } + } + #endif + return false; +} + +bool FindMethod(DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, UString &name) +{ + UInt32 i; + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if (methodId == codec.Id) + { + name = codec.Name; + return true; + } + } + #ifdef EXTERNAL_CODECS + if (__externalCodecs) + for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++) + { + const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; + if (methodId == codec.Id) + { + name = codec.Name; + return true; + } + } + #endif + 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, + CMyComPtr<ICompressFilter> &filter, + CMyComPtr<ICompressCoder> &coder, + CMyComPtr<ICompressCoder2> &coder2, + bool encode, bool onlyCoder) +{ + UInt32 i; + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if (codec.Id == methodId) + { + if (encode) + { + if (codec.CreateEncoder) + { + void *p = codec.CreateEncoder(); + if (codec.IsFilter) filter = (ICompressFilter *)p; + else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p; + else coder2 = (ICompressCoder2 *)p; + break; + } + } + else + if (codec.CreateDecoder) + { + void *p = codec.CreateDecoder(); + if (codec.IsFilter) filter = (ICompressFilter *)p; + else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p; + else coder2 = (ICompressCoder2 *)p; + break; + } + } + } + + #ifdef EXTERNAL_CODECS + if (!filter && !coder && !coder2 && __externalCodecs) + for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++) + { + const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; + if (codec.Id == methodId) + { + if (encode) + { + if (codec.EncoderIsAssigned) + { + if (codec.IsSimpleCodec()) + { + 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(__externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter)); + } + } + else + { + RINOK(__externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2)); + } + break; + } + } + else + if (codec.DecoderIsAssigned) + { + if (codec.IsSimpleCodec()) + { + 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(__externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter)); + } + } + else + { + RINOK(__externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2)); + } + break; + } + } + } + #endif + + if (onlyCoder && filter) + { + CFilterCoder *coderSpec = new CFilterCoder; + coder = coderSpec; + coderSpec->Filter = filter; + } + return S_OK; +} + +HRESULT CreateCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr<ICompressCoder> &coder, + CMyComPtr<ICompressCoder2> &coder2, + bool encode) +{ + CMyComPtr<ICompressFilter> filter; + return CreateCoder( + EXTERNAL_CODECS_LOC_VARS + methodId, + filter, coder, coder2, encode, true); +} + +HRESULT CreateCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr<ICompressCoder> &coder, bool encode) +{ + CMyComPtr<ICompressFilter> filter; + CMyComPtr<ICompressCoder2> coder2; + return CreateCoder( + EXTERNAL_CODECS_LOC_VARS + methodId, + coder, coder2, encode); +} + +HRESULT CreateFilter( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr<ICompressFilter> &filter, + bool encode) +{ + CMyComPtr<ICompressCoder> coder; + CMyComPtr<ICompressCoder2> coder2; + return CreateCoder( + EXTERNAL_CODECS_LOC_VARS + 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/3rdparty/7zip/unix/CPP/7zip/Common/CreateCoder.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/CreateCoder.h new file mode 100644 index 000000000..fe1f6ccfe --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/CreateCoder.h @@ -0,0 +1,127 @@ +// CreateCoder.h + +#ifndef __CREATE_CODER_H +#define __CREATE_CODER_H + +#include "../../Common/MyCom.h" +#include "../../Common/MyString.h" +#include "../ICoder.h" + +#include "MethodId.h" + +#ifdef EXTERNAL_CODECS + +struct CCodecInfoEx +{ + UString Name; + CMethodId Id; + UInt32 NumInStreams; + UInt32 NumOutStreams; + bool EncoderIsAssigned; + bool DecoderIsAssigned; + + bool IsSimpleCodec() const { return NumOutStreams == 1 && NumInStreams == 1; } + CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {} +}; + +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 __externalCodecs.GetCodecs = compressCodecsInfo; return __externalCodecs.LoadCodecs(); COM_TRY_END } +#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler) + +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 CExternalCodecs __externalCodecs; +#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2, + +#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, + +#else + +#define PUBLIC_ISetCompressCodecsInfo +#define QUERY_ENTRY_ISetCompressCodecsInfo +#define DECL_ISetCompressCodecsInfo +#define IMPL_ISetCompressCodecsInfo +#define EXTERNAL_CODECS_VARS2 +#define DECL_EXTERNAL_CODECS_VARS +#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2 +#define DECL_EXTERNAL_CODECS_LOC_VARS2 +#define EXTERNAL_CODECS_LOC_VARS2 +#define DECL_EXTERNAL_CODECS_LOC_VARS +#define EXTERNAL_CODECS_LOC_VARS + +#endif + +bool FindMethod( + DECL_EXTERNAL_CODECS_LOC_VARS + const UString &name, CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams); + +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 + CMethodId methodId, + CMyComPtr<ICompressFilter> &filter, + CMyComPtr<ICompressCoder> &coder, + CMyComPtr<ICompressCoder2> &coder2, + bool encode, bool onlyCoder); + +HRESULT CreateCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr<ICompressCoder> &coder, + CMyComPtr<ICompressCoder2> &coder2, + bool encode); + +HRESULT CreateCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr<ICompressCoder> &coder, bool encode); + +HRESULT CreateFilter( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + 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/3rdparty/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp new file mode 100644 index 000000000..958360fac --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp @@ -0,0 +1,55 @@ +// FilePathAutoRename.cpp + +#include "StdAfx.h" + +#include "../../Common/Defs.h" +#include "../../Common/IntToString.h" + +#include "../../Windows/FileFind.h" + +#include "FilePathAutoRename.h" + +using namespace NWindows; + +static bool MakeAutoName(const FString &name, + const FString &extension, unsigned value, FString &path) +{ + FChar number[16]; + ConvertUInt32ToString(value, number); + path = name; + path += number; + path += extension; + return NFile::NFind::DoesFileOrDirExist(path); +} + +bool AutoRenamePath(FString &fullProcessedPath) +{ + FString path; + int dotPos = fullProcessedPath.ReverseFind(FTEXT('.')); + + int slashPos = fullProcessedPath.ReverseFind(FTEXT('/')); + #ifdef _WIN32 + int slash1Pos = fullProcessedPath.ReverseFind(FTEXT('\\')); + slashPos = MyMax(slashPos, slash1Pos); + #endif + + FString name, extension; + if (dotPos > slashPos && dotPos > 0) + { + name.SetFrom(fullProcessedPath, dotPos); + extension = fullProcessedPath.Ptr(dotPos); + } + else + name = fullProcessedPath; + name += L'_'; + unsigned left = 1, right = (1 << 30); + while (left != right) + { + unsigned mid = (left + right) / 2; + if (MakeAutoName(name, extension, mid, path)) + left = mid + 1; + else + right = mid; + } + return !MakeAutoName(name, extension, right, fullProcessedPath); +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h new file mode 100644 index 000000000..7b576591c --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h @@ -0,0 +1,10 @@ +// FilePathAutoRename.h + +#ifndef __FILE_PATH_AUTO_RENAME_H +#define __FILE_PATH_AUTO_RENAME_H + +#include "../../Common/MyString.h" + +bool AutoRenamePath(FString &fullProcessedPath); + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FileStreams.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FileStreams.cpp new file mode 100644 index 000000000..ee1cc54e2 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FileStreams.cpp @@ -0,0 +1,435 @@ +// FileStreams.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 +#include <fcntl.h> +#include <unistd.h> +#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) +{ + #ifdef _WIN32 + if (result) + return S_OK; + DWORD lastError = ::GetLastError(); + if (lastError == 0) + return E_FAIL; + return HRESULT_FROM_WIN32(lastError); + #else + return result ? S_OK: E_FAIL; + #endif +} + +#ifdef SUPPORT_DEVICE_FILE + +static const UInt32 kClusterSize = 1 << 18; +CInFileStream::CInFileStream(): + VirtPos(0), + PhyPos(0), + Buf(0), + BufSize(0), + SupportHardLinks(false) +{ +} + +#endif + +CInFileStream::~CInFileStream() +{ + #ifdef SUPPORT_DEVICE_FILE + MidFree(Buf); + #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) + *processedSize = realProcessedSize; + #ifdef SUPPORT_DEVICE_FILE + VirtPos += realProcessedSize; + PhyPos += realProcessedSize; + #endif + return ConvertBoolToHRESULT(result); + + #else + + if (processedSize) + *processedSize = 0; + ssize_t res = File.Read(data, (size_t)size); + if (res == -1) + return E_FAIL; + if (processedSize) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +#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 + + 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) + *processedSize = 0; + ssize_t res; + do + { + res = read(0, data, (size_t)size); + } + while (res < 0 && (errno == EINTR)); + if (res == -1) + return E_FAIL; + if (processedSize) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +#endif + +STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + 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); + + #ifdef SUPPORT_DEVICE_FILE + PhyPos = VirtPos = realNewPosition; + #endif + + if (newPosition) + *newPosition = realNewPosition; + return ConvertBoolToHRESULT(result); + + #else + + off_t res = File.Seek((off_t)offset, seekOrigin); + if (res == -1) + return E_FAIL; + if (newPosition) + *newPosition = (UInt64)res; + return S_OK; + + #endif +} + +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 + +HRESULT COutFileStream::Close() +{ + return ConvertBoolToHRESULT(File.Close()); +} + +STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + #ifdef USE_WIN_FILE + + UInt32 realProcessedSize; + bool result = File.WritePart(data, size, realProcessedSize); + ProcessedSize += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return ConvertBoolToHRESULT(result); + + #else + + if (processedSize) + *processedSize = 0; + ssize_t res = File.Write(data, (size_t)size); + if (res == -1) + return E_FAIL; + if (processedSize) + *processedSize = (UInt32)res; + ProcessedSize += res; + return S_OK; + + #endif +} + +STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + if (seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + #ifdef USE_WIN_FILE + + UInt64 realNewPosition; + bool result = File.Seek(offset, seekOrigin, realNewPosition); + if (newPosition) + *newPosition = realNewPosition; + return ConvertBoolToHRESULT(result); + + #else + + off_t res = File.Seek((off_t)offset, seekOrigin); + if (res == -1) + return E_FAIL; + if (newPosition) + *newPosition = (UInt64)res; + return S_OK; + + #endif +} + +STDMETHODIMP COutFileStream::SetSize(UInt64 newSize) +{ + #ifdef USE_WIN_FILE + UInt64 currentPos; + if (!File.Seek(0, FILE_CURRENT, currentPos)) + return E_FAIL; + bool result = File.SetLength(newSize); + UInt64 currentPos2; + result = result && File.Seek(currentPos, currentPos2); + return result ? S_OK : E_FAIL; + #else + return E_FAIL; + #endif +} + +#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) + *processedSize = 0; + + #ifdef _WIN32 + UInt32 realProcessedSize; + BOOL res = TRUE; + if (size > 0) + { + // Seems that Windows doesn't like big amounts writing to stdout. + // So we limit portions by 32KB. + UInt32 sizeTemp = (1 << 15); + if (sizeTemp > size) + sizeTemp = size; + res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), + data, sizeTemp, (DWORD *)&realProcessedSize, NULL); + size -= realProcessedSize; + data = (const void *)((const Byte *)data + realProcessedSize); + if (processedSize) + *processedSize += realProcessedSize; + } + return ConvertBoolToHRESULT(res != FALSE); + + #else + + ssize_t res; + do + { + res = write(1, data, (size_t)size); + } + while (res < 0 && (errno == EINTR)); + if (res == -1) + return E_FAIL; + if (processedSize) + *processedSize = (UInt32)res; + return S_OK; + + return S_OK; + #endif +} + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FileStreams.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FileStreams.h new file mode 100644 index 000000000..a80cbad4d --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FileStreams.h @@ -0,0 +1,146 @@ +// 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 +#include "../../Common/C_FileIO.h" +#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(); + + bool Open(CFSTR fileName) + { + return File.Open(fileName,_ignoreSymbolicLink); + } + + bool OpenShared(CFSTR fileName , bool /* shareForWrite */ ) + { + return File.Open(fileName,_ignoreSymbolicLink); + } + + 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: + public ISequentialInStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + virtual ~CStdInFileStream() {} + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +class COutFileStream: + public IOutStream, + public CMyUnknownImp +{ +public: + #ifdef USE_WIN_FILE + NWindows::NFile::NIO::COutFile File; + #else + NC::NFile::NIO::COutFile File; + #endif + virtual ~COutFileStream() {} + bool Create(CFSTR fileName, bool createAlways) + { + ProcessedSize = 0; + return File.Create(fileName, createAlways); + } + bool Open(CFSTR fileName, DWORD creationDisposition) + { + ProcessedSize = 0; + return File.Open(fileName, creationDisposition); + } + + HRESULT Close(); + + UInt64 ProcessedSize; + + #ifdef USE_WIN_FILE + bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) + { + return File.SetTime(cTime, aTime, mTime); + } + bool SetMTime(const FILETIME *mTime) { return File.SetMTime(mTime); } + #endif + + + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(UInt64 newSize); +}; + +class CStdOutFileStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + virtual ~CStdOutFileStream() {} + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilterCoder.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilterCoder.cpp new file mode 100644 index 000000000..3a2023b35 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilterCoder.cpp @@ -0,0 +1,265 @@ +// FilterCoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../../Common/Defs.h" + +#include "FilterCoder.h" +#include "StreamUtils.h" + +static const UInt32 kBufferSize = 1 << 17; + +CFilterCoder::CFilterCoder() +{ + _buffer = (Byte *)::MidAlloc(kBufferSize); + if (_buffer == 0) + throw 1; +} + +CFilterCoder::~CFilterCoder() +{ + ::MidFree(_buffer); +} + +HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size) +{ + if (_outSizeIsDefined) + { + UInt64 remSize = _outSize - _nowPos64; + if (size > remSize) + size = (UInt32)remSize; + } + RINOK(WriteStream(outStream, _buffer, size)); + _nowPos64 += size; + return S_OK; +} + +STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + RINOK(Init()); + UInt32 bufferPos = 0; + _outSizeIsDefined = (outSize != 0); + if (_outSizeIsDefined) + _outSize = *outSize; + + 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); + if (bufferPos > endPos) + { + for (; endPos < bufferPos; endPos++) + _buffer[endPos] = 0; + bufferPos = Filter->Filter(_buffer, endPos); + } + + if (bufferPos == 0) + { + if (endPos == 0) + return S_OK; + return WriteWithLimit(outStream, endPos); + } + RINOK(WriteWithLimit(outStream, bufferPos)); + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64)); + } + UInt32 i = 0; + while (bufferPos < endPos) + _buffer[i++] = _buffer[bufferPos++]; + bufferPos = i; + } + return S_OK; +} + +STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream) +{ + _bufferPos = 0; + _outStream = outStream; + return Init(); +} + +STDMETHODIMP CFilterCoder::ReleaseOutStream() +{ + _outStream.Release(); + return S_OK; +} + + +STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != NULL) + *processedSize = 0; + while (size > 0) + { + UInt32 sizeTemp = MyMin(size, kBufferSize - _bufferPos); + memcpy(_buffer + _bufferPos, data, sizeTemp); + size -= sizeTemp; + if (processedSize != NULL) + *processedSize += sizeTemp; + data = (const Byte *)data + sizeTemp; + UInt32 endPos = _bufferPos + sizeTemp; + _bufferPos = Filter->Filter(_buffer, endPos); + if (_bufferPos == 0) + { + _bufferPos = endPos; + break; + } + if (_bufferPos > endPos) + { + if (size != 0) + return E_FAIL; + break; + } + RINOK(WriteWithLimit(_outStream, _bufferPos)); + UInt32 i = 0; + while (_bufferPos < endPos) + _buffer[i++] = _buffer[_bufferPos++]; + _bufferPos = i; + } + return S_OK; +} + +STDMETHODIMP CFilterCoder::Flush() +{ + if (_bufferPos != 0) + { + // _buffer contains only data refused by previous Filter->Filter call. + UInt32 endPos = Filter->Filter(_buffer, _bufferPos); + if (endPos > _bufferPos) + { + for (; _bufferPos < endPos; _bufferPos++) + _buffer[_bufferPos] = 0; + if (Filter->Filter(_buffer, endPos) != endPos) + return E_FAIL; + } + RINOK(WriteWithLimit(_outStream, _bufferPos)); + _bufferPos = 0; + } + CMyComPtr<IOutStreamFlush> flush; + _outStream.QueryInterface(IID_IOutStreamFlush, &flush); + if (flush) + return flush->Flush(); + return S_OK; +} + + +void CFilterCoder::SetInStream_NoSubFilterInit(ISequentialInStream *inStream) +{ + _convertedPosBegin = _convertedPosEnd = _bufferPos = 0; + _inStream = inStream; + Init2(); +} + +STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream) +{ + SetInStream_NoSubFilterInit(inStream); + return Init(); +} + +STDMETHODIMP CFilterCoder::ReleaseInStream() +{ + _inStream.Release(); + return S_OK; +} + +STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != NULL) + *processedSize = 0; + while (size > 0) + { + if (_convertedPosBegin != _convertedPosEnd) + { + UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin); + memcpy(data, _buffer + _convertedPosBegin, sizeTemp); + _convertedPosBegin += sizeTemp; + data = (void *)((Byte *)data + sizeTemp); + size -= sizeTemp; + if (processedSize != NULL) + *processedSize += sizeTemp; + break; + } + UInt32 i; + for (i = 0; _convertedPosEnd + i < _bufferPos; i++) + _buffer[i] = _buffer[_convertedPosEnd + i]; + _bufferPos = i; + _convertedPosBegin = _convertedPosEnd = 0; + size_t processedSizeTemp = kBufferSize - _bufferPos; + RINOK(ReadStream(_inStream, _buffer + _bufferPos, &processedSizeTemp)); + _bufferPos += (UInt32)processedSizeTemp; + _convertedPosEnd = Filter->Filter(_buffer, _bufferPos); + if (_convertedPosEnd == 0) + { + if (_bufferPos == 0) + break; + _convertedPosEnd = _bufferPos; // check it + continue; + } + if (_convertedPosEnd > _bufferPos) + { + for (; _bufferPos < _convertedPosEnd; _bufferPos++) + _buffer[_bufferPos] = 0; + _convertedPosEnd = Filter->Filter(_buffer, _bufferPos); + } + } + return S_OK; +} + +#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 +STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) +{ + return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties); +} + +STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + return _writeCoderProperties->WriteCoderProperties(outStream); +} + +/* +STDMETHODIMP CFilterCoder::ResetSalt() +{ + return _CryptoResetSalt->ResetSalt(); +} +*/ + +STDMETHODIMP CFilterCoder::ResetInitVector() +{ + return _CryptoResetInitVector->ResetInitVector(); +} +#endif + +STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + return _setDecoderProperties->SetDecoderProperties2(data, size); +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilterCoder.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilterCoder.h new file mode 100644 index 000000000..2b8f142f5 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/FilterCoder.h @@ -0,0 +1,142 @@ +// FilterCoder.h + +#ifndef __FILTER_CODER_H +#define __FILTER_CODER_H + +#include "../../Common/MyCom.h" +#include "../ICoder.h" +#include "../IPassword.h" + +#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, + public ICompressSetInStream, + public ISequentialInStream, + public ICompressSetOutStream, + public ISequentialOutStream, + public IOutStreamFlush, + + #ifndef _NO_CRYPTO + public ICryptoSetPassword, + public ICryptoProperties, + #endif + #ifndef EXTRACT_ONLY + public ICompressSetCoderProperties, + public ICompressWriteCoderProperties, + // public ICryptoResetSalt, + public ICryptoResetInitVector, + #endif + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ +protected: + Byte *_buffer; + CMyComPtr<ISequentialInStream> _inStream; + CMyComPtr<ISequentialOutStream> _outStream; + UInt32 _bufferPos; + UInt32 _convertedPosBegin; + UInt32 _convertedPosEnd; + bool _outSizeIsDefined; + UInt64 _outSize; + UInt64 _nowPos64; + + 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; + // CMyComPtr<ICryptoResetSalt> _CryptoResetSalt; + CMyComPtr<ICryptoResetInitVector> _CryptoResetInitVector; + #endif + CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties; +public: + CMyComPtr<ICompressFilter> Filter; + + CFilterCoder(); + ~CFilterCoder(); + HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size); + +public: + MY_QUERYINTERFACE_BEGIN2(ICompressCoder) + MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) + MY_QUERYINTERFACE_ENTRY(ISequentialInStream) + MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream) + MY_QUERYINTERFACE_ENTRY(ISequentialOutStream) + MY_QUERYINTERFACE_ENTRY(IOutStreamFlush) + + #ifndef _NO_CRYPTO + MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword) + MY_QUERYINTERFACE_ENTRY_AG(ICryptoProperties, Filter, _cryptoProperties) + #endif + + #ifndef EXTRACT_ONLY + MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties) + MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties) + // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt) + MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector) + #endif + + MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties) + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \ + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); + STDMETHOD(ReleaseOutStream)(); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Flush)(); + + #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, + const PROPVARIANT *properties, UInt32 numProperties); + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + // STDMETHOD(ResetSalt)(); + STDMETHOD(ResetInitVector)(); + #endif + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + void SetInStream_NoSubFilterInit(ISequentialInStream *inStream); + +}; + +class CInStreamReleaser +{ +public: + CFilterCoder *FilterCoder; + CInStreamReleaser(): FilterCoder(0) {} + ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); } +}; + +class COutStreamReleaser +{ +public: + CFilterCoder *FilterCoder; + COutStreamReleaser(): FilterCoder(0) {} + ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); } +}; + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/InBuffer.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/InBuffer.cpp new file mode 100644 index 000000000..133d95b38 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/InBuffer.cpp @@ -0,0 +1,135 @@ +// InBuffer.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "InBuffer.h" + +CInBufferBase::CInBufferBase() throw(): + _buf(0), + _bufLim(0), + _bufBase(0), + _stream(0), + _processedSize(0), + _bufSize(0), + _wasFinished(false), + NumExtraBytes(0) +{} + +bool CInBuffer::Create(size_t bufSize) throw() +{ + const unsigned kMinBlockSize = 1; + if (bufSize < kMinBlockSize) + bufSize = kMinBlockSize; + if (_bufBase != 0 && _bufSize == bufSize) + return true; + Free(); + _bufSize = bufSize; + _bufBase = (Byte *)::MidAlloc(bufSize); + return (_bufBase != 0); +} + +void CInBuffer::Free() throw() +{ + ::MidFree(_bufBase); + _bufBase = 0; +} + +void CInBufferBase::Init() throw() +{ + _processedSize = 0; + _buf = _bufBase; + _bufLim = _buf; + _wasFinished = false; + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif + NumExtraBytes = 0; +} + +bool CInBufferBase::ReadBlock() +{ + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return false; + #endif + if (_wasFinished) + return false; + _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 + _bufLim = _buf + processed; + _wasFinished = (processed == 0); + return !_wasFinished; +} + +bool CInBufferBase::ReadByte_FromNewBlock(Byte &b) +{ + if (!ReadBlock()) + { + NumExtraBytes++; + b = 0xFF; + return false; + } + b = *_buf++; + return true; +} + +Byte CInBufferBase::ReadByte_FromNewBlock() +{ + if (!ReadBlock()) + { + NumExtraBytes++; + return 0xFF; + } + 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/3rdparty/7zip/unix/CPP/7zip/Common/InBuffer.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/InBuffer.h new file mode 100644 index 000000000..dd3c66808 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/InBuffer.h @@ -0,0 +1,90 @@ +// InBuffer.h + +#ifndef __IN_BUFFER_H +#define __IN_BUFFER_H + +#include "../../Common/MyException.h" +#include "../IStream.h" + +#ifndef _NO_EXCEPTIONS +struct CInBufferException: public CSystemException +{ + CInBufferException(HRESULT errorCode): CSystemException(errorCode) {} +}; +#endif + +class CInBufferBase +{ +protected: + Byte *_buf; + Byte *_bufLim; + Byte *_bufBase; + + ISequentialInStream *_stream; + UInt64 _processedSize; + 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(); + bool ReadByte_FromNewBlock(Byte &b); + Byte ReadByte_FromNewBlock(); + +public: + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + UInt32 NumExtraBytes; + + 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; + } + + void Init() throw(); + + bool ReadByte(Byte &b) + { + if (_buf >= _bufLim) + return ReadByte_FromNewBlock(b); + b = *_buf++; + return true; + } + + Byte ReadByte() + { + if (_buf >= _bufLim) + return ReadByte_FromNewBlock(); + return *_buf++; + } + + 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/3rdparty/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp new file mode 100644 index 000000000..be65ba32f --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp @@ -0,0 +1,119 @@ +// InOutTempBuffer.cpp + +#include "StdAfx.h" + +#include "../../../C/7zCrc.h" + +#include "../../Common/Defs.h" + +#include "InOutTempBuffer.h" +#include "StreamUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static const UInt32 kTempBufSize = (1 << 20); + +static CFSTR kTempFilePrefixString = FTEXT("7zt"); + +CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { } + +void CInOutTempBuffer::Create() +{ + if (!_buf) + _buf = new Byte[kTempBufSize]; +} + +CInOutTempBuffer::~CInOutTempBuffer() +{ + delete []_buf; +} + +void CInOutTempBuffer::InitWriting() +{ + _bufPos = 0; + _tempFileCreated = false; + _size = 0; + _crc = CRC_INIT_VAL; +} + +bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size) +{ + if (size == 0) + return true; + if (!_tempFileCreated) + { + if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile)) + return false; + _tempFileCreated = true; + } + UInt32 processed; + if (!_outFile.Write(data, size, processed)) + return false; + _crc = CrcUpdate(_crc, data, processed); + _size += processed; + return (processed == size); +} + +bool CInOutTempBuffer::Write(const void *data, UInt32 size) +{ + if (_bufPos < kTempBufSize) + { + UInt32 cur = MyMin(kTempBufSize - _bufPos, size); + memcpy(_buf + _bufPos, data, cur); + _crc = CrcUpdate(_crc, data, cur); + _bufPos += cur; + size -= cur; + data = ((const Byte *)data) + cur; + _size += cur; + } + return WriteToFile(data, size); +} + +HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) +{ + if (!_outFile.Close()) + return E_FAIL; + + UInt64 size = 0; + UInt32 crc = CRC_INIT_VAL; + + if (_bufPos > 0) + { + RINOK(WriteStream(stream, _buf, _bufPos)); + crc = CrcUpdate(crc, _buf, _bufPos); + size += _bufPos; + } + if (_tempFileCreated) + { + NIO::CInFile inFile; + if (!inFile.Open(_tempFile.GetPath())) + return E_FAIL; + while (size < _size) + { + UInt32 processed; + if (!inFile.ReadPart(_buf, kTempBufSize, processed)) + return E_FAIL; + if (processed == 0) + break; + RINOK(WriteStream(stream, _buf, processed)); + crc = CrcUpdate(crc, _buf, processed); + size += processed; + } + } + return (_crc == crc && size == _size) ? S_OK : E_FAIL; +} + +STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed) +{ + if (!_buf->Write(data, size)) + { + if (processed != NULL) + *processed = 0; + return E_FAIL; + } + if (processed != NULL) + *processed = size; + return S_OK; +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h new file mode 100644 index 000000000..256d72420 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h @@ -0,0 +1,46 @@ +// InOutTempBuffer.h + +#ifndef __IN_OUT_TEMP_BUFFER_H +#define __IN_OUT_TEMP_BUFFER_H + +#include "../../Common/MyCom.h" +#include "../../Windows/FileDir.h" + +#include "../IStream.h" + +class CInOutTempBuffer +{ + NWindows::NFile::NDir::CTempFile _tempFile; + NWindows::NFile::NIO::COutFile _outFile; + Byte *_buf; + UInt32 _bufPos; + bool _tempFileCreated; + UInt64 _size; + UInt32 _crc; + + bool WriteToFile(const void *data, UInt32 size); +public: + CInOutTempBuffer(); + ~CInOutTempBuffer(); + void Create(); + + void InitWriting(); + bool Write(const void *data, UInt32 size); + + HRESULT WriteToStream(ISequentialOutStream *stream); + UInt64 GetDataSize() const { return _size; } +}; + +class CSequentialOutTempBufferImp: + public ISequentialOutStream, + public CMyUnknownImp +{ + CInOutTempBuffer *_buf; +public: + void Init(CInOutTempBuffer *buffer) { _buf = buffer; } + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp new file mode 100644 index 000000000..5f20dcda4 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp @@ -0,0 +1,349 @@ +// LimitedStreams.cpp + +#include "StdAfx.h" + +#include "LimitedStreams.h" +#include "../../Common/Defs.h" + +STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + UInt32 sizeToRead = (UInt32)MyMin((_size - _pos), (UInt64)size); + HRESULT result = S_OK; + if (sizeToRead > 0) + { + result = _stream->Read(data, sizeToRead, &realProcessedSize); + _pos += realProcessedSize; + if (realProcessedSize == 0) + _wasFinished = true; + } + if (processedSize) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CLimitedInStream::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; + if (newPos != _physPos) + { + _physPos = newPos; + RINOK(SeekToPhys()); + } + HRESULT res = _stream->Read(data, size, &size); + if (processedSize) + *processedSize = size; + _physPos += size; + _virtPos += size; + return res; +} + +STDMETHODIMP CLimitedInStream::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; +} + +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) + *processedSize = 0; + if (_virtPos >= Size) + return S_OK; + + if (_curRem == 0) + { + UInt32 blockSize = (UInt32)1 << BlockSizeLog; + UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog); + UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); + UInt32 phyBlock = Vector[virtBlock]; + UInt64 newPos = StartOffset + ((UInt64)phyBlock << BlockSizeLog) + offsetInBlock; + if (newPos != _physPos) + { + _physPos = newPos; + RINOK(SeekToPhys()); + } + _curRem = blockSize - offsetInBlock; + for (int i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++) + _curRem += (UInt32)1 << BlockSizeLog; + UInt64 rem = Size - _virtPos; + if (_curRem > rem) + _curRem = (UInt32)rem; + } + if (size > _curRem) + size = _curRem; + HRESULT res = Stream->Read(data, size, &size); + if (processedSize) + *processedSize = size; + _physPos += size; + _virtPos += size; + _curRem -= size; + return res; +} + +STDMETHODIMP CClusterInStream::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; + if (_virtPos != (UInt64)offset) + _curRem = 0; + _virtPos = offset; + if (newPosition) + *newPosition = offset; + return S_OK; +} + + +STDMETHODIMP CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + 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) + *processedSize = 0; + if (size > _size) + { + if (_size == 0) + { + _overflow = true; + if (!_overflowIsAllowed) + return E_FAIL; + if (processedSize) + *processedSize = size; + return S_OK; + } + size = (UInt32)_size; + } + if (_stream) + result = _stream->Write(data, size, &size); + _size -= size; + 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/3rdparty/7zip/unix/CPP/7zip/Common/LimitedStreams.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/LimitedStreams.h new file mode 100644 index 000000000..b14616f3b --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/LimitedStreams.h @@ -0,0 +1,251 @@ +// LimitedStreams.h + +#ifndef __LIMITED_STREAMS_H +#define __LIMITED_STREAMS_H + +#include "../../Common/MyBuffer.h" +#include "../../Common/MyCom.h" +#include "../../Common/MyVector.h" +#include "../IStream.h" + +class CLimitedSequentialInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + CMyComPtr<ISequentialInStream> _stream; + UInt64 _size; + UInt64 _pos; + bool _wasFinished; +public: + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(UInt64 streamSize) + { + _size = streamSize; + _pos = 0; + _wasFinished = false; + } + + MY_UNKNOWN_IMP1(ISequentialInStream) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + UInt64 GetSize() const { return _pos; } + bool WasFinished() const { return _wasFinished; } +}; + +class CLimitedInStream: + public IInStream, + public CMyUnknownImp +{ + CMyComPtr<IInStream> _stream; + UInt64 _virtPos; + UInt64 _physPos; + UInt64 _size; + UInt64 _startOffset; + + HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } +public: + void SetStream(IInStream *stream) { _stream = stream; } + 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); } +}; + +HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream); + +class CClusterInStream: + public IInStream, + public CMyUnknownImp +{ + UInt64 _virtPos; + UInt64 _physPos; + UInt32 _curRem; +public: + CMyComPtr<IInStream> Stream; + UInt64 StartOffset; + UInt64 Size; + unsigned BlockSizeLog; + CRecordVector<UInt32> Vector; + + HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } + + HRESULT InitAndSeek() + { + _curRem = 0; + _virtPos = 0; + _physPos = StartOffset; + if (Vector.Size() > 0) + { + _physPos = StartOffset + (Vector[0] << BlockSizeLog); + return SeekToPhys(); + } + return S_OK; + } + + MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +}; + +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, + public CMyUnknownImp +{ + CMyComPtr<ISequentialOutStream> _stream; + UInt64 _size; + bool _overflow; + bool _overflowIsAllowed; +public: + MY_UNKNOWN_IMP1(ISequentialOutStream) + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(UInt64 size, bool overflowIsAllowed = false) + { + _size = size; + _overflow = false; + _overflowIsAllowed = overflowIsAllowed; + } + bool IsFinishedOK() const { return (_size == 0 && !_overflow); } + 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/3rdparty/7zip/unix/CPP/7zip/Common/LockedStream.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/LockedStream.cpp new file mode 100644 index 000000000..f05601cb6 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/LockedStream.cpp @@ -0,0 +1,23 @@ +// LockedStream.cpp + +#include "StdAfx.h" + +#include "LockedStream.h" + +HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size, + UInt32 *processedSize) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL)); + return _stream->Read(data, size, processedSize); +} + +STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize); + _pos += realProcessedSize; + if (processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/LockedStream.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/LockedStream.h new file mode 100644 index 000000000..486e4220b --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/LockedStream.h @@ -0,0 +1,38 @@ +// LockedStream.h + +#ifndef __LOCKEDSTREAM_H +#define __LOCKEDSTREAM_H + +#include "../../Windows/Synchronization.h" +#include "../../Common/MyCom.h" +#include "../IStream.h" + +class CLockedInStream +{ + CMyComPtr<IInStream> _stream; + NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + void Init(IInStream *stream) + { _stream = stream; } + HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize); +}; + +class CLockedSequentialInStreamImp: + public ISequentialInStream, + public CMyUnknownImp +{ + CLockedInStream *_lockedInStream; + UInt64 _pos; +public: + void Init(CLockedInStream *lockedInStream, UInt64 startPos) + { + _lockedInStream = lockedInStream; + _pos = startPos; + } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/MethodId.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/MethodId.h new file mode 100644 index 000000000..28b615fcd --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/MethodId.h @@ -0,0 +1,10 @@ +// MethodId.h + +#ifndef __7Z_METHOD_ID_H +#define __7Z_METHOD_ID_H + +#include "../../Common/MyTypes.h" + +typedef UInt64 CMethodId; + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/MethodProps.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/MethodProps.cpp new file mode 100644 index 000000000..ff61995b7 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/MethodProps.cpp @@ -0,0 +1,441 @@ +// MethodProps.cpp + +#include "StdAfx.h" + +#include "../../Common/StringToInt.h" + +#include "MethodProps.h" + +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 + + 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) +{ + if (name.IsEmpty()) + { + switch (prop.vt) + { + case VT_UI4: + numThreads = prop.ulVal; + break; + default: + { + bool val; + RINOK(PROPVARIANT_to_bool(prop, val)); + numThreads = (val ? defaultNumThreads : 1); + break; + } + } + 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 ¶m, 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)) + { + 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) + { + bool res; + if (!StringToBool(value, res)) + return E_INVALIDARG; + propValue = res; + } + else if (!value.IsEmpty()) + { + 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 ¶m = 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; + } + 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/3rdparty/7zip/unix/CPP/7zip/Common/MethodProps.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/MethodProps.h new file mode 100644 index 000000000..39e2ee937 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/MethodProps.h @@ -0,0 +1,185 @@ +// MethodProps.h + +#ifndef __7Z_METHOD_PROPS_H +#define __7Z_METHOD_PROPS_H + +#include "../../Common/MyString.h" + +#include "../../Windows/PropVariant.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 CProps +{ + 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; +}; + +class CMethodProps: public CProps +{ + 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); +}; + +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/3rdparty/7zip/unix/CPP/7zip/Common/OutBuffer.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/OutBuffer.cpp new file mode 100644 index 000000000..4ba34a053 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/OutBuffer.cpp @@ -0,0 +1,111 @@ +// OutBuffer.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "OutBuffer.h" + +bool COutBuffer::Create(UInt32 bufSize) throw() +{ + const UInt32 kMinBlockSize = 1; + if (bufSize < kMinBlockSize) + bufSize = kMinBlockSize; + if (_buf != 0 && _bufSize == bufSize) + return true; + Free(); + _bufSize = bufSize; + _buf = (Byte *)::MidAlloc(bufSize); + return (_buf != 0); +} + +void COutBuffer::Free() throw() +{ + ::MidFree(_buf); + _buf = 0; +} + +void COutBuffer::Init() throw() +{ + _streamPos = 0; + _limitPos = _bufSize; + _pos = 0; + _processedSize = 0; + _overDict = false; + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + +UInt64 COutBuffer::GetProcessedSize() const throw() +{ + UInt64 res = _processedSize + _pos - _streamPos; + if (_streamPos > _pos) + res += _bufSize; + return res; +} + + +HRESULT COutBuffer::FlushPart() throw() +{ + // _streamPos < _bufSize + UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos); + HRESULT result = S_OK; + #ifdef _NO_EXCEPTIONS + result = ErrorCode; + #endif + if (_buf2 != 0) + { + memcpy(_buf2, _buf + _streamPos, size); + _buf2 += size; + } + + if (_stream != 0 + #ifdef _NO_EXCEPTIONS + && (ErrorCode == S_OK) + #endif + ) + { + UInt32 processedSize = 0; + result = _stream->Write(_buf + _streamPos, size, &processedSize); + size = processedSize; + } + _streamPos += size; + if (_streamPos == _bufSize) + _streamPos = 0; + if (_pos == _bufSize) + { + _overDict = true; + _pos = 0; + } + _limitPos = (_streamPos > _pos) ? _streamPos : _bufSize; + _processedSize += size; + return result; +} + +HRESULT COutBuffer::Flush() throw() +{ + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return ErrorCode; + #endif + + while (_streamPos != _pos) + { + HRESULT result = FlushPart(); + if (result != S_OK) + return result; + } + return S_OK; +} + +void COutBuffer::FlushWithCheck() +{ + HRESULT result = Flush(); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else + if (result != S_OK) + throw COutBufferException(result); + #endif +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/OutBuffer.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/OutBuffer.h new file mode 100644 index 000000000..0baad3636 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/OutBuffer.h @@ -0,0 +1,63 @@ +// OutBuffer.h + +#ifndef __OUT_BUFFER_H +#define __OUT_BUFFER_H + +#include "../IStream.h" +#include "../../Common/MyCom.h" +#include "../../Common/MyException.h" + +#ifndef _NO_EXCEPTIONS +struct COutBufferException: public CSystemException +{ + COutBufferException(HRESULT errorCode): CSystemException(errorCode) {} +}; +#endif + +class COutBuffer +{ +protected: + Byte *_buf; + UInt32 _pos; + UInt32 _limitPos; + UInt32 _streamPos; + UInt32 _bufSize; + ISequentialOutStream *_stream; + UInt64 _processedSize; + Byte *_buf2; + bool _overDict; + + HRESULT FlushPart() throw(); +public: + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + + COutBuffer(): _buf(0), _pos(0), _stream(0), _buf2(0) {} + ~COutBuffer() { Free(); } + + 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 WriteByte(Byte b) + { + _buf[_pos++] = b; + if (_pos == _limitPos) + FlushWithCheck(); + } + void WriteBytes(const void *data, size_t size) + { + for (size_t i = 0; i < size; i++) + WriteByte(((const Byte *)data)[i]); + } + + UInt64 GetProcessedSize() const throw(); +}; + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp new file mode 100644 index 000000000..bac45c1c2 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp @@ -0,0 +1,42 @@ +// ProgressUtils.cpp + +#include "StdAfx.h" + +#include "ProgressUtils.h" + +CLocalProgress::CLocalProgress() +{ + ProgressOffset = InSize = OutSize = 0; + SendRatio = SendProgress = true; +} + +void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) +{ + _ratioProgress.Release(); + _progress = progress; + _progress.QueryInterface(IID_ICompressProgressInfo, &_ratioProgress); + _inSizeIsMain = inSizeIsMain; +} + +STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + UInt64 inSizeNew = InSize, outSizeNew = OutSize; + if (inSize) + inSizeNew += (*inSize); + if (outSize) + outSizeNew += (*outSize); + if (SendRatio && _ratioProgress) + { + RINOK(_ratioProgress->SetRatioInfo(&inSizeNew, &outSizeNew)); + } + inSizeNew += ProgressOffset; + outSizeNew += ProgressOffset; + if (SendProgress) + return _progress->SetCompleted(_inSizeIsMain ? &inSizeNew : &outSizeNew); + return S_OK; +} + +HRESULT CLocalProgress::SetCur() +{ + return SetRatioInfo(NULL, NULL); +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/ProgressUtils.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/ProgressUtils.h new file mode 100644 index 000000000..bae5395c1 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/ProgressUtils.h @@ -0,0 +1,34 @@ +// ProgressUtils.h + +#ifndef __PROGRESSUTILS_H +#define __PROGRESSUTILS_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" +#include "../IProgress.h" + +class CLocalProgress: + public ICompressProgressInfo, + public CMyUnknownImp +{ + CMyComPtr<IProgress> _progress; + CMyComPtr<ICompressProgressInfo> _ratioProgress; + bool _inSizeIsMain; +public: + UInt64 ProgressOffset; + UInt64 InSize; + UInt64 OutSize; + bool SendRatio; + bool SendProgress; + + CLocalProgress(); + void Init(IProgress *progress, bool inSizeIsMain); + HRESULT SetCur(); + + MY_UNKNOWN_IMP + + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/PropId.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/PropId.cpp new file mode 100644 index 000000000..10daef715 --- /dev/null +++ b/src/libs/3rdparty/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/3rdparty/7zip/unix/CPP/7zip/Common/RegisterArc.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/RegisterArc.h new file mode 100644 index 000000000..82bd09673 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/RegisterArc.h @@ -0,0 +1,73 @@ +// RegisterArc.h + +#ifndef __REGISTER_ARC_H +#define __REGISTER_ARC_H + +#include "../Archive/IArchive.h" + +#include <mutex> + +struct CArcInfo +{ + const char *Name; + const char *Ext; + const char *AddExt; + + Byte ClassId; + + 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) throw(); + +#define REGISTER_ARC_NAME(x) CRegister ## x + +#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/3rdparty/7zip/unix/CPP/7zip/Common/RegisterCodec.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/RegisterCodec.h new file mode 100644 index 000000000..0c6662a6c --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/RegisterCodec.h @@ -0,0 +1,66 @@ +// RegisterCodec.h + +#ifndef __REGISTER_CODEC_H +#define __REGISTER_CODEC_H + +#include "../Common/MethodId.h" +#include "../ICoder.h" + +#include <mutex> + +typedef void * (*CreateCodecP)(); +struct CCodecInfo +{ + CreateCodecP CreateDecoder; + CreateCodecP CreateEncoder; + CMethodId Id; + const wchar_t *Name; + UInt32 NumInStreams; + bool IsFilter; + std::once_flag once; +}; + +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)() \ + { \ + 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 (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/3rdparty/7zip/unix/CPP/7zip/Common/StreamBinder.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamBinder.cpp new file mode 100644 index 000000000..43feef1ba --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamBinder.cpp @@ -0,0 +1,129 @@ +// StreamBinder.cpp + +#include "StdAfx.h" + +#include "../../Common/MyCom.h" + +#include "StreamBinder.h" + +class CBinderInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + CStreamBinder *_binder; +public: + MY_UNKNOWN_IMP + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + ~CBinderInStream() { _binder->CloseRead(); } + CBinderInStream(CStreamBinder *binder): _binder(binder) {} +}; + +STDMETHODIMP CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) + { return _binder->Read(data, size, processedSize); } + +class CBinderOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + CStreamBinder *_binder; +public: + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + ~CBinderOutStream() { _binder->CloseWrite(); } + CBinderOutStream(CStreamBinder *binder): _binder(binder) {} +}; + +STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) + { return _binder->Write(data, size, processedSize); } + + + +WRes CStreamBinder::CreateEvents() +{ + _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() +{ + _waitWrite = true; + _canRead_Event.Reset(); + _readingWasClosed_Event.Reset(); + ProcessedSize = 0; +} + + +void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream) +{ + _waitWrite = true; + _bufSize = 0; + _buf = NULL; + ProcessedSize = 0; + + CBinderInStream *inStreamSpec = new CBinderInStream(this); + CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); + *inStream = inStreamLoc.Detach(); + + CBinderOutStream *outStreamSpec = new CBinderOutStream(this); + CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec); + *outStream = outStreamLoc.Detach(); +} + +// (_canRead_Event && _bufSize == 0) means that stream is finished. + +HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size != 0) + { + if (_waitWrite) + { + 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) + { + _waitWrite = true; + _canRead_Event.Reset(); + _canWrite_Event.Set(); + } + } + } + return S_OK; +} + +HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size != 0) + { + _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) + return S_FALSE; + if (processedSize) + *processedSize = size; + } + return S_OK; +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamBinder.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamBinder.h new file mode 100644 index 000000000..aba6b8e17 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamBinder.h @@ -0,0 +1,35 @@ +// StreamBinder.h + +#ifndef __STREAM_BINDER_H +#define __STREAM_BINDER_H + +#include "../../Windows/Synchronization.h" + +#include "../IStream.h" + +class CStreamBinder +{ + 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: + UInt64 ProcessedSize; + + WRes CreateEvents(); + void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream); + void ReInit(); + HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); + HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize); + void CloseRead() { _readingWasClosed_Event.Set(); } + void CloseWrite() + { + // _bufSize must be = 0 + _canRead_Event.Set(); + } +}; + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamObjects.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamObjects.cpp new file mode 100644 index 000000000..7721c3a7e --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamObjects.cpp @@ -0,0 +1,250 @@ +// StreamObjects.cpp + +#include "StdAfx.h" + +#include <stdlib.h> + +#include "../../../C/Alloc.h" + +#include "StreamObjects.h" + +STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (_pos >= _size) + return S_OK; + size_t rem = _size - (size_t)_pos; + if (rem > size) + rem = (size_t)size; + memcpy(data, _data + (size_t)_pos, rem); + _pos += rem; + if (processedSize) + *processedSize = (UInt32)rem; + return S_OK; +} + +STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + switch (seekOrigin) + { + 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 = offset; + return S_OK; +} + +/* +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) throw() +{ + if (cap <= _capacity) + return true; + size_t delta; + if (_capacity > 64) + delta = _capacity / 4; + else if (_capacity > 8) + delta = 16; + else + delta = 4; + cap = MyMax(_capacity + delta, cap); + Byte *buf = (Byte *)realloc(_buf, cap); + if (!buf) + return false; + _buf = buf; + _capacity = cap; + return true; +} + +Byte *CDynBufSeqOutStream::GetBufPtrForWriting(size_t addSize) +{ + addSize += _size; + if (addSize < _size) + return NULL; + if (!_buffer.EnsureCapacity(addSize)) + return NULL; + return (Byte *)_buffer + _size; +} + +void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const +{ + dest.CopyFrom((const Byte *)_buffer, _size); +} + +STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + Byte *buf = GetBufPtrForWriting(size); + if (!buf) + return E_OUTOFMEMORY; + memcpy(buf, data, size); + UpdateSize(size); + if (processedSize) + *processedSize = size; + return S_OK; +} + +STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + size_t rem = _size - _pos; + if (rem > size) + rem = (size_t)size; + memcpy(_buffer + _pos, data, rem); + _pos += rem; + if (processedSize) + *processedSize = (UInt32)rem; + return (rem != 0 || size == 0) ? S_OK : E_FAIL; +} + +STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Write(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return result; +} + +static const UInt64 kEmptyTag = (UInt64)(Int64)-1; + +void CCachedInStream::Free() throw() +{ + MyFree(_tags); + _tags = 0; + MidFree(_data); + _data = 0; +} + +bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw() +{ + unsigned sizeLog = blockSizeLog + numBlocksLog; + if (sizeLog >= sizeof(size_t) * 8) + return false; + size_t dataSize = (size_t)1 << sizeLog; + if (_data == 0 || dataSize != _dataSize) + { + MidFree(_data); + _data = (Byte *)MidAlloc(dataSize); + if (_data == 0) + return false; + _dataSize = dataSize; + } + if (_tags == 0 || numBlocksLog != _numBlocksLog) + { + MyFree(_tags); + _tags = (UInt64 *)MyAlloc(sizeof(UInt64) << numBlocksLog); + if (_tags == 0) + return false; + _numBlocksLog = numBlocksLog; + } + _blockSizeLog = blockSizeLog; + return true; +} + +void CCachedInStream::Init(UInt64 size) throw() +{ + _size = size; + _pos = 0; + size_t numBlocks = (size_t)1 << _numBlocksLog; + for (size_t i = 0; i < numBlocks; i++) + _tags[i] = kEmptyTag; +} + +STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (_pos >= _size) + return S_OK; + + { + UInt64 rem = _size - _pos; + if (size > rem) + size = (UInt32)rem; + } + + while (size != 0) + { + UInt64 cacheTag = _pos >> _blockSizeLog; + size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1); + Byte *p = _data + (cacheIndex << _blockSizeLog); + if (_tags[cacheIndex] != cacheTag) + { + UInt64 remInBlock = _size - (cacheTag << _blockSizeLog); + size_t blockSize = (size_t)1 << _blockSizeLog; + if (blockSize > remInBlock) + blockSize = (size_t)remInBlock; + RINOK(ReadBlock(cacheTag, p, blockSize)); + _tags[cacheIndex] = cacheTag; + } + size_t offset = (size_t)_pos & (((size_t)1 << _blockSizeLog) - 1); + UInt32 cur = (UInt32)MyMin(((size_t)1 << _blockSizeLog) - offset, (size_t)size); + memcpy(data, p + offset, cur); + if (processedSize) + *processedSize += cur; + data = (void *)((const Byte *)data + cur); + _pos += cur; + size -= cur; + } + + return S_OK; +} + +STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + switch (seekOrigin) + { + 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 = offset; + return S_OK; +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamObjects.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamObjects.h new file mode 100644 index 000000000..d0c86b566 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamObjects.h @@ -0,0 +1,140 @@ +// StreamObjects.h + +#ifndef __STREAM_OBJECTS_H +#define __STREAM_OBJECTS_H + +#include "../../Common/MyBuffer.h" +#include "../../Common/MyCom.h" +#include "../../Common/MyVector.h" + +#include "../IStream.h" + +struct CReferenceBuf: + public IUnknown, + public CMyUnknownImp +{ + CByteBuffer Buf; + MY_UNKNOWN_IMP +}; + +class CBufInStream: + public IInStream, + public CMyUnknownImp +{ + const Byte *_data; + UInt64 _pos; + size_t _size; + CMyComPtr<IUnknown> _ref; +public: + void Init(const Byte *data, size_t size, IUnknown *ref = 0) + { + _data = data; + _size = size; + _pos = 0; + _ref = ref; + } + void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.Size(), ref); } + + MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +}; + +// 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; + Byte *_buf; +public: + CByteDynBuffer(): _capacity(0), _buf(0) {}; + // there is no copy constructor. So don't copy this object. + ~CByteDynBuffer() { Free(); } + 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) throw(); +}; + +class CDynBufSeqOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + CByteDynBuffer _buffer; + size_t _size; +public: + CDynBufSeqOutStream(): _size(0) {} + void Init() { _size = 0; } + size_t GetSize() const { return _size; } + const Byte *GetBuffer() const { return _buffer; } + void CopyToBuffer(CByteBuffer &dest) const; + Byte *GetBufPtrForWriting(size_t addSize); + void UpdateSize(size_t addSize) { _size += addSize; } + + MY_UNKNOWN_IMP1(ISequentialOutStream) + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +class CBufPtrSeqOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + Byte *_buffer; + size_t _size; + size_t _pos; +public: + void Init(Byte *buffer, size_t size) + { + _buffer = buffer; + _pos = 0; + _size = size; + } + size_t GetPos() const { return _pos; } + + MY_UNKNOWN_IMP1(ISequentialOutStream) + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +class CSequentialOutStreamSizeCount: + public ISequentialOutStream, + public CMyUnknownImp +{ + CMyComPtr<ISequentialOutStream> _stream; + UInt64 _size; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void Init() { _size = 0; } + UInt64 GetSize() const { return _size; } + + MY_UNKNOWN_IMP1(ISequentialOutStream) + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +class CCachedInStream: + public IInStream, + public CMyUnknownImp +{ + UInt64 *_tags; + Byte *_data; + size_t _dataSize; + unsigned _blockSizeLog; + unsigned _numBlocksLog; + UInt64 _size; + UInt64 _pos; +protected: + virtual HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) = 0; +public: + CCachedInStream(): _tags(0), _data(0) {} + virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!! + void Free() throw(); + bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw(); + void Init(UInt64 size) throw(); + + MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +}; + +#endif diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamUtils.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamUtils.cpp new file mode 100644 index 000000000..1402f4205 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamUtils.cpp @@ -0,0 +1,56 @@ +// StreamUtils.cpp + +#include "StdAfx.h" + +#include "StreamUtils.h" + +static const UInt32 kBlockSize = ((UInt32)1 << 31); + +HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw() +{ + size_t size = *processedSize; + *processedSize = 0; + while (size != 0) + { + UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; + UInt32 processedSizeLoc; + HRESULT res = stream->Read(data, curSize, &processedSizeLoc); + *processedSize += processedSizeLoc; + data = (void *)((Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + return S_OK; + } + return S_OK; +} + +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) 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) throw() +{ + while (size != 0) + { + UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; + UInt32 processedSizeLoc; + HRESULT res = stream->Write(data, curSize, &processedSizeLoc); + data = (const void *)((const Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + return E_FAIL; + } + return S_OK; +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamUtils.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamUtils.h new file mode 100644 index 000000000..ae914c004 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/StreamUtils.h @@ -0,0 +1,13 @@ +// StreamUtils.h + +#ifndef __STREAM_UTILS_H +#define __STREAM_UTILS_H + +#include "../IStream.h" + +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/3rdparty/7zip/unix/CPP/7zip/Common/UniqBlocks.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/UniqBlocks.cpp new file mode 100644 index 000000000..7fcc88f5e --- /dev/null +++ b/src/libs/3rdparty/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/3rdparty/7zip/unix/CPP/7zip/Common/UniqBlocks.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/UniqBlocks.h new file mode 100644 index 000000000..9c08b09f4 --- /dev/null +++ b/src/libs/3rdparty/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/3rdparty/7zip/unix/CPP/7zip/Common/VirtThread.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/VirtThread.cpp new file mode 100644 index 000000000..77e3c1acf --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/VirtThread.cpp @@ -0,0 +1,48 @@ +// VirtThread.cpp + +#include "StdAfx.h" + +#include "VirtThread.h" + +static THREAD_FUNC_DECL CoderThread(void *p) +{ + for (;;) + { + CVirtThread *t = (CVirtThread *)p; + t->StartEvent.Lock(); + if (t->Exit) + return 0; + t->Execute(); + t->FinishedEvent.Set(); + } +} + +WRes CVirtThread::Create() +{ + RINOK(StartEvent.CreateIfNotCreated()); + RINOK(FinishedEvent.CreateIfNotCreated()); + StartEvent.Reset(); + FinishedEvent.Reset(); + Exit = false; + if (Thread.IsCreated()) + return S_OK; + return Thread.Create(CoderThread, this); +} + +void CVirtThread::Start() +{ + Exit = false; + StartEvent.Set(); +} + +void CVirtThread::WaitThreadFinish() +{ + Exit = true; + if (StartEvent.IsCreated()) + StartEvent.Set(); + if (Thread.IsCreated()) + { + Thread.Wait(); + Thread.Close(); + } +} diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/VirtThread.h b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/VirtThread.h new file mode 100644 index 000000000..ebee158ca --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Common/VirtThread.h @@ -0,0 +1,24 @@ +// VirtThread.h + +#ifndef __VIRT_THREAD_H +#define __VIRT_THREAD_H + +#include "../../Windows/Synchronization.h" +#include "../../Windows/Thread.h" + +struct CVirtThread +{ + NWindows::NSynchronization::CAutoResetEvent StartEvent; + NWindows::NSynchronization::CAutoResetEvent FinishedEvent; + NWindows::CThread Thread; + bool Exit; + + ~CVirtThread() { WaitThreadFinish(); } + void WaitThreadFinish(); // call it in destructor of child class ! + WRes Create(); + void Start(); + virtual void Execute() = 0; + void WaitExecuteFinish() { FinishedEvent.Lock(); } +}; + +#endif |