Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(640)

Side by Side Diff: third_party/lzma/v4_65/files/CPP/7zip/Archive/7z/7zHandlerOut.cpp

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // 7zHandlerOut.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../Windows/PropVariant.h"
6
7 #include "../../../Common/ComTry.h"
8 #include "../../../Common/StringToInt.h"
9
10 #include "../../ICoder.h"
11
12 #include "../Common/ItemNameUtils.h"
13 #include "../Common/ParseProperties.h"
14
15 #include "7zHandler.h"
16 #include "7zOut.h"
17 #include "7zUpdate.h"
18
19 using namespace NWindows;
20
21 namespace NArchive {
22 namespace N7z {
23
24 static const wchar_t *kLZMAMethodName = L"LZMA";
25 static const wchar_t *kCopyMethod = L"Copy";
26 static const wchar_t *kDefaultMethodName = kLZMAMethodName;
27
28 static const UInt32 kLzmaAlgorithmX5 = 1;
29 static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
30 static const UInt32 kDictionaryForHeaders = 1 << 20;
31 static const UInt32 kNumFastBytesForHeaders = 273;
32 static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
33
34 static inline bool IsCopyMethod(const UString &methodName)
35 { return (methodName.CompareNoCase(kCopyMethod) == 0); }
36
37 STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
38 {
39 *type = NFileTimeType::kWindows;
40 return S_OK;
41 }
42
43 HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
44 IArchiveUpdateCallback *updateCallback)
45 {
46 CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
47 if (!getTextPassword)
48 {
49 CMyComPtr<IArchiveUpdateCallback> udateCallback2(updateCallback);
50 udateCallback2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword) ;
51 }
52
53 if (getTextPassword)
54 {
55 CMyComBSTR password;
56 Int32 passwordIsDefined;
57 RINOK(getTextPassword->CryptoGetTextPassword2(
58 &passwordIsDefined, &password));
59 methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
60 if (methodMode.PasswordIsDefined)
61 methodMode.Password = password;
62 }
63 else
64 methodMode.PasswordIsDefined = false;
65 return S_OK;
66 }
67
68 HRESULT CHandler::SetCompressionMethod(
69 CCompressionMethodMode &methodMode,
70 CCompressionMethodMode &headerMethod)
71 {
72 HRESULT res = SetCompressionMethod(methodMode, _methods
73 #ifdef COMPRESS_MT
74 , _numThreads
75 #endif
76 );
77 RINOK(res);
78 methodMode.Binds = _binds;
79
80 if (_compressHeaders)
81 {
82 // headerMethod.Methods.Add(methodMode.Methods.Back());
83
84 CObjectVector<COneMethodInfo> headerMethodInfoVector;
85 COneMethodInfo oneMethodInfo;
86 oneMethodInfo.MethodName = kLZMAMethodName;
87 {
88 CProp prop;
89 prop.Id = NCoderPropID::kMatchFinder;
90 prop.Value = kLzmaMatchFinderForHeaders;
91 oneMethodInfo.Props.Add(prop);
92 }
93 {
94 CProp prop;
95 prop.Id = NCoderPropID::kAlgorithm;
96 prop.Value = kAlgorithmForHeaders;
97 oneMethodInfo.Props.Add(prop);
98 }
99 {
100 CProp prop;
101 prop.Id = NCoderPropID::kNumFastBytes;
102 prop.Value = (UInt32)kNumFastBytesForHeaders;
103 oneMethodInfo.Props.Add(prop);
104 }
105 {
106 CProp prop;
107 prop.Id = NCoderPropID::kDictionarySize;
108 prop.Value = (UInt32)kDictionaryForHeaders;
109 oneMethodInfo.Props.Add(prop);
110 }
111 headerMethodInfoVector.Add(oneMethodInfo);
112 HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
113 #ifdef COMPRESS_MT
114 ,1
115 #endif
116 );
117 RINOK(res);
118 }
119 return S_OK;
120 }
121
122 HRESULT CHandler::SetCompressionMethod(
123 CCompressionMethodMode &methodMode,
124 CObjectVector<COneMethodInfo> &methodsInfo
125 #ifdef COMPRESS_MT
126 , UInt32 numThreads
127 #endif
128 )
129 {
130 UInt32 level = _level;
131
132 if (methodsInfo.IsEmpty())
133 {
134 COneMethodInfo oneMethodInfo;
135 oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName) ;
136 methodsInfo.Add(oneMethodInfo);
137 }
138
139 bool needSolid = false;
140 for(int i = 0; i < methodsInfo.Size(); i++)
141 {
142 COneMethodInfo &oneMethodInfo = methodsInfo[i];
143 SetCompressionMethod2(oneMethodInfo
144 #ifdef COMPRESS_MT
145 , numThreads
146 #endif
147 );
148
149 if (!IsCopyMethod(oneMethodInfo.MethodName))
150 needSolid = true;
151
152 CMethodFull methodFull;
153
154 if (!FindMethod(
155 EXTERNAL_CODECS_VARS
156 oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, method Full.NumOutStreams))
157 return E_INVALIDARG;
158 methodFull.Props = oneMethodInfo.Props;
159 methodMode.Methods.Add(methodFull);
160
161 if (!_numSolidBytesDefined)
162 {
163 for (int j = 0; j < methodFull.Props.Size(); j++)
164 {
165 const CProp &prop = methodFull.Props[j];
166 if ((prop.Id == NCoderPropID::kDictionarySize ||
167 prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI 4)
168 {
169 _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
170 const UInt64 kMinSize = (1 << 24);
171 if (_numSolidBytes < kMinSize)
172 _numSolidBytes = kMinSize;
173 _numSolidBytesDefined = true;
174 break;
175 }
176 }
177 }
178 }
179
180 if (!needSolid && !_numSolidBytesDefined)
181 {
182 _numSolidBytesDefined = true;
183 _numSolidBytes = 0;
184 }
185 return S_OK;
186 }
187
188 static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool w riteTime, PROPID propID, UInt64 &ft, bool &ftDefined)
189 {
190 ft = 0;
191 ftDefined = false;
192 if (!writeTime)
193 return S_OK;
194 NCOM::CPropVariant prop;
195 RINOK(updateCallback->GetProperty(index, propID, &prop));
196 if (prop.vt == VT_FILETIME)
197 {
198 ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);
199 ftDefined = true;
200 }
201 else if (prop.vt != VT_EMPTY)
202 return E_INVALIDARG;
203 return S_OK;
204 }
205
206 STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt ems,
207 IArchiveUpdateCallback *updateCallback)
208 {
209 COM_TRY_BEGIN
210
211 const CArchiveDatabaseEx *db = 0;
212 #ifdef _7Z_VOL
213 if(_volumes.Size() > 1)
214 return E_FAIL;
215 const CVolume *volume = 0;
216 if (_volumes.Size() == 1)
217 {
218 volume = &_volumes.Front();
219 db = &volume->Database;
220 }
221 #else
222 if (_inStream != 0)
223 db = &_db;
224 #endif
225
226 CObjectVector<CUpdateItem> updateItems;
227
228 for (UInt32 i = 0; i < numItems; i++)
229 {
230 Int32 newData;
231 Int32 newProperties;
232 UInt32 indexInArchive;
233 if (!updateCallback)
234 return E_FAIL;
235 RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProperties, &indexI nArchive));
236 CUpdateItem ui;
237 ui.NewProperties = IntToBool(newProperties);
238 ui.NewData = IntToBool(newData);
239 ui.IndexInArchive = indexInArchive;
240 ui.IndexInClient = i;
241 ui.IsAnti = false;
242 ui.Size = 0;
243
244 if (ui.IndexInArchive != -1)
245 {
246 const CFileItem &fi = db->Files[ui.IndexInArchive];
247 ui.Name = fi.Name;
248 ui.IsDir = fi.IsDir;
249 ui.Size = fi.Size;
250 ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
251
252 ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
253 ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
254 ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
255 }
256
257 if (ui.NewProperties)
258 {
259 bool nameIsDefined;
260 bool folderStatusIsDefined;
261 {
262 NCOM::CPropVariant prop;
263 RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
264 if (prop.vt == VT_EMPTY)
265 ui.AttribDefined = false;
266 else if (prop.vt != VT_UI4)
267 return E_INVALIDARG;
268 else
269 {
270 ui.Attrib = prop.ulVal;
271 ui.AttribDefined = true;
272 }
273 }
274
275 // we need MTime to sort files.
276 RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTime Defined));
277 RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATime Defined));
278 RINOK(GetTime(updateCallback, i, true, kpidMTime, ui.MTime, ui.MTime Defined));
279
280 {
281 NCOM::CPropVariant prop;
282 RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
283 if (prop.vt == VT_EMPTY)
284 nameIsDefined = false;
285 else if (prop.vt != VT_BSTR)
286 return E_INVALIDARG;
287 else
288 {
289 ui.Name = NItemName::MakeLegalName(prop.bstrVal);
290 nameIsDefined = true;
291 }
292 }
293 {
294 NCOM::CPropVariant prop;
295 RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop));
296 if (prop.vt == VT_EMPTY)
297 folderStatusIsDefined = false;
298 else if (prop.vt != VT_BOOL)
299 return E_INVALIDARG;
300 else
301 {
302 ui.IsDir = (prop.boolVal != VARIANT_FALSE);
303 folderStatusIsDefined = true;
304 }
305 }
306
307 {
308 NCOM::CPropVariant prop;
309 RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop));
310 if (prop.vt == VT_EMPTY)
311 ui.IsAnti = false;
312 else if (prop.vt != VT_BOOL)
313 return E_INVALIDARG;
314 else
315 ui.IsAnti = (prop.boolVal != VARIANT_FALSE);
316 }
317
318 if (ui.IsAnti)
319 {
320 ui.AttribDefined = false;
321
322 ui.CTimeDefined = false;
323 ui.ATimeDefined = false;
324 ui.MTimeDefined = false;
325
326 ui.Size = 0;
327 }
328
329 if (!folderStatusIsDefined && ui.AttribDefined)
330 ui.SetDirStatusFromAttrib();
331 }
332
333 if (ui.NewData)
334 {
335 NCOM::CPropVariant prop;
336 RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
337 if (prop.vt != VT_UI8)
338 return E_INVALIDARG;
339 ui.Size = (UInt64)prop.uhVal.QuadPart;
340 if (ui.Size != 0 && ui.IsAnti)
341 return E_INVALIDARG;
342 }
343 updateItems.Add(ui);
344 }
345
346 CCompressionMethodMode methodMode, headerMethod;
347 RINOK(SetCompressionMethod(methodMode, headerMethod));
348 #ifdef COMPRESS_MT
349 methodMode.NumThreads = _numThreads;
350 headerMethod.NumThreads = 1;
351 #endif
352
353 RINOK(SetPassword(methodMode, updateCallback));
354
355 bool compressMainHeader = _compressHeaders; // check it
356
357 bool encryptHeaders = false;
358
359 if (methodMode.PasswordIsDefined)
360 {
361 if (_encryptHeadersSpecified)
362 encryptHeaders = _encryptHeaders;
363 #ifndef _NO_CRYPTO
364 else
365 encryptHeaders = _passwordIsDefined;
366 #endif
367 compressMainHeader = true;
368 if(encryptHeaders)
369 RINOK(SetPassword(headerMethod, updateCallback));
370 }
371
372 if (numItems < 2)
373 compressMainHeader = false;
374
375 CUpdateOptions options;
376 options.Method = &methodMode;
377 options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
378 options.UseFilters = _level != 0 && _autoFilter;
379 options.MaxFilter = _level >= 8;
380
381 options.HeaderOptions.CompressMainHeader = compressMainHeader;
382 options.HeaderOptions.WriteCTime = WriteCTime;
383 options.HeaderOptions.WriteATime = WriteATime;
384 options.HeaderOptions.WriteMTime = WriteMTime;
385
386 options.NumSolidFiles = _numSolidFiles;
387 options.NumSolidBytes = _numSolidBytes;
388 options.SolidExtension = _solidExtension;
389 options.RemoveSfxBlock = _removeSfxBlock;
390 options.VolumeMode = _volumeMode;
391
392 COutArchive archive;
393 CArchiveDatabase newDatabase;
394 HRESULT res = Update(
395 EXTERNAL_CODECS_VARS
396 #ifdef _7Z_VOL
397 volume ? volume->Stream: 0,
398 volume ? db : 0,
399 #else
400 _inStream,
401 db,
402 #endif
403 updateItems,
404 archive, newDatabase, outStream, updateCallback, options);
405
406 RINOK(res);
407
408 updateItems.ClearAndFree();
409
410 return archive.WriteDatabase(EXTERNAL_CODECS_VARS
411 newDatabase, options.HeaderMethod, options.HeaderOptions);
412
413 COM_TRY_END
414 }
415
416 static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream )
417 {
418 stream = 0;
419 int index = ParseStringToUInt32(srcString, coder);
420 if (index == 0)
421 return E_INVALIDARG;
422 srcString.Delete(0, index);
423 if (srcString[0] == 'S')
424 {
425 srcString.Delete(0);
426 int index = ParseStringToUInt32(srcString, stream);
427 if (index == 0)
428 return E_INVALIDARG;
429 srcString.Delete(0, index);
430 }
431 return S_OK;
432 }
433
434 static HRESULT GetBindInfo(UString &srcString, CBind &bind)
435 {
436 RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));
437 if (srcString[0] != ':')
438 return E_INVALIDARG;
439 srcString.Delete(0);
440 RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));
441 if (!srcString.IsEmpty())
442 return E_INVALIDARG;
443 return S_OK;
444 }
445
446 STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v alues, Int32 numProperties)
447 {
448 COM_TRY_BEGIN
449 _binds.Clear();
450 BeforeSetProperty();
451
452 for (int i = 0; i < numProperties; i++)
453 {
454 UString name = names[i];
455 name.MakeUpper();
456 if (name.IsEmpty())
457 return E_INVALIDARG;
458
459 const PROPVARIANT &value = values[i];
460
461 if (name[0] == 'B')
462 {
463 name.Delete(0);
464 CBind bind;
465 RINOK(GetBindInfo(name, bind));
466 _binds.Add(bind);
467 continue;
468 }
469
470 RINOK(SetProperty(name, value));
471 }
472
473 return S_OK;
474 COM_TRY_END
475 }
476
477 }}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698