1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
// GZipUpdate.cpp
#include "StdAfx.h"
#include "GZipUpdate.h"
#include "Common/Defs.h"
#include "Common/StringConvert.h"
#include "Windows/Defs.h"
#include "Windows/PropVariant.h"
#include "../../ICoder.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/CreateCoder.h"
#include "../../Compress/Copy/CopyCoder.h"
#include "../Common/InStreamWithCRC.h"
namespace NArchive {
namespace NGZip {
static const CMethodId kMethodId_Deflate = 0x040108;
static const Byte kHostOS = NFileHeader::NHostOS::kFAT;
HRESULT UpdateArchive(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream * /* inStream */,
UInt64 unpackSize,
ISequentialOutStream *outStream,
const CItem &newItem,
const CCompressionMethodMode &compressionMethod,
int indexInClient,
IArchiveUpdateCallback *updateCallback)
{
UInt64 complexity = unpackSize;
RINOK(updateCallback->SetTotal(complexity));
CMyComPtr<ICompressCoder> deflateEncoder;
complexity = 0;
RINOK(updateCallback->SetCompleted(&complexity));
CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(indexInClient, &fileInStream));
CSequentialInStreamWithCRC *inStreamSpec = new CSequentialInStreamWithCRC;
CMyComPtr<ISequentialInStream> crcStream(inStreamSpec);
inStreamSpec->SetStream(fileInStream);
inStreamSpec->Init();
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
COutArchive outArchive;
outArchive.Create(outStream);
CItem item = newItem;
item.CompressionMethod = NFileHeader::NCompressionMethod::kDeflate;
item.ExtraFlags = 0;
item.HostOS = kHostOS;
RINOK(outArchive.WriteHeader(item));
{
RINOK(CreateCoder(
EXTERNAL_CODECS_LOC_VARS
kMethodId_Deflate, deflateEncoder, true));
if (!deflateEncoder)
return E_NOTIMPL;
NWindows::NCOM::CPropVariant properties[] =
{
compressionMethod.Algo,
compressionMethod.NumPasses,
compressionMethod.NumFastBytes,
compressionMethod.NumMatchFinderCycles
};
PROPID propIDs[] =
{
NCoderPropID::kAlgorithm,
NCoderPropID::kNumPasses,
NCoderPropID::kNumFastBytes,
NCoderPropID::kMatchFinderCycles
};
int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
if (!compressionMethod.NumMatchFinderCyclesDefined)
numProps--;
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
RINOK(deflateEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps));
}
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress));
item.FileCRC = inStreamSpec->GetCRC();
item.UnPackSize32 = (UInt32)inStreamSpec->GetSize();
RINOK(outArchive.WritePostHeader(item));
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
}}
|