Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Archive/GZip/GZipHandlerOut.cpp')
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipHandlerOut.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp b/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp
new file mode 100755
index 00000000..cc896016
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp
@@ -0,0 +1,200 @@
+// Archive/GZip/OutHandler.cpp
+
+#include "StdAfx.h"
+
+#include "GZipHandler.h"
+#include "GZipUpdate.h"
+
+#include "Common/StringConvert.h"
+#include "Common/StringToInt.h"
+
+#include "Windows/Time.h"
+#include "Windows/FileFind.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../Common/ParseProperties.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NGZip {
+
+static const UInt32 kNumPassesX1 = 1;
+static const UInt32 kNumPassesX7 = 3;
+static const UInt32 kNumPassesX9 = 10;
+
+static const UInt32 kNumFastBytesX1 = 32;
+static const UInt32 kNumFastBytesX7 = 64;
+static const UInt32 kNumFastBytesX9 = 128;
+
+
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
+{
+ *timeType = NFileTimeType::kUnix;
+ return S_OK;
+}
+
+static HRESULT CopyStreams(ISequentialInStream *inStream, ISequentialOutStream *outStream)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
+}
+
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ if (numItems != 1)
+ return E_INVALIDARG;
+
+ UInt64 size;
+ Int32 newData;
+ Int32 newProperties;
+ UInt32 indexInArchive;
+ UInt32 itemIndex = 0;
+ if (!updateCallback)
+ return E_FAIL;
+ RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProperties, &indexInArchive));
+
+ CItem newItem = m_Item;
+ newItem.ExtraFlags = 0;
+ newItem.Flags = 0;
+ if (IntToBool(newProperties))
+ {
+ UInt32 attributes;
+ FILETIME utcTime;
+ UString name;
+ bool isDirectory;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(itemIndex, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ attributes = 0;
+ else if (propVariant.vt != VT_UI4)
+ return E_INVALIDARG;
+ else
+ attributes = propVariant.ulVal;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(itemIndex, kpidLastWriteTime, &propVariant));
+ if (propVariant.vt != VT_FILETIME)
+ return E_INVALIDARG;
+ utcTime = propVariant.filetime;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(itemIndex, kpidPath, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ name.Empty();
+ else if (propVariant.vt != VT_BSTR)
+ return E_INVALIDARG;
+ else
+ name = propVariant.bstrVal;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(itemIndex, kpidIsFolder, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ isDirectory = false;
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ isDirectory = (propVariant.boolVal != VARIANT_FALSE);
+ }
+ if (isDirectory || NFile::NFind::NAttributes::IsDirectory(attributes))
+ return E_INVALIDARG;
+ if(!FileTimeToUnixTime(utcTime, newItem.Time))
+ return E_INVALIDARG;
+ newItem.Name = UnicodeStringToMultiByte(name, CP_ACP);
+ int dirDelimiterPos = newItem.Name.ReverseFind(CHAR_PATH_SEPARATOR);
+ if (dirDelimiterPos >= 0)
+ newItem.Name = newItem.Name.Mid(dirDelimiterPos + 1);
+
+ newItem.SetNameIsPresentFlag(!newItem.Name.IsEmpty());
+ }
+
+ if (IntToBool(newData))
+ {
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &propVariant));
+ if (propVariant.vt != VT_UI8)
+ return E_INVALIDARG;
+ size = propVariant.uhVal.QuadPart;
+ }
+ newItem.UnPackSize32 = (UInt32)size;
+
+ UInt32 level = m_Level;
+ if (level == 0xFFFFFFFF)
+ level = 5;
+ if (m_Method.NumPasses == 0xFFFFFFFF)
+ m_Method.NumPasses = (level >= 9 ? kNumPassesX9 :
+ (level >= 7 ? kNumPassesX7 :
+ kNumPassesX1));
+ if (m_Method.NumFastBytes == 0xFFFFFFFF)
+ m_Method.NumFastBytes = (level >= 9 ? kNumFastBytesX9 :
+ (level >= 7 ? kNumFastBytesX7 :
+ kNumFastBytesX1));
+
+ return UpdateArchive(m_Stream, size, outStream, newItem, m_Method, itemIndex, updateCallback);
+ }
+
+ if (indexInArchive != 0)
+ return E_INVALIDARG;
+
+ if (IntToBool(newProperties))
+ {
+ COutArchive outArchive;
+ outArchive.Create(outStream);
+ outArchive.WriteHeader(newItem);
+ RINOK(m_Stream->Seek(m_StreamStartPosition + m_DataOffset, STREAM_SEEK_SET, NULL));
+ }
+ else
+ {
+ RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
+ }
+ return CopyStreams(m_Stream, outStream);
+}
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+ InitMethodProperties();
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = names[i];
+ name.MakeUpper();
+ const PROPVARIANT &prop = values[i];
+ if (name[0] == L'X')
+ {
+ UInt32 level = 9;
+ RINOK(ParsePropValue(name.Mid(1), prop, level));
+ m_Level = level;
+ }
+ else if (name.Left(4) == L"PASS")
+ {
+ UInt32 num = kNumPassesX9;
+ RINOK(ParsePropValue(name.Mid(4), prop, num));
+ m_Method.NumPasses = num;
+ }
+ else if (name.Left(2) == L"FB")
+ {
+ UInt32 num = kNumFastBytesX9;
+ RINOK(ParsePropValue(name.Mid(2), prop, num));
+ m_Method.NumFastBytes = num;
+ }
+ else if (name.Left(2) == L"MC")
+ {
+ UInt32 num = 0xFFFFFFFF;
+ RINOK(ParsePropValue(name.Mid(2), prop, num));
+ m_Method.NumMatchFinderCycles = num;
+ m_Method.NumMatchFinderCyclesDefined = true;
+ }
+ else
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+}}