1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// 7zOut.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/7zCrc.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Common/AutoPtr.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/StreamObjects.h" 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zOut.h" 12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 13baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size) 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (size > 0) 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF); 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 processedSize; 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(stream->Write(data, curSize, &processedSize)); 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (processedSize == 0) 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync data = (const void *)((const Byte *)data + processedSize); 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size -= processedSize; 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 28baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive { 29baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace N7z { 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 31baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteDirect(const void *data, UInt32 size) 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ::WriteBytes(SeqStream, data, size); 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 36baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteSignature() 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte buf[8]; 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync memcpy(buf, kSignature, kSignatureSize); 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync buf[kSignatureSize] = kMajorVersion; 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync buf[kSignatureSize + 1] = 3; 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return WriteDirect(buf, 8); 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _7Z_VOL 46baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteFinishSignature() 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteDirect(kFinishSignature, kSignatureSize)); 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchiveVersion av; 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync av.Major = kMajorVersion; 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync av.Minor = 2; 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteDirectByte(av.Major)); 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return WriteDirectByte(av.Minor); 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 57baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void SetUInt32(Byte *p, UInt32 d) 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < 4; i++, d >>= 8) 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p[i] = (Byte)d; 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 63baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void SetUInt64(Byte *p, UInt64 d) 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < 8; i++, d >>= 8) 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p[i] = (Byte)d; 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 69baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteStartHeader(const CStartHeader &h) 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte buf[24]; 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetUInt64(buf + 4, h.NextHeaderOffset); 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetUInt64(buf + 12, h.NextHeaderSize); 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetUInt32(buf + 20, h.NextHeaderCRC); 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetUInt32(buf, CrcCalc(buf + 4, 20)); 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return WriteDirect(buf, 24); 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _7Z_VOL 80baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h) 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCRC crc; 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync crc.UpdateUInt64(h.NextHeaderOffset); 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync crc.UpdateUInt64(h.NextHeaderSize); 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync crc.UpdateUInt32(h.NextHeaderCRC); 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync crc.UpdateUInt64(h.ArchiveStartOffset); 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync crc.UpdateUInt64(h.AdditionalStartBlockSize); 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteDirectUInt32(crc.GetDigest())); 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteDirectUInt64(h.NextHeaderOffset)); 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteDirectUInt64(h.NextHeaderSize)); 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteDirectUInt32(h.NextHeaderCRC)); 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteDirectUInt64(h.ArchiveStartOffset)); 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return WriteDirectUInt64(h.AdditionalStartBlockSize); 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 97baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Close(); 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _7Z_VOL 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // endMarker = false; 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _endMarker = endMarker; 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SeqStream = stream; 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!endMarker) 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SeqStream.QueryInterface(IID_IOutStream, &Stream); 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!Stream) 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_NOTIMPL; 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // endMarker = true; 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _7Z_VOL 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (endMarker) 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CStartHeader sh; 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sh.NextHeaderOffset = (UInt32)(Int32)-1; 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sh.NextHeaderSize = (UInt32)(Int32)-1; 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sh.NextHeaderCRC = 0; 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteStartHeader(sh); 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!Stream) 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteSignature()); 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos)); 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 136baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::Close() 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SeqStream.Release(); 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Stream.Release(); 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 142baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::SkipPrefixArchiveHeader() 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _7Z_VOL 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_endMarker) 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return Stream->Seek(24, STREAM_SEEK_CUR, NULL); 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 151baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 COutArchive::GetPos() const 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_countMode) 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _countSize; 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_writeToStream) 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _outByte.GetProcessedSize(); 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _outByte2.GetPos(); 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 160baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteBytes(const void *data, size_t size) 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_countMode) 163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _countSize += size; 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (_writeToStream) 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outByte.WriteBytes(data, size); 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _crc = CrcUpdate(_crc, data, size); 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outByte2.WriteBytes(data, size); 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 173baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteByte(Byte b) 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_countMode) 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _countSize++; 177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (_writeToStream) 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outByte.WriteByte(b); 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _crc = CRC_UPDATE_BYTE(_crc, b); 181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outByte2.WriteByte(b); 184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 186baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteUInt32(UInt32 value) 187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < 4; i++) 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte((Byte)value); 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync value >>= 8; 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 195baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteUInt64(UInt64 value) 196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < 8; i++) 198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte((Byte)value); 200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync value >>= 8; 201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 204baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteNumber(UInt64 value) 205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte firstByte = 0; 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte mask = 0x80; 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < 8; i++) 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (value < ((UInt64(1) << ( 7 * (i + 1))))) 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync firstByte |= Byte(value >> (8 * i)); 214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync firstByte |= mask; 217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync mask >>= 1; 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(firstByte); 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;i > 0; i--) 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte((Byte)value); 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync value >>= 8; 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 227baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UInt32 GetBigNumberSize(UInt64 value) 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 1; i < 9; i++) 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (value < (((UInt64)1 << (i * 7)))) 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return i; 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _7Z_VOL 237baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props) 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 result = GetBigNumberSize(dataSize) * 2 + 41; 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (nameLength != 0) 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nameLength = (nameLength + 1) * 2; 243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync result += nameLength + GetBigNumberSize(nameLength) + 2; 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (props) 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync result += 20; 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (result >= 128) 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync result++; 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync result += kSignatureSize + 2 + kFinishHeaderSize; 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return result; 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 255baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props) 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props); 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int testSize; 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (volSize > headersSizeBase) 260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync testSize = volSize - headersSizeBase; 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync testSize = 1; 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props); 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 pureSize = 1; 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (volSize > headersSize) 266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pureSize = volSize - headersSize; 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return pureSize; 268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 271baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteFolder(const CFolder &folder) 272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(folder.Coders.Size()); 274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < folder.Coders.Size(); i++) 276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CCoderInfo &coder = folder.Coders[i]; 278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t propsSize = coder.Props.GetCapacity(); 280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 id = coder.MethodID; 282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int idSize; 283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (idSize = 1; idSize < sizeof(id); idSize++) 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((id >> (8 * idSize)) == 0) 285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync BYTE longID[15]; 287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int t = idSize - 1; t >= 0 ; t--, id >>= 8) 288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync longID[t] = (Byte)(id & 0xFF); 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte b; 290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync b = (Byte)(idSize & 0xF); 291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool isComplex = !coder.IsSimpleCoder(); 292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync b |= (isComplex ? 0x10 : 0); 293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync b |= ((propsSize != 0) ? 0x20 : 0 ); 294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(b); 295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteBytes(longID, idSize); 296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (isComplex) 297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(coder.NumInStreams); 299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(coder.NumOutStreams); 300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (propsSize == 0) 302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(propsSize); 304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteBytes(coder.Props, propsSize); 305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < folder.BindPairs.Size(); i++) 308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CBindPair &bindPair = folder.BindPairs[i]; 310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(bindPair.InIndex); 311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(bindPair.OutIndex); 312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (folder.PackStreams.Size() > 1) 314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < folder.PackStreams.Size(); i++) 315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(folder.PackStreams[i]); 317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 320baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteBoolVector(const CBoolVector &boolVector) 321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte b = 0; 323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte mask = 0x80; 324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < boolVector.Size(); i++) 325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (boolVector[i]) 327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync b |= mask; 328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync mask >>= 1; 329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (mask == 0) 330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(b); 332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync mask = 0x80; 333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync b = 0; 334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (mask != 0x80) 337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(b); 338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 341baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteHashDigests( 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CRecordVector<bool> &digestsDefined, 343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CRecordVector<UInt32> &digests) 344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numDefined = 0; 346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < digestsDefined.Size(); i++) 348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (digestsDefined[i]) 349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDefined++; 350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numDefined == 0) 351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kCRC); 354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numDefined == digestsDefined.Size()) 355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(1); 356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(0); 359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteBoolVector(digestsDefined); 360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < digests.Size(); i++) 362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (digestsDefined[i]) 363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteUInt32(digests[i]); 364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 366baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WritePackInfo( 367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 dataOffset, 368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CRecordVector<UInt64> &packSizes, 369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CRecordVector<bool> &packCRCsDefined, 370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CRecordVector<UInt32> &packCRCs) 371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (packSizes.IsEmpty()) 373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kPackInfo); 375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(dataOffset); 376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(packSizes.Size()); 377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kSize); 378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < packSizes.Size(); i++) 379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(packSizes[i]); 380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteHashDigests(packCRCsDefined, packCRCs); 382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kEnd); 384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 386baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders) 387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (folders.IsEmpty()) 389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kUnpackInfo); 392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kFolder); 394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(folders.Size()); 395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(0); 397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < folders.Size(); i++) 398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteFolder(folders[i]); 399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kCodersUnpackSize); 402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < folders.Size(); i++) 404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CFolder &folder = folders[i]; 406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int j = 0; j < folder.UnpackSizes.Size(); j++) 407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(folder.UnpackSizes[j]); 408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<bool> unpackCRCsDefined; 411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt32> unpackCRCs; 412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < folders.Size(); i++) 413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CFolder &folder = folders[i]; 415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unpackCRCsDefined.Add(folder.UnpackCRCDefined); 416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unpackCRCs.Add(folder.UnpackCRC); 417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteHashDigests(unpackCRCsDefined, unpackCRCs); 419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kEnd); 421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 423baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteSubStreamsInfo( 424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CObjectVector<CFolder> &folders, 425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CRecordVector<CNum> &numUnpackStreamsInFolders, 426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CRecordVector<UInt64> &unpackSizes, 427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CRecordVector<bool> &digestsDefined, 428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CRecordVector<UInt32> &digests) 429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kSubStreamsInfo); 431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) 434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numUnpackStreamsInFolders[i] != 1) 436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kNumUnpackStream); 438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) 439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(numUnpackStreamsInFolders[i]); 440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool needFlag = true; 446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum index = 0; 447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) 448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (CNum j = 0; j < numUnpackStreamsInFolders[i]; j++) 449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (j + 1 != numUnpackStreamsInFolders[i]) 451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (needFlag) 453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kSize); 454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync needFlag = false; 455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(unpackSizes[index]); 456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync index++; 458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<bool> digestsDefined2; 461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt32> digests2; 462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int digestIndex = 0; 464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < folders.Size(); i++) 465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numSubStreams = (int)numUnpackStreamsInFolders[i]; 467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numSubStreams == 1 && folders[i].UnpackCRCDefined) 468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digestIndex++; 469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int j = 0; j < numSubStreams; j++, digestIndex++) 471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digestsDefined2.Add(digestsDefined[digestIndex]); 473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digests2.Add(digests[digestIndex]); 474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteHashDigests(digestsDefined2, digests2); 477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kEnd); 478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 480baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::SkipAlign(unsigned /* pos */, unsigned /* alignSize */) 481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* 486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field. 487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 488baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::SkipAlign(unsigned pos, unsigned alignSize) 489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos += (unsigned)GetPos(); 491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos &= (alignSize - 1); 492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos == 0) 493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned skip = alignSize - pos; 495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (skip < 2) 496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync skip += alignSize; 497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync skip -= 2; 498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kDummy); 499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte((Byte)skip); 500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (unsigned i = 0; i < skip; i++) 501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(0); 502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/ 504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 505baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; } 506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 507baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize) 508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v); 510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2; 511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize); 512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(type); 514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(dataSize); 515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numDefined == v.Size()) 516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(1); 517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(0); 520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteBoolVector(v); 521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(0); 523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 525baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type) 526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numDefined = 0; 528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < v.Defined.Size(); i++) 531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (v.Defined[i]) 532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDefined++; 533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numDefined == 0) 535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteAlignedBoolHeader(v.Defined, numDefined, type, 8); 538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < v.Defined.Size(); i++) 540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (v.Defined[i]) 541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteUInt64(v.Values[i]); 542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 544baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::EncodeStream( 545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync DECL_EXTERNAL_CODECS_LOC_VARS 546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CEncoder &encoder, const CByteBuffer &data, 547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders) 548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBufInStream *streamSpec = new CBufInStream; 550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISequentialInStream> stream = streamSpec; 551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSpec->Init(data, data.GetCapacity()); 552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CFolder folderItem; 553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folderItem.UnpackCRCDefined = true; 554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folderItem.UnpackCRC = CrcCalc(data, data.GetCapacity()); 555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 dataSize64 = data.GetCapacity(); 556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(encoder.Encode( 557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EXTERNAL_CODECS_LOC_VARS 558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL)) 559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folders.Add(folderItem); 560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 561baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 563baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteHeader( 564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CArchiveDatabase &db, 565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CHeaderOptions &headerOptions, 566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 &headerOffset) 567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 packedSize = 0; 571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < db.PackSizes.Size(); i++) 572baa3858d3f5d128a5c8466b700098109edcad5f2repo sync packedSize += db.PackSizes[i]; 573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerOffset = packedSize; 575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kHeader); 577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // Archive Properties 579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (db.Folders.Size() > 0) 581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kMainStreamsInfo); 583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WritePackInfo(0, db.PackSizes, 584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db.PackCRCsDefined, 585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db.PackCRCs); 586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteUnpackInfo(db.Folders); 588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt64> unpackSizes; 590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<bool> digestsDefined; 591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt32> digests; 592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < db.Files.Size(); i++) 593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CFileItem &file = db.Files[i]; 595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!file.HasStream) 596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unpackSizes.Add(file.Size); 598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digestsDefined.Add(file.CrcDefined); 599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digests.Add(file.Crc); 600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteSubStreamsInfo( 603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db.Folders, 604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db.NumUnpackStreamsVector, 605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unpackSizes, 606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digestsDefined, 607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digests); 608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kEnd); 609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (db.Files.IsEmpty()) 612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kEnd); 614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kFilesInfo); 618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(db.Files.Size()); 619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* ---------- Empty Streams ---------- */ 622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBoolVector emptyStreamVector; 623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync emptyStreamVector.Reserve(db.Files.Size()); 624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numEmptyStreams = 0; 625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < db.Files.Size(); i++) 626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (db.Files[i].HasStream) 627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync emptyStreamVector.Add(false); 628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync emptyStreamVector.Add(true); 631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numEmptyStreams++; 632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numEmptyStreams > 0) 634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kEmptyStream); 636baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(Bv_GetSizeInBytes(emptyStreamVector)); 637baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteBoolVector(emptyStreamVector); 638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBoolVector emptyFileVector, antiVector; 640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync emptyFileVector.Reserve(numEmptyStreams); 641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync antiVector.Reserve(numEmptyStreams); 642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum numEmptyFiles = 0, numAntiItems = 0; 643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < db.Files.Size(); i++) 644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 645baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CFileItem &file = db.Files[i]; 646baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!file.HasStream) 647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync emptyFileVector.Add(!file.IsDir); 649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!file.IsDir) 650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numEmptyFiles++; 651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool isAnti = db.IsItemAnti(i); 652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync antiVector.Add(isAnti); 653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (isAnti) 654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numAntiItems++; 655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numEmptyFiles > 0) 659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kEmptyFile); 661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(Bv_GetSizeInBytes(emptyFileVector)); 662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteBoolVector(emptyFileVector); 663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numAntiItems > 0) 666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 667baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kAnti); 668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(Bv_GetSizeInBytes(antiVector)); 669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteBoolVector(antiVector); 670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* ---------- Names ---------- */ 677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numDefined = 0; 679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t namesDataSize = 0; 680baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < db.Files.Size(); i++) 681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UString &name = db.Files[i].Name; 683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!name.IsEmpty()) 684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDefined++; 685baa3858d3f5d128a5c8466b700098109edcad5f2repo sync namesDataSize += (name.Length() + 1) * 2; 686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numDefined > 0) 689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync namesDataSize++; 691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SkipAlign(2 + GetBigNumberSize(namesDataSize), 2); 692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kName); 694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteNumber(namesDataSize); 695baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(0); 696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < db.Files.Size(); i++) 697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UString &name = db.Files[i].Name; 699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int t = 0; t <= name.Length(); t++) 700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 701baa3858d3f5d128a5c8466b700098109edcad5f2repo sync wchar_t c = name[t]; 702baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte((Byte)c); 703baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte((Byte)(c >> 8)); 704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 705baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 708baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (headerOptions.WriteCTime) WriteUInt64DefVector(db.CTime, NID::kCTime); 710baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (headerOptions.WriteATime) WriteUInt64DefVector(db.ATime, NID::kATime); 711baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (headerOptions.WriteMTime) WriteUInt64DefVector(db.MTime, NID::kMTime); 712baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteUInt64DefVector(db.StartPos, NID::kStartPos); 713baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 714baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 715baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* ---------- Write Attrib ---------- */ 716baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBoolVector boolVector; 717baa3858d3f5d128a5c8466b700098109edcad5f2repo sync boolVector.Reserve(db.Files.Size()); 718baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numDefined = 0; 719baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < db.Files.Size(); i++) 720baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 721baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool defined = db.Files[i].AttribDefined; 722baa3858d3f5d128a5c8466b700098109edcad5f2repo sync boolVector.Add(defined); 723baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (defined) 724baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDefined++; 725baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 726baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numDefined > 0) 727baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 728baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttributes, 4); 729baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < db.Files.Size(); i++) 730baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 731baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CFileItem &file = db.Files[i]; 732baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (file.AttribDefined) 733baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteUInt32(file.Attrib); 734baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 735baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 736baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 737baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 738baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kEnd); // for files 739baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kEnd); // for headers 740baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 741baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 742baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteDatabase( 743baa3858d3f5d128a5c8466b700098109edcad5f2repo sync DECL_EXTERNAL_CODECS_LOC_VARS 744baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CArchiveDatabase &db, 745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CCompressionMethodMode *options, 746baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CHeaderOptions &headerOptions) 747baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 748baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!db.CheckNumFiles()) 749baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 750baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 751baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 headerOffset; 752baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 headerCRC; 753baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 headerSize; 754baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (db.IsEmpty()) 755baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 756baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerSize = 0; 757baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerOffset = 0; 758baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerCRC = CrcCalc(0, 0); 759baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 760baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 761baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 762baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool encodeHeaders = false; 763baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options != 0) 764baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options->IsEmpty()) 765baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options = 0; 766baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options != 0) 767baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options->PasswordIsDefined || headerOptions.CompressMainHeader) 768baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encodeHeaders = true; 769baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outByte.SetStream(SeqStream); 771baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outByte.Init(); 772baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _crc = CRC_INIT_VAL; 773baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _countMode = encodeHeaders; 774baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _writeToStream = true; 775baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _countSize = 0; 776baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteHeader(db, headerOptions, headerOffset); 777baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 778baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (encodeHeaders) 779baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 780baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CByteBuffer buf; 781baa3858d3f5d128a5c8466b700098109edcad5f2repo sync buf.SetCapacity(_countSize); 782baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outByte2.Init((Byte *)buf, _countSize); 783baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 784baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _countMode = false; 785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _writeToStream = false; 786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteHeader(db, headerOptions, headerOffset); 787baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 788baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_countSize != _outByte2.GetPos()) 789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCompressionMethodMode encryptOptions; 792baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encryptOptions.PasswordIsDefined = options->PasswordIsDefined; 793baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encryptOptions.Password = options->Password; 794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions); 795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt64> packSizes; 796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<CFolder> folders; 797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(EncodeStream( 798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EXTERNAL_CODECS_LOC_VARS 799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encoder, buf, 800baa3858d3f5d128a5c8466b700098109edcad5f2repo sync packSizes, folders)); 801baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _writeToStream = true; 803baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (folders.Size() == 0) 805baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw 1; 806baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 807baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteID(NID::kEncodedHeader); 808baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WritePackInfo(headerOffset, packSizes, 809baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<bool>(), CRecordVector<UInt32>()); 810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteUnpackInfo(folders); 811baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteByte(NID::kEnd); 812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < packSizes.Size(); i++) 813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerOffset += packSizes[i]; 814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_outByte.Flush()); 816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerCRC = CRC_GET_DIGEST(_crc); 817baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerSize = _outByte.GetProcessedSize(); 818baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _7Z_VOL 820baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_endMarker) 821baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CFinishHeader h; 823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync h.NextHeaderSize = headerSize; 824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync h.NextHeaderCRC = headerCRC; 825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync h.NextHeaderOffset = 826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64(0) - (headerSize + 827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 4 + kFinishHeaderSize); 828baa3858d3f5d128a5c8466b700098109edcad5f2repo sync h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset; 829baa3858d3f5d128a5c8466b700098109edcad5f2repo sync h.AdditionalStartBlockSize = 0; 830baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteFinishHeader(h)); 831baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return WriteFinishSignature(); 832baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 833baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 834baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 835baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 836baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CStartHeader h; 837baa3858d3f5d128a5c8466b700098109edcad5f2repo sync h.NextHeaderSize = headerSize; 838baa3858d3f5d128a5c8466b700098109edcad5f2repo sync h.NextHeaderCRC = headerCRC; 839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync h.NextHeaderOffset = headerOffset; 840baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL)); 841baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return WriteStartHeader(h); 842baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 844baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 845baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CArchiveDatabase::GetFile(int index, CFileItem &file, CFileItem2 &file2) const 846baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 847baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file = Files[index]; 848baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file2.CTimeDefined = CTime.GetItem(index, file2.CTime); 849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file2.ATimeDefined = ATime.GetItem(index, file2.ATime); 850baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file2.MTimeDefined = MTime.GetItem(index, file2.MTime); 851baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file2.StartPosDefined = StartPos.GetItem(index, file2.StartPos); 852baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file2.IsAnti = IsItemAnti(index); 853baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 854baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 855baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CArchiveDatabase::AddFile(const CFileItem &file, const CFileItem2 &file2) 856baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 857baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int index = Files.Size(); 858baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CTime.SetItem(index, file2.CTimeDefined, file2.CTime); 859baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ATime.SetItem(index, file2.ATimeDefined, file2.ATime); 860baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MTime.SetItem(index, file2.MTimeDefined, file2.MTime); 861baa3858d3f5d128a5c8466b700098109edcad5f2repo sync StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos); 862baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetItemAnti(index, file2.IsAnti); 863baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Files.Add(file); 864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 865baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 866baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}} 867