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:
Diffstat (limited to 'CPP/7zip/Common')
-rwxr-xr-xCPP/7zip/Common/CreateCoder.cpp292
-rwxr-xr-xCPP/7zip/Common/CreateCoder.h98
-rwxr-xr-xCPP/7zip/Common/FilterCoder.cpp246
-rwxr-xr-xCPP/7zip/Common/FilterCoder.h130
-rwxr-xr-xCPP/7zip/Common/InBuffer.cpp5
-rwxr-xr-xCPP/7zip/Common/MemBlocks.h6
-rwxr-xr-xCPP/7zip/Common/MethodId.cpp27
-rwxr-xr-xCPP/7zip/Common/MethodId.h10
-rwxr-xr-xCPP/7zip/Common/OutBuffer.cpp5
-rwxr-xr-xCPP/7zip/Common/OutMemStream.cpp11
-rwxr-xr-xCPP/7zip/Common/OutMemStream.h4
-rwxr-xr-xCPP/7zip/Common/RegisterArc.h36
-rwxr-xr-xCPP/7zip/Common/RegisterCodec.h33
-rwxr-xr-xCPP/7zip/Common/StreamBinder.cpp2
14 files changed, 897 insertions, 8 deletions
diff --git a/CPP/7zip/Common/CreateCoder.cpp b/CPP/7zip/Common/CreateCoder.cpp
new file mode 100755
index 00000000..ae0f98fd
--- /dev/null
+++ b/CPP/7zip/Common/CreateCoder.cpp
@@ -0,0 +1,292 @@
+// CreateCoder.cpp
+
+#include "StdAfx.h"
+
+#include "CreateCoder.h"
+
+#include "../../Windows/PropVariant.h"
+#include "../../Windows/Defs.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)
+{
+ if (g_NumCodecs < kNumCodecsMax)
+ g_Codecs[g_NumCodecs++] = codecInfo;
+}
+
+#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 LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)
+{
+ UInt32 num;
+ RINOK(codecsInfo->GetNumberOfMethods(&num));
+ for (UInt32 i = 0; i < num; i++)
+ {
+ CCodecInfoEx info;
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));
+ // if (prop.vt != VT_BSTR)
+ // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
+ // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);
+ if (prop.vt != VT_UI8)
+ {
+ continue; // old Interface
+ // return E_INVALIDARG;
+ }
+ info.Id = prop.uhVal.QuadPart;
+ prop.Clear();
+
+ RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));
+ if (prop.vt == VT_BSTR)
+ info.Name = prop.bstrVal;
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;;
+
+ RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));
+ RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));
+ RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
+ RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
+
+ externalCodecs.Add(info);
+ }
+ return S_OK;
+}
+
+#endif
+
+bool FindMethod(
+ #ifdef EXTERNAL_CODECS
+ ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
+ #endif
+ const UString &name,
+ CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
+{
+ UInt32 i;
+ for (i = 0; i < g_NumCodecs; i++)
+ {
+ const CCodecInfo &codec = *g_Codecs[i];
+ if (name.CompareNoCase(codec.Name) == 0)
+ {
+ methodId = codec.Id;
+ numInStreams = codec.NumInStreams;
+ numOutStreams = 1;
+ return true;
+ }
+ }
+ #ifdef EXTERNAL_CODECS
+ if (externalCodecs)
+ for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ {
+ const CCodecInfoEx &codec = (*externalCodecs)[i];
+ if (codec.Name.CompareNoCase(name) == 0)
+ {
+ methodId = codec.Id;
+ numInStreams = codec.NumInStreams;
+ numOutStreams = codec.NumOutStreams;
+ return true;
+ }
+ }
+ #endif
+ return false;
+}
+
+bool FindMethod(
+ #ifdef EXTERNAL_CODECS
+ ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
+ #endif
+ 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->Size(); i++)
+ {
+ const CCodecInfoEx &codec = (*externalCodecs)[i];
+ if (methodId == codec.Id)
+ {
+ name = codec.Name;
+ return true;
+ }
+ }
+ #endif
+ return false;
+}
+
+HRESULT CreateCoder(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ CMyComPtr<ICompressFilter> &filter,
+ CMyComPtr<ICompressCoder> &coder,
+ CMyComPtr<ICompressCoder2> &coder2,
+ bool encode, bool onlyCoder)
+{
+ bool created = false;
+ 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;
+ created = (p != 0);
+ 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;
+ created = (p != 0);
+ break;
+ }
+ }
+ }
+
+ #ifdef EXTERNAL_CODECS
+ if (!created && externalCodecs)
+ for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ {
+ const CCodecInfoEx &codec = (*externalCodecs)[i];
+ if (codec.Id == methodId)
+ {
+ if (encode)
+ {
+ if (codec.EncoderIsAssigned)
+ {
+ if (codec.IsSimpleCodec())
+ {
+ HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
+ if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
+ return result;
+ if (!coder)
+ {
+ RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
+ }
+ }
+ else
+ {
+ RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
+ }
+ break;
+ }
+ }
+ else
+ if (codec.DecoderIsAssigned)
+ {
+ if (codec.IsSimpleCodec())
+ {
+ HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
+ if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
+ return result;
+ if (!coder)
+ {
+ RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
+ }
+ }
+ else
+ {
+ RINOK(codecsInfo->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);
+}
diff --git a/CPP/7zip/Common/CreateCoder.h b/CPP/7zip/Common/CreateCoder.h
new file mode 100755
index 00000000..9b2f3869
--- /dev/null
+++ b/CPP/7zip/Common/CreateCoder.h
@@ -0,0 +1,98 @@
+// CreateCoder.h
+
+#ifndef __CREATECODER_H
+#define __CREATECODER_H
+
+#include "Common/MyCom.h"
+#include "Common/String.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) {}
+};
+
+HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs);
+
+#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) { \
+ _codecsInfo = compressCodecsInfo; return LoadExternalCodecs(_codecsInfo, _externalCodecs); }
+#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler)
+
+#define EXTERNAL_CODECS_VARS2 _codecsInfo, &_externalCodecs
+
+#define DECL_EXTERNAL_CODECS_VARS CMyComPtr<ICompressCodecsInfo> _codecsInfo; CObjectVector<CCodecInfoEx> _externalCodecs;
+#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2,
+
+#define DECL_EXTERNAL_CODECS_LOC_VARS2 ICompressCodecsInfo *codecsInfo, const CObjectVector<CCodecInfoEx> *externalCodecs
+#define EXTERNAL_CODECS_LOC_VARS2 codecsInfo, externalCodecs
+
+#define DECL_EXTERNAL_CODECS_LOC_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);
+
+
+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);
+
+#endif
diff --git a/CPP/7zip/Common/FilterCoder.cpp b/CPP/7zip/Common/FilterCoder.cpp
new file mode 100755
index 00000000..9b019c7d
--- /dev/null
+++ b/CPP/7zip/Common/FilterCoder.cpp
@@ -0,0 +1,246 @@
+// FilterCoder.cpp
+
+#include "StdAfx.h"
+
+#include "FilterCoder.h"
+extern "C"
+{
+#include "../../../C/Alloc.h"
+}
+#include "../../Common/Defs.h"
+#include "StreamUtils.h"
+
+static const int kBufferSize = 1 << 17;
+
+CFilterCoder::CFilterCoder()
+{
+ _buffer = (Byte *)::MidAlloc(kBufferSize);
+}
+
+CFilterCoder::~CFilterCoder()
+{
+ ::MidFree(_buffer);
+}
+
+HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size)
+{
+ if (_outSizeIsDefined)
+ {
+ UInt64 remSize = _outSize - _nowPos64;
+ if (size > remSize)
+ size = (UInt32)remSize;
+ }
+ UInt32 processedSize = 0;
+ RINOK(WriteStream(outStream, _buffer, size, &processedSize));
+ if (size != processedSize)
+ return E_FAIL;
+ _nowPos64 += processedSize;
+ 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(NeedMore())
+ {
+ UInt32 processedSize;
+
+ // Change it: It can be optimized using ReadPart
+ RINOK(ReadStream(inStream, _buffer + bufferPos, kBufferSize - bufferPos, &processedSize));
+
+ UInt32 endPos = bufferPos + 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 WriteWithLimit(outStream, endPos);
+ return S_OK;
+ }
+ 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;
+}
+
+// #ifdef _ST_MODE
+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)
+{
+ UInt32 processedSizeTotal = 0;
+ while(size > 0)
+ {
+ UInt32 sizeMax = kBufferSize - _bufferPos;
+ UInt32 sizeTemp = size;
+ if (sizeTemp > sizeMax)
+ sizeTemp = sizeMax;
+ memmove(_buffer + _bufferPos, data, sizeTemp);
+ size -= sizeTemp;
+ processedSizeTotal += 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;
+ }
+ if (processedSize != NULL)
+ *processedSize = processedSizeTotal;
+ return S_OK;
+}
+
+STDMETHODIMP CFilterCoder::Flush()
+{
+ if (_bufferPos != 0)
+ {
+ 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;
+ }
+ UInt32 processedSize;
+ RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize));
+ if (_bufferPos != processedSize)
+ return E_FAIL;
+ _bufferPos = 0;
+ }
+ CMyComPtr<IOutStreamFlush> flush;
+ _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
+ if (flush)
+ return flush->Flush();
+ return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+{
+ _convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
+ _inStream = inStream;
+ return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseInStream()
+{
+ _inStream.Release();
+ return S_OK;
+};
+
+STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeTotal = 0;
+ while(size > 0)
+ {
+ if (_convertedPosBegin != _convertedPosEnd)
+ {
+ UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);
+ memmove(data, _buffer + _convertedPosBegin, sizeTemp);
+ _convertedPosBegin += sizeTemp;
+ data = (void *)((Byte *)data + sizeTemp);
+ size -= sizeTemp;
+ processedSizeTotal += sizeTemp;
+ break;
+ }
+ int i;
+ for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
+ _buffer[i] = _buffer[i + _convertedPosEnd];
+ _bufferPos = i;
+ _convertedPosBegin = _convertedPosEnd = 0;
+ UInt32 processedSizeTemp;
+ UInt32 size0 = kBufferSize - _bufferPos;
+ // Optimize it:
+ RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp));
+ _bufferPos = _bufferPos + processedSizeTemp;
+ _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ if (_convertedPosEnd == 0)
+ {
+ if (_bufferPos == 0)
+ break;
+ else
+ {
+ _convertedPosEnd = _bufferPos; // check it
+ continue;
+ }
+ }
+ if (_convertedPosEnd > _bufferPos)
+ {
+ for (; _bufferPos < _convertedPosEnd; _bufferPos++)
+ _buffer[_bufferPos] = 0;
+ _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = processedSizeTotal;
+ return S_OK;
+}
+
+// #endif // _ST_MODE
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ return _setPassword->CryptoSetPassword(data, size);
+}
+#endif
+
+#ifndef EXTRACT_ONLY
+STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ return _writeCoderProperties->WriteCoderProperties(outStream);
+}
+#endif
+
+STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ return _setDecoderProperties->SetDecoderProperties2(data, size);
+}
diff --git a/CPP/7zip/Common/FilterCoder.h b/CPP/7zip/Common/FilterCoder.h
new file mode 100755
index 00000000..36334364
--- /dev/null
+++ b/CPP/7zip/Common/FilterCoder.h
@@ -0,0 +1,130 @@
+// FilterCoder.h
+
+#ifndef __FILTERCODER_H
+#define __FILTERCODER_H
+
+#include "../../Common/MyCom.h"
+#include "../ICoder.h"
+#include "../IPassword.h"
+
+#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \
+{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
+*outObject = (void *)(i *)this; AddRef(); return S_OK; }
+
+class CFilterCoder:
+ public ICompressCoder,
+ // #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ISequentialInStream,
+ public ICompressSetOutStream,
+ public ISequentialOutStream,
+ public IOutStreamFlush,
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ public ICryptoSetPassword,
+ #endif
+ #ifndef EXTRACT_ONLY
+ public ICompressWriteCoderProperties,
+ #endif
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+protected:
+ Byte *_buffer;
+ // #ifdef _ST_MODE
+ CMyComPtr<ISequentialInStream> _inStream;
+ CMyComPtr<ISequentialOutStream> _outStream;
+ UInt32 _bufferPos;
+ UInt32 _convertedPosBegin;
+ UInt32 _convertedPosEnd;
+ // #endif
+ bool _outSizeIsDefined;
+ UInt64 _outSize;
+ UInt64 _nowPos64;
+
+ HRESULT Init()
+ {
+ _nowPos64 = 0;
+ _outSizeIsDefined = false;
+ return Filter->Init();
+ }
+
+ CMyComPtr<ICryptoSetPassword> _setPassword;
+ #ifndef EXTRACT_ONLY
+ CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;
+ #endif
+ CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties;
+public:
+ CMyComPtr<ICompressFilter> Filter;
+
+ CFilterCoder();
+ ~CFilterCoder();
+ HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size);
+ bool NeedMore() const
+ { return (!_outSizeIsDefined || (_nowPos64 < _outSize)); }
+
+public:
+ MY_QUERYINTERFACE_BEGIN
+ MY_QUERYINTERFACE_ENTRY(ICompressCoder)
+ // #ifdef _ST_MODE
+ MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
+ MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+
+ MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)
+ MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)
+ MY_QUERYINTERFACE_ENTRY(IOutStreamFlush)
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties)
+ #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);
+ // #ifdef _ST_MODE
+ 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)();
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+ #endif
+ #ifndef EXTRACT_ONLY
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ #endif
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+// #ifdef _ST_MODE
+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
+
+#endif
diff --git a/CPP/7zip/Common/InBuffer.cpp b/CPP/7zip/Common/InBuffer.cpp
index 02f2adfa..5c4361a3 100755
--- a/CPP/7zip/Common/InBuffer.cpp
+++ b/CPP/7zip/Common/InBuffer.cpp
@@ -4,7 +4,10 @@
#include "InBuffer.h"
-#include "../../Common/Alloc.h"
+extern "C"
+{
+ #include "../../../C/Alloc.h"
+}
CInBuffer::CInBuffer():
_buffer(0),
diff --git a/CPP/7zip/Common/MemBlocks.h b/CPP/7zip/Common/MemBlocks.h
index 31cd3546..c33f712c 100755
--- a/CPP/7zip/Common/MemBlocks.h
+++ b/CPP/7zip/Common/MemBlocks.h
@@ -3,7 +3,11 @@
#ifndef __MEMBLOCKS_H
#define __MEMBLOCKS_H
-#include "Common/Alloc.h"
+extern "C"
+{
+#include "../../../C/Alloc.h"
+}
+
#include "Common/Types.h"
#include "Common/Vector.h"
diff --git a/CPP/7zip/Common/MethodId.cpp b/CPP/7zip/Common/MethodId.cpp
new file mode 100755
index 00000000..5a0c80aa
--- /dev/null
+++ b/CPP/7zip/Common/MethodId.cpp
@@ -0,0 +1,27 @@
+// MethodID.cpp
+
+#include "StdAfx.h"
+
+#include "MethodID.h"
+#include "../../Common/String.h"
+
+static inline wchar_t GetHex(Byte value)
+{
+ return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+UString ConvertMethodIdToString(UInt64 id)
+{
+ wchar_t s[32];
+ int len = 32;
+ s[--len] = 0;
+ do
+ {
+ s[--len] = GetHex((Byte)id & 0xF);
+ id >>= 4;
+ s[--len] = GetHex((Byte)id & 0xF);
+ id >>= 4;
+ }
+ while (id != 0);
+ return s + len;
+}
diff --git a/CPP/7zip/Common/MethodId.h b/CPP/7zip/Common/MethodId.h
new file mode 100755
index 00000000..42306326
--- /dev/null
+++ b/CPP/7zip/Common/MethodId.h
@@ -0,0 +1,10 @@
+// MethodID.h
+
+#ifndef __7Z_METHOD_ID_H
+#define __7Z_METHOD_ID_H
+
+#include "../../Common/Types.h"
+
+typedef UInt64 CMethodId;
+
+#endif
diff --git a/CPP/7zip/Common/OutBuffer.cpp b/CPP/7zip/Common/OutBuffer.cpp
index a73fa7c5..a63862b9 100755
--- a/CPP/7zip/Common/OutBuffer.cpp
+++ b/CPP/7zip/Common/OutBuffer.cpp
@@ -4,7 +4,10 @@
#include "OutBuffer.h"
-#include "../../Common/Alloc.h"
+extern "C"
+{
+ #include "../../../C/Alloc.h"
+}
bool COutBuffer::Create(UInt32 bufferSize)
{
diff --git a/CPP/7zip/Common/OutMemStream.cpp b/CPP/7zip/Common/OutMemStream.cpp
index 2953afd8..ddc31486 100755
--- a/CPP/7zip/Common/OutMemStream.cpp
+++ b/CPP/7zip/Common/OutMemStream.cpp
@@ -65,8 +65,8 @@ STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *process
}
continue;
}
- HANDLE events[4] = { StopWritingEvent, WriteToRealStreamEvent, NoLockEvent, _memManager->Semaphore };
- DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 4 : 2), events, FALSE, INFINITE);
+ HANDLE events[3] = { StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore };
+ DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 3 : 2), events, FALSE, INFINITE);
switch (waitResult)
{
case (WAIT_OBJECT_0 + 0):
@@ -81,18 +81,23 @@ STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *process
*processedSize += processedSize2;
return res;
}
+ /*
case (WAIT_OBJECT_0 + 2):
{
+ // it has bug: no write.
if (!Blocks.SwitchToNoLockMode(_memManager))
return E_FAIL;
break;
}
- case (WAIT_OBJECT_0 + 3):
+ */
+ case (WAIT_OBJECT_0 + 2):
break;
default:
return E_FAIL;
}
Blocks.Blocks.Add(_memManager->AllocateBlock());
+ if (Blocks.Blocks.Back() == 0)
+ return E_FAIL;
}
return S_OK;
}
diff --git a/CPP/7zip/Common/OutMemStream.h b/CPP/7zip/Common/OutMemStream.h
index ea98de17..a8bd1711 100755
--- a/CPP/7zip/Common/OutMemStream.h
+++ b/CPP/7zip/Common/OutMemStream.h
@@ -18,7 +18,7 @@ class COutMemStream:
bool _unlockEventWasSent;
NWindows::NSynchronization::CAutoResetEvent StopWritingEvent;
NWindows::NSynchronization::CAutoResetEvent WriteToRealStreamEvent;
- NWindows::NSynchronization::CAutoResetEvent NoLockEvent;
+ // NWindows::NSynchronization::CAutoResetEvent NoLockEvent;
HRESULT StopWriteResult;
CMemLockBlocks Blocks;
@@ -66,11 +66,13 @@ public:
WriteToRealStreamEvent.Set();
}
+ /*
void SetNoLockMode()
{
_unlockEventWasSent = true;
NoLockEvent.Set();
}
+ */
void StopWriting(HRESULT res)
{
diff --git a/CPP/7zip/Common/RegisterArc.h b/CPP/7zip/Common/RegisterArc.h
new file mode 100755
index 00000000..57730214
--- /dev/null
+++ b/CPP/7zip/Common/RegisterArc.h
@@ -0,0 +1,36 @@
+// RegisterArc.h
+
+#ifndef __REGISTERARC_H
+#define __REGISTERARC_H
+
+#include "../Archive/IArchive.h"
+
+typedef IInArchive * (*CreateInArchiveP)();
+typedef IOutArchive * (*CreateOutArchiveP)();
+
+struct CArcInfo
+{
+ const wchar_t *Name;
+ const wchar_t *Ext;
+ const wchar_t *AddExt;
+ Byte ClassId;
+ Byte Signature[16];
+ int SignatureSize;
+ bool KeepName;
+ CreateInArchiveP CreateInArchive;
+ CreateOutArchiveP CreateOutArchive;
+};
+
+void RegisterArc(const CArcInfo *arcInfo);
+
+#define REGISTER_ARC_NAME(x) CRegister ## x
+
+#define REGISTER_ARC_DEC_SIG(x) struct REGISTER_ARC_NAME(x) { \
+ REGISTER_ARC_NAME(x)() { g_ArcInfo.Signature[0]--; RegisterArc(&g_ArcInfo); }}; \
+ static REGISTER_ARC_NAME(x) g_RegisterArc;
+
+#define REGISTER_ARC(x) struct REGISTER_ARC_NAME(x) { \
+ REGISTER_ARC_NAME(x)() { RegisterArc(&g_ArcInfo); }}; \
+ static REGISTER_ARC_NAME(x) g_RegisterArc;
+
+#endif
diff --git a/CPP/7zip/Common/RegisterCodec.h b/CPP/7zip/Common/RegisterCodec.h
new file mode 100755
index 00000000..6ce4a7f8
--- /dev/null
+++ b/CPP/7zip/Common/RegisterCodec.h
@@ -0,0 +1,33 @@
+// RegisterCodec.h
+
+#ifndef __REGISTERCODEC_H
+#define __REGISTERCODEC_H
+
+#include "../Common/MethodID.h"
+
+typedef void * (*CreateCodecP)();
+struct CCodecInfo
+{
+ CreateCodecP CreateDecoder;
+ CreateCodecP CreateEncoder;
+ CMethodId Id;
+ const wchar_t *Name;
+ UInt32 NumInStreams;
+ bool IsFilter;
+};
+
+void RegisterCodec(const CCodecInfo *codecInfo);
+
+#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x
+
+#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \
+ REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \
+ static REGISTER_CODEC_NAME(x) g_RegisterCodec;
+
+#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x
+#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \
+ REGISTER_CODECS_NAME(x)() { for (int i = 0; i < sizeof(g_CodecsInfo) / sizeof(g_CodecsInfo[0]); i++) \
+ RegisterCodec(&g_CodecsInfo[i]); }}; \
+ static REGISTER_CODECS_NAME(x) g_RegisterCodecs;
+
+#endif
diff --git a/CPP/7zip/Common/StreamBinder.cpp b/CPP/7zip/Common/StreamBinder.cpp
index 2984c2d9..f83939cb 100755
--- a/CPP/7zip/Common/StreamBinder.cpp
+++ b/CPP/7zip/Common/StreamBinder.cpp
@@ -145,7 +145,7 @@ HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSiz
if (waitResult != WAIT_OBJECT_0 + 0)
{
// ReadingWasClosed = true;
- return E_FAIL;
+ return S_FALSE;
}
// if(!_allBytesAreWritenEvent.Lock())
// return E_FAIL;