4.45 beta

This commit is contained in:
Igor Pavlov
2007-04-17 00:00:00 +00:00
committed by Kornel Lesiński
parent d9666cf046
commit a145bfc7cf
458 changed files with 13144 additions and 18608 deletions

292
CPP/7zip/Common/CreateCoder.cpp Executable file
View File

@@ -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);
}

98
CPP/7zip/Common/CreateCoder.h Executable file
View File

@@ -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

246
CPP/7zip/Common/FilterCoder.cpp Executable file
View File

@@ -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);
}

130
CPP/7zip/Common/FilterCoder.h Executable file
View File

@@ -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

View File

@@ -4,7 +4,10 @@
#include "InBuffer.h"
#include "../../Common/Alloc.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
CInBuffer::CInBuffer():
_buffer(0),

View File

@@ -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"

27
CPP/7zip/Common/MethodId.cpp Executable file
View File

@@ -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;
}

10
CPP/7zip/Common/MethodId.h Executable file
View File

@@ -0,0 +1,10 @@
// MethodID.h
#ifndef __7Z_METHOD_ID_H
#define __7Z_METHOD_ID_H
#include "../../Common/Types.h"
typedef UInt64 CMethodId;
#endif

View File

@@ -4,7 +4,10 @@
#include "OutBuffer.h"
#include "../../Common/Alloc.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
bool COutBuffer::Create(UInt32 bufferSize)
{

View File

@@ -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;
}

View File

@@ -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)
{

36
CPP/7zip/Common/RegisterArc.h Executable file
View File

@@ -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

33
CPP/7zip/Common/RegisterCodec.h Executable file
View File

@@ -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

View File

@@ -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;