1370b324cSopenharmony_ci// 7zOut.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include "../../../../C/7zCrc.h" 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include "../../../Common/AutoPtr.h" 8370b324cSopenharmony_ci// #include "../../../Common/UTFConvert.h" 9370b324cSopenharmony_ci 10370b324cSopenharmony_ci#include "../../Common/StreamObjects.h" 11370b324cSopenharmony_ci 12370b324cSopenharmony_ci#include "7zOut.h" 13370b324cSopenharmony_ci 14370b324cSopenharmony_cinamespace NArchive { 15370b324cSopenharmony_cinamespace N7z { 16370b324cSopenharmony_ci 17370b324cSopenharmony_cistatic void FillSignature(Byte *buf) 18370b324cSopenharmony_ci{ 19370b324cSopenharmony_ci memcpy(buf, kSignature, kSignatureSize); 20370b324cSopenharmony_ci buf[kSignatureSize] = kMajorVersion; 21370b324cSopenharmony_ci buf[kSignatureSize + 1] = 4; 22370b324cSopenharmony_ci} 23370b324cSopenharmony_ci 24370b324cSopenharmony_ci#ifdef Z7_7Z_VOL 25370b324cSopenharmony_ciHRESULT COutArchive::WriteFinishSignature() 26370b324cSopenharmony_ci{ 27370b324cSopenharmony_ci RINOK(WriteDirect(kFinishSignature, kSignatureSize)); 28370b324cSopenharmony_ci CArchiveVersion av; 29370b324cSopenharmony_ci av.Major = kMajorVersion; 30370b324cSopenharmony_ci av.Minor = 2; 31370b324cSopenharmony_ci RINOK(WriteDirectByte(av.Major)); 32370b324cSopenharmony_ci return WriteDirectByte(av.Minor); 33370b324cSopenharmony_ci} 34370b324cSopenharmony_ci#endif 35370b324cSopenharmony_ci 36370b324cSopenharmony_cistatic void SetUInt32(Byte *p, UInt32 d) 37370b324cSopenharmony_ci{ 38370b324cSopenharmony_ci for (int i = 0; i < 4; i++, d >>= 8) 39370b324cSopenharmony_ci p[i] = (Byte)d; 40370b324cSopenharmony_ci} 41370b324cSopenharmony_ci 42370b324cSopenharmony_cistatic void SetUInt64(Byte *p, UInt64 d) 43370b324cSopenharmony_ci{ 44370b324cSopenharmony_ci for (int i = 0; i < 8; i++, d >>= 8) 45370b324cSopenharmony_ci p[i] = (Byte)d; 46370b324cSopenharmony_ci} 47370b324cSopenharmony_ci 48370b324cSopenharmony_ciHRESULT COutArchive::WriteStartHeader(const CStartHeader &h) 49370b324cSopenharmony_ci{ 50370b324cSopenharmony_ci Byte buf[32]; 51370b324cSopenharmony_ci FillSignature(buf); 52370b324cSopenharmony_ci SetUInt64(buf + 8 + 4, h.NextHeaderOffset); 53370b324cSopenharmony_ci SetUInt64(buf + 8 + 12, h.NextHeaderSize); 54370b324cSopenharmony_ci SetUInt32(buf + 8 + 20, h.NextHeaderCRC); 55370b324cSopenharmony_ci SetUInt32(buf + 8, CrcCalc(buf + 8 + 4, 20)); 56370b324cSopenharmony_ci return WriteDirect(buf, sizeof(buf)); 57370b324cSopenharmony_ci} 58370b324cSopenharmony_ci 59370b324cSopenharmony_ci#ifdef Z7_7Z_VOL 60370b324cSopenharmony_ciHRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h) 61370b324cSopenharmony_ci{ 62370b324cSopenharmony_ci CCRC crc; 63370b324cSopenharmony_ci crc.UpdateUInt64(h.NextHeaderOffset); 64370b324cSopenharmony_ci crc.UpdateUInt64(h.NextHeaderSize); 65370b324cSopenharmony_ci crc.UpdateUInt32(h.NextHeaderCRC); 66370b324cSopenharmony_ci crc.UpdateUInt64(h.ArchiveStartOffset); 67370b324cSopenharmony_ci crc.UpdateUInt64(h.AdditionalStartBlockSize); 68370b324cSopenharmony_ci RINOK(WriteDirectUInt32(crc.GetDigest())); 69370b324cSopenharmony_ci RINOK(WriteDirectUInt64(h.NextHeaderOffset)); 70370b324cSopenharmony_ci RINOK(WriteDirectUInt64(h.NextHeaderSize)); 71370b324cSopenharmony_ci RINOK(WriteDirectUInt32(h.NextHeaderCRC)); 72370b324cSopenharmony_ci RINOK(WriteDirectUInt64(h.ArchiveStartOffset)); 73370b324cSopenharmony_ci return WriteDirectUInt64(h.AdditionalStartBlockSize); 74370b324cSopenharmony_ci} 75370b324cSopenharmony_ci#endif 76370b324cSopenharmony_ci 77370b324cSopenharmony_ciHRESULT COutArchive::Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */) 78370b324cSopenharmony_ci{ 79370b324cSopenharmony_ci Close(); 80370b324cSopenharmony_ci #ifdef Z7_7Z_VOL 81370b324cSopenharmony_ci // endMarker = false; 82370b324cSopenharmony_ci _endMarker = endMarker; 83370b324cSopenharmony_ci #endif 84370b324cSopenharmony_ci SeqStream = stream; 85370b324cSopenharmony_ci // if (!endMarker) 86370b324cSopenharmony_ci { 87370b324cSopenharmony_ci SeqStream.QueryInterface(IID_IOutStream, &Stream); 88370b324cSopenharmony_ci if (!Stream) 89370b324cSopenharmony_ci { 90370b324cSopenharmony_ci return E_NOTIMPL; 91370b324cSopenharmony_ci // endMarker = true; 92370b324cSopenharmony_ci } 93370b324cSopenharmony_ci RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_signatureHeaderPos)) 94370b324cSopenharmony_ci Byte buf[32]; 95370b324cSopenharmony_ci FillSignature(buf); 96370b324cSopenharmony_ci memset(&buf[8], 0, 32 - 8); 97370b324cSopenharmony_ci return WriteDirect(buf, sizeof(buf)); 98370b324cSopenharmony_ci } 99370b324cSopenharmony_ci #ifdef Z7_7Z_VOL 100370b324cSopenharmony_ci if (endMarker) 101370b324cSopenharmony_ci { 102370b324cSopenharmony_ci /* 103370b324cSopenharmony_ci CStartHeader sh; 104370b324cSopenharmony_ci sh.NextHeaderOffset = (UInt32)(Int32)-1; 105370b324cSopenharmony_ci sh.NextHeaderSize = (UInt32)(Int32)-1; 106370b324cSopenharmony_ci sh.NextHeaderCRC = 0; 107370b324cSopenharmony_ci WriteStartHeader(sh); 108370b324cSopenharmony_ci return S_OK; 109370b324cSopenharmony_ci */ 110370b324cSopenharmony_ci } 111370b324cSopenharmony_ci #endif 112370b324cSopenharmony_ci} 113370b324cSopenharmony_ci 114370b324cSopenharmony_civoid COutArchive::Close() 115370b324cSopenharmony_ci{ 116370b324cSopenharmony_ci SeqStream.Release(); 117370b324cSopenharmony_ci Stream.Release(); 118370b324cSopenharmony_ci} 119370b324cSopenharmony_ci 120370b324cSopenharmony_ciUInt64 COutArchive::GetPos() const 121370b324cSopenharmony_ci{ 122370b324cSopenharmony_ci if (_countMode) 123370b324cSopenharmony_ci return _countSize; 124370b324cSopenharmony_ci if (_writeToStream) 125370b324cSopenharmony_ci return _outByte.GetProcessedSize(); 126370b324cSopenharmony_ci return _outByte2.GetPos(); 127370b324cSopenharmony_ci} 128370b324cSopenharmony_ci 129370b324cSopenharmony_civoid COutArchive::WriteBytes(const void *data, size_t size) 130370b324cSopenharmony_ci{ 131370b324cSopenharmony_ci if (_countMode) 132370b324cSopenharmony_ci _countSize += size; 133370b324cSopenharmony_ci else if (_writeToStream) 134370b324cSopenharmony_ci { 135370b324cSopenharmony_ci _outByte.WriteBytes(data, size); 136370b324cSopenharmony_ci _crc = CrcUpdate(_crc, data, size); 137370b324cSopenharmony_ci } 138370b324cSopenharmony_ci else 139370b324cSopenharmony_ci _outByte2.WriteBytes(data, size); 140370b324cSopenharmony_ci} 141370b324cSopenharmony_ci 142370b324cSopenharmony_civoid COutArchive::WriteByte(Byte b) 143370b324cSopenharmony_ci{ 144370b324cSopenharmony_ci if (_countMode) 145370b324cSopenharmony_ci _countSize++; 146370b324cSopenharmony_ci else if (_writeToStream) 147370b324cSopenharmony_ci { 148370b324cSopenharmony_ci _outByte.WriteByte(b); 149370b324cSopenharmony_ci _crc = CRC_UPDATE_BYTE(_crc, b); 150370b324cSopenharmony_ci } 151370b324cSopenharmony_ci else 152370b324cSopenharmony_ci _outByte2.WriteByte(b); 153370b324cSopenharmony_ci} 154370b324cSopenharmony_ci 155370b324cSopenharmony_civoid COutArchive::WriteUInt32(UInt32 value) 156370b324cSopenharmony_ci{ 157370b324cSopenharmony_ci for (int i = 0; i < 4; i++) 158370b324cSopenharmony_ci { 159370b324cSopenharmony_ci WriteByte((Byte)value); 160370b324cSopenharmony_ci value >>= 8; 161370b324cSopenharmony_ci } 162370b324cSopenharmony_ci} 163370b324cSopenharmony_ci 164370b324cSopenharmony_civoid COutArchive::WriteUInt64(UInt64 value) 165370b324cSopenharmony_ci{ 166370b324cSopenharmony_ci for (int i = 0; i < 8; i++) 167370b324cSopenharmony_ci { 168370b324cSopenharmony_ci WriteByte((Byte)value); 169370b324cSopenharmony_ci value >>= 8; 170370b324cSopenharmony_ci } 171370b324cSopenharmony_ci} 172370b324cSopenharmony_ci 173370b324cSopenharmony_civoid COutArchive::WriteNumber(UInt64 value) 174370b324cSopenharmony_ci{ 175370b324cSopenharmony_ci Byte firstByte = 0; 176370b324cSopenharmony_ci Byte mask = 0x80; 177370b324cSopenharmony_ci int i; 178370b324cSopenharmony_ci for (i = 0; i < 8; i++) 179370b324cSopenharmony_ci { 180370b324cSopenharmony_ci if (value < ((UInt64(1) << ( 7 * (i + 1))))) 181370b324cSopenharmony_ci { 182370b324cSopenharmony_ci firstByte |= Byte(value >> (8 * i)); 183370b324cSopenharmony_ci break; 184370b324cSopenharmony_ci } 185370b324cSopenharmony_ci firstByte |= mask; 186370b324cSopenharmony_ci mask = (Byte)(mask >> 1); 187370b324cSopenharmony_ci } 188370b324cSopenharmony_ci WriteByte(firstByte); 189370b324cSopenharmony_ci for (; i > 0; i--) 190370b324cSopenharmony_ci { 191370b324cSopenharmony_ci WriteByte((Byte)value); 192370b324cSopenharmony_ci value >>= 8; 193370b324cSopenharmony_ci } 194370b324cSopenharmony_ci} 195370b324cSopenharmony_ci 196370b324cSopenharmony_cistatic unsigned GetBigNumberSize(UInt64 value) 197370b324cSopenharmony_ci{ 198370b324cSopenharmony_ci unsigned i; 199370b324cSopenharmony_ci for (i = 1; i < 9; i++) 200370b324cSopenharmony_ci if (value < (((UInt64)1 << (i * 7)))) 201370b324cSopenharmony_ci break; 202370b324cSopenharmony_ci return i; 203370b324cSopenharmony_ci} 204370b324cSopenharmony_ci 205370b324cSopenharmony_ci#ifdef Z7_7Z_VOL 206370b324cSopenharmony_ciUInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props) 207370b324cSopenharmony_ci{ 208370b324cSopenharmony_ci UInt32 result = GetBigNumberSize(dataSize) * 2 + 41; 209370b324cSopenharmony_ci if (nameLength != 0) 210370b324cSopenharmony_ci { 211370b324cSopenharmony_ci nameLength = (nameLength + 1) * 2; 212370b324cSopenharmony_ci result += nameLength + GetBigNumberSize(nameLength) + 2; 213370b324cSopenharmony_ci } 214370b324cSopenharmony_ci if (props) 215370b324cSopenharmony_ci { 216370b324cSopenharmony_ci result += 20; 217370b324cSopenharmony_ci } 218370b324cSopenharmony_ci if (result >= 128) 219370b324cSopenharmony_ci result++; 220370b324cSopenharmony_ci result += kSignatureSize + 2 + kFinishHeaderSize; 221370b324cSopenharmony_ci return result; 222370b324cSopenharmony_ci} 223370b324cSopenharmony_ci 224370b324cSopenharmony_ciUInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props) 225370b324cSopenharmony_ci{ 226370b324cSopenharmony_ci UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props); 227370b324cSopenharmony_ci int testSize; 228370b324cSopenharmony_ci if (volSize > headersSizeBase) 229370b324cSopenharmony_ci testSize = volSize - headersSizeBase; 230370b324cSopenharmony_ci else 231370b324cSopenharmony_ci testSize = 1; 232370b324cSopenharmony_ci UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props); 233370b324cSopenharmony_ci UInt64 pureSize = 1; 234370b324cSopenharmony_ci if (volSize > headersSize) 235370b324cSopenharmony_ci pureSize = volSize - headersSize; 236370b324cSopenharmony_ci return pureSize; 237370b324cSopenharmony_ci} 238370b324cSopenharmony_ci#endif 239370b324cSopenharmony_ci 240370b324cSopenharmony_civoid COutArchive::WriteFolder(const CFolder &folder) 241370b324cSopenharmony_ci{ 242370b324cSopenharmony_ci WriteNumber(folder.Coders.Size()); 243370b324cSopenharmony_ci unsigned i; 244370b324cSopenharmony_ci 245370b324cSopenharmony_ci for (i = 0; i < folder.Coders.Size(); i++) 246370b324cSopenharmony_ci { 247370b324cSopenharmony_ci const CCoderInfo &coder = folder.Coders[i]; 248370b324cSopenharmony_ci { 249370b324cSopenharmony_ci UInt64 id = coder.MethodID; 250370b324cSopenharmony_ci unsigned idSize; 251370b324cSopenharmony_ci for (idSize = 1; idSize < sizeof(id); idSize++) 252370b324cSopenharmony_ci if ((id >> (8 * idSize)) == 0) 253370b324cSopenharmony_ci break; 254370b324cSopenharmony_ci // idSize &= 0xF; // idSize is smaller than 16 already 255370b324cSopenharmony_ci Byte temp[16]; 256370b324cSopenharmony_ci for (unsigned t = idSize; t != 0; t--, id >>= 8) 257370b324cSopenharmony_ci temp[t] = (Byte)(id & 0xFF); 258370b324cSopenharmony_ci 259370b324cSopenharmony_ci unsigned b = idSize; 260370b324cSopenharmony_ci const bool isComplex = !coder.IsSimpleCoder(); 261370b324cSopenharmony_ci b |= (isComplex ? 0x10 : 0); 262370b324cSopenharmony_ci 263370b324cSopenharmony_ci const size_t propsSize = coder.Props.Size(); 264370b324cSopenharmony_ci b |= ((propsSize != 0) ? 0x20 : 0); 265370b324cSopenharmony_ci temp[0] = (Byte)b; 266370b324cSopenharmony_ci WriteBytes(temp, idSize + 1); 267370b324cSopenharmony_ci if (isComplex) 268370b324cSopenharmony_ci { 269370b324cSopenharmony_ci WriteNumber(coder.NumStreams); 270370b324cSopenharmony_ci WriteNumber(1); // NumOutStreams; 271370b324cSopenharmony_ci } 272370b324cSopenharmony_ci if (propsSize == 0) 273370b324cSopenharmony_ci continue; 274370b324cSopenharmony_ci WriteNumber(propsSize); 275370b324cSopenharmony_ci WriteBytes(coder.Props, propsSize); 276370b324cSopenharmony_ci } 277370b324cSopenharmony_ci } 278370b324cSopenharmony_ci 279370b324cSopenharmony_ci for (i = 0; i < folder.Bonds.Size(); i++) 280370b324cSopenharmony_ci { 281370b324cSopenharmony_ci const CBond &bond = folder.Bonds[i]; 282370b324cSopenharmony_ci WriteNumber(bond.PackIndex); 283370b324cSopenharmony_ci WriteNumber(bond.UnpackIndex); 284370b324cSopenharmony_ci } 285370b324cSopenharmony_ci 286370b324cSopenharmony_ci if (folder.PackStreams.Size() > 1) 287370b324cSopenharmony_ci for (i = 0; i < folder.PackStreams.Size(); i++) 288370b324cSopenharmony_ci WriteNumber(folder.PackStreams[i]); 289370b324cSopenharmony_ci} 290370b324cSopenharmony_ci 291370b324cSopenharmony_civoid COutArchive::WriteBoolVector(const CBoolVector &boolVector) 292370b324cSopenharmony_ci{ 293370b324cSopenharmony_ci Byte b = 0; 294370b324cSopenharmony_ci Byte mask = 0x80; 295370b324cSopenharmony_ci FOR_VECTOR (i, boolVector) 296370b324cSopenharmony_ci { 297370b324cSopenharmony_ci if (boolVector[i]) 298370b324cSopenharmony_ci b |= mask; 299370b324cSopenharmony_ci mask = (Byte)(mask >> 1); 300370b324cSopenharmony_ci if (mask == 0) 301370b324cSopenharmony_ci { 302370b324cSopenharmony_ci WriteByte(b); 303370b324cSopenharmony_ci mask = 0x80; 304370b324cSopenharmony_ci b = 0; 305370b324cSopenharmony_ci } 306370b324cSopenharmony_ci } 307370b324cSopenharmony_ci if (mask != 0x80) 308370b324cSopenharmony_ci WriteByte(b); 309370b324cSopenharmony_ci} 310370b324cSopenharmony_ci 311370b324cSopenharmony_cistatic inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; } 312370b324cSopenharmony_ci 313370b324cSopenharmony_civoid COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector) 314370b324cSopenharmony_ci{ 315370b324cSopenharmony_ci WriteByte(id); 316370b324cSopenharmony_ci WriteNumber(Bv_GetSizeInBytes(boolVector)); 317370b324cSopenharmony_ci WriteBoolVector(boolVector); 318370b324cSopenharmony_ci} 319370b324cSopenharmony_ci 320370b324cSopenharmony_ciunsigned BoolVector_CountSum(const CBoolVector &v); 321370b324cSopenharmony_ci 322370b324cSopenharmony_civoid COutArchive::WriteHashDigests(const CUInt32DefVector &digests) 323370b324cSopenharmony_ci{ 324370b324cSopenharmony_ci const unsigned numDefined = BoolVector_CountSum(digests.Defs); 325370b324cSopenharmony_ci if (numDefined == 0) 326370b324cSopenharmony_ci return; 327370b324cSopenharmony_ci 328370b324cSopenharmony_ci WriteByte(NID::kCRC); 329370b324cSopenharmony_ci if (numDefined == digests.Defs.Size()) 330370b324cSopenharmony_ci WriteByte(1); 331370b324cSopenharmony_ci else 332370b324cSopenharmony_ci { 333370b324cSopenharmony_ci WriteByte(0); 334370b324cSopenharmony_ci WriteBoolVector(digests.Defs); 335370b324cSopenharmony_ci } 336370b324cSopenharmony_ci 337370b324cSopenharmony_ci for (unsigned i = 0; i < digests.Defs.Size(); i++) 338370b324cSopenharmony_ci if (digests.Defs[i]) 339370b324cSopenharmony_ci WriteUInt32(digests.Vals[i]); 340370b324cSopenharmony_ci} 341370b324cSopenharmony_ci 342370b324cSopenharmony_civoid COutArchive::WritePackInfo( 343370b324cSopenharmony_ci UInt64 dataOffset, 344370b324cSopenharmony_ci const CRecordVector<UInt64> &packSizes, 345370b324cSopenharmony_ci const CUInt32DefVector &packCRCs) 346370b324cSopenharmony_ci{ 347370b324cSopenharmony_ci if (packSizes.IsEmpty()) 348370b324cSopenharmony_ci return; 349370b324cSopenharmony_ci WriteByte(NID::kPackInfo); 350370b324cSopenharmony_ci WriteNumber(dataOffset); 351370b324cSopenharmony_ci WriteNumber(packSizes.Size()); 352370b324cSopenharmony_ci WriteByte(NID::kSize); 353370b324cSopenharmony_ci FOR_VECTOR (i, packSizes) 354370b324cSopenharmony_ci WriteNumber(packSizes[i]); 355370b324cSopenharmony_ci 356370b324cSopenharmony_ci WriteHashDigests(packCRCs); 357370b324cSopenharmony_ci 358370b324cSopenharmony_ci WriteByte(NID::kEnd); 359370b324cSopenharmony_ci} 360370b324cSopenharmony_ci 361370b324cSopenharmony_civoid COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders, const COutFolders &outFolders) 362370b324cSopenharmony_ci{ 363370b324cSopenharmony_ci if (folders.IsEmpty()) 364370b324cSopenharmony_ci return; 365370b324cSopenharmony_ci 366370b324cSopenharmony_ci WriteByte(NID::kUnpackInfo); 367370b324cSopenharmony_ci 368370b324cSopenharmony_ci WriteByte(NID::kFolder); 369370b324cSopenharmony_ci WriteNumber(folders.Size()); 370370b324cSopenharmony_ci { 371370b324cSopenharmony_ci WriteByte(0); 372370b324cSopenharmony_ci FOR_VECTOR (i, folders) 373370b324cSopenharmony_ci WriteFolder(folders[i]); 374370b324cSopenharmony_ci } 375370b324cSopenharmony_ci 376370b324cSopenharmony_ci WriteByte(NID::kCodersUnpackSize); 377370b324cSopenharmony_ci FOR_VECTOR (i, outFolders.CoderUnpackSizes) 378370b324cSopenharmony_ci WriteNumber(outFolders.CoderUnpackSizes[i]); 379370b324cSopenharmony_ci 380370b324cSopenharmony_ci WriteHashDigests(outFolders.FolderUnpackCRCs); 381370b324cSopenharmony_ci 382370b324cSopenharmony_ci WriteByte(NID::kEnd); 383370b324cSopenharmony_ci} 384370b324cSopenharmony_ci 385370b324cSopenharmony_civoid COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders, 386370b324cSopenharmony_ci const COutFolders &outFolders, 387370b324cSopenharmony_ci const CRecordVector<UInt64> &unpackSizes, 388370b324cSopenharmony_ci const CUInt32DefVector &digests) 389370b324cSopenharmony_ci{ 390370b324cSopenharmony_ci const CRecordVector<CNum> &numUnpackStreamsInFolders = outFolders.NumUnpackStreamsVector; 391370b324cSopenharmony_ci WriteByte(NID::kSubStreamsInfo); 392370b324cSopenharmony_ci 393370b324cSopenharmony_ci unsigned i; 394370b324cSopenharmony_ci for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) 395370b324cSopenharmony_ci if (numUnpackStreamsInFolders[i] != 1) 396370b324cSopenharmony_ci { 397370b324cSopenharmony_ci WriteByte(NID::kNumUnpackStream); 398370b324cSopenharmony_ci for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) 399370b324cSopenharmony_ci WriteNumber(numUnpackStreamsInFolders[i]); 400370b324cSopenharmony_ci break; 401370b324cSopenharmony_ci } 402370b324cSopenharmony_ci 403370b324cSopenharmony_ci for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) 404370b324cSopenharmony_ci if (numUnpackStreamsInFolders[i] > 1) 405370b324cSopenharmony_ci { 406370b324cSopenharmony_ci WriteByte(NID::kSize); 407370b324cSopenharmony_ci CNum index = 0; 408370b324cSopenharmony_ci for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) 409370b324cSopenharmony_ci { 410370b324cSopenharmony_ci CNum num = numUnpackStreamsInFolders[i]; 411370b324cSopenharmony_ci for (CNum j = 0; j < num; j++) 412370b324cSopenharmony_ci { 413370b324cSopenharmony_ci if (j + 1 != num) 414370b324cSopenharmony_ci WriteNumber(unpackSizes[index]); 415370b324cSopenharmony_ci index++; 416370b324cSopenharmony_ci } 417370b324cSopenharmony_ci } 418370b324cSopenharmony_ci break; 419370b324cSopenharmony_ci } 420370b324cSopenharmony_ci 421370b324cSopenharmony_ci CUInt32DefVector digests2; 422370b324cSopenharmony_ci 423370b324cSopenharmony_ci unsigned digestIndex = 0; 424370b324cSopenharmony_ci for (i = 0; i < folders.Size(); i++) 425370b324cSopenharmony_ci { 426370b324cSopenharmony_ci unsigned numSubStreams = (unsigned)numUnpackStreamsInFolders[i]; 427370b324cSopenharmony_ci if (numSubStreams == 1 && outFolders.FolderUnpackCRCs.ValidAndDefined(i)) 428370b324cSopenharmony_ci digestIndex++; 429370b324cSopenharmony_ci else 430370b324cSopenharmony_ci for (unsigned j = 0; j < numSubStreams; j++, digestIndex++) 431370b324cSopenharmony_ci { 432370b324cSopenharmony_ci digests2.Defs.Add(digests.Defs[digestIndex]); 433370b324cSopenharmony_ci digests2.Vals.Add(digests.Vals[digestIndex]); 434370b324cSopenharmony_ci } 435370b324cSopenharmony_ci } 436370b324cSopenharmony_ci WriteHashDigests(digests2); 437370b324cSopenharmony_ci WriteByte(NID::kEnd); 438370b324cSopenharmony_ci} 439370b324cSopenharmony_ci 440370b324cSopenharmony_ci// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field. 441370b324cSopenharmony_ci 442370b324cSopenharmony_civoid COutArchive::SkipToAligned(unsigned pos, unsigned alignShifts) 443370b324cSopenharmony_ci{ 444370b324cSopenharmony_ci if (!_useAlign) 445370b324cSopenharmony_ci return; 446370b324cSopenharmony_ci 447370b324cSopenharmony_ci const unsigned alignSize = (unsigned)1 << alignShifts; 448370b324cSopenharmony_ci pos += (unsigned)GetPos(); 449370b324cSopenharmony_ci pos &= (alignSize - 1); 450370b324cSopenharmony_ci if (pos == 0) 451370b324cSopenharmony_ci return; 452370b324cSopenharmony_ci unsigned skip = alignSize - pos; 453370b324cSopenharmony_ci if (skip < 2) 454370b324cSopenharmony_ci skip += alignSize; 455370b324cSopenharmony_ci skip -= 2; 456370b324cSopenharmony_ci WriteByte(NID::kDummy); 457370b324cSopenharmony_ci WriteByte((Byte)skip); 458370b324cSopenharmony_ci for (unsigned i = 0; i < skip; i++) 459370b324cSopenharmony_ci WriteByte(0); 460370b324cSopenharmony_ci} 461370b324cSopenharmony_ci 462370b324cSopenharmony_civoid COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts) 463370b324cSopenharmony_ci{ 464370b324cSopenharmony_ci const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v); 465370b324cSopenharmony_ci const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2; 466370b324cSopenharmony_ci SkipToAligned(3 + bvSize + GetBigNumberSize(dataSize), itemSizeShifts); 467370b324cSopenharmony_ci 468370b324cSopenharmony_ci WriteByte(type); 469370b324cSopenharmony_ci WriteNumber(dataSize); 470370b324cSopenharmony_ci if (numDefined == v.Size()) 471370b324cSopenharmony_ci WriteByte(1); 472370b324cSopenharmony_ci else 473370b324cSopenharmony_ci { 474370b324cSopenharmony_ci WriteByte(0); 475370b324cSopenharmony_ci WriteBoolVector(v); 476370b324cSopenharmony_ci } 477370b324cSopenharmony_ci WriteByte(0); // 0 means no switching to external stream 478370b324cSopenharmony_ci} 479370b324cSopenharmony_ci 480370b324cSopenharmony_civoid COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type) 481370b324cSopenharmony_ci{ 482370b324cSopenharmony_ci const unsigned numDefined = BoolVector_CountSum(v.Defs); 483370b324cSopenharmony_ci if (numDefined == 0) 484370b324cSopenharmony_ci return; 485370b324cSopenharmony_ci 486370b324cSopenharmony_ci WriteAlignedBools(v.Defs, numDefined, type, 3); 487370b324cSopenharmony_ci 488370b324cSopenharmony_ci for (unsigned i = 0; i < v.Defs.Size(); i++) 489370b324cSopenharmony_ci if (v.Defs[i]) 490370b324cSopenharmony_ci WriteUInt64(v.Vals[i]); 491370b324cSopenharmony_ci} 492370b324cSopenharmony_ci 493370b324cSopenharmony_ciHRESULT COutArchive::EncodeStream( 494370b324cSopenharmony_ci DECL_EXTERNAL_CODECS_LOC_VARS 495370b324cSopenharmony_ci CEncoder &encoder, const CByteBuffer &data, 496370b324cSopenharmony_ci CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders) 497370b324cSopenharmony_ci{ 498370b324cSopenharmony_ci CBufInStream *streamSpec = new CBufInStream; 499370b324cSopenharmony_ci CMyComPtr<ISequentialInStream> stream = streamSpec; 500370b324cSopenharmony_ci streamSpec->Init(data, data.Size()); 501370b324cSopenharmony_ci outFolders.FolderUnpackCRCs.Defs.Add(true); 502370b324cSopenharmony_ci outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size())); 503370b324cSopenharmony_ci // outFolders.NumUnpackStreamsVector.Add(1); 504370b324cSopenharmony_ci const UInt64 dataSize64 = data.Size(); 505370b324cSopenharmony_ci const UInt64 expectSize = data.Size(); 506370b324cSopenharmony_ci RINOK(encoder.Encode1( 507370b324cSopenharmony_ci EXTERNAL_CODECS_LOC_VARS 508370b324cSopenharmony_ci stream, 509370b324cSopenharmony_ci // NULL, 510370b324cSopenharmony_ci &dataSize64, // inSizeForReduce 511370b324cSopenharmony_ci expectSize, 512370b324cSopenharmony_ci folders.AddNew(), 513370b324cSopenharmony_ci // outFolders.CoderUnpackSizes, unpackSize, 514370b324cSopenharmony_ci SeqStream, packSizes, NULL)) 515370b324cSopenharmony_ci if (!streamSpec->WasFinished()) 516370b324cSopenharmony_ci return E_FAIL; 517370b324cSopenharmony_ci encoder.Encode_Post(dataSize64, outFolders.CoderUnpackSizes); 518370b324cSopenharmony_ci return S_OK; 519370b324cSopenharmony_ci} 520370b324cSopenharmony_ci 521370b324cSopenharmony_civoid COutArchive::WriteHeader( 522370b324cSopenharmony_ci const CArchiveDatabaseOut &db, 523370b324cSopenharmony_ci // const CHeaderOptions &headerOptions, 524370b324cSopenharmony_ci UInt64 &headerOffset) 525370b324cSopenharmony_ci{ 526370b324cSopenharmony_ci /* 527370b324cSopenharmony_ci bool thereIsSecure = (db.SecureBuf.Size() != 0); 528370b324cSopenharmony_ci */ 529370b324cSopenharmony_ci _useAlign = true; 530370b324cSopenharmony_ci 531370b324cSopenharmony_ci { 532370b324cSopenharmony_ci UInt64 packSize = 0; 533370b324cSopenharmony_ci FOR_VECTOR (i, db.PackSizes) 534370b324cSopenharmony_ci packSize += db.PackSizes[i]; 535370b324cSopenharmony_ci headerOffset = packSize; 536370b324cSopenharmony_ci } 537370b324cSopenharmony_ci 538370b324cSopenharmony_ci 539370b324cSopenharmony_ci WriteByte(NID::kHeader); 540370b324cSopenharmony_ci 541370b324cSopenharmony_ci /* 542370b324cSopenharmony_ci { 543370b324cSopenharmony_ci // It's example for per archive properies writing 544370b324cSopenharmony_ci 545370b324cSopenharmony_ci WriteByte(NID::kArchiveProperties); 546370b324cSopenharmony_ci 547370b324cSopenharmony_ci // you must use random 40-bit number that will identify you 548370b324cSopenharmony_ci // then you can use same kDeveloperID for any properties and methods 549370b324cSopenharmony_ci const UInt64 kDeveloperID = 0x123456789A; // change that value to real random 40-bit number 550370b324cSopenharmony_ci 551370b324cSopenharmony_ci #define GENERATE_7Z_ID(developerID, subID) (((UInt64)0x3F << 56) | ((UInt64)developerID << 16) | subID) 552370b324cSopenharmony_ci 553370b324cSopenharmony_ci { 554370b324cSopenharmony_ci const UInt64 kSubID = 0x1; // you can use small number for subID 555370b324cSopenharmony_ci const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID); 556370b324cSopenharmony_ci WriteNumber(kID); 557370b324cSopenharmony_ci const unsigned kPropsSize = 3; // it's example size 558370b324cSopenharmony_ci WriteNumber(kPropsSize); 559370b324cSopenharmony_ci for (unsigned i = 0; i < kPropsSize; i++) 560370b324cSopenharmony_ci WriteByte((Byte)(i & 0xFF)); 561370b324cSopenharmony_ci } 562370b324cSopenharmony_ci { 563370b324cSopenharmony_ci const UInt64 kSubID = 0x2; // you can use small number for subID 564370b324cSopenharmony_ci const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID); 565370b324cSopenharmony_ci WriteNumber(kID); 566370b324cSopenharmony_ci const unsigned kPropsSize = 5; // it's example size 567370b324cSopenharmony_ci WriteNumber(kPropsSize); 568370b324cSopenharmony_ci for (unsigned i = 0; i < kPropsSize; i++) 569370b324cSopenharmony_ci WriteByte((Byte)(i + 16)); 570370b324cSopenharmony_ci } 571370b324cSopenharmony_ci WriteByte(NID::kEnd); 572370b324cSopenharmony_ci } 573370b324cSopenharmony_ci */ 574370b324cSopenharmony_ci 575370b324cSopenharmony_ci if (db.Folders.Size() > 0) 576370b324cSopenharmony_ci { 577370b324cSopenharmony_ci WriteByte(NID::kMainStreamsInfo); 578370b324cSopenharmony_ci WritePackInfo(0, db.PackSizes, db.PackCRCs); 579370b324cSopenharmony_ci WriteUnpackInfo(db.Folders, (const COutFolders &)db); 580370b324cSopenharmony_ci 581370b324cSopenharmony_ci CRecordVector<UInt64> unpackSizes; 582370b324cSopenharmony_ci CUInt32DefVector digests; 583370b324cSopenharmony_ci FOR_VECTOR (i, db.Files) 584370b324cSopenharmony_ci { 585370b324cSopenharmony_ci const CFileItem &file = db.Files[i]; 586370b324cSopenharmony_ci if (!file.HasStream) 587370b324cSopenharmony_ci continue; 588370b324cSopenharmony_ci unpackSizes.Add(file.Size); 589370b324cSopenharmony_ci digests.Defs.Add(file.CrcDefined); 590370b324cSopenharmony_ci digests.Vals.Add(file.Crc); 591370b324cSopenharmony_ci } 592370b324cSopenharmony_ci 593370b324cSopenharmony_ci WriteSubStreamsInfo(db.Folders, (const COutFolders &)db, unpackSizes, digests); 594370b324cSopenharmony_ci WriteByte(NID::kEnd); 595370b324cSopenharmony_ci } 596370b324cSopenharmony_ci 597370b324cSopenharmony_ci if (db.Files.IsEmpty()) 598370b324cSopenharmony_ci { 599370b324cSopenharmony_ci WriteByte(NID::kEnd); 600370b324cSopenharmony_ci return; 601370b324cSopenharmony_ci } 602370b324cSopenharmony_ci 603370b324cSopenharmony_ci WriteByte(NID::kFilesInfo); 604370b324cSopenharmony_ci WriteNumber(db.Files.Size()); 605370b324cSopenharmony_ci 606370b324cSopenharmony_ci { 607370b324cSopenharmony_ci /* ---------- Empty Streams ---------- */ 608370b324cSopenharmony_ci CBoolVector emptyStreamVector; 609370b324cSopenharmony_ci emptyStreamVector.ClearAndSetSize(db.Files.Size()); 610370b324cSopenharmony_ci unsigned numEmptyStreams = 0; 611370b324cSopenharmony_ci { 612370b324cSopenharmony_ci FOR_VECTOR (i, db.Files) 613370b324cSopenharmony_ci if (db.Files[i].HasStream) 614370b324cSopenharmony_ci emptyStreamVector[i] = false; 615370b324cSopenharmony_ci else 616370b324cSopenharmony_ci { 617370b324cSopenharmony_ci emptyStreamVector[i] = true; 618370b324cSopenharmony_ci numEmptyStreams++; 619370b324cSopenharmony_ci } 620370b324cSopenharmony_ci } 621370b324cSopenharmony_ci 622370b324cSopenharmony_ci if (numEmptyStreams != 0) 623370b324cSopenharmony_ci { 624370b324cSopenharmony_ci WritePropBoolVector(NID::kEmptyStream, emptyStreamVector); 625370b324cSopenharmony_ci 626370b324cSopenharmony_ci CBoolVector emptyFileVector, antiVector; 627370b324cSopenharmony_ci emptyFileVector.ClearAndSetSize(numEmptyStreams); 628370b324cSopenharmony_ci antiVector.ClearAndSetSize(numEmptyStreams); 629370b324cSopenharmony_ci bool thereAreEmptyFiles = false, thereAreAntiItems = false; 630370b324cSopenharmony_ci unsigned cur = 0; 631370b324cSopenharmony_ci 632370b324cSopenharmony_ci FOR_VECTOR (i, db.Files) 633370b324cSopenharmony_ci { 634370b324cSopenharmony_ci const CFileItem &file = db.Files[i]; 635370b324cSopenharmony_ci if (file.HasStream) 636370b324cSopenharmony_ci continue; 637370b324cSopenharmony_ci emptyFileVector[cur] = !file.IsDir; 638370b324cSopenharmony_ci if (!file.IsDir) 639370b324cSopenharmony_ci thereAreEmptyFiles = true; 640370b324cSopenharmony_ci bool isAnti = db.IsItemAnti(i); 641370b324cSopenharmony_ci antiVector[cur] = isAnti; 642370b324cSopenharmony_ci if (isAnti) 643370b324cSopenharmony_ci thereAreAntiItems = true; 644370b324cSopenharmony_ci cur++; 645370b324cSopenharmony_ci } 646370b324cSopenharmony_ci 647370b324cSopenharmony_ci if (thereAreEmptyFiles) 648370b324cSopenharmony_ci WritePropBoolVector(NID::kEmptyFile, emptyFileVector); 649370b324cSopenharmony_ci if (thereAreAntiItems) 650370b324cSopenharmony_ci WritePropBoolVector(NID::kAnti, antiVector); 651370b324cSopenharmony_ci } 652370b324cSopenharmony_ci } 653370b324cSopenharmony_ci 654370b324cSopenharmony_ci 655370b324cSopenharmony_ci { 656370b324cSopenharmony_ci /* ---------- Names ---------- */ 657370b324cSopenharmony_ci 658370b324cSopenharmony_ci unsigned numDefined = 0; 659370b324cSopenharmony_ci size_t namesDataSize = 0; 660370b324cSopenharmony_ci FOR_VECTOR (i, db.Files) 661370b324cSopenharmony_ci { 662370b324cSopenharmony_ci const UString &name = db.Names[i]; 663370b324cSopenharmony_ci if (!name.IsEmpty()) 664370b324cSopenharmony_ci numDefined++; 665370b324cSopenharmony_ci const size_t numUtfChars = 666370b324cSopenharmony_ci /* 667370b324cSopenharmony_ci #if WCHAR_MAX > 0xffff 668370b324cSopenharmony_ci Get_Num_Utf16_chars_from_wchar_string(name.Ptr()); 669370b324cSopenharmony_ci #else 670370b324cSopenharmony_ci */ 671370b324cSopenharmony_ci name.Len(); 672370b324cSopenharmony_ci // #endif 673370b324cSopenharmony_ci namesDataSize += (numUtfChars + 1) * 2; 674370b324cSopenharmony_ci } 675370b324cSopenharmony_ci 676370b324cSopenharmony_ci if (numDefined > 0) 677370b324cSopenharmony_ci { 678370b324cSopenharmony_ci namesDataSize++; 679370b324cSopenharmony_ci SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4); 680370b324cSopenharmony_ci 681370b324cSopenharmony_ci WriteByte(NID::kName); 682370b324cSopenharmony_ci WriteNumber(namesDataSize); 683370b324cSopenharmony_ci WriteByte(0); 684370b324cSopenharmony_ci FOR_VECTOR (i, db.Files) 685370b324cSopenharmony_ci { 686370b324cSopenharmony_ci const UString &name = db.Names[i]; 687370b324cSopenharmony_ci for (unsigned t = 0; t <= name.Len(); t++) 688370b324cSopenharmony_ci { 689370b324cSopenharmony_ci wchar_t c = name[t]; 690370b324cSopenharmony_ci 691370b324cSopenharmony_ci /* 692370b324cSopenharmony_ci #if WCHAR_MAX > 0xffff 693370b324cSopenharmony_ci if (c >= 0x10000) 694370b324cSopenharmony_ci { 695370b324cSopenharmony_ci c -= 0x10000; 696370b324cSopenharmony_ci if (c < (1 << 20)) 697370b324cSopenharmony_ci { 698370b324cSopenharmony_ci unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF); 699370b324cSopenharmony_ci WriteByte((Byte)c0); 700370b324cSopenharmony_ci WriteByte((Byte)(c0 >> 8)); 701370b324cSopenharmony_ci c = 0xdc00 + (c & 0x3FF); 702370b324cSopenharmony_ci } 703370b324cSopenharmony_ci else 704370b324cSopenharmony_ci c = '_'; // we change character unsupported by UTF16 705370b324cSopenharmony_ci } 706370b324cSopenharmony_ci #endif 707370b324cSopenharmony_ci */ 708370b324cSopenharmony_ci 709370b324cSopenharmony_ci WriteByte((Byte)c); 710370b324cSopenharmony_ci WriteByte((Byte)(c >> 8)); 711370b324cSopenharmony_ci } 712370b324cSopenharmony_ci } 713370b324cSopenharmony_ci } 714370b324cSopenharmony_ci } 715370b324cSopenharmony_ci 716370b324cSopenharmony_ci /* if (headerOptions.WriteCTime) */ WriteUInt64DefVector(db.CTime, NID::kCTime); 717370b324cSopenharmony_ci /* if (headerOptions.WriteATime) */ WriteUInt64DefVector(db.ATime, NID::kATime); 718370b324cSopenharmony_ci /* if (headerOptions.WriteMTime) */ WriteUInt64DefVector(db.MTime, NID::kMTime); 719370b324cSopenharmony_ci WriteUInt64DefVector(db.StartPos, NID::kStartPos); 720370b324cSopenharmony_ci 721370b324cSopenharmony_ci { 722370b324cSopenharmony_ci /* ---------- Write Attrib ---------- */ 723370b324cSopenharmony_ci const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs); 724370b324cSopenharmony_ci 725370b324cSopenharmony_ci if (numDefined != 0) 726370b324cSopenharmony_ci { 727370b324cSopenharmony_ci WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2); 728370b324cSopenharmony_ci FOR_VECTOR (i, db.Attrib.Defs) 729370b324cSopenharmony_ci { 730370b324cSopenharmony_ci if (db.Attrib.Defs[i]) 731370b324cSopenharmony_ci WriteUInt32(db.Attrib.Vals[i]); 732370b324cSopenharmony_ci } 733370b324cSopenharmony_ci } 734370b324cSopenharmony_ci } 735370b324cSopenharmony_ci 736370b324cSopenharmony_ci /* 737370b324cSopenharmony_ci { 738370b324cSopenharmony_ci // ---------- Write IsAux ---------- 739370b324cSopenharmony_ci if (BoolVector_CountSum(db.IsAux) != 0) 740370b324cSopenharmony_ci WritePropBoolVector(NID::kIsAux, db.IsAux); 741370b324cSopenharmony_ci } 742370b324cSopenharmony_ci 743370b324cSopenharmony_ci { 744370b324cSopenharmony_ci // ---------- Write Parent ---------- 745370b324cSopenharmony_ci CBoolVector boolVector; 746370b324cSopenharmony_ci boolVector.Reserve(db.Files.Size()); 747370b324cSopenharmony_ci unsigned numIsDir = 0; 748370b324cSopenharmony_ci unsigned numParentLinks = 0; 749370b324cSopenharmony_ci for (i = 0; i < db.Files.Size(); i++) 750370b324cSopenharmony_ci { 751370b324cSopenharmony_ci const CFileItem &file = db.Files[i]; 752370b324cSopenharmony_ci bool defined = !file.IsAltStream; 753370b324cSopenharmony_ci boolVector.Add(defined); 754370b324cSopenharmony_ci if (defined) 755370b324cSopenharmony_ci numIsDir++; 756370b324cSopenharmony_ci if (file.Parent >= 0) 757370b324cSopenharmony_ci numParentLinks++; 758370b324cSopenharmony_ci } 759370b324cSopenharmony_ci if (numParentLinks > 0) 760370b324cSopenharmony_ci { 761370b324cSopenharmony_ci // WriteAlignedBools(boolVector, numDefined, NID::kParent, 2); 762370b324cSopenharmony_ci const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector); 763370b324cSopenharmony_ci const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1; 764370b324cSopenharmony_ci SkipToAligned(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 2); 765370b324cSopenharmony_ci 766370b324cSopenharmony_ci WriteByte(NID::kParent); 767370b324cSopenharmony_ci WriteNumber(dataSize); 768370b324cSopenharmony_ci if (numIsDir == boolVector.Size()) 769370b324cSopenharmony_ci WriteByte(1); 770370b324cSopenharmony_ci else 771370b324cSopenharmony_ci { 772370b324cSopenharmony_ci WriteByte(0); 773370b324cSopenharmony_ci WriteBoolVector(boolVector); 774370b324cSopenharmony_ci } 775370b324cSopenharmony_ci for (i = 0; i < db.Files.Size(); i++) 776370b324cSopenharmony_ci { 777370b324cSopenharmony_ci const CFileItem &file = db.Files[i]; 778370b324cSopenharmony_ci // if (file.Parent >= 0) 779370b324cSopenharmony_ci WriteUInt32(file.Parent); 780370b324cSopenharmony_ci } 781370b324cSopenharmony_ci } 782370b324cSopenharmony_ci } 783370b324cSopenharmony_ci 784370b324cSopenharmony_ci if (thereIsSecure) 785370b324cSopenharmony_ci { 786370b324cSopenharmony_ci UInt64 secureDataSize = 1 + 4 + 787370b324cSopenharmony_ci db.SecureBuf.Size() + 788370b324cSopenharmony_ci db.SecureSizes.Size() * 4; 789370b324cSopenharmony_ci // secureDataSize += db.SecureIDs.Size() * 4; 790370b324cSopenharmony_ci for (i = 0; i < db.SecureIDs.Size(); i++) 791370b324cSopenharmony_ci secureDataSize += GetBigNumberSize(db.SecureIDs[i]); 792370b324cSopenharmony_ci SkipToAligned(2 + GetBigNumberSize(secureDataSize), 2); 793370b324cSopenharmony_ci WriteByte(NID::kNtSecure); 794370b324cSopenharmony_ci WriteNumber(secureDataSize); 795370b324cSopenharmony_ci WriteByte(0); 796370b324cSopenharmony_ci WriteUInt32(db.SecureSizes.Size()); 797370b324cSopenharmony_ci for (i = 0; i < db.SecureSizes.Size(); i++) 798370b324cSopenharmony_ci WriteUInt32(db.SecureSizes[i]); 799370b324cSopenharmony_ci WriteBytes(db.SecureBuf, db.SecureBuf.Size()); 800370b324cSopenharmony_ci for (i = 0; i < db.SecureIDs.Size(); i++) 801370b324cSopenharmony_ci { 802370b324cSopenharmony_ci WriteNumber(db.SecureIDs[i]); 803370b324cSopenharmony_ci // WriteUInt32(db.SecureIDs[i]); 804370b324cSopenharmony_ci } 805370b324cSopenharmony_ci } 806370b324cSopenharmony_ci */ 807370b324cSopenharmony_ci 808370b324cSopenharmony_ci WriteByte(NID::kEnd); // for files 809370b324cSopenharmony_ci WriteByte(NID::kEnd); // for headers 810370b324cSopenharmony_ci} 811370b324cSopenharmony_ci 812370b324cSopenharmony_ciHRESULT COutArchive::WriteDatabase( 813370b324cSopenharmony_ci DECL_EXTERNAL_CODECS_LOC_VARS 814370b324cSopenharmony_ci const CArchiveDatabaseOut &db, 815370b324cSopenharmony_ci const CCompressionMethodMode *options, 816370b324cSopenharmony_ci const CHeaderOptions &headerOptions) 817370b324cSopenharmony_ci{ 818370b324cSopenharmony_ci if (!db.CheckNumFiles()) 819370b324cSopenharmony_ci return E_FAIL; 820370b324cSopenharmony_ci 821370b324cSopenharmony_ci UInt64 headerOffset; 822370b324cSopenharmony_ci UInt32 headerCRC; 823370b324cSopenharmony_ci UInt64 headerSize; 824370b324cSopenharmony_ci if (db.IsEmpty()) 825370b324cSopenharmony_ci { 826370b324cSopenharmony_ci headerSize = 0; 827370b324cSopenharmony_ci headerOffset = 0; 828370b324cSopenharmony_ci headerCRC = CrcCalc(NULL, 0); 829370b324cSopenharmony_ci } 830370b324cSopenharmony_ci else 831370b324cSopenharmony_ci { 832370b324cSopenharmony_ci bool encodeHeaders = false; 833370b324cSopenharmony_ci if (options) 834370b324cSopenharmony_ci if (options->IsEmpty()) 835370b324cSopenharmony_ci options = NULL; 836370b324cSopenharmony_ci if (options) 837370b324cSopenharmony_ci if (options->PasswordIsDefined || headerOptions.CompressMainHeader) 838370b324cSopenharmony_ci encodeHeaders = true; 839370b324cSopenharmony_ci 840370b324cSopenharmony_ci _outByte.SetStream(SeqStream); 841370b324cSopenharmony_ci _outByte.Init(); 842370b324cSopenharmony_ci _crc = CRC_INIT_VAL; 843370b324cSopenharmony_ci _countMode = encodeHeaders; 844370b324cSopenharmony_ci _writeToStream = true; 845370b324cSopenharmony_ci _countSize = 0; 846370b324cSopenharmony_ci WriteHeader(db, /* headerOptions, */ headerOffset); 847370b324cSopenharmony_ci 848370b324cSopenharmony_ci if (encodeHeaders) 849370b324cSopenharmony_ci { 850370b324cSopenharmony_ci CByteBuffer buf(_countSize); 851370b324cSopenharmony_ci _outByte2.Init((Byte *)buf, _countSize); 852370b324cSopenharmony_ci 853370b324cSopenharmony_ci _countMode = false; 854370b324cSopenharmony_ci _writeToStream = false; 855370b324cSopenharmony_ci WriteHeader(db, /* headerOptions, */ headerOffset); 856370b324cSopenharmony_ci 857370b324cSopenharmony_ci if (_countSize != _outByte2.GetPos()) 858370b324cSopenharmony_ci return E_FAIL; 859370b324cSopenharmony_ci 860370b324cSopenharmony_ci CCompressionMethodMode encryptOptions; 861370b324cSopenharmony_ci encryptOptions.PasswordIsDefined = options->PasswordIsDefined; 862370b324cSopenharmony_ci encryptOptions.Password = options->Password; 863370b324cSopenharmony_ci CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions); 864370b324cSopenharmony_ci CRecordVector<UInt64> packSizes; 865370b324cSopenharmony_ci CObjectVector<CFolder> folders; 866370b324cSopenharmony_ci COutFolders outFolders; 867370b324cSopenharmony_ci 868370b324cSopenharmony_ci RINOK(EncodeStream( 869370b324cSopenharmony_ci EXTERNAL_CODECS_LOC_VARS 870370b324cSopenharmony_ci encoder, buf, 871370b324cSopenharmony_ci packSizes, folders, outFolders)) 872370b324cSopenharmony_ci 873370b324cSopenharmony_ci _writeToStream = true; 874370b324cSopenharmony_ci 875370b324cSopenharmony_ci if (folders.Size() == 0) 876370b324cSopenharmony_ci throw 1; 877370b324cSopenharmony_ci 878370b324cSopenharmony_ci WriteID(NID::kEncodedHeader); 879370b324cSopenharmony_ci WritePackInfo(headerOffset, packSizes, CUInt32DefVector()); 880370b324cSopenharmony_ci WriteUnpackInfo(folders, outFolders); 881370b324cSopenharmony_ci WriteByte(NID::kEnd); 882370b324cSopenharmony_ci FOR_VECTOR (i, packSizes) 883370b324cSopenharmony_ci headerOffset += packSizes[i]; 884370b324cSopenharmony_ci } 885370b324cSopenharmony_ci RINOK(_outByte.Flush()) 886370b324cSopenharmony_ci headerCRC = CRC_GET_DIGEST(_crc); 887370b324cSopenharmony_ci headerSize = _outByte.GetProcessedSize(); 888370b324cSopenharmony_ci } 889370b324cSopenharmony_ci #ifdef Z7_7Z_VOL 890370b324cSopenharmony_ci if (_endMarker) 891370b324cSopenharmony_ci { 892370b324cSopenharmony_ci CFinishHeader h; 893370b324cSopenharmony_ci h.NextHeaderSize = headerSize; 894370b324cSopenharmony_ci h.NextHeaderCRC = headerCRC; 895370b324cSopenharmony_ci h.NextHeaderOffset = 896370b324cSopenharmony_ci UInt64(0) - (headerSize + 897370b324cSopenharmony_ci 4 + kFinishHeaderSize); 898370b324cSopenharmony_ci h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset; 899370b324cSopenharmony_ci h.AdditionalStartBlockSize = 0; 900370b324cSopenharmony_ci RINOK(WriteFinishHeader(h)); 901370b324cSopenharmony_ci return WriteFinishSignature(); 902370b324cSopenharmony_ci } 903370b324cSopenharmony_ci else 904370b324cSopenharmony_ci #endif 905370b324cSopenharmony_ci if (Stream) 906370b324cSopenharmony_ci { 907370b324cSopenharmony_ci CStartHeader h; 908370b324cSopenharmony_ci h.NextHeaderSize = headerSize; 909370b324cSopenharmony_ci h.NextHeaderCRC = headerCRC; 910370b324cSopenharmony_ci h.NextHeaderOffset = headerOffset; 911370b324cSopenharmony_ci RINOK(Stream->Seek((Int64)_signatureHeaderPos, STREAM_SEEK_SET, NULL)) 912370b324cSopenharmony_ci return WriteStartHeader(h); 913370b324cSopenharmony_ci } 914370b324cSopenharmony_ci return S_OK; 915370b324cSopenharmony_ci} 916370b324cSopenharmony_ci 917370b324cSopenharmony_civoid CUInt32DefVector::SetItem(unsigned index, bool defined, UInt32 value) 918370b324cSopenharmony_ci{ 919370b324cSopenharmony_ci while (index >= Defs.Size()) 920370b324cSopenharmony_ci Defs.Add(false); 921370b324cSopenharmony_ci Defs[index] = defined; 922370b324cSopenharmony_ci if (!defined) 923370b324cSopenharmony_ci return; 924370b324cSopenharmony_ci while (index >= Vals.Size()) 925370b324cSopenharmony_ci Vals.Add(0); 926370b324cSopenharmony_ci Vals[index] = value; 927370b324cSopenharmony_ci} 928370b324cSopenharmony_ci 929370b324cSopenharmony_civoid CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value) 930370b324cSopenharmony_ci{ 931370b324cSopenharmony_ci while (index >= Defs.Size()) 932370b324cSopenharmony_ci Defs.Add(false); 933370b324cSopenharmony_ci Defs[index] = defined; 934370b324cSopenharmony_ci if (!defined) 935370b324cSopenharmony_ci return; 936370b324cSopenharmony_ci while (index >= Vals.Size()) 937370b324cSopenharmony_ci Vals.Add(0); 938370b324cSopenharmony_ci Vals[index] = value; 939370b324cSopenharmony_ci} 940370b324cSopenharmony_ci 941370b324cSopenharmony_civoid CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name) 942370b324cSopenharmony_ci{ 943370b324cSopenharmony_ci unsigned index = Files.Size(); 944370b324cSopenharmony_ci CTime.SetItem(index, file2.CTimeDefined, file2.CTime); 945370b324cSopenharmony_ci ATime.SetItem(index, file2.ATimeDefined, file2.ATime); 946370b324cSopenharmony_ci MTime.SetItem(index, file2.MTimeDefined, file2.MTime); 947370b324cSopenharmony_ci StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos); 948370b324cSopenharmony_ci Attrib.SetItem(index, file2.AttribDefined, file2.Attrib); 949370b324cSopenharmony_ci SetItem_Anti(index, file2.IsAnti); 950370b324cSopenharmony_ci // SetItem_Aux(index, file2.IsAux); 951370b324cSopenharmony_ci Names.Add(name); 952370b324cSopenharmony_ci Files.Add(file); 953370b324cSopenharmony_ci} 954370b324cSopenharmony_ci 955370b324cSopenharmony_ci}} 956