Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2008-05-05 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:55 +0300
commit3901bf0ab88106a5b031cba7bc18d60cdebf7eef (patch)
tree808a2489abed822223b118b64e0553db80af6087 /CPP/7zip/Archive/Lzma
parentbd1fa36322ac27f5715433b388742893d6524516 (diff)
4.58 beta
Diffstat (limited to 'CPP/7zip/Archive/Lzma')
-rwxr-xr-xCPP/7zip/Archive/Lzma/LzmaArcRegister.cpp14
-rwxr-xr-xCPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp86
-rwxr-xr-xCPP/7zip/Archive/Lzma/LzmaFiltersDecode.h26
-rwxr-xr-xCPP/7zip/Archive/Lzma/LzmaHandler.cpp243
-rwxr-xr-xCPP/7zip/Archive/Lzma/LzmaHandler.h69
-rwxr-xr-xCPP/7zip/Archive/Lzma/LzmaIn.cpp56
-rwxr-xr-xCPP/7zip/Archive/Lzma/LzmaIn.h16
-rwxr-xr-xCPP/7zip/Archive/Lzma/LzmaItem.h27
-rwxr-xr-xCPP/7zip/Archive/Lzma/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Lzma/lzma.icobin0 -> 3638 bytes
10 files changed, 545 insertions, 0 deletions
diff --git a/CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp b/CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp
new file mode 100755
index 00000000..bbeb177b
--- /dev/null
+++ b/CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp
@@ -0,0 +1,14 @@
+// LzmaArcRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterArc.h"
+
+#include "LzmaHandler.h"
+
+static IInArchive *CreateArc() { return new NArchive::NLzma::CHandler; }
+
+static CArcInfo g_ArcInfo =
+ { L"Lzma", L"lzma lzma86", 0, 0xA, {0 }, 0, true, CreateArc, NULL };
+
+REGISTER_ARC(Lzma)
diff --git a/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp
new file mode 100755
index 00000000..d3450616
--- /dev/null
+++ b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp
@@ -0,0 +1,86 @@
+// LzmaFiltersDecode.cpp
+
+#include "StdAfx.h"
+
+#include "LzmaFiltersDecode.h"
+
+namespace NArchive {
+namespace NLzma {
+
+static const UInt64 k_LZMA = 0x030101;
+static const UInt64 k_BCJ = 0x03030103;
+
+HRESULT CDecoder::Code(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const CHeader &block,
+ ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ UInt64 *inProcessedSize, ICompressProgressInfo *progress)
+{
+ *inProcessedSize = (UInt64)(Int64)-1;
+
+ if (block.FilterMethod > 1)
+ return E_NOTIMPL;
+
+ if (!_lzmaDecoder)
+ {
+ RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS k_LZMA, _lzmaDecoder, false));
+ if (_lzmaDecoder == 0)
+ return E_NOTIMPL;
+ }
+
+ {
+ CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
+ _lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
+ if (!setDecoderProperties)
+ return E_NOTIMPL;
+ RINOK(setDecoderProperties->SetDecoderProperties2(block.LzmaProps, 5));
+ }
+
+ bool filteredMode = (block.FilterMethod == 1);
+
+ CMyComPtr<ICompressSetOutStream> setOutStream;
+
+ if (filteredMode)
+ {
+ if (!_bcjStream)
+ {
+ CMyComPtr<ICompressCoder> coder;
+ RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS k_BCJ, coder, false));
+ if (!coder)
+ return E_NOTIMPL;
+ coder.QueryInterface(IID_ISequentialOutStream, &_bcjStream);
+ if (!_bcjStream)
+ return E_NOTIMPL;
+ }
+
+ _bcjStream.QueryInterface(IID_ICompressSetOutStream, &setOutStream);
+ if (!setOutStream)
+ return E_NOTIMPL;
+ RINOK(setOutStream->SetOutStream(outStream));
+ outStream = _bcjStream;
+ }
+
+ const UInt64 *unpackSize = block.HasUnpackSize() ? &block.UnpackSize : NULL;
+ RINOK(_lzmaDecoder->Code(inStream, outStream, NULL, unpackSize, progress));
+
+ if (filteredMode)
+ {
+ CMyComPtr<IOutStreamFlush> flush;
+ _bcjStream.QueryInterface(IID_IOutStreamFlush, &flush);
+ if (flush)
+ {
+ RINOK(flush->Flush());
+ }
+ RINOK(setOutStream->ReleaseOutStream());
+ }
+
+ CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
+ _lzmaDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize);
+ if (getInStreamProcessedSize)
+ {
+ RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(inProcessedSize));
+ }
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h
new file mode 100755
index 00000000..a9f4927b
--- /dev/null
+++ b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h
@@ -0,0 +1,26 @@
+// LzmaFiltersDecode.h
+
+#ifndef __LZMA_FILTERS_DECODE_H
+#define __LZMA_FILTERS_DECODE_H
+
+#include "../../Common/CreateCoder.h"
+
+#include "LzmaItem.h"
+
+namespace NArchive {
+namespace NLzma {
+
+class CDecoder
+{
+ CMyComPtr<ICompressCoder> _lzmaDecoder;
+ CMyComPtr<ISequentialOutStream> _bcjStream;
+public:
+ HRESULT Code(DECL_EXTERNAL_CODECS_LOC_VARS
+ const CHeader &block,
+ ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ UInt64 *inProcessedSize, ICompressProgressInfo *progress);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Lzma/LzmaHandler.cpp b/CPP/7zip/Archive/Lzma/LzmaHandler.cpp
new file mode 100755
index 00000000..70126aa4
--- /dev/null
+++ b/CPP/7zip/Archive/Lzma/LzmaHandler.cpp
@@ -0,0 +1,243 @@
+// LzmaHandler.cpp
+
+#include "StdAfx.h"
+
+#include "LzmaHandler.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+#include "Common/IntToString.h"
+
+#include "Windows/PropVariant.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/StreamUtils.h"
+#include "../Common/DummyOutStream.h"
+
+#include "LzmaFiltersDecode.h"
+
+namespace NArchive {
+namespace NLzma {
+
+STATPROPSTG kProps[] =
+{
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidMethod, VT_UI1}
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps_NO
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = 1;
+ return S_OK;
+}
+
+static void ConvertUInt32ToString(UInt32 value, wchar_t *s)
+{
+ ConvertUInt64ToString(value, s + MyStringLen(s));
+}
+
+static void DictSizeToString(UInt32 value, wchar_t *s)
+{
+ for (int i = 0; i <= 31; i++)
+ if ((UInt32(1) << i) == value)
+ {
+ ConvertUInt32ToString(i, s);
+ return;
+ }
+ wchar_t c = L'b';
+ if ((value & ((1 << 20) - 1)) == 0)
+ {
+ value >>= 20;
+ c = L'm';
+ }
+ else if ((value & ((1 << 10) - 1)) == 0)
+ {
+ value >>= 10;
+ c = L'k';
+ }
+ ConvertUInt32ToString(value, s);
+ int p = MyStringLen(s);
+ s[p++] = c;
+ s[p++] = L'\0';
+}
+
+static void MyStrCat(wchar_t *d, const wchar_t *s)
+{
+ MyStringCopy(d + MyStringLen(d), s);
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ if (index != 0)
+ return E_INVALIDARG;
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case kpidSize:
+ if (m_StreamInfo.HasUnpackSize())
+ propVariant = (UInt64)m_StreamInfo.UnpackSize;
+ break;
+ case kpidPackedSize:
+ propVariant = (UInt64)m_PackSize;
+ break;
+ case kpidMethod:
+ {
+ wchar_t s[64];
+ s[0] = '\0';
+ if (m_StreamInfo.IsThereFilter)
+ {
+ const wchar_t *f;
+ if (m_StreamInfo.FilterMethod == 0)
+ f = L"Copy";
+ else if (m_StreamInfo.FilterMethod == 1)
+ f = L"BCJ";
+ else
+ f = L"Unknown";
+ MyStrCat(s, f);
+ MyStrCat(s, L" ");
+ }
+ MyStrCat(s, L"LZMA:");
+ DictSizeToString(m_StreamInfo.GetDicSize(), s);
+ propVariant = s;
+ break;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Open(IInStream *inStream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ {
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition));
+
+ HRESULT res = ReadStreamHeader(inStream, m_StreamInfo);
+ if (res != S_OK)
+ return S_FALSE;
+
+ Byte b;
+ RINOK(ReadStream_FALSE(inStream, &b, 1));
+ if (b != 0)
+ return S_FALSE;
+
+ UInt64 endPos;
+ RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos));
+ m_PackSize = endPos - m_StreamStartPosition - m_StreamInfo.GetHeaderSize();
+
+ m_Stream = inStream;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ m_Stream.Release();
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (!allFilesMode)
+ {
+ if (numItems == 0)
+ return S_OK;
+ if (numItems != 1)
+ return E_INVALIDARG;
+ if (indices[0] != 0)
+ return E_INVALIDARG;
+ }
+
+ bool testMode = (_aTestMode != 0);
+
+ RINOK(extractCallback->SetTotal(m_PackSize));
+
+ UInt64 currentTotalPacked = 0;
+
+ CDummyOutStream *outStreamSpec = new CDummyOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+
+ {
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode = testMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+
+ RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
+
+ outStreamSpec->SetStream(realOutStream);
+ outStreamSpec->Init();
+ if(!testMode && !realOutStream)
+ return S_OK;
+ extractCallback->PrepareOperation(askMode);
+ }
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, true);
+
+ CDecoder decoder;
+ RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
+ UInt64 streamPos = m_StreamStartPosition;
+ Int32 opRes = NArchive::NExtract::NOperationResult::kOK;
+ bool firstItem = true;
+ for (;;)
+ {
+ CHeader st;
+ HRESULT result = ReadStreamHeader(m_Stream, st);
+ if (result != S_OK)
+ {
+ if (firstItem)
+ return E_FAIL;
+ break;
+ }
+ firstItem = false;
+
+ lps->OutSize = outStreamSpec->GetSize();
+ lps->InSize = currentTotalPacked;
+ RINOK(lps->SetCur());
+
+ streamPos += st.GetHeaderSize();
+ UInt64 packProcessed;
+
+ {
+ result = decoder.Code(
+ EXTERNAL_CODECS_VARS
+ st, m_Stream, outStream, &packProcessed, progress);
+ if (result == E_NOTIMPL)
+ {
+ opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
+ break;
+ }
+ if (result == S_FALSE)
+ {
+ opRes = NArchive::NExtract::NOperationResult::kDataError;
+ break;
+ }
+ RINOK(result);
+ }
+
+ if (packProcessed == (UInt64)(Int64)-1)
+ break;
+ RINOK(m_Stream->Seek(streamPos + packProcessed, STREAM_SEEK_SET, NULL));
+ currentTotalPacked += packProcessed;
+ streamPos += packProcessed;
+ }
+ outStream.Release();
+ return extractCallback->SetOperationResult(opRes);
+ COM_TRY_END
+}
+
+IMPL_ISetCompressCodecsInfo
+
+}}
diff --git a/CPP/7zip/Archive/Lzma/LzmaHandler.h b/CPP/7zip/Archive/Lzma/LzmaHandler.h
new file mode 100755
index 00000000..e4078309
--- /dev/null
+++ b/CPP/7zip/Archive/Lzma/LzmaHandler.h
@@ -0,0 +1,69 @@
+// Lzma/Handler.h
+
+#ifndef __GZIP_HANDLER_H
+#define __GZIP_HANDLER_H
+
+#include "Common/MyCom.h"
+
+#include "../IArchive.h"
+#include "../../Common/CreateCoder.h"
+
+#include "LzmaIn.h"
+
+namespace NArchive {
+namespace NLzma {
+
+// const UInt64 k_LZMA = 0x030101;
+
+class CHandler:
+ public IInArchive,
+ PUBLIC_ISetCompressCodecsInfo
+ public CMyUnknownImp
+{
+public:
+ MY_QUERYINTERFACE_BEGIN
+ MY_QUERYINTERFACE_ENTRY(IInArchive)
+ QUERY_ENTRY_ISetCompressCodecsInfo
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ STDMETHOD(Open)(IInStream *inStream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback);
+ STDMETHOD(Close)();
+
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback);
+
+ STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+
+ STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
+ STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+
+ UString GetMethodString();
+public:
+ CHandler() { }
+
+private:
+ CHeader m_StreamInfo;
+ UInt64 m_StreamStartPosition;
+ UInt64 m_PackSize;
+
+ CMyComPtr<IInStream> m_Stream;
+
+ DECL_EXTERNAL_CODECS_VARS
+
+ DECL_ISetCompressCodecsInfo
+
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Lzma/LzmaIn.cpp b/CPP/7zip/Archive/Lzma/LzmaIn.cpp
new file mode 100755
index 00000000..342b01e1
--- /dev/null
+++ b/CPP/7zip/Archive/Lzma/LzmaIn.cpp
@@ -0,0 +1,56 @@
+// Archive/LzmaIn.cpp
+
+#include "StdAfx.h"
+
+#include "LzmaIn.h"
+
+#include "../../Common/StreamUtils.h"
+
+namespace NArchive {
+namespace NLzma {
+
+static bool CheckDictSize(const Byte *p)
+{
+ UInt32 dicSize = GetUi32(p);
+ int i;
+ for (i = 1; i <= 30; i++)
+ if (dicSize == ((UInt32)2 << i) || dicSize == ((UInt32)3 << i))
+ return true;
+ return false;
+}
+
+HRESULT ReadStreamHeader(ISequentialInStream *inStream, CHeader &block)
+{
+ Byte sig[5 + 9];
+ RINOK(ReadStream_FALSE(inStream, sig, 5 + 8));
+
+ const Byte kMaxProp0Val = 5 * 5 * 9 - 1;
+ if (sig[0] > kMaxProp0Val)
+ return S_FALSE;
+
+ for (int i = 0; i < 5; i++)
+ block.LzmaProps[i] = sig[i];
+
+ block.IsThereFilter = false;
+ block.FilterMethod = 0;
+
+ if (!CheckDictSize(sig + 1))
+ {
+ if (sig[0] > 1 || sig[1] > kMaxProp0Val)
+ return S_FALSE;
+ block.IsThereFilter = true;
+ block.FilterMethod = sig[0];
+ for (int i = 0; i < 5; i++)
+ block.LzmaProps[i] = sig[i + 1];
+ if (!CheckDictSize(block.LzmaProps + 1))
+ return S_FALSE;
+ RINOK(ReadStream_FALSE(inStream, sig + 5 + 8, 1));
+ }
+ UInt32 unpOffset = 5 + (block.IsThereFilter ? 1 : 0);
+ block.UnpackSize = GetUi64(sig + unpOffset);
+ if (block.HasUnpackSize() && block.UnpackSize >= ((UInt64)1 << 56))
+ return S_FALSE;
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Lzma/LzmaIn.h b/CPP/7zip/Archive/Lzma/LzmaIn.h
new file mode 100755
index 00000000..6f237f2d
--- /dev/null
+++ b/CPP/7zip/Archive/Lzma/LzmaIn.h
@@ -0,0 +1,16 @@
+// Archive/LzmaIn.h
+
+#ifndef __ARCHIVE_LZMA_IN_H
+#define __ARCHIVE_LZMA_IN_H
+
+#include "LzmaItem.h"
+#include "../../IStream.h"
+
+namespace NArchive {
+namespace NLzma {
+
+HRESULT ReadStreamHeader(ISequentialInStream *inStream, CHeader &st);
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Lzma/LzmaItem.h b/CPP/7zip/Archive/Lzma/LzmaItem.h
new file mode 100755
index 00000000..8fcae210
--- /dev/null
+++ b/CPP/7zip/Archive/Lzma/LzmaItem.h
@@ -0,0 +1,27 @@
+// Archive/LzmaItem.h
+
+#ifndef __ARCHIVE_LZMA_ITEM_H
+#define __ARCHIVE_LZMA_ITEM_H
+
+#include "Common/Types.h"
+
+#include "../../../../C/CpuArch.h"
+
+namespace NArchive {
+namespace NLzma {
+
+struct CHeader
+{
+ UInt64 UnpackSize;
+ bool IsThereFilter;
+ Byte FilterMethod;
+ Byte LzmaProps[5];
+
+ UInt32 GetDicSize() const { return GetUi32(LzmaProps + 1); }
+ bool HasUnpackSize() const { return (UnpackSize != (UInt64)(Int64)-1); }
+ unsigned GetHeaderSize() const { return 5 + 8 + (IsThereFilter ? 1 : 0); }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Lzma/StdAfx.h b/CPP/7zip/Archive/Lzma/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/Lzma/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Lzma/lzma.ico b/CPP/7zip/Archive/Lzma/lzma.ico
new file mode 100755
index 00000000..1f4f754c
--- /dev/null
+++ b/CPP/7zip/Archive/Lzma/lzma.ico
Binary files differ