mirror of
https://github.com/Xevion/easy7zip.git
synced 2026-02-01 12:24:16 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
Executable → Regular
+144
-141
@@ -2,10 +2,10 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "Common/MyString.h"
|
||||
#include "../../Common/ComTry.h"
|
||||
#include "../../Common/MyString.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "../../Windows/PropVariant.h"
|
||||
|
||||
#include "../Common/ProgressUtils.h"
|
||||
#include "../Common/RegisterArc.h"
|
||||
@@ -19,15 +19,16 @@ using namespace NWindows;
|
||||
namespace NArchive {
|
||||
namespace NSplit {
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
static const Byte kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidSize, VT_UI8}
|
||||
kpidPath,
|
||||
kpidSize
|
||||
};
|
||||
|
||||
STATPROPSTG kArcProps[] =
|
||||
static const Byte kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidNumVolumes, VT_UI4}
|
||||
kpidNumVolumes,
|
||||
kpidTotalPhySize
|
||||
};
|
||||
|
||||
class CHandler:
|
||||
@@ -35,10 +36,12 @@ class CHandler:
|
||||
public IInArchiveGetStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UString _subName;
|
||||
CObjectVector<CMyComPtr<IInStream> > _streams;
|
||||
CRecordVector<UInt64> _sizes;
|
||||
UString _subName;
|
||||
UInt64 _totalSize;
|
||||
|
||||
HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
|
||||
INTERFACE_IInArchive(;)
|
||||
@@ -51,9 +54,11 @@ IMP_IInArchive_ArcProps
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
switch (propID)
|
||||
{
|
||||
case kpidMainSubfile: prop = (UInt32)0; break;
|
||||
case kpidPhySize: if (!_sizes.IsEmpty()) prop = _sizes[0]; break;
|
||||
case kpidTotalPhySize: prop = _totalSize; break;
|
||||
case kpidNumVolumes: prop = (UInt32)_streams.Size(); break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
@@ -72,20 +77,18 @@ struct CSeqName
|
||||
if (_splitStyle)
|
||||
{
|
||||
int i;
|
||||
int numLetters = _changedPart.Length();
|
||||
int numLetters = _changedPart.Len();
|
||||
for (i = numLetters - 1; i >= 0; i--)
|
||||
{
|
||||
wchar_t c = _changedPart[i];
|
||||
if (c == 'z')
|
||||
{
|
||||
c = 'a';
|
||||
newName = c + newName;
|
||||
newName.InsertAtFront('a');
|
||||
continue;
|
||||
}
|
||||
else if (c == 'Z')
|
||||
{
|
||||
c = 'A';
|
||||
newName = c + newName;
|
||||
newName.InsertAtFront('A');
|
||||
continue;
|
||||
}
|
||||
c++;
|
||||
@@ -99,33 +102,32 @@ struct CSeqName
|
||||
newName += newChar;
|
||||
break;
|
||||
}
|
||||
newName = c + newName;
|
||||
newName.InsertAtFront(c);
|
||||
i--;
|
||||
for (; i >= 0; i--)
|
||||
newName = _changedPart[i] + newName;
|
||||
newName.InsertAtFront(_changedPart[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
int numLetters = _changedPart.Length();
|
||||
int numLetters = _changedPart.Len();
|
||||
for (i = numLetters - 1; i >= 0; i--)
|
||||
{
|
||||
wchar_t c = _changedPart[i];
|
||||
if (c == L'9')
|
||||
if (c == '9')
|
||||
{
|
||||
c = L'0';
|
||||
newName = c + newName;
|
||||
newName.InsertAtFront('0');
|
||||
if (i == 0)
|
||||
newName = UString(L'1') + newName;
|
||||
newName.InsertAtFront('1');
|
||||
continue;
|
||||
}
|
||||
c++;
|
||||
newName = c + newName;
|
||||
newName.InsertAtFront(c);
|
||||
i--;
|
||||
for (; i >= 0; i--)
|
||||
newName = _changedPart[i] + newName;
|
||||
newName.InsertAtFront(_changedPart[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -134,142 +136,139 @@ struct CSeqName
|
||||
}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
Close();
|
||||
if (openArchiveCallback == 0)
|
||||
if (!callback)
|
||||
return S_FALSE;
|
||||
// try
|
||||
|
||||
CMyComPtr<IArchiveOpenVolumeCallback> volumeCallback;
|
||||
callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback);
|
||||
if (!volumeCallback)
|
||||
return S_FALSE;
|
||||
|
||||
UString name;
|
||||
{
|
||||
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback;
|
||||
if (openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback,
|
||||
&openVolumeCallback) != S_OK)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(volumeCallback->GetProperty(kpidName, &prop));
|
||||
if (prop.vt != VT_BSTR)
|
||||
return S_FALSE;
|
||||
|
||||
UString name;
|
||||
name = prop.bstrVal;
|
||||
}
|
||||
|
||||
int dotPos = name.ReverseFind('.');
|
||||
const UString prefix = name.Left(dotPos + 1);
|
||||
const UString ext = name.Ptr(dotPos + 1);
|
||||
UString ext2 = ext;
|
||||
ext2.MakeLower_Ascii();
|
||||
|
||||
CSeqName seqName;
|
||||
|
||||
unsigned numLetters = 2;
|
||||
bool splitStyle = false;
|
||||
|
||||
if (ext2.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "aa"))
|
||||
{
|
||||
splitStyle = true;
|
||||
while (numLetters < ext2.Len())
|
||||
{
|
||||
if (ext2[ext2.Len() - numLetters - 1] != 'a')
|
||||
break;
|
||||
numLetters++;
|
||||
}
|
||||
}
|
||||
else if (ext.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "01"))
|
||||
{
|
||||
while (numLetters < ext2.Len())
|
||||
{
|
||||
if (ext2[ext2.Len() - numLetters - 1] != '0')
|
||||
break;
|
||||
numLetters++;
|
||||
}
|
||||
if (numLetters != ext.Len())
|
||||
return S_FALSE;
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
|
||||
seqName._unchangedPart = prefix + ext.Left(ext2.Len() - numLetters);
|
||||
seqName._changedPart = ext.RightPtr(numLetters);
|
||||
seqName._splitStyle = splitStyle;
|
||||
|
||||
if (prefix.Len() < 1)
|
||||
_subName = L"file";
|
||||
else
|
||||
_subName.SetFrom(prefix, prefix.Len() - 1);
|
||||
|
||||
UInt64 size;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(volumeCallback->GetProperty(kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = prop.uhVal.QuadPart;
|
||||
}
|
||||
|
||||
_totalSize += size;
|
||||
_sizes.Add(size);
|
||||
_streams.Add(stream);
|
||||
|
||||
{
|
||||
UInt64 numFiles = _streams.Size();
|
||||
RINOK(callback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const UString fullName = seqName.GetNextName();
|
||||
CMyComPtr<IInStream> nextStream;
|
||||
HRESULT result = volumeCallback->GetStream(fullName, &nextStream);
|
||||
if (result == S_FALSE)
|
||||
break;
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
if (!stream)
|
||||
break;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
|
||||
if (prop.vt != VT_BSTR)
|
||||
return S_FALSE;
|
||||
name = prop.bstrVal;
|
||||
}
|
||||
|
||||
int dotPos = name.ReverseFind('.');
|
||||
UString prefix, ext;
|
||||
if (dotPos >= 0)
|
||||
{
|
||||
prefix = name.Left(dotPos + 1);
|
||||
ext = name.Mid(dotPos + 1);
|
||||
}
|
||||
else
|
||||
ext = name;
|
||||
UString extBig = ext;
|
||||
extBig.MakeUpper();
|
||||
|
||||
CSeqName seqName;
|
||||
|
||||
int numLetters = 2;
|
||||
bool splitStyle = false;
|
||||
if (extBig.Right(2) == L"AA")
|
||||
{
|
||||
splitStyle = true;
|
||||
while (numLetters < extBig.Length())
|
||||
{
|
||||
if (extBig[extBig.Length() - numLetters - 1] != 'A')
|
||||
break;
|
||||
numLetters++;
|
||||
}
|
||||
}
|
||||
else if (ext.Right(2) == L"01")
|
||||
{
|
||||
while (numLetters < extBig.Length())
|
||||
{
|
||||
if (extBig[extBig.Length() - numLetters - 1] != '0')
|
||||
break;
|
||||
numLetters++;
|
||||
}
|
||||
if (numLetters != ext.Length())
|
||||
return S_FALSE;
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
|
||||
_streams.Add(stream);
|
||||
|
||||
seqName._unchangedPart = prefix + ext.Left(extBig.Length() - numLetters);
|
||||
seqName._changedPart = ext.Right(numLetters);
|
||||
seqName._splitStyle = splitStyle;
|
||||
|
||||
if (prefix.Length() < 1)
|
||||
_subName = L"file";
|
||||
else
|
||||
_subName = prefix.Left(prefix.Length() - 1);
|
||||
|
||||
_totalSize = 0;
|
||||
UInt64 size;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));
|
||||
RINOK(volumeCallback->GetProperty(kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = prop.uhVal.QuadPart;
|
||||
}
|
||||
_totalSize += size;
|
||||
_sizes.Add(size);
|
||||
|
||||
if (openArchiveCallback != NULL)
|
||||
_streams.Add(nextStream);
|
||||
{
|
||||
UInt64 numFiles = _streams.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
RINOK(callback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
UString fullName = seqName.GetNextName();
|
||||
CMyComPtr<IInStream> nextStream;
|
||||
HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
|
||||
if (result == S_FALSE)
|
||||
break;
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
if (!stream)
|
||||
break;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = prop.uhVal.QuadPart;
|
||||
}
|
||||
_totalSize += size;
|
||||
_sizes.Add(size);
|
||||
_streams.Add(nextStream);
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
UInt64 numFiles = _streams.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
catch(...)
|
||||
if (_streams.Size() == 1)
|
||||
{
|
||||
return S_FALSE;
|
||||
if (splitStyle)
|
||||
return S_FALSE;
|
||||
}
|
||||
*/
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
HRESULT res = Open2(stream, callback);
|
||||
if (res != S_OK)
|
||||
Close();
|
||||
return res;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_sizes.Clear();
|
||||
_totalSize = 0;
|
||||
_subName.Empty();
|
||||
_streams.Clear();
|
||||
_sizes.Clear();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -281,8 +280,8 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
NCOM::CPropVariant prop;
|
||||
switch (propID)
|
||||
{
|
||||
case kpidPath: prop = _subName; break;
|
||||
case kpidSize:
|
||||
@@ -300,7 +299,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
COM_TRY_BEGIN
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||
if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
|
||||
return E_INVALIDARG;
|
||||
|
||||
UInt64 currentTotalSize = 0;
|
||||
@@ -321,7 +320,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
for (int i = 0; i < _streams.Size(); i++)
|
||||
FOR_VECTOR (i, _streams)
|
||||
{
|
||||
lps->InSize = lps->OutSize = currentTotalSize;
|
||||
RINOK(lps->SetCur());
|
||||
@@ -343,7 +342,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
*stream = 0;
|
||||
CMultiStream *streamSpec = new CMultiStream;
|
||||
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
|
||||
for (int i = 0; i < _streams.Size(); i++)
|
||||
FOR_VECTOR (i, _streams)
|
||||
{
|
||||
CMultiStream::CSubStreamInfo subStreamInfo;
|
||||
subStreamInfo.Stream = _streams[i];
|
||||
@@ -356,10 +355,14 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
IMP_CreateArcIn
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Split", L"001", 0, 0xEA, { 0 }, 0, false, CreateArc, 0 };
|
||||
{ "Split", "001", 0, 0xEA,
|
||||
0, { 0 },
|
||||
0,
|
||||
0,
|
||||
CreateArc };
|
||||
|
||||
REGISTER_ARC(Split)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user