PhysicsFS 2.0.3 imported.
This commit is contained in:
parent
bcc0937726
commit
993311d151
459 changed files with 87785 additions and 0 deletions
121
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
Normal file
121
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
// CoderMixer2.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CoderMixer2.h"
|
||||
|
||||
namespace NCoderMixer {
|
||||
|
||||
CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
|
||||
_srcBindInfo(srcBindInfo)
|
||||
{
|
||||
srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams);
|
||||
|
||||
UInt32 j;
|
||||
for (j = 0; j < NumSrcInStreams; j++)
|
||||
{
|
||||
_srcInToDestOutMap.Add(0);
|
||||
DestOutToSrcInMap.Add(0);
|
||||
}
|
||||
for (j = 0; j < _numSrcOutStreams; j++)
|
||||
{
|
||||
_srcOutToDestInMap.Add(0);
|
||||
_destInToSrcOutMap.Add(0);
|
||||
}
|
||||
|
||||
UInt32 destInOffset = 0;
|
||||
UInt32 destOutOffset = 0;
|
||||
UInt32 srcInOffset = NumSrcInStreams;
|
||||
UInt32 srcOutOffset = _numSrcOutStreams;
|
||||
|
||||
for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i];
|
||||
|
||||
srcInOffset -= srcCoderInfo.NumInStreams;
|
||||
srcOutOffset -= srcCoderInfo.NumOutStreams;
|
||||
|
||||
UInt32 j;
|
||||
for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++)
|
||||
{
|
||||
UInt32 index = srcInOffset + j;
|
||||
_srcInToDestOutMap[index] = destOutOffset;
|
||||
DestOutToSrcInMap[destOutOffset] = index;
|
||||
}
|
||||
for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++)
|
||||
{
|
||||
UInt32 index = srcOutOffset + j;
|
||||
_srcOutToDestInMap[index] = destInOffset;
|
||||
_destInToSrcOutMap[destInOffset] = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)
|
||||
{
|
||||
destBindInfo.Coders.Clear();
|
||||
destBindInfo.BindPairs.Clear();
|
||||
destBindInfo.InStreams.Clear();
|
||||
destBindInfo.OutStreams.Clear();
|
||||
|
||||
int i;
|
||||
for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i];
|
||||
CCoderStreamsInfo destCoderInfo;
|
||||
destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams;
|
||||
destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams;
|
||||
destBindInfo.Coders.Add(destCoderInfo);
|
||||
}
|
||||
for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i];
|
||||
CBindPair destBindPair;
|
||||
destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex];
|
||||
destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex];
|
||||
destBindInfo.BindPairs.Add(destBindPair);
|
||||
}
|
||||
for (i = 0; i < _srcBindInfo.InStreams.Size(); i++)
|
||||
destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);
|
||||
for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++)
|
||||
destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
|
||||
}
|
||||
|
||||
CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
|
||||
NumInStreams(numInStreams),
|
||||
NumOutStreams(numOutStreams)
|
||||
{
|
||||
InSizes.Reserve(NumInStreams);
|
||||
InSizePointers.Reserve(NumInStreams);
|
||||
OutSizePointers.Reserve(NumOutStreams);
|
||||
OutSizePointers.Reserve(NumOutStreams);
|
||||
}
|
||||
|
||||
static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
|
||||
CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
|
||||
{
|
||||
sizes.Clear();
|
||||
sizePointers.Clear();
|
||||
for(UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
if (srcSizes == 0 || srcSizes[i] == NULL)
|
||||
{
|
||||
sizes.Add(0);
|
||||
sizePointers.Add(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
sizes.Add(*srcSizes[i]);
|
||||
sizePointers.Add(&sizes.Back());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes,
|
||||
const UInt64 **outSizes)
|
||||
{
|
||||
SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
|
||||
SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
|
||||
}
|
||||
|
||||
}
|
174
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
Normal file
174
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
Normal file
|
@ -0,0 +1,174 @@
|
|||
// CoderMixer2.h
|
||||
|
||||
#ifndef __CODER_MIXER2_H
|
||||
#define __CODER_MIXER2_H
|
||||
|
||||
#include "../../../Common/MyVector.h"
|
||||
#include "../../../Common/Types.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
namespace NCoderMixer {
|
||||
|
||||
struct CBindPair
|
||||
{
|
||||
UInt32 InIndex;
|
||||
UInt32 OutIndex;
|
||||
};
|
||||
|
||||
struct CCoderStreamsInfo
|
||||
{
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
};
|
||||
|
||||
struct CBindInfo
|
||||
{
|
||||
CRecordVector<CCoderStreamsInfo> Coders;
|
||||
CRecordVector<CBindPair> BindPairs;
|
||||
CRecordVector<UInt32> InStreams;
|
||||
CRecordVector<UInt32> OutStreams;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Coders.Clear();
|
||||
BindPairs.Clear();
|
||||
InStreams.Clear();
|
||||
OutStreams.Clear();
|
||||
}
|
||||
|
||||
/*
|
||||
UInt32 GetCoderStartOutStream(UInt32 coderIndex) const
|
||||
{
|
||||
UInt32 numOutStreams = 0;
|
||||
for (UInt32 i = 0; i < coderIndex; i++)
|
||||
numOutStreams += Coders[i].NumOutStreams;
|
||||
return numOutStreams;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const
|
||||
{
|
||||
numInStreams = 0;
|
||||
numOutStreams = 0;
|
||||
for (int i = 0; i < Coders.Size(); i++)
|
||||
{
|
||||
const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
|
||||
numInStreams += coderStreamsInfo.NumInStreams;
|
||||
numOutStreams += coderStreamsInfo.NumOutStreams;
|
||||
}
|
||||
}
|
||||
|
||||
int FindBinderForInStream(UInt32 inStream) const
|
||||
{
|
||||
for (int i = 0; i < BindPairs.Size(); i++)
|
||||
if (BindPairs[i].InIndex == inStream)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
int FindBinderForOutStream(UInt32 outStream) const
|
||||
{
|
||||
for (int i = 0; i < BindPairs.Size(); i++)
|
||||
if (BindPairs[i].OutIndex == outStream)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const
|
||||
{
|
||||
UInt32 streamIndex = 0;
|
||||
for (UInt32 i = 0; i < coderIndex; i++)
|
||||
streamIndex += Coders[i].NumInStreams;
|
||||
return streamIndex;
|
||||
}
|
||||
|
||||
UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const
|
||||
{
|
||||
UInt32 streamIndex = 0;
|
||||
for (UInt32 i = 0; i < coderIndex; i++)
|
||||
streamIndex += Coders[i].NumOutStreams;
|
||||
return streamIndex;
|
||||
}
|
||||
|
||||
|
||||
void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
|
||||
UInt32 &coderStreamIndex) const
|
||||
{
|
||||
for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
|
||||
{
|
||||
UInt32 curSize = Coders[coderIndex].NumInStreams;
|
||||
if (streamIndex < curSize)
|
||||
{
|
||||
coderStreamIndex = streamIndex;
|
||||
return;
|
||||
}
|
||||
streamIndex -= curSize;
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
|
||||
UInt32 &coderStreamIndex) const
|
||||
{
|
||||
for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
|
||||
{
|
||||
UInt32 curSize = Coders[coderIndex].NumOutStreams;
|
||||
if (streamIndex < curSize)
|
||||
{
|
||||
coderStreamIndex = streamIndex;
|
||||
return;
|
||||
}
|
||||
streamIndex -= curSize;
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
};
|
||||
|
||||
class CBindReverseConverter
|
||||
{
|
||||
UInt32 _numSrcOutStreams;
|
||||
NCoderMixer::CBindInfo _srcBindInfo;
|
||||
CRecordVector<UInt32> _srcInToDestOutMap;
|
||||
CRecordVector<UInt32> _srcOutToDestInMap;
|
||||
CRecordVector<UInt32> _destInToSrcOutMap;
|
||||
public:
|
||||
UInt32 NumSrcInStreams;
|
||||
CRecordVector<UInt32> DestOutToSrcInMap;
|
||||
|
||||
CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo);
|
||||
void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo);
|
||||
};
|
||||
|
||||
struct CCoderInfo2
|
||||
{
|
||||
CMyComPtr<ICompressCoder> Coder;
|
||||
CMyComPtr<ICompressCoder2> Coder2;
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
|
||||
CRecordVector<UInt64> InSizes;
|
||||
CRecordVector<UInt64> OutSizes;
|
||||
CRecordVector<const UInt64 *> InSizePointers;
|
||||
CRecordVector<const UInt64 *> OutSizePointers;
|
||||
|
||||
CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams);
|
||||
void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
|
||||
|
||||
HRESULT QueryInterface(REFGUID iid, void** pp) const
|
||||
{
|
||||
IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
|
||||
return p->QueryInterface(iid, pp);
|
||||
}
|
||||
};
|
||||
|
||||
class CCoderMixer2
|
||||
{
|
||||
public:
|
||||
virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) = 0;
|
||||
virtual void ReInit() = 0;
|
||||
virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
228
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
Normal file
228
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
Normal file
|
@ -0,0 +1,228 @@
|
|||
// CoderMixer2MT.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CoderMixer2MT.h"
|
||||
|
||||
namespace NCoderMixer {
|
||||
|
||||
CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
|
||||
CCoderInfo2(numInStreams, numOutStreams)
|
||||
{
|
||||
InStreams.Reserve(NumInStreams);
|
||||
InStreamPointers.Reserve(NumInStreams);
|
||||
OutStreams.Reserve(NumOutStreams);
|
||||
OutStreamPointers.Reserve(NumOutStreams);
|
||||
}
|
||||
|
||||
void CCoder2::Execute() { Code(NULL); }
|
||||
|
||||
void CCoder2::Code(ICompressProgressInfo *progress)
|
||||
{
|
||||
InStreamPointers.Clear();
|
||||
OutStreamPointers.Clear();
|
||||
UInt32 i;
|
||||
for (i = 0; i < NumInStreams; i++)
|
||||
{
|
||||
if (InSizePointers[i] != NULL)
|
||||
InSizePointers[i] = &InSizes[i];
|
||||
InStreamPointers.Add((ISequentialInStream *)InStreams[i]);
|
||||
}
|
||||
for (i = 0; i < NumOutStreams; i++)
|
||||
{
|
||||
if (OutSizePointers[i] != NULL)
|
||||
OutSizePointers[i] = &OutSizes[i];
|
||||
OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
|
||||
}
|
||||
if (Coder)
|
||||
Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
|
||||
InSizePointers[0], OutSizePointers[0], progress);
|
||||
else
|
||||
Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
|
||||
&OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < InStreams.Size(); i++)
|
||||
InStreams[i].Release();
|
||||
for (i = 0; i < OutStreams.Size(); i++)
|
||||
OutStreams[i].Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
|
||||
CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
|
||||
{
|
||||
sizes.Clear();
|
||||
sizePointers.Clear();
|
||||
for(UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
if (srcSizes == 0 || srcSizes[i] == NULL)
|
||||
{
|
||||
sizes.Add(0);
|
||||
sizePointers.Add(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
sizes.Add(*srcSizes[i]);
|
||||
sizePointers.Add(&sizes.Back());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
|
||||
{
|
||||
SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
|
||||
SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// CCoderMixer2MT
|
||||
|
||||
HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
|
||||
{
|
||||
_bindInfo = bindInfo;
|
||||
_streamBinders.Clear();
|
||||
for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
|
||||
{
|
||||
_streamBinders.Add(CStreamBinder());
|
||||
RINOK(_streamBinders.Back().CreateEvents());
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CCoderMixer2MT::AddCoderCommon()
|
||||
{
|
||||
const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];
|
||||
CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);
|
||||
_coders.Add(threadCoderInfo);
|
||||
}
|
||||
|
||||
void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
|
||||
{
|
||||
AddCoderCommon();
|
||||
_coders.Back().Coder = coder;
|
||||
}
|
||||
|
||||
void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
|
||||
{
|
||||
AddCoderCommon();
|
||||
_coders.Back().Coder2 = coder;
|
||||
}
|
||||
|
||||
|
||||
void CCoderMixer2MT::ReInit()
|
||||
{
|
||||
for(int i = 0; i < _streamBinders.Size(); i++)
|
||||
_streamBinders[i].ReInit();
|
||||
}
|
||||
|
||||
|
||||
HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams)
|
||||
{
|
||||
/*
|
||||
if (_coders.Size() != _bindInfo.Coders.Size())
|
||||
throw 0;
|
||||
*/
|
||||
int i;
|
||||
for(i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
CCoder2 &coderInfo = _coders[i];
|
||||
const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
|
||||
coderInfo.InStreams.Clear();
|
||||
UInt32 j;
|
||||
for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
|
||||
coderInfo.InStreams.Add(NULL);
|
||||
coderInfo.OutStreams.Clear();
|
||||
for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
|
||||
coderInfo.OutStreams.Add(NULL);
|
||||
}
|
||||
|
||||
for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
|
||||
{
|
||||
const CBindPair &bindPair = _bindInfo.BindPairs[i];
|
||||
UInt32 inCoderIndex, inCoderStreamIndex;
|
||||
UInt32 outCoderIndex, outCoderStreamIndex;
|
||||
_bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
|
||||
_bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
|
||||
|
||||
_streamBinders[i].CreateStreams(
|
||||
&_coders[inCoderIndex].InStreams[inCoderStreamIndex],
|
||||
&_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
|
||||
}
|
||||
|
||||
for(i = 0; i < _bindInfo.InStreams.Size(); i++)
|
||||
{
|
||||
UInt32 inCoderIndex, inCoderStreamIndex;
|
||||
_bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
|
||||
_coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
|
||||
}
|
||||
|
||||
for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
UInt32 outCoderIndex, outCoderStreamIndex;
|
||||
_bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
|
||||
_coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
|
||||
{
|
||||
for (int i = 0; i < _coders.Size(); i++)
|
||||
if (_coders[i].Result == code)
|
||||
return code;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
|
||||
const UInt64 ** /* inSizes */,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 ** /* outSizes */,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
|
||||
numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
|
||||
return E_INVALIDARG;
|
||||
|
||||
Init(inStreams, outStreams);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
if (i != _progressCoderIndex)
|
||||
{
|
||||
RINOK(_coders[i].Create());
|
||||
}
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
if (i != _progressCoderIndex)
|
||||
_coders[i].Start();
|
||||
|
||||
_coders[_progressCoderIndex].Code(progress);
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
if (i != _progressCoderIndex)
|
||||
_coders[i].WaitFinish();
|
||||
|
||||
RINOK(ReturnIfError(E_ABORT));
|
||||
RINOK(ReturnIfError(E_OUTOFMEMORY));
|
||||
RINOK(ReturnIfError(S_FALSE));
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
HRESULT result = _coders[i].Result;
|
||||
if (result != S_OK && result != E_FAIL)
|
||||
return result;
|
||||
}
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
HRESULT result = _coders[i].Result;
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// CoderMixer2MT.h
|
||||
|
||||
#ifndef __CODER_MIXER2_MT_H
|
||||
#define __CODER_MIXER2_MT_H
|
||||
|
||||
#include "CoderMixer2.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../Common/StreamBinder.h"
|
||||
#include "../../Common/VirtThread.h"
|
||||
|
||||
namespace NCoderMixer {
|
||||
|
||||
struct CCoder2: public CCoderInfo2, public CVirtThread
|
||||
{
|
||||
HRESULT Result;
|
||||
CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
|
||||
CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
|
||||
CRecordVector<ISequentialInStream*> InStreamPointers;
|
||||
CRecordVector<ISequentialOutStream*> OutStreamPointers;
|
||||
|
||||
CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
|
||||
void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
|
||||
virtual void Execute();
|
||||
void Code(ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
SetBindInfo()
|
||||
for each coder
|
||||
AddCoder[2]()
|
||||
SetProgressIndex(UInt32 coderIndex);
|
||||
|
||||
for each file
|
||||
{
|
||||
ReInit()
|
||||
for each coder
|
||||
SetCoderInfo
|
||||
Code
|
||||
}
|
||||
*/
|
||||
|
||||
class CCoderMixer2MT:
|
||||
public ICompressCoder2,
|
||||
public CCoderMixer2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CBindInfo _bindInfo;
|
||||
CObjectVector<CStreamBinder> _streamBinders;
|
||||
int _progressCoderIndex;
|
||||
|
||||
void AddCoderCommon();
|
||||
HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams);
|
||||
HRESULT ReturnIfError(HRESULT code);
|
||||
public:
|
||||
CObjectVector<CCoder2> _coders;
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
HRESULT SetBindInfo(const CBindInfo &bindInfo);
|
||||
void AddCoder(ICompressCoder *coder);
|
||||
void AddCoder2(ICompressCoder2 *coder);
|
||||
void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; }
|
||||
|
||||
void ReInit();
|
||||
void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
|
||||
{ _coders[coderIndex].SetCoderInfo(inSizes, outSizes); }
|
||||
UInt64 GetWriteProcessedSize(UInt32 binderIndex) const
|
||||
{ return _streamBinders[binderIndex].ProcessedSize; }
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
// CrossThreadProgress.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CrossThreadProgress.h"
|
||||
|
||||
STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
InSize = inSize;
|
||||
OutSize = outSize;
|
||||
ProgressEvent.Set();
|
||||
WaitEvent.Lock();
|
||||
return Result;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// CrossThreadProgress.h
|
||||
|
||||
#ifndef __CROSSTHREADPROGRESS_H
|
||||
#define __CROSSTHREADPROGRESS_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
class CCrossThreadProgress:
|
||||
public ICompressProgressInfo,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
const UInt64 *InSize;
|
||||
const UInt64 *OutSize;
|
||||
HRESULT Result;
|
||||
NWindows::NSynchronization::CAutoResetEvent ProgressEvent;
|
||||
NWindows::NSynchronization::CAutoResetEvent WaitEvent;
|
||||
|
||||
HRes Create()
|
||||
{
|
||||
RINOK(ProgressEvent.CreateIfNotCreated());
|
||||
return WaitEvent.CreateIfNotCreated();
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
ProgressEvent.Reset();
|
||||
WaitEvent.Reset();
|
||||
}
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,22 @@
|
|||
// DummyOutStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DummyOutStream.h"
|
||||
|
||||
STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result;
|
||||
if(!_stream)
|
||||
{
|
||||
realProcessedSize = size;
|
||||
result = S_OK;
|
||||
}
|
||||
else
|
||||
result = _stream->Write(data, size, &realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// DummyOutStream.h
|
||||
|
||||
#ifndef __DUMMYOUTSTREAM_H
|
||||
#define __DUMMYOUTSTREAM_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
class CDummyOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> _stream;
|
||||
UInt64 _size;
|
||||
public:
|
||||
void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
|
||||
void Init() { _size = 0; }
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
UInt64 GetSize() const { return _size; }
|
||||
};
|
||||
|
||||
#endif
|
618
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
Normal file
618
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
Normal file
|
@ -0,0 +1,618 @@
|
|||
// HandlerOutCommon.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "HandlerOut.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
#include "../../../Common/StringToInt.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../Common/ParseProperties.h"
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
#include "../../../Windows/System.h"
|
||||
#endif
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
namespace NArchive {
|
||||
|
||||
static const wchar_t *kCopyMethod = L"Copy";
|
||||
static const wchar_t *kLZMAMethodName = L"LZMA";
|
||||
static const wchar_t *kLZMA2MethodName = L"LZMA2";
|
||||
static const wchar_t *kBZip2MethodName = L"BZip2";
|
||||
static const wchar_t *kPpmdMethodName = L"PPMd";
|
||||
static const wchar_t *kDeflateMethodName = L"Deflate";
|
||||
static const wchar_t *kDeflate64MethodName = L"Deflate64";
|
||||
|
||||
static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
|
||||
static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
|
||||
|
||||
static const UInt32 kLzmaAlgoX1 = 0;
|
||||
static const UInt32 kLzmaAlgoX5 = 1;
|
||||
|
||||
static const UInt32 kLzmaDicSizeX1 = 1 << 16;
|
||||
static const UInt32 kLzmaDicSizeX3 = 1 << 20;
|
||||
static const UInt32 kLzmaDicSizeX5 = 1 << 24;
|
||||
static const UInt32 kLzmaDicSizeX7 = 1 << 25;
|
||||
static const UInt32 kLzmaDicSizeX9 = 1 << 26;
|
||||
|
||||
static const UInt32 kLzmaFastBytesX1 = 32;
|
||||
static const UInt32 kLzmaFastBytesX7 = 64;
|
||||
|
||||
static const UInt32 kPpmdMemSizeX1 = (1 << 22);
|
||||
static const UInt32 kPpmdMemSizeX5 = (1 << 24);
|
||||
static const UInt32 kPpmdMemSizeX7 = (1 << 26);
|
||||
static const UInt32 kPpmdMemSizeX9 = (192 << 20);
|
||||
|
||||
static const UInt32 kPpmdOrderX1 = 4;
|
||||
static const UInt32 kPpmdOrderX5 = 6;
|
||||
static const UInt32 kPpmdOrderX7 = 16;
|
||||
static const UInt32 kPpmdOrderX9 = 32;
|
||||
|
||||
static const UInt32 kDeflateAlgoX1 = 0;
|
||||
static const UInt32 kDeflateAlgoX5 = 1;
|
||||
|
||||
static const UInt32 kDeflateFastBytesX1 = 32;
|
||||
static const UInt32 kDeflateFastBytesX7 = 64;
|
||||
static const UInt32 kDeflateFastBytesX9 = 128;
|
||||
|
||||
static const UInt32 kDeflatePassesX1 = 1;
|
||||
static const UInt32 kDeflatePassesX7 = 3;
|
||||
static const UInt32 kDeflatePassesX9 = 10;
|
||||
|
||||
static const UInt32 kBZip2NumPassesX1 = 1;
|
||||
static const UInt32 kBZip2NumPassesX7 = 2;
|
||||
static const UInt32 kBZip2NumPassesX9 = 7;
|
||||
|
||||
static const UInt32 kBZip2DicSizeX1 = 100000;
|
||||
static const UInt32 kBZip2DicSizeX3 = 500000;
|
||||
static const UInt32 kBZip2DicSizeX5 = 900000;
|
||||
|
||||
static const wchar_t *kDefaultMethodName = kLZMAMethodName;
|
||||
|
||||
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
|
||||
static const UInt32 kDictionaryForHeaders = 1 << 20;
|
||||
static const UInt32 kNumFastBytesForHeaders = 273;
|
||||
static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5;
|
||||
|
||||
static bool AreEqual(const UString &methodName, const wchar_t *s)
|
||||
{ return (methodName.CompareNoCase(s) == 0); }
|
||||
|
||||
static inline bool IsLZMAMethod(const UString &methodName)
|
||||
{
|
||||
return
|
||||
AreEqual(methodName, kLZMAMethodName) ||
|
||||
AreEqual(methodName, kLZMA2MethodName);
|
||||
}
|
||||
|
||||
static inline bool IsBZip2Method(const UString &methodName)
|
||||
{ return AreEqual(methodName, kBZip2MethodName); }
|
||||
|
||||
static inline bool IsPpmdMethod(const UString &methodName)
|
||||
{ return AreEqual(methodName, kPpmdMethodName); }
|
||||
|
||||
static inline bool IsDeflateMethod(const UString &methodName)
|
||||
{
|
||||
return
|
||||
AreEqual(methodName, kDeflateMethodName) ||
|
||||
AreEqual(methodName, kDeflate64MethodName);
|
||||
}
|
||||
|
||||
struct CNameToPropID
|
||||
{
|
||||
PROPID PropID;
|
||||
VARTYPE VarType;
|
||||
const wchar_t *Name;
|
||||
};
|
||||
|
||||
CNameToPropID g_NameToPropID[] =
|
||||
{
|
||||
{ NCoderPropID::kOrder, VT_UI4, L"O" },
|
||||
{ NCoderPropID::kPosStateBits, VT_UI4, L"PB" },
|
||||
{ NCoderPropID::kLitContextBits, VT_UI4, L"LC" },
|
||||
{ NCoderPropID::kLitPosBits, VT_UI4, L"LP" },
|
||||
{ NCoderPropID::kEndMarker, VT_BOOL, L"eos" },
|
||||
|
||||
{ NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
|
||||
{ NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
|
||||
{ NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
|
||||
{ NCoderPropID::kAlgorithm, VT_UI4, L"a" },
|
||||
{ NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
|
||||
{ NCoderPropID::kNumThreads, VT_UI4, L"mt" }
|
||||
};
|
||||
|
||||
static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
|
||||
{
|
||||
if (varType == srcProp.vt)
|
||||
{
|
||||
destProp = srcProp;
|
||||
return true;
|
||||
}
|
||||
if (varType == VT_UI1)
|
||||
{
|
||||
if (srcProp.vt == VT_UI4)
|
||||
{
|
||||
UInt32 value = srcProp.ulVal;
|
||||
if (value > 0xFF)
|
||||
return false;
|
||||
destProp = (Byte)value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (varType == VT_BOOL)
|
||||
{
|
||||
bool res;
|
||||
if (SetBoolProperty(res, srcProp) != S_OK)
|
||||
return false;
|
||||
destProp = res;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int FindPropIdFromStringName(const UString &name)
|
||||
{
|
||||
for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
|
||||
if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID,
|
||||
const NWindows::NCOM::CPropVariant &value)
|
||||
{
|
||||
for (int j = 0; j < oneMethodInfo.Properties.Size(); j++)
|
||||
if (oneMethodInfo.Properties[j].Id == propID)
|
||||
return;
|
||||
CProp property;
|
||||
property.Id = propID;
|
||||
property.Value = value;
|
||||
oneMethodInfo.Properties.Add(property);
|
||||
}
|
||||
|
||||
void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
|
||||
#ifdef COMPRESS_MT
|
||||
, UInt32 numThreads
|
||||
#endif
|
||||
)
|
||||
{
|
||||
UInt32 level = _level;
|
||||
if (oneMethodInfo.MethodName.IsEmpty())
|
||||
oneMethodInfo.MethodName = kDefaultMethodName;
|
||||
|
||||
if (IsLZMAMethod(oneMethodInfo.MethodName))
|
||||
{
|
||||
UInt32 dicSize =
|
||||
(level >= 9 ? kLzmaDicSizeX9 :
|
||||
(level >= 7 ? kLzmaDicSizeX7 :
|
||||
(level >= 5 ? kLzmaDicSizeX5 :
|
||||
(level >= 3 ? kLzmaDicSizeX3 :
|
||||
kLzmaDicSizeX1))));
|
||||
|
||||
UInt32 algo =
|
||||
(level >= 5 ? kLzmaAlgoX5 :
|
||||
kLzmaAlgoX1);
|
||||
|
||||
UInt32 fastBytes =
|
||||
(level >= 7 ? kLzmaFastBytesX7 :
|
||||
kLzmaFastBytesX1);
|
||||
|
||||
const wchar_t *matchFinder =
|
||||
(level >= 5 ? kLzmaMatchFinderX5 :
|
||||
kLzmaMatchFinderX1);
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
|
||||
#ifdef COMPRESS_MT
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||
#endif
|
||||
}
|
||||
else if (IsDeflateMethod(oneMethodInfo.MethodName))
|
||||
{
|
||||
UInt32 fastBytes =
|
||||
(level >= 9 ? kDeflateFastBytesX9 :
|
||||
(level >= 7 ? kDeflateFastBytesX7 :
|
||||
kDeflateFastBytesX1));
|
||||
|
||||
UInt32 numPasses =
|
||||
(level >= 9 ? kDeflatePassesX9 :
|
||||
(level >= 7 ? kDeflatePassesX7 :
|
||||
kDeflatePassesX1));
|
||||
|
||||
UInt32 algo =
|
||||
(level >= 5 ? kDeflateAlgoX5 :
|
||||
kDeflateAlgoX1);
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
|
||||
}
|
||||
else if (IsBZip2Method(oneMethodInfo.MethodName))
|
||||
{
|
||||
UInt32 numPasses =
|
||||
(level >= 9 ? kBZip2NumPassesX9 :
|
||||
(level >= 7 ? kBZip2NumPassesX7 :
|
||||
kBZip2NumPassesX1));
|
||||
|
||||
UInt32 dicSize =
|
||||
(level >= 5 ? kBZip2DicSizeX5 :
|
||||
(level >= 3 ? kBZip2DicSizeX3 :
|
||||
kBZip2DicSizeX1));
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
|
||||
#ifdef COMPRESS_MT
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||
#endif
|
||||
}
|
||||
else if (IsPpmdMethod(oneMethodInfo.MethodName))
|
||||
{
|
||||
UInt32 useMemSize =
|
||||
(level >= 9 ? kPpmdMemSizeX9 :
|
||||
(level >= 7 ? kPpmdMemSizeX7 :
|
||||
(level >= 5 ? kPpmdMemSizeX5 :
|
||||
kPpmdMemSizeX1)));
|
||||
|
||||
UInt32 order =
|
||||
(level >= 9 ? kPpmdOrderX9 :
|
||||
(level >= 7 ? kPpmdOrderX7 :
|
||||
(level >= 5 ? kPpmdOrderX5 :
|
||||
kPpmdOrderX1)));
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
|
||||
}
|
||||
}
|
||||
|
||||
static void SplitParams(const UString &srcString, UStringVector &subStrings)
|
||||
{
|
||||
subStrings.Clear();
|
||||
UString name;
|
||||
int len = srcString.Length();
|
||||
if (len == 0)
|
||||
return;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
wchar_t c = srcString[i];
|
||||
if (c == L':')
|
||||
{
|
||||
subStrings.Add(name);
|
||||
name.Empty();
|
||||
}
|
||||
else
|
||||
name += c;
|
||||
}
|
||||
subStrings.Add(name);
|
||||
}
|
||||
|
||||
static void SplitParam(const UString ¶m, UString &name, UString &value)
|
||||
{
|
||||
int eqPos = param.Find(L'=');
|
||||
if (eqPos >= 0)
|
||||
{
|
||||
name = param.Left(eqPos);
|
||||
value = param.Mid(eqPos + 1);
|
||||
return;
|
||||
}
|
||||
for(int i = 0; i < param.Length(); i++)
|
||||
{
|
||||
wchar_t c = param[i];
|
||||
if (c >= L'0' && c <= L'9')
|
||||
{
|
||||
name = param.Left(i);
|
||||
value = param.Mid(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
name = param;
|
||||
}
|
||||
|
||||
HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
|
||||
{
|
||||
CProp property;
|
||||
if (
|
||||
name.CompareNoCase(L"D") == 0 ||
|
||||
name.CompareNoCase(L"MEM") == 0)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
RINOK(ParsePropDictionaryValue(value, dicSize));
|
||||
if (name.CompareNoCase(L"D") == 0)
|
||||
property.Id = NCoderPropID::kDictionarySize;
|
||||
else
|
||||
property.Id = NCoderPropID::kUsedMemorySize;
|
||||
property.Value = dicSize;
|
||||
oneMethodInfo.Properties.Add(property);
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = FindPropIdFromStringName(name);
|
||||
if (index < 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
const CNameToPropID &nameToPropID = g_NameToPropID[index];
|
||||
property.Id = nameToPropID.PropID;
|
||||
|
||||
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
|
||||
{
|
||||
UInt32 number;
|
||||
if (ParseStringToUInt32(value, number) == value.Length())
|
||||
propValue = number;
|
||||
else
|
||||
propValue = value;
|
||||
}
|
||||
|
||||
if (!ConvertProperty(propValue, nameToPropID.VarType, property.Value))
|
||||
return E_INVALIDARG;
|
||||
|
||||
oneMethodInfo.Properties.Add(property);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)
|
||||
{
|
||||
UStringVector params;
|
||||
SplitParams(srcString, params);
|
||||
if (params.Size() > 0)
|
||||
oneMethodInfo.MethodName = params[0];
|
||||
for (int i = 1; i < params.Size(); i++)
|
||||
{
|
||||
const UString ¶m = params[i];
|
||||
UString name, value;
|
||||
SplitParam(param, name, value);
|
||||
RINOK(SetParam(oneMethodInfo, name, value));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COutHandler::SetSolidSettings(const UString &s)
|
||||
{
|
||||
bool res;
|
||||
if (StringToBool(s, res))
|
||||
{
|
||||
if (res)
|
||||
InitSolid();
|
||||
else
|
||||
_numSolidFiles = 1;
|
||||
return S_OK;
|
||||
}
|
||||
UString s2 = s;
|
||||
s2.MakeUpper();
|
||||
for (int i = 0; i < s2.Length();)
|
||||
{
|
||||
const wchar_t *start = ((const wchar_t *)s2) + i;
|
||||
const wchar_t *end;
|
||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
||||
if (start == end)
|
||||
{
|
||||
if (s2[i++] != 'E')
|
||||
return E_INVALIDARG;
|
||||
_solidExtension = true;
|
||||
continue;
|
||||
}
|
||||
i += (int)(end - start);
|
||||
if (i == s2.Length())
|
||||
return E_INVALIDARG;
|
||||
wchar_t c = s2[i++];
|
||||
switch(c)
|
||||
{
|
||||
case 'F':
|
||||
if (v < 1)
|
||||
v = 1;
|
||||
_numSolidFiles = v;
|
||||
break;
|
||||
case 'B':
|
||||
_numSolidBytes = v;
|
||||
_numSolidBytesDefined = true;
|
||||
break;
|
||||
case 'K':
|
||||
_numSolidBytes = (v << 10);
|
||||
_numSolidBytesDefined = true;
|
||||
break;
|
||||
case 'M':
|
||||
_numSolidBytes = (v << 20);
|
||||
_numSolidBytesDefined = true;
|
||||
break;
|
||||
case 'G':
|
||||
_numSolidBytes = (v << 30);
|
||||
_numSolidBytesDefined = true;
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value)
|
||||
{
|
||||
switch(value.vt)
|
||||
{
|
||||
case VT_EMPTY:
|
||||
InitSolid();
|
||||
return S_OK;
|
||||
case VT_BSTR:
|
||||
return SetSolidSettings(value.bstrVal);
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
void COutHandler::Init()
|
||||
{
|
||||
_removeSfxBlock = false;
|
||||
_compressHeaders = true;
|
||||
_encryptHeaders = false;
|
||||
|
||||
WriteModified = true;
|
||||
WriteCreated = false;
|
||||
WriteAccessed = false;
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
|
||||
#endif
|
||||
|
||||
_level = 5;
|
||||
_autoFilter = true;
|
||||
_volumeMode = false;
|
||||
_crcSize = 4;
|
||||
InitSolid();
|
||||
}
|
||||
|
||||
void COutHandler::BeforeSetProperty()
|
||||
{
|
||||
Init();
|
||||
#ifdef COMPRESS_MT
|
||||
numProcessors = NSystem::GetNumberOfProcessors();
|
||||
#endif
|
||||
|
||||
mainDicSize = 0xFFFFFFFF;
|
||||
mainDicMethodIndex = 0xFFFFFFFF;
|
||||
minNumber = 0;
|
||||
_crcSize = 4;
|
||||
}
|
||||
|
||||
HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
|
||||
{
|
||||
UString name = nameSpec;
|
||||
name.MakeUpper();
|
||||
if (name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (name[0] == 'X')
|
||||
{
|
||||
name.Delete(0);
|
||||
_level = 9;
|
||||
return ParsePropValue(name, value, _level);
|
||||
}
|
||||
|
||||
if (name[0] == L'S')
|
||||
{
|
||||
name.Delete(0);
|
||||
if (name.IsEmpty())
|
||||
return SetSolidSettings(value);
|
||||
if (value.vt != VT_EMPTY)
|
||||
return E_INVALIDARG;
|
||||
return SetSolidSettings(name);
|
||||
}
|
||||
|
||||
if (name == L"CRC")
|
||||
{
|
||||
_crcSize = 4;
|
||||
name.Delete(0, 3);
|
||||
return ParsePropValue(name, value, _crcSize);
|
||||
}
|
||||
|
||||
UInt32 number;
|
||||
int index = ParseStringToUInt32(name, number);
|
||||
UString realName = name.Mid(index);
|
||||
if (index == 0)
|
||||
{
|
||||
if(name.Left(2).CompareNoCase(L"MT") == 0)
|
||||
{
|
||||
#ifdef COMPRESS_MT
|
||||
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
if (name.CompareNoCase(L"RSFX") == 0)
|
||||
return SetBoolProperty(_removeSfxBlock, value);
|
||||
if (name.CompareNoCase(L"F") == 0)
|
||||
return SetBoolProperty(_autoFilter, value);
|
||||
if (name.CompareNoCase(L"HC") == 0)
|
||||
return SetBoolProperty(_compressHeaders, value);
|
||||
if (name.CompareNoCase(L"HCF") == 0)
|
||||
{
|
||||
bool compressHeadersFull = true;
|
||||
RINOK(SetBoolProperty(compressHeadersFull, value));
|
||||
if (!compressHeadersFull)
|
||||
return E_INVALIDARG;
|
||||
return S_OK;
|
||||
}
|
||||
if (name.CompareNoCase(L"HE") == 0)
|
||||
return SetBoolProperty(_encryptHeaders, value);
|
||||
if (name.CompareNoCase(L"TM") == 0)
|
||||
return SetBoolProperty(WriteModified, value);
|
||||
if (name.CompareNoCase(L"TC") == 0)
|
||||
return SetBoolProperty(WriteCreated, value);
|
||||
if (name.CompareNoCase(L"TA") == 0)
|
||||
return SetBoolProperty(WriteAccessed, value);
|
||||
if (name.CompareNoCase(L"V") == 0)
|
||||
return SetBoolProperty(_volumeMode, value);
|
||||
number = 0;
|
||||
}
|
||||
if (number > 10000)
|
||||
return E_FAIL;
|
||||
if (number < minNumber)
|
||||
return E_INVALIDARG;
|
||||
number -= minNumber;
|
||||
for(int j = _methods.Size(); j <= (int)number; j++)
|
||||
{
|
||||
COneMethodInfo oneMethodInfo;
|
||||
_methods.Add(oneMethodInfo);
|
||||
}
|
||||
|
||||
COneMethodInfo &oneMethodInfo = _methods[number];
|
||||
|
||||
if (realName.Length() == 0)
|
||||
{
|
||||
if (value.vt != VT_BSTR)
|
||||
return E_INVALIDARG;
|
||||
|
||||
RINOK(SetParams(oneMethodInfo, value.bstrVal));
|
||||
}
|
||||
else
|
||||
{
|
||||
CProp property;
|
||||
if (realName.Left(1).CompareNoCase(L"D") == 0)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize));
|
||||
property.Id = NCoderPropID::kDictionarySize;
|
||||
property.Value = dicSize;
|
||||
oneMethodInfo.Properties.Add(property);
|
||||
if (number <= mainDicMethodIndex)
|
||||
mainDicSize = dicSize;
|
||||
}
|
||||
else if (realName.Left(3).CompareNoCase(L"MEM") == 0)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize));
|
||||
property.Id = NCoderPropID::kUsedMemorySize;
|
||||
property.Value = dicSize;
|
||||
oneMethodInfo.Properties.Add(property);
|
||||
if (number <= mainDicMethodIndex)
|
||||
mainDicSize = dicSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = FindPropIdFromStringName(realName);
|
||||
if (index < 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
const CNameToPropID &nameToPropID = g_NameToPropID[index];
|
||||
property.Id = nameToPropID.PropID;
|
||||
|
||||
if (!ConvertProperty(value, nameToPropID.VarType, property.Value))
|
||||
return E_INVALIDARG;
|
||||
|
||||
oneMethodInfo.Properties.Add(property);
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}
|
86
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/HandlerOut.h
Normal file
86
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/HandlerOut.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
// HandlerOut.h
|
||||
|
||||
#ifndef __HANDLER_OUT_H
|
||||
#define __HANDLER_OUT_H
|
||||
|
||||
#include "../../Common/MethodProps.h"
|
||||
#include "../../Common/CreateCoder.h"
|
||||
|
||||
namespace NArchive {
|
||||
|
||||
struct COneMethodInfo
|
||||
{
|
||||
CObjectVector<CProp> Properties;
|
||||
UString MethodName;
|
||||
};
|
||||
|
||||
class COutHandler
|
||||
{
|
||||
public:
|
||||
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
|
||||
|
||||
HRESULT SetSolidSettings(const UString &s);
|
||||
HRESULT SetSolidSettings(const PROPVARIANT &value);
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 _numThreads;
|
||||
#endif
|
||||
|
||||
UInt32 _crcSize;
|
||||
|
||||
CObjectVector<COneMethodInfo> _methods;
|
||||
bool _removeSfxBlock;
|
||||
|
||||
UInt64 _numSolidFiles;
|
||||
UInt64 _numSolidBytes;
|
||||
bool _numSolidBytesDefined;
|
||||
bool _solidExtension;
|
||||
|
||||
bool _compressHeaders;
|
||||
bool _encryptHeaders;
|
||||
|
||||
bool WriteModified;
|
||||
bool WriteCreated;
|
||||
bool WriteAccessed;
|
||||
|
||||
bool _autoFilter;
|
||||
UInt32 _level;
|
||||
|
||||
bool _volumeMode;
|
||||
|
||||
HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
|
||||
HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
|
||||
|
||||
void SetCompressionMethod2(COneMethodInfo &oneMethodInfo
|
||||
#ifdef COMPRESS_MT
|
||||
, UInt32 numThreads
|
||||
#endif
|
||||
);
|
||||
|
||||
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
|
||||
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
|
||||
void InitSolid()
|
||||
{
|
||||
InitSolidFiles();
|
||||
InitSolidSize();
|
||||
_solidExtension = false;
|
||||
_numSolidBytesDefined = false;
|
||||
}
|
||||
|
||||
void Init();
|
||||
|
||||
COutHandler() { Init(); }
|
||||
|
||||
void BeforeSetProperty();
|
||||
|
||||
UInt32 minNumber;
|
||||
UInt32 numProcessors;
|
||||
UInt32 mainDicSize;
|
||||
UInt32 mainDicMethodIndex;
|
||||
|
||||
DECL_EXTERNAL_CODECS_VARS
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
// InStreamWithCRC.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "InStreamWithCRC.h"
|
||||
|
||||
STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if (size > 0 && realProcessedSize == 0)
|
||||
_wasFinished = true;
|
||||
_crc = CrcUpdate(_crc, data, realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||
if (size > 0 && realProcessedSize == 0)
|
||||
_wasFinished = true;
|
||||
_size += realProcessedSize;
|
||||
_crc = CrcUpdate(_crc, data, realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||
{
|
||||
if (seekOrigin != STREAM_SEEK_SET || offset != 0)
|
||||
return E_FAIL;
|
||||
_size = 0;
|
||||
_crc = CRC_INIT_VAL;
|
||||
return _stream->Seek(offset, seekOrigin, newPosition);
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
// InStreamWithCRC.h
|
||||
|
||||
#ifndef __INSTREAMWITHCRC_H
|
||||
#define __INSTREAMWITHCRC_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
|
||||
class CSequentialInStreamWithCRC:
|
||||
public ISequentialInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
private:
|
||||
CMyComPtr<ISequentialInStream> _stream;
|
||||
UInt64 _size;
|
||||
UInt32 _crc;
|
||||
bool _wasFinished;
|
||||
public:
|
||||
void SetStream(ISequentialInStream *stream) { _stream = stream; }
|
||||
void Init()
|
||||
{
|
||||
_size = 0;
|
||||
_wasFinished = false;
|
||||
_crc = CRC_INIT_VAL;
|
||||
}
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
|
||||
UInt64 GetSize() const { return _size; }
|
||||
bool WasFinished() const { return _wasFinished; }
|
||||
};
|
||||
|
||||
class CInStreamWithCRC:
|
||||
public IInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(IInStream)
|
||||
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
private:
|
||||
CMyComPtr<IInStream> _stream;
|
||||
UInt64 _size;
|
||||
UInt32 _crc;
|
||||
bool _wasFinished;
|
||||
public:
|
||||
void SetStream(IInStream *stream) { _stream = stream; }
|
||||
void Init()
|
||||
{
|
||||
_size = 0;
|
||||
_wasFinished = false;
|
||||
_crc = CRC_INIT_VAL;
|
||||
}
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
|
||||
UInt64 GetSize() const { return _size; }
|
||||
bool WasFinished() const { return _wasFinished; }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,59 @@
|
|||
// Archive/Common/ItemNameUtils.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ItemNameUtils.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NItemName {
|
||||
|
||||
static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;
|
||||
static const wchar_t kDirDelimiter = L'/';
|
||||
|
||||
UString MakeLegalName(const UString &name)
|
||||
{
|
||||
UString zipName = name;
|
||||
zipName.Replace(kOSDirDelimiter, kDirDelimiter);
|
||||
return zipName;
|
||||
}
|
||||
|
||||
UString GetOSName(const UString &name)
|
||||
{
|
||||
UString newName = name;
|
||||
newName.Replace(kDirDelimiter, kOSDirDelimiter);
|
||||
return newName;
|
||||
}
|
||||
|
||||
UString GetOSName2(const UString &name)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
return UString();
|
||||
UString newName = GetOSName(name);
|
||||
if (newName[newName.Length() - 1] == kOSDirDelimiter)
|
||||
newName.Delete(newName.Length() - 1);
|
||||
return newName;
|
||||
}
|
||||
|
||||
bool HasTailSlash(const AString &name, UINT codePage)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
return false;
|
||||
LPCSTR prev =
|
||||
#ifdef _WIN32
|
||||
CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
|
||||
#else
|
||||
(LPCSTR)(name) + (name.Length() - 1);
|
||||
#endif
|
||||
return (*prev == '/');
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
UString WinNameToOSName(const UString &name)
|
||||
{
|
||||
UString newName = name;
|
||||
newName.Replace(L'\\', kOSDirDelimiter);
|
||||
return newName;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
|
@ -0,0 +1,24 @@
|
|||
// Archive/Common/ItemNameUtils.h
|
||||
|
||||
#ifndef __ARCHIVE_ITEMNAMEUTILS_H
|
||||
#define __ARCHIVE_ITEMNAMEUTILS_H
|
||||
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NItemName {
|
||||
|
||||
UString MakeLegalName(const UString &name);
|
||||
UString GetOSName(const UString &name);
|
||||
UString GetOSName2(const UString &name);
|
||||
bool HasTailSlash(const AString &name, UINT codePage);
|
||||
|
||||
#ifdef _WIN32
|
||||
inline UString WinNameToOSName(const UString &name) { return name; }
|
||||
#else
|
||||
UString WinNameToOSName(const UString &name);
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
201
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
Normal file
201
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
Normal file
|
@ -0,0 +1,201 @@
|
|||
// MultiStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "MultiStream.h"
|
||||
|
||||
STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if(processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
while(_streamIndex < Streams.Size() && size > 0)
|
||||
{
|
||||
CSubStreamInfo &s = Streams[_streamIndex];
|
||||
if (_pos == s.Size)
|
||||
{
|
||||
_streamIndex++;
|
||||
_pos = 0;
|
||||
continue;
|
||||
}
|
||||
RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0));
|
||||
UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos));
|
||||
UInt32 realProcessed;
|
||||
HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed);
|
||||
data = (void *)((Byte *)data + realProcessed);
|
||||
size -= realProcessed;
|
||||
if(processedSize != NULL)
|
||||
*processedSize += realProcessed;
|
||||
_pos += realProcessed;
|
||||
_seekPos += realProcessed;
|
||||
RINOK(result);
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
|
||||
UInt64 *newPosition)
|
||||
{
|
||||
UInt64 newPos;
|
||||
switch(seekOrigin)
|
||||
{
|
||||
case STREAM_SEEK_SET:
|
||||
newPos = offset;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
newPos = _seekPos + offset;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
newPos = _totalLength + offset;
|
||||
break;
|
||||
default:
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
_seekPos = 0;
|
||||
for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++)
|
||||
{
|
||||
UInt64 size = Streams[_streamIndex].Size;
|
||||
if (newPos < _seekPos + size)
|
||||
{
|
||||
_pos = newPos - _seekPos;
|
||||
_seekPos += _pos;
|
||||
if (newPosition != 0)
|
||||
*newPosition = newPos;
|
||||
return S_OK;
|
||||
}
|
||||
_seekPos += size;
|
||||
}
|
||||
if (newPos == _seekPos)
|
||||
{
|
||||
if (newPosition != 0)
|
||||
*newPosition = newPos;
|
||||
return S_OK;
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
class COutVolumeStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
int _volIndex;
|
||||
UInt64 _volSize;
|
||||
UInt64 _curPos;
|
||||
CMyComPtr<ISequentialOutStream> _volumeStream;
|
||||
COutArchive _archive;
|
||||
CCRC _crc;
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
CFileItem _file;
|
||||
CUpdateOptions _options;
|
||||
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
|
||||
void Init(IArchiveUpdateCallback2 *volumeCallback,
|
||||
const UString &name)
|
||||
{
|
||||
_file.Name = name;
|
||||
_file.IsStartPosDefined = true;
|
||||
_file.StartPos = 0;
|
||||
|
||||
VolumeCallback = volumeCallback;
|
||||
_volIndex = 0;
|
||||
_volSize = 0;
|
||||
}
|
||||
|
||||
HRESULT Flush();
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
HRESULT COutVolumeStream::Flush()
|
||||
{
|
||||
if (_volumeStream)
|
||||
{
|
||||
_file.UnPackSize = _curPos;
|
||||
_file.FileCRC = _crc.GetDigest();
|
||||
RINOK(WriteVolumeHeader(_archive, _file, _options));
|
||||
_archive.Close();
|
||||
_volumeStream.Release();
|
||||
_file.StartPos += _file.UnPackSize;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if(processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
while(size > 0)
|
||||
{
|
||||
if (_streamIndex >= Streams.Size())
|
||||
{
|
||||
CSubStreamInfo subStream;
|
||||
RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size));
|
||||
RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream));
|
||||
subStream.Pos = 0;
|
||||
Streams.Add(subStream);
|
||||
continue;
|
||||
}
|
||||
CSubStreamInfo &subStream = Streams[_streamIndex];
|
||||
if (_offsetPos >= subStream.Size)
|
||||
{
|
||||
_offsetPos -= subStream.Size;
|
||||
_streamIndex++;
|
||||
continue;
|
||||
}
|
||||
if (_offsetPos != subStream.Pos)
|
||||
{
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
|
||||
RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
|
||||
subStream.Pos = _offsetPos;
|
||||
}
|
||||
|
||||
UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
|
||||
UInt32 realProcessed;
|
||||
RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
|
||||
data = (void *)((Byte *)data + realProcessed);
|
||||
size -= realProcessed;
|
||||
subStream.Pos += realProcessed;
|
||||
_offsetPos += realProcessed;
|
||||
_absPos += realProcessed;
|
||||
if (_absPos > _length)
|
||||
_length = _absPos;
|
||||
if(processedSize != NULL)
|
||||
*processedSize += realProcessed;
|
||||
if (subStream.Pos == subStream.Size)
|
||||
{
|
||||
_streamIndex++;
|
||||
_offsetPos = 0;
|
||||
}
|
||||
if (realProcessed != curSize && realProcessed == 0)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||
{
|
||||
if(seekOrigin >= 3)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
switch(seekOrigin)
|
||||
{
|
||||
case STREAM_SEEK_SET:
|
||||
_absPos = offset;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
_absPos += offset;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
_absPos = _length + offset;
|
||||
break;
|
||||
}
|
||||
_offsetPos = _absPos;
|
||||
_streamIndex = 0;
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
76
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/MultiStream.h
Normal file
76
lib/physfs-2.0.3/lzma/CPP/7zip/Archive/Common/MultiStream.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
// MultiStream.h
|
||||
|
||||
#ifndef __MULTISTREAM_H
|
||||
#define __MULTISTREAM_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../../Common/MyVector.h"
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
class CMultiStream:
|
||||
public IInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
int _streamIndex;
|
||||
UInt64 _pos;
|
||||
UInt64 _seekPos;
|
||||
UInt64 _totalLength;
|
||||
public:
|
||||
struct CSubStreamInfo
|
||||
{
|
||||
CMyComPtr<IInStream> Stream;
|
||||
UInt64 Pos;
|
||||
UInt64 Size;
|
||||
};
|
||||
CObjectVector<CSubStreamInfo> Streams;
|
||||
void Init()
|
||||
{
|
||||
_streamIndex = 0;
|
||||
_pos = 0;
|
||||
_seekPos = 0;
|
||||
_totalLength = 0;
|
||||
for (int i = 0; i < Streams.Size(); i++)
|
||||
_totalLength += Streams[i].Size;
|
||||
}
|
||||
|
||||
MY_UNKNOWN_IMP1(IInStream)
|
||||
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
};
|
||||
|
||||
/*
|
||||
class COutMultiStream:
|
||||
public IOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
int _streamIndex; // required stream
|
||||
UInt64 _offsetPos; // offset from start of _streamIndex index
|
||||
UInt64 _absPos;
|
||||
UInt64 _length;
|
||||
|
||||
struct CSubStreamInfo
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> Stream;
|
||||
UInt64 Size;
|
||||
UInt64 Pos;
|
||||
};
|
||||
CObjectVector<CSubStreamInfo> Streams;
|
||||
public:
|
||||
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
|
||||
void Init()
|
||||
{
|
||||
_streamIndex = 0;
|
||||
_offsetPos = 0;
|
||||
_absPos = 0;
|
||||
_length = 0;
|
||||
}
|
||||
|
||||
MY_UNKNOWN_IMP1(IOutStream)
|
||||
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
};
|
||||
*/
|
||||
|
||||
#endif
|
|
@ -0,0 +1,24 @@
|
|||
// OutStreamWithCRC.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "OutStreamWithCRC.h"
|
||||
|
||||
STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result;
|
||||
if(!_stream)
|
||||
{
|
||||
realProcessedSize = size;
|
||||
result = S_OK;
|
||||
}
|
||||
else
|
||||
result = _stream->Write(data, size, &realProcessedSize);
|
||||
if (_calculate)
|
||||
_crc = CrcUpdate(_crc, data, realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// OutStreamWithCRC.h
|
||||
|
||||
#ifndef __OUTSTREAMWITHCRC_H
|
||||
#define __OUTSTREAMWITHCRC_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
|
||||
class COutStreamWithCRC:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> _stream;
|
||||
UInt64 _size;
|
||||
UInt32 _crc;
|
||||
bool _calculate;
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
void Init(bool calculate = true)
|
||||
{
|
||||
_size = 0;
|
||||
_calculate = calculate;
|
||||
_crc = CRC_INIT_VAL;
|
||||
}
|
||||
void InitCRC() { _crc = CRC_INIT_VAL; }
|
||||
UInt64 GetSize() const { return _size; }
|
||||
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,174 @@
|
|||
// ParseProperties.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ParseProperties.h"
|
||||
|
||||
#include "Common/StringToInt.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
|
||||
{
|
||||
if (prop.vt == VT_UI4)
|
||||
{
|
||||
if (!name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
resValue = prop.ulVal;
|
||||
}
|
||||
else if (prop.vt == VT_EMPTY)
|
||||
{
|
||||
if(!name.IsEmpty())
|
||||
{
|
||||
const wchar_t *start = name;
|
||||
const wchar_t *end;
|
||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
||||
if (end - start != name.Length())
|
||||
return E_INVALIDARG;
|
||||
resValue = (UInt32)v;
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const int kLogarithmicSizeLimit = 32;
|
||||
static const wchar_t kByteSymbol = L'B';
|
||||
static const wchar_t kKiloByteSymbol = L'K';
|
||||
static const wchar_t kMegaByteSymbol = L'M';
|
||||
|
||||
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
|
||||
{
|
||||
UString srcString = srcStringSpec;
|
||||
srcString.MakeUpper();
|
||||
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UInt64 number = ConvertStringToUInt64(start, &end);
|
||||
int numDigits = (int)(end - start);
|
||||
if (numDigits == 0 || srcString.Length() > numDigits + 1)
|
||||
return E_INVALIDARG;
|
||||
if (srcString.Length() == numDigits)
|
||||
{
|
||||
if (number >= kLogarithmicSizeLimit)
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)1 << (int)number;
|
||||
return S_OK;
|
||||
}
|
||||
switch (srcString[numDigits])
|
||||
{
|
||||
case kByteSymbol:
|
||||
if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)number;
|
||||
break;
|
||||
case kKiloByteSymbol:
|
||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)(number << 10);
|
||||
break;
|
||||
case kMegaByteSymbol:
|
||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)(number << 20);
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
{
|
||||
if (prop.vt == VT_UI4)
|
||||
{
|
||||
UInt32 logDicSize = prop.ulVal;
|
||||
if (logDicSize >= 32)
|
||||
return E_INVALIDARG;
|
||||
resValue = (UInt32)1 << logDicSize;
|
||||
return S_OK;
|
||||
}
|
||||
if (prop.vt == VT_BSTR)
|
||||
return ParsePropDictionaryValue(prop.bstrVal, resValue);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return ParsePropDictionaryValue(name, resValue);
|
||||
}
|
||||
|
||||
bool StringToBool(const UString &s, bool &res)
|
||||
{
|
||||
if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0)
|
||||
{
|
||||
res = true;
|
||||
return true;
|
||||
}
|
||||
if (s.CompareNoCase(L"OFF") == 0)
|
||||
{
|
||||
res = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
|
||||
{
|
||||
switch(value.vt)
|
||||
{
|
||||
case VT_EMPTY:
|
||||
dest = true;
|
||||
return S_OK;
|
||||
/*
|
||||
case VT_UI4:
|
||||
dest = (value.ulVal != 0);
|
||||
break;
|
||||
*/
|
||||
case VT_BSTR:
|
||||
return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG;
|
||||
}
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
int ParseStringToUInt32(const UString &srcString, UInt32 &number)
|
||||
{
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UInt64 number64 = ConvertStringToUInt64(start, &end);
|
||||
if (number64 > 0xFFFFFFFF)
|
||||
{
|
||||
number = 0;
|
||||
return 0;
|
||||
}
|
||||
number = (UInt32)number64;
|
||||
return (int)(end - start);
|
||||
}
|
||||
|
||||
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(SetBoolProperty(val, prop));
|
||||
numThreads = (val ? defaultNumThreads : 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 number;
|
||||
int index = ParseStringToUInt32(name, number);
|
||||
if (index != name.Length())
|
||||
return E_INVALIDARG;
|
||||
numThreads = number;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
// ParseProperties.h
|
||||
|
||||
#ifndef __PARSEPROPERTIES_H
|
||||
#define __PARSEPROPERTIES_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "Common/Types.h"
|
||||
|
||||
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
|
||||
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
|
||||
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
|
||||
|
||||
bool StringToBool(const UString &s, bool &res);
|
||||
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
|
||||
int ParseStringToUInt32(const UString &srcString, UInt32 &number);
|
||||
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue