summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp')
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp265
1 files changed, 152 insertions, 113 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp
index 3e70f466e7b..7f8fa5b5229 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp
@@ -5,6 +5,7 @@
#include "../../../../C/7zCrc.h"
#include "../../../Common/AutoPtr.h"
+// #include "../../../Common/UTFConvert.h"
#include "../../Common/StreamObjects.h"
@@ -13,16 +14,14 @@
namespace NArchive {
namespace N7z {
-HRESULT COutArchive::WriteSignature()
+static void FillSignature(Byte *buf)
{
- Byte buf[8];
memcpy(buf, kSignature, kSignatureSize);
buf[kSignatureSize] = kMajorVersion;
buf[kSignatureSize + 1] = 4;
- return WriteDirect(buf, 8);
}
-#ifdef _7Z_VOL
+#ifdef Z7_7Z_VOL
HRESULT COutArchive::WriteFinishSignature()
{
RINOK(WriteDirect(kFinishSignature, kSignatureSize));
@@ -48,15 +47,16 @@ static void SetUInt64(Byte *p, UInt64 d)
HRESULT COutArchive::WriteStartHeader(const CStartHeader &h)
{
- Byte buf[24];
- SetUInt64(buf + 4, h.NextHeaderOffset);
- SetUInt64(buf + 12, h.NextHeaderSize);
- SetUInt32(buf + 20, h.NextHeaderCRC);
- SetUInt32(buf, CrcCalc(buf + 4, 20));
- return WriteDirect(buf, 24);
+ Byte buf[32];
+ FillSignature(buf);
+ SetUInt64(buf + 8 + 4, h.NextHeaderOffset);
+ SetUInt64(buf + 8 + 12, h.NextHeaderSize);
+ SetUInt32(buf + 8 + 20, h.NextHeaderCRC);
+ SetUInt32(buf + 8, CrcCalc(buf + 8 + 4, 20));
+ return WriteDirect(buf, sizeof(buf));
}
-#ifdef _7Z_VOL
+#ifdef Z7_7Z_VOL
HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h)
{
CCRC crc;
@@ -74,15 +74,15 @@ HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h)
}
#endif
-HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
+HRESULT COutArchive::Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */)
{
Close();
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
// endMarker = false;
_endMarker = endMarker;
#endif
SeqStream = stream;
- if (!endMarker)
+ // if (!endMarker)
{
SeqStream.QueryInterface(IID_IOutStream, &Stream);
if (!Stream)
@@ -90,8 +90,13 @@ HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
return E_NOTIMPL;
// endMarker = true;
}
+ RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_signatureHeaderPos))
+ Byte buf[32];
+ FillSignature(buf);
+ memset(&buf[8], 0, 32 - 8);
+ return WriteDirect(buf, sizeof(buf));
}
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
if (endMarker)
{
/*
@@ -100,17 +105,10 @@ HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
sh.NextHeaderSize = (UInt32)(Int32)-1;
sh.NextHeaderCRC = 0;
WriteStartHeader(sh);
+ return S_OK;
*/
}
- else
#endif
- {
- if (!Stream)
- return E_FAIL;
- RINOK(WriteSignature());
- RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos));
- }
- return S_OK;
}
void COutArchive::Close()
@@ -119,17 +117,6 @@ void COutArchive::Close()
Stream.Release();
}
-HRESULT COutArchive::SkipPrefixArchiveHeader()
-{
- #ifdef _7Z_VOL
- if (_endMarker)
- return S_OK;
- #endif
- Byte buf[24];
- memset(buf, 0, 24);
- return WriteDirect(buf, 24);
-}
-
UInt64 COutArchive::GetPos() const
{
if (_countMode)
@@ -196,7 +183,7 @@ void COutArchive::WriteNumber(UInt64 value)
break;
}
firstByte |= mask;
- mask >>= 1;
+ mask = (Byte)(mask >> 1);
}
WriteByte(firstByte);
for (; i > 0; i--)
@@ -206,16 +193,16 @@ void COutArchive::WriteNumber(UInt64 value)
}
}
-static UInt32 GetBigNumberSize(UInt64 value)
+static unsigned GetBigNumberSize(UInt64 value)
{
- int i;
+ unsigned i;
for (i = 1; i < 9; i++)
if (value < (((UInt64)1 << (i * 7))))
break;
return i;
}
-#ifdef _7Z_VOL
+#ifdef Z7_7Z_VOL
UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props)
{
UInt32 result = GetBigNumberSize(dataSize) * 2 + 41;
@@ -264,18 +251,18 @@ void COutArchive::WriteFolder(const CFolder &folder)
for (idSize = 1; idSize < sizeof(id); idSize++)
if ((id >> (8 * idSize)) == 0)
break;
- idSize &= 0xF;
+ // idSize &= 0xF; // idSize is smaller than 16 already
Byte temp[16];
for (unsigned t = idSize; t != 0; t--, id >>= 8)
temp[t] = (Byte)(id & 0xFF);
- Byte b = (Byte)(idSize);
- bool isComplex = !coder.IsSimpleCoder();
+ unsigned b = idSize;
+ const bool isComplex = !coder.IsSimpleCoder();
b |= (isComplex ? 0x10 : 0);
- size_t propsSize = coder.Props.Size();
+ const size_t propsSize = coder.Props.Size();
b |= ((propsSize != 0) ? 0x20 : 0);
- temp[0] = b;
+ temp[0] = (Byte)b;
WriteBytes(temp, idSize + 1);
if (isComplex)
{
@@ -309,7 +296,7 @@ void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
{
if (boolVector[i])
b |= mask;
- mask >>= 1;
+ mask = (Byte)(mask >> 1);
if (mask == 0)
{
WriteByte(b);
@@ -330,13 +317,11 @@ void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector)
WriteBoolVector(boolVector);
}
+unsigned BoolVector_CountSum(const CBoolVector &v);
+
void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
{
- unsigned numDefined = 0;
- unsigned i;
- for (i = 0; i < digests.Defs.Size(); i++)
- if (digests.Defs[i])
- numDefined++;
+ const unsigned numDefined = BoolVector_CountSum(digests.Defs);
if (numDefined == 0)
return;
@@ -348,7 +333,8 @@ void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
WriteByte(0);
WriteBoolVector(digests.Defs);
}
- for (i = 0; i < digests.Defs.Size(); i++)
+
+ for (unsigned i = 0; i < digests.Defs.Size(); i++)
if (digests.Defs[i])
WriteUInt32(digests.Vals[i]);
}
@@ -453,10 +439,12 @@ void COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders,
// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.
-void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
+void COutArchive::SkipToAligned(unsigned pos, unsigned alignShifts)
{
if (!_useAlign)
return;
+
+ const unsigned alignSize = (unsigned)1 << alignShifts;
pos += (unsigned)GetPos();
pos &= (alignSize - 1);
if (pos == 0)
@@ -471,11 +459,11 @@ void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
WriteByte(0);
}
-void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize)
+void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts)
{
const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
- const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2;
- SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize);
+ const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2;
+ SkipToAligned(3 + bvSize + GetBigNumberSize(dataSize), itemSizeShifts);
WriteByte(type);
WriteNumber(dataSize);
@@ -486,24 +474,18 @@ void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefin
WriteByte(0);
WriteBoolVector(v);
}
- WriteByte(0);
+ WriteByte(0); // 0 means no switching to external stream
}
void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
{
- unsigned numDefined = 0;
-
- unsigned i;
- for (i = 0; i < v.Defs.Size(); i++)
- if (v.Defs[i])
- numDefined++;
-
+ const unsigned numDefined = BoolVector_CountSum(v.Defs);
if (numDefined == 0)
return;
- WriteAlignedBoolHeader(v.Defs, numDefined, type, 8);
+ WriteAlignedBools(v.Defs, numDefined, type, 3);
- for (i = 0; i < v.Defs.Size(); i++)
+ for (unsigned i = 0; i < v.Defs.Size(); i++)
if (v.Defs[i])
WriteUInt64(v.Vals[i]);
}
@@ -519,14 +501,20 @@ HRESULT COutArchive::EncodeStream(
outFolders.FolderUnpackCRCs.Defs.Add(true);
outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size()));
// outFolders.NumUnpackStreamsVector.Add(1);
- UInt64 dataSize64 = data.Size();
- UInt64 unpackSize;
- RINOK(encoder.Encode(
+ const UInt64 dataSize64 = data.Size();
+ const UInt64 expectSize = data.Size();
+ RINOK(encoder.Encode1(
EXTERNAL_CODECS_LOC_VARS
stream,
// NULL,
- &dataSize64,
- folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL))
+ &dataSize64, // inSizeForReduce
+ expectSize,
+ folders.AddNew(),
+ // outFolders.CoderUnpackSizes, unpackSize,
+ SeqStream, packSizes, NULL))
+ if (!streamSpec->WasFinished())
+ return E_FAIL;
+ encoder.Encode_Post(dataSize64, outFolders.CoderUnpackSizes);
return S_OK;
}
@@ -550,7 +538,39 @@ void COutArchive::WriteHeader(
WriteByte(NID::kHeader);
- // Archive Properties
+ /*
+ {
+ // It's example for per archive properies writing
+
+ WriteByte(NID::kArchiveProperties);
+
+ // you must use random 40-bit number that will identify you
+ // then you can use same kDeveloperID for any properties and methods
+ const UInt64 kDeveloperID = 0x123456789A; // change that value to real random 40-bit number
+
+ #define GENERATE_7Z_ID(developerID, subID) (((UInt64)0x3F << 56) | ((UInt64)developerID << 16) | subID)
+
+ {
+ const UInt64 kSubID = 0x1; // you can use small number for subID
+ const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID);
+ WriteNumber(kID);
+ const unsigned kPropsSize = 3; // it's example size
+ WriteNumber(kPropsSize);
+ for (unsigned i = 0; i < kPropsSize; i++)
+ WriteByte((Byte)(i & 0xFF));
+ }
+ {
+ const UInt64 kSubID = 0x2; // you can use small number for subID
+ const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID);
+ WriteNumber(kID);
+ const unsigned kPropsSize = 5; // it's example size
+ WriteNumber(kPropsSize);
+ for (unsigned i = 0; i < kPropsSize; i++)
+ WriteByte((Byte)(i + 16));
+ }
+ WriteByte(NID::kEnd);
+ }
+ */
if (db.Folders.Size() > 0)
{
@@ -642,13 +662,21 @@ void COutArchive::WriteHeader(
const UString &name = db.Names[i];
if (!name.IsEmpty())
numDefined++;
- namesDataSize += (name.Len() + 1) * 2;
+ const size_t numUtfChars =
+ /*
+ #if WCHAR_MAX > 0xffff
+ Get_Num_Utf16_chars_from_wchar_string(name.Ptr());
+ #else
+ */
+ name.Len();
+ // #endif
+ namesDataSize += (numUtfChars + 1) * 2;
}
if (numDefined > 0)
{
namesDataSize++;
- SkipAlign(2 + GetBigNumberSize(namesDataSize), 16);
+ SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4);
WriteByte(NID::kName);
WriteNumber(namesDataSize);
@@ -659,6 +687,25 @@ void COutArchive::WriteHeader(
for (unsigned t = 0; t <= name.Len(); t++)
{
wchar_t c = name[t];
+
+ /*
+ #if WCHAR_MAX > 0xffff
+ if (c >= 0x10000)
+ {
+ c -= 0x10000;
+ if (c < (1 << 20))
+ {
+ unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF);
+ WriteByte((Byte)c0);
+ WriteByte((Byte)(c0 >> 8));
+ c = 0xdc00 + (c & 0x3FF);
+ }
+ else
+ c = '_'; // we change character unsupported by UTF16
+ }
+ #endif
+ */
+
WriteByte((Byte)c);
WriteByte((Byte)(c >> 8));
}
@@ -673,28 +720,15 @@ void COutArchive::WriteHeader(
{
/* ---------- Write Attrib ---------- */
- CBoolVector boolVector;
- boolVector.ClearAndSetSize(db.Files.Size());
- unsigned numDefined = 0;
-
- {
- FOR_VECTOR (i, db.Files)
- {
- bool defined = db.Files[i].AttribDefined;
- boolVector[i] = defined;
- if (defined)
- numDefined++;
- }
- }
+ const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs);
if (numDefined != 0)
{
- WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4);
- FOR_VECTOR (i, db.Files)
+ WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2);
+ FOR_VECTOR (i, db.Attrib.Defs)
{
- const CFileItem &file = db.Files[i];
- if (file.AttribDefined)
- WriteUInt32(file.Attrib);
+ if (db.Attrib.Defs[i])
+ WriteUInt32(db.Attrib.Vals[i]);
}
}
}
@@ -702,18 +736,8 @@ void COutArchive::WriteHeader(
/*
{
// ---------- Write IsAux ----------
- unsigned numAux = 0;
- const CBoolVector &isAux = db.IsAux;
- for (i = 0; i < isAux.Size(); i++)
- if (isAux[i])
- numAux++;
- if (numAux > 0)
- {
- const unsigned bvSize = Bv_GetSizeInBytes(isAux);
- WriteByte(NID::kIsAux);
- WriteNumber(bvSize);
- WriteBoolVector(isAux);
- }
+ if (BoolVector_CountSum(db.IsAux) != 0)
+ WritePropBoolVector(NID::kIsAux, db.IsAux);
}
{
@@ -734,10 +758,10 @@ void COutArchive::WriteHeader(
}
if (numParentLinks > 0)
{
- // WriteAlignedBoolHeader(boolVector, numDefined, NID::kParent, 4);
+ // WriteAlignedBools(boolVector, numDefined, NID::kParent, 2);
const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector);
const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1;
- SkipAlign(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 4);
+ SkipToAligned(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 2);
WriteByte(NID::kParent);
WriteNumber(dataSize);
@@ -765,7 +789,7 @@ void COutArchive::WriteHeader(
// secureDataSize += db.SecureIDs.Size() * 4;
for (i = 0; i < db.SecureIDs.Size(); i++)
secureDataSize += GetBigNumberSize(db.SecureIDs[i]);
- SkipAlign(2 + GetBigNumberSize(secureDataSize), 4);
+ SkipToAligned(2 + GetBigNumberSize(secureDataSize), 2);
WriteByte(NID::kNtSecure);
WriteNumber(secureDataSize);
WriteByte(0);
@@ -801,15 +825,15 @@ HRESULT COutArchive::WriteDatabase(
{
headerSize = 0;
headerOffset = 0;
- headerCRC = CrcCalc(0, 0);
+ headerCRC = CrcCalc(NULL, 0);
}
else
{
bool encodeHeaders = false;
- if (options != 0)
+ if (options)
if (options->IsEmpty())
- options = 0;
- if (options != 0)
+ options = NULL;
+ if (options)
if (options->PasswordIsDefined || headerOptions.CompressMainHeader)
encodeHeaders = true;
@@ -844,7 +868,7 @@ HRESULT COutArchive::WriteDatabase(
RINOK(EncodeStream(
EXTERNAL_CODECS_LOC_VARS
encoder, buf,
- packSizes, folders, outFolders));
+ packSizes, folders, outFolders))
_writeToStream = true;
@@ -858,11 +882,11 @@ HRESULT COutArchive::WriteDatabase(
FOR_VECTOR (i, packSizes)
headerOffset += packSizes[i];
}
- RINOK(_outByte.Flush());
+ RINOK(_outByte.Flush())
headerCRC = CRC_GET_DIGEST(_crc);
headerSize = _outByte.GetProcessedSize();
}
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
if (_endMarker)
{
CFinishHeader h;
@@ -878,14 +902,28 @@ HRESULT COutArchive::WriteDatabase(
}
else
#endif
+ if (Stream)
{
CStartHeader h;
h.NextHeaderSize = headerSize;
h.NextHeaderCRC = headerCRC;
h.NextHeaderOffset = headerOffset;
- RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
+ RINOK(Stream->Seek((Int64)_signatureHeaderPos, STREAM_SEEK_SET, NULL))
return WriteStartHeader(h);
}
+ return S_OK;
+}
+
+void CUInt32DefVector::SetItem(unsigned index, bool defined, UInt32 value)
+{
+ while (index >= Defs.Size())
+ Defs.Add(false);
+ Defs[index] = defined;
+ if (!defined)
+ return;
+ while (index >= Vals.Size())
+ Vals.Add(0);
+ Vals[index] = value;
}
void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value)
@@ -907,6 +945,7 @@ void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2
ATime.SetItem(index, file2.ATimeDefined, file2.ATime);
MTime.SetItem(index, file2.MTimeDefined, file2.MTime);
StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);
+ Attrib.SetItem(index, file2.AttribDefined, file2.Attrib);
SetItem_Anti(index, file2.IsAnti);
// SetItem_Aux(index, file2.IsAux);
Names.Add(name);