diff -r 0135e64c6c66 -r c4fd2813b127 misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zOut.cpp --- a/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zOut.cpp Wed May 16 18:22:28 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1026 +0,0 @@ -// 7zOut.cpp - -#include "StdAfx.h" - -#include "../../../Common/AutoPtr.h" -#include "../../Common/StreamObjects.h" - -#include "7zOut.h" - -extern "C" -{ -#include "../../../../C/7zCrc.h" -} - -static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size) -{ - while (size > 0) - { - UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF); - UInt32 processedSize; - RINOK(stream->Write(data, curSize, &processedSize)); - if(processedSize == 0) - return E_FAIL; - data = (const void *)((const Byte *)data + processedSize); - size -= processedSize; - } - return S_OK; -} - -namespace NArchive { -namespace N7z { - -HRESULT COutArchive::WriteDirect(const void *data, UInt32 size) -{ - return ::WriteBytes(SeqStream, data, size); -} - -UInt32 CrcUpdateUInt32(UInt32 crc, UInt32 value) -{ - for (int i = 0; i < 4; i++, value >>= 8) - crc = CRC_UPDATE_BYTE(crc, (Byte)value); - return crc; -} - -UInt32 CrcUpdateUInt64(UInt32 crc, UInt64 value) -{ - for (int i = 0; i < 8; i++, value >>= 8) - crc = CRC_UPDATE_BYTE(crc, (Byte)value); - return crc; -} - -HRESULT COutArchive::WriteDirectUInt32(UInt32 value) -{ - for (int i = 0; i < 4; i++) - { - RINOK(WriteDirectByte((Byte)value)); - value >>= 8; - } - return S_OK; -} - -HRESULT COutArchive::WriteDirectUInt64(UInt64 value) -{ - for (int i = 0; i < 8; i++) - { - RINOK(WriteDirectByte((Byte)value)); - value >>= 8; - } - return S_OK; -} - -HRESULT COutArchive::WriteSignature() -{ - RINOK(WriteDirect(kSignature, kSignatureSize)); - RINOK(WriteDirectByte(kMajorVersion)); - return WriteDirectByte(2); -} - -#ifdef _7Z_VOL -HRESULT COutArchive::WriteFinishSignature() -{ - RINOK(WriteDirect(kFinishSignature, kSignatureSize)); - CArchiveVersion av; - av.Major = kMajorVersion; - av.Minor = 2; - RINOK(WriteDirectByte(av.Major)); - return WriteDirectByte(av.Minor); -} -#endif - -HRESULT COutArchive::WriteStartHeader(const CStartHeader &h) -{ - UInt32 crc = CRC_INIT_VAL; - crc = CrcUpdateUInt64(crc, h.NextHeaderOffset); - crc = CrcUpdateUInt64(crc, h.NextHeaderSize); - crc = CrcUpdateUInt32(crc, h.NextHeaderCRC); - RINOK(WriteDirectUInt32(CRC_GET_DIGEST(crc))); - RINOK(WriteDirectUInt64(h.NextHeaderOffset)); - RINOK(WriteDirectUInt64(h.NextHeaderSize)); - return WriteDirectUInt32(h.NextHeaderCRC); -} - -#ifdef _7Z_VOL -HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h) -{ - CCRC crc; - crc.UpdateUInt64(h.NextHeaderOffset); - crc.UpdateUInt64(h.NextHeaderSize); - crc.UpdateUInt32(h.NextHeaderCRC); - crc.UpdateUInt64(h.ArchiveStartOffset); - crc.UpdateUInt64(h.AdditionalStartBlockSize); - RINOK(WriteDirectUInt32(crc.GetDigest())); - RINOK(WriteDirectUInt64(h.NextHeaderOffset)); - RINOK(WriteDirectUInt64(h.NextHeaderSize)); - RINOK(WriteDirectUInt32(h.NextHeaderCRC)); - RINOK(WriteDirectUInt64(h.ArchiveStartOffset)); - return WriteDirectUInt64(h.AdditionalStartBlockSize); -} -#endif - -HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) -{ - Close(); - #ifdef _7Z_VOL - // endMarker = false; - _endMarker = endMarker; - #endif - SeqStream = stream; - if (!endMarker) - { - SeqStream.QueryInterface(IID_IOutStream, &Stream); - if (!Stream) - { - return E_NOTIMPL; - // endMarker = true; - } - } - #ifdef _7Z_VOL - if (endMarker) - { - /* - CStartHeader sh; - sh.NextHeaderOffset = (UInt32)(Int32)-1; - sh.NextHeaderSize = (UInt32)(Int32)-1; - sh.NextHeaderCRC = 0; - WriteStartHeader(sh); - */ - } - else - #endif - { - if (!Stream) - return E_FAIL; - RINOK(WriteSignature()); - RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos)); - } - return S_OK; -} - -void COutArchive::Close() -{ - SeqStream.Release(); - Stream.Release(); -} - -HRESULT COutArchive::SkeepPrefixArchiveHeader() -{ - #ifdef _7Z_VOL - if (_endMarker) - return S_OK; - #endif - return Stream->Seek(24, STREAM_SEEK_CUR, NULL); -} - -HRESULT COutArchive::WriteBytes(const void *data, size_t size) -{ - if (_mainMode) - { - if (_dynamicMode) - _dynamicBuffer.Write(data, size); - else - _outByte.WriteBytes(data, size); - _crc = CrcUpdate(_crc, data, size); - } - else - { - if (_countMode) - _countSize += size; - else - RINOK(_outByte2.Write(data, size)); - } - return S_OK; -} - -HRESULT COutArchive::WriteBytes(const CByteBuffer &data) -{ - return WriteBytes(data, data.GetCapacity()); -} - -HRESULT COutArchive::WriteByte(Byte b) -{ - return WriteBytes(&b, 1); -} - -HRESULT COutArchive::WriteUInt32(UInt32 value) -{ - for (int i = 0; i < 4; i++) - { - RINOK(WriteByte((Byte)value)); - value >>= 8; - } - return S_OK; -} - -HRESULT COutArchive::WriteNumber(UInt64 value) -{ - Byte firstByte = 0; - Byte mask = 0x80; - int i; - for (i = 0; i < 8; i++) - { - if (value < ((UInt64(1) << ( 7 * (i + 1))))) - { - firstByte |= Byte(value >> (8 * i)); - break; - } - firstByte |= mask; - mask >>= 1; - } - RINOK(WriteByte(firstByte)); - for (;i > 0; i--) - { - RINOK(WriteByte((Byte)value)); - value >>= 8; - } - return S_OK; -} - -#ifdef _7Z_VOL -static UInt32 GetBigNumberSize(UInt64 value) -{ - int i; - for (i = 0; i < 8; i++) - if (value < ((UInt64(1) << ( 7 * (i + 1))))) - break; - return 1 + i; -} - -UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props) -{ - UInt32 result = GetBigNumberSize(dataSize) * 2 + 41; - if (nameLength != 0) - { - nameLength = (nameLength + 1) * 2; - result += nameLength + GetBigNumberSize(nameLength) + 2; - } - if (props) - { - result += 20; - } - if (result >= 128) - result++; - result += kSignatureSize + 2 + kFinishHeaderSize; - return result; -} - -UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props) -{ - UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props); - int testSize; - if (volSize > headersSizeBase) - testSize = volSize - headersSizeBase; - else - testSize = 1; - UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props); - UInt64 pureSize = 1; - if (volSize > headersSize) - pureSize = volSize - headersSize; - return pureSize; -} -#endif - -HRESULT COutArchive::WriteFolder(const CFolder &folder) -{ - RINOK(WriteNumber(folder.Coders.Size())); - int i; - for (i = 0; i < folder.Coders.Size(); i++) - { - const CCoderInfo &coder = folder.Coders[i]; - { - size_t propertiesSize = coder.Properties.GetCapacity(); - - UInt64 id = coder.MethodID; - int idSize; - for (idSize = 1; idSize < sizeof(id); idSize++) - if ((id >> (8 * idSize)) == 0) - break; - BYTE longID[15]; - for (int t = idSize - 1; t >= 0 ; t--, id >>= 8) - longID[t] = (Byte)(id & 0xFF); - Byte b; - b = (Byte)(idSize & 0xF); - bool isComplex = !coder.IsSimpleCoder(); - b |= (isComplex ? 0x10 : 0); - b |= ((propertiesSize != 0) ? 0x20 : 0 ); - RINOK(WriteByte(b)); - RINOK(WriteBytes(longID, idSize)); - if (isComplex) - { - RINOK(WriteNumber(coder.NumInStreams)); - RINOK(WriteNumber(coder.NumOutStreams)); - } - if (propertiesSize == 0) - continue; - RINOK(WriteNumber(propertiesSize)); - RINOK(WriteBytes(coder.Properties, propertiesSize)); - } - } - for (i = 0; i < folder.BindPairs.Size(); i++) - { - const CBindPair &bindPair = folder.BindPairs[i]; - RINOK(WriteNumber(bindPair.InIndex)); - RINOK(WriteNumber(bindPair.OutIndex)); - } - if (folder.PackStreams.Size() > 1) - for (i = 0; i < folder.PackStreams.Size(); i++) - { - RINOK(WriteNumber(folder.PackStreams[i])); - } - return S_OK; -} - -HRESULT COutArchive::WriteBoolVector(const CBoolVector &boolVector) -{ - Byte b = 0; - Byte mask = 0x80; - for(int i = 0; i < boolVector.Size(); i++) - { - if (boolVector[i]) - b |= mask; - mask >>= 1; - if (mask == 0) - { - RINOK(WriteByte(b)); - mask = 0x80; - b = 0; - } - } - if (mask != 0x80) - { - RINOK(WriteByte(b)); - } - return S_OK; -} - - -HRESULT COutArchive::WriteHashDigests( - const CRecordVector &digestsDefined, - const CRecordVector &digests) -{ - int numDefined = 0; - int i; - for(i = 0; i < digestsDefined.Size(); i++) - if (digestsDefined[i]) - numDefined++; - if (numDefined == 0) - return S_OK; - - RINOK(WriteByte(NID::kCRC)); - if (numDefined == digestsDefined.Size()) - { - RINOK(WriteByte(1)); - } - else - { - RINOK(WriteByte(0)); - RINOK(WriteBoolVector(digestsDefined)); - } - for(i = 0; i < digests.Size(); i++) - { - if(digestsDefined[i]) - RINOK(WriteUInt32(digests[i])); - } - return S_OK; -} - -HRESULT COutArchive::WritePackInfo( - UInt64 dataOffset, - const CRecordVector &packSizes, - const CRecordVector &packCRCsDefined, - const CRecordVector &packCRCs) -{ - if (packSizes.IsEmpty()) - return S_OK; - RINOK(WriteByte(NID::kPackInfo)); - RINOK(WriteNumber(dataOffset)); - RINOK(WriteNumber(packSizes.Size())); - RINOK(WriteByte(NID::kSize)); - for(int i = 0; i < packSizes.Size(); i++) - RINOK(WriteNumber(packSizes[i])); - - RINOK(WriteHashDigests(packCRCsDefined, packCRCs)); - - return WriteByte(NID::kEnd); -} - -HRESULT COutArchive::WriteUnPackInfo(const CObjectVector &folders) -{ - if (folders.IsEmpty()) - return S_OK; - - RINOK(WriteByte(NID::kUnPackInfo)); - - RINOK(WriteByte(NID::kFolder)); - RINOK(WriteNumber(folders.Size())); - { - RINOK(WriteByte(0)); - for(int i = 0; i < folders.Size(); i++) - RINOK(WriteFolder(folders[i])); - } - - RINOK(WriteByte(NID::kCodersUnPackSize)); - int i; - for(i = 0; i < folders.Size(); i++) - { - const CFolder &folder = folders[i]; - for (int j = 0; j < folder.UnPackSizes.Size(); j++) - RINOK(WriteNumber(folder.UnPackSizes[j])); - } - - CRecordVector unPackCRCsDefined; - CRecordVector unPackCRCs; - for(i = 0; i < folders.Size(); i++) - { - const CFolder &folder = folders[i]; - unPackCRCsDefined.Add(folder.UnPackCRCDefined); - unPackCRCs.Add(folder.UnPackCRC); - } - RINOK(WriteHashDigests(unPackCRCsDefined, unPackCRCs)); - - return WriteByte(NID::kEnd); -} - -HRESULT COutArchive::WriteSubStreamsInfo( - const CObjectVector &folders, - const CRecordVector &numUnPackStreamsInFolders, - const CRecordVector &unPackSizes, - const CRecordVector &digestsDefined, - const CRecordVector &digests) -{ - RINOK(WriteByte(NID::kSubStreamsInfo)); - - int i; - for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) - { - if (numUnPackStreamsInFolders[i] != 1) - { - RINOK(WriteByte(NID::kNumUnPackStream)); - for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) - RINOK(WriteNumber(numUnPackStreamsInFolders[i])); - break; - } - } - - - bool needFlag = true; - CNum index = 0; - for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) - for (CNum j = 0; j < numUnPackStreamsInFolders[i]; j++) - { - if (j + 1 != numUnPackStreamsInFolders[i]) - { - if (needFlag) - RINOK(WriteByte(NID::kSize)); - needFlag = false; - RINOK(WriteNumber(unPackSizes[index])); - } - index++; - } - - CRecordVector digestsDefined2; - CRecordVector digests2; - - int digestIndex = 0; - for (i = 0; i < folders.Size(); i++) - { - int numSubStreams = (int)numUnPackStreamsInFolders[i]; - if (numSubStreams == 1 && folders[i].UnPackCRCDefined) - digestIndex++; - else - for (int j = 0; j < numSubStreams; j++, digestIndex++) - { - digestsDefined2.Add(digestsDefined[digestIndex]); - digests2.Add(digests[digestIndex]); - } - } - RINOK(WriteHashDigests(digestsDefined2, digests2)); - return WriteByte(NID::kEnd); -} - -HRESULT COutArchive::WriteTime( - const CObjectVector &files, Byte type) -{ - ///////////////////////////////////////////////// - // CreationTime - CBoolVector boolVector; - boolVector.Reserve(files.Size()); - bool thereAreDefined = false; - bool allDefined = true; - int i; - for(i = 0; i < files.Size(); i++) - { - const CFileItem &item = files[i]; - bool defined; - switch(type) - { - case NID::kCreationTime: - defined = item.IsCreationTimeDefined; - break; - case NID::kLastWriteTime: - defined = item.IsLastWriteTimeDefined; - break; - case NID::kLastAccessTime: - defined = item.IsLastAccessTimeDefined; - break; - default: - throw 1; - } - boolVector.Add(defined); - thereAreDefined = (thereAreDefined || defined); - allDefined = (allDefined && defined); - } - if (!thereAreDefined) - return S_OK; - RINOK(WriteByte(type)); - size_t dataSize = 1 + 1; - dataSize += files.Size() * 8; - if (allDefined) - { - RINOK(WriteNumber(dataSize)); - WriteByte(1); - } - else - { - RINOK(WriteNumber(1 + (boolVector.Size() + 7) / 8 + dataSize)); - WriteByte(0); - RINOK(WriteBoolVector(boolVector)); - } - RINOK(WriteByte(0)); - for(i = 0; i < files.Size(); i++) - { - if (boolVector[i]) - { - const CFileItem &item = files[i]; - CArchiveFileTime timeValue; - timeValue.dwLowDateTime = 0; - timeValue.dwHighDateTime = 0; - switch(type) - { - case NID::kCreationTime: - timeValue = item.CreationTime; - break; - case NID::kLastWriteTime: - timeValue = item.LastWriteTime; - break; - case NID::kLastAccessTime: - timeValue = item.LastAccessTime; - break; - } - RINOK(WriteUInt32(timeValue.dwLowDateTime)); - RINOK(WriteUInt32(timeValue.dwHighDateTime)); - } - } - return S_OK; -} - -HRESULT COutArchive::EncodeStream( - DECL_EXTERNAL_CODECS_LOC_VARS - CEncoder &encoder, const Byte *data, size_t dataSize, - CRecordVector &packSizes, CObjectVector &folders) -{ - CSequentialInStreamImp *streamSpec = new CSequentialInStreamImp; - CMyComPtr stream = streamSpec; - streamSpec->Init(data, dataSize); - CFolder folderItem; - folderItem.UnPackCRCDefined = true; - folderItem.UnPackCRC = CrcCalc(data, dataSize); - UInt64 dataSize64 = dataSize; - RINOK(encoder.Encode( - EXTERNAL_CODECS_LOC_VARS - stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL)) - folders.Add(folderItem); - return S_OK; -} - -HRESULT COutArchive::EncodeStream( - DECL_EXTERNAL_CODECS_LOC_VARS - CEncoder &encoder, const CByteBuffer &data, - CRecordVector &packSizes, CObjectVector &folders) -{ - return EncodeStream( - EXTERNAL_CODECS_LOC_VARS - encoder, data, data.GetCapacity(), packSizes, folders); -} - -static void WriteUInt32ToBuffer(Byte *data, UInt32 value) -{ - for (int i = 0; i < 4; i++) - { - *data++ = (Byte)value; - value >>= 8; - } -} - -static void WriteUInt64ToBuffer(Byte *data, UInt64 value) -{ - for (int i = 0; i < 8; i++) - { - *data++ = (Byte)value; - value >>= 8; - } -} - - -HRESULT COutArchive::WriteHeader( - const CArchiveDatabase &database, - const CHeaderOptions &headerOptions, - UInt64 &headerOffset) -{ - int i; - - ///////////////////////////////// - // Names - - CNum numDefinedNames = 0; - size_t namesDataSize = 0; - for(i = 0; i < database.Files.Size(); i++) - { - const UString &name = database.Files[i].Name; - if (!name.IsEmpty()) - numDefinedNames++; - namesDataSize += (name.Length() + 1) * 2; - } - - CByteBuffer namesData; - if (numDefinedNames > 0) - { - namesData.SetCapacity((size_t)namesDataSize); - size_t pos = 0; - for(int i = 0; i < database.Files.Size(); i++) - { - const UString &name = database.Files[i].Name; - for (int t = 0; t < name.Length(); t++) - { - wchar_t c = name[t]; - namesData[pos++] = Byte(c); - namesData[pos++] = Byte(c >> 8); - } - namesData[pos++] = 0; - namesData[pos++] = 0; - } - } - - ///////////////////////////////// - // Write Attributes - CBoolVector attributesBoolVector; - attributesBoolVector.Reserve(database.Files.Size()); - int numDefinedAttributes = 0; - for(i = 0; i < database.Files.Size(); i++) - { - bool defined = database.Files[i].AreAttributesDefined; - attributesBoolVector.Add(defined); - if (defined) - numDefinedAttributes++; - } - - CByteBuffer attributesData; - if (numDefinedAttributes > 0) - { - attributesData.SetCapacity(numDefinedAttributes * 4); - size_t pos = 0; - for(i = 0; i < database.Files.Size(); i++) - { - const CFileItem &file = database.Files[i]; - if (file.AreAttributesDefined) - { - WriteUInt32ToBuffer(attributesData + pos, file.Attributes); - pos += 4; - } - } - } - - ///////////////////////////////// - // Write StartPos - CBoolVector startsBoolVector; - startsBoolVector.Reserve(database.Files.Size()); - int numDefinedStarts = 0; - for(i = 0; i < database.Files.Size(); i++) - { - bool defined = database.Files[i].IsStartPosDefined; - startsBoolVector.Add(defined); - if (defined) - numDefinedStarts++; - } - - CByteBuffer startsData; - if (numDefinedStarts > 0) - { - startsData.SetCapacity(numDefinedStarts * 8); - size_t pos = 0; - for(i = 0; i < database.Files.Size(); i++) - { - const CFileItem &file = database.Files[i]; - if (file.IsStartPosDefined) - { - WriteUInt64ToBuffer(startsData + pos, file.StartPos); - pos += 8; - } - } - } - - ///////////////////////////////// - // Write Last Write Time - // /* - CNum numDefinedLastWriteTimes = 0; - for(i = 0; i < database.Files.Size(); i++) - if (database.Files[i].IsLastWriteTimeDefined) - numDefinedLastWriteTimes++; - - if (numDefinedLastWriteTimes > 0) - { - CByteBuffer lastWriteTimeData; - lastWriteTimeData.SetCapacity(numDefinedLastWriteTimes * 8); - size_t pos = 0; - for(i = 0; i < database.Files.Size(); i++) - { - const CFileItem &file = database.Files[i]; - if (file.IsLastWriteTimeDefined) - { - WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwLowDateTime); - pos += 4; - WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwHighDateTime); - pos += 4; - } - } - } - // */ - - - UInt64 packedSize = 0; - for(i = 0; i < database.PackSizes.Size(); i++) - packedSize += database.PackSizes[i]; - - headerOffset = packedSize; - - _mainMode = true; - - _outByte.SetStream(SeqStream); - _outByte.Init(); - _crc = CRC_INIT_VAL; - - - RINOK(WriteByte(NID::kHeader)); - - // Archive Properties - - if (database.Folders.Size() > 0) - { - RINOK(WriteByte(NID::kMainStreamsInfo)); - RINOK(WritePackInfo(0, database.PackSizes, - database.PackCRCsDefined, - database.PackCRCs)); - - RINOK(WriteUnPackInfo(database.Folders)); - - CRecordVector unPackSizes; - CRecordVector digestsDefined; - CRecordVector digests; - for (i = 0; i < database.Files.Size(); i++) - { - const CFileItem &file = database.Files[i]; - if (!file.HasStream) - continue; - unPackSizes.Add(file.UnPackSize); - digestsDefined.Add(file.IsFileCRCDefined); - digests.Add(file.FileCRC); - } - - RINOK(WriteSubStreamsInfo( - database.Folders, - database.NumUnPackStreamsVector, - unPackSizes, - digestsDefined, - digests)); - RINOK(WriteByte(NID::kEnd)); - } - - if (database.Files.IsEmpty()) - { - RINOK(WriteByte(NID::kEnd)); - return _outByte.Flush(); - } - - RINOK(WriteByte(NID::kFilesInfo)); - RINOK(WriteNumber(database.Files.Size())); - - CBoolVector emptyStreamVector; - emptyStreamVector.Reserve(database.Files.Size()); - int numEmptyStreams = 0; - for(i = 0; i < database.Files.Size(); i++) - if (database.Files[i].HasStream) - emptyStreamVector.Add(false); - else - { - emptyStreamVector.Add(true); - numEmptyStreams++; - } - if (numEmptyStreams > 0) - { - RINOK(WriteByte(NID::kEmptyStream)); - RINOK(WriteNumber((emptyStreamVector.Size() + 7) / 8)); - RINOK(WriteBoolVector(emptyStreamVector)); - - CBoolVector emptyFileVector, antiVector; - emptyFileVector.Reserve(numEmptyStreams); - antiVector.Reserve(numEmptyStreams); - CNum numEmptyFiles = 0, numAntiItems = 0; - for(i = 0; i < database.Files.Size(); i++) - { - const CFileItem &file = database.Files[i]; - if (!file.HasStream) - { - emptyFileVector.Add(!file.IsDirectory); - if (!file.IsDirectory) - numEmptyFiles++; - antiVector.Add(file.IsAnti); - if (file.IsAnti) - numAntiItems++; - } - } - - if (numEmptyFiles > 0) - { - RINOK(WriteByte(NID::kEmptyFile)); - RINOK(WriteNumber((emptyFileVector.Size() + 7) / 8)); - RINOK(WriteBoolVector(emptyFileVector)); - } - - if (numAntiItems > 0) - { - RINOK(WriteByte(NID::kAnti)); - RINOK(WriteNumber((antiVector.Size() + 7) / 8)); - RINOK(WriteBoolVector(antiVector)); - } - } - - if (numDefinedNames > 0) - { - ///////////////////////////////////////////////// - RINOK(WriteByte(NID::kName)); - { - RINOK(WriteNumber(1 + namesData.GetCapacity())); - RINOK(WriteByte(0)); - RINOK(WriteBytes(namesData)); - } - - } - - if (headerOptions.WriteCreated) - { - RINOK(WriteTime(database.Files, NID::kCreationTime)); - } - if (headerOptions.WriteModified) - { - RINOK(WriteTime(database.Files, NID::kLastWriteTime)); - } - if (headerOptions.WriteAccessed) - { - RINOK(WriteTime(database.Files, NID::kLastAccessTime)); - } - - if (numDefinedAttributes > 0) - { - RINOK(WriteByte(NID::kWinAttributes)); - size_t size = 2; - if (numDefinedAttributes != database.Files.Size()) - size += (attributesBoolVector.Size() + 7) / 8 + 1; - size += attributesData.GetCapacity(); - - RINOK(WriteNumber(size)); - if (numDefinedAttributes == database.Files.Size()) - { - RINOK(WriteByte(1)); - } - else - { - RINOK(WriteByte(0)); - RINOK(WriteBoolVector(attributesBoolVector)); - } - - { - RINOK(WriteByte(0)); - RINOK(WriteBytes(attributesData)); - } - } - - if (numDefinedStarts > 0) - { - RINOK(WriteByte(NID::kStartPos)); - size_t size = 2; - if (numDefinedStarts != database.Files.Size()) - size += (startsBoolVector.Size() + 7) / 8 + 1; - size += startsData.GetCapacity(); - - RINOK(WriteNumber(size)); - if (numDefinedStarts == database.Files.Size()) - { - RINOK(WriteByte(1)); - } - else - { - RINOK(WriteByte(0)); - RINOK(WriteBoolVector(startsBoolVector)); - } - - { - RINOK(WriteByte(0)); - RINOK(WriteBytes(startsData)); - } - } - - RINOK(WriteByte(NID::kEnd)); // for files - RINOK(WriteByte(NID::kEnd)); // for headers - - return _outByte.Flush(); -} - -HRESULT COutArchive::WriteDatabase( - DECL_EXTERNAL_CODECS_LOC_VARS - const CArchiveDatabase &database, - const CCompressionMethodMode *options, - const CHeaderOptions &headerOptions) -{ - UInt64 headerOffset; - UInt32 headerCRC; - UInt64 headerSize; - if (database.IsEmpty()) - { - headerSize = 0; - headerOffset = 0; - headerCRC = CrcCalc(0, 0); - } - else - { - _dynamicBuffer.Init(); - _dynamicMode = false; - - if (options != 0) - if (options->IsEmpty()) - options = 0; - if (options != 0) - if (options->PasswordIsDefined || headerOptions.CompressMainHeader) - _dynamicMode = true; - RINOK(WriteHeader(database, headerOptions, headerOffset)); - - if (_dynamicMode) - { - CCompressionMethodMode encryptOptions; - encryptOptions.PasswordIsDefined = options->PasswordIsDefined; - encryptOptions.Password = options->Password; - CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions); - CRecordVector packSizes; - CObjectVector folders; - RINOK(EncodeStream( - EXTERNAL_CODECS_LOC_VARS - encoder, _dynamicBuffer, - _dynamicBuffer.GetSize(), packSizes, folders)); - _dynamicMode = false; - _mainMode = true; - - _outByte.SetStream(SeqStream); - _outByte.Init(); - _crc = CRC_INIT_VAL; - - if (folders.Size() == 0) - throw 1; - - RINOK(WriteID(NID::kEncodedHeader)); - RINOK(WritePackInfo(headerOffset, packSizes, - CRecordVector(), CRecordVector())); - RINOK(WriteUnPackInfo(folders)); - RINOK(WriteByte(NID::kEnd)); - for (int i = 0; i < packSizes.Size(); i++) - headerOffset += packSizes[i]; - RINOK(_outByte.Flush()); - } - headerCRC = CRC_GET_DIGEST(_crc); - headerSize = _outByte.GetProcessedSize(); - } - #ifdef _7Z_VOL - if (_endMarker) - { - CFinishHeader h; - h.NextHeaderSize = headerSize; - h.NextHeaderCRC = headerCRC; - h.NextHeaderOffset = - UInt64(0) - (headerSize + - 4 + kFinishHeaderSize); - h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset; - h.AdditionalStartBlockSize = 0; - RINOK(WriteFinishHeader(h)); - return WriteFinishSignature(); - } - else - #endif - { - CStartHeader h; - h.NextHeaderSize = headerSize; - h.NextHeaderCRC = headerCRC; - h.NextHeaderOffset = headerOffset; - RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL)); - return WriteStartHeader(h); - } -} - -}}