static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2) { size_t c1 = a1.GetCapacity(); size_t c2 = a2.GetCapacity(); RINOZ_COMP(c1, c2); for (size_t i = 0; i < c1; i++) RINOZ_COMP(a1[i], a2[i]); return 0; }
HRESULT OpenArchive(IInStream *inStream, const CHeader &h, CByteBuffer &xml, CDatabase &db) { RINOK(UnpackData(inStream, h.XmlResource, h.IsLzxMode(), xml, NULL)); RINOK(ReadStreams(inStream, h, db)); bool needBootMetadata = !h.MetadataResource.IsEmpty(); if (h.PartNumber == 1) { int imageIndex = 1; for (int j = 0; j < db.Streams.Size(); j++) { // if (imageIndex > 1) break; const CStreamInfo &si = db.Streams[j]; if (!si.Resource.IsMetadata() || si.PartNumber != h.PartNumber) continue; Byte hash[kHashSize]; CByteBuffer metadata; RINOK(UnpackData(inStream, si.Resource, h.IsLzxMode(), metadata, hash)); if (memcmp(hash, si.Hash, kHashSize) != 0) return S_FALSE; wchar_t sz[32]; ConvertUInt64ToString(imageIndex++, sz); UString s = sz; s += WCHAR_PATH_SEPARATOR; RINOK(ParseDir(metadata, metadata.GetCapacity(), s, db.Items)); if (needBootMetadata) if (h.MetadataResource.Offset == si.Resource.Offset) needBootMetadata = false; } } if (needBootMetadata) { CByteBuffer metadata; RINOK(UnpackData(inStream, h.MetadataResource, h.IsLzxMode(), metadata, NULL)); RINOK(ParseDir(metadata, metadata.GetCapacity(), L"0" WSTRING_PATH_SEPARATOR, db.Items)); } return S_OK; }
HRESULT ReadStreams(IInStream *inStream, const CHeader &h, CDatabase &db) { CByteBuffer offsetBuf; RINOK(UnpackData(inStream, h.OffsetResource, h.IsLzxMode(), offsetBuf, NULL)); for (size_t i = 0; i + kStreamInfoSize <= offsetBuf.GetCapacity(); i += kStreamInfoSize) { CStreamInfo s; GetStream((const Byte *)offsetBuf + i, s); if (s.PartNumber == h.PartNumber) db.Streams.Add(s); } return S_OK; }
void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment) { SeekTo(m_BasePosition); UInt64 cdOffset = GetCurrentPosition(); for(int i = 0; i < items.Size(); i++) WriteCentralHeader(items[i]); UInt64 cd64EndOffset = GetCurrentPosition(); UInt64 cdSize = cd64EndOffset - cdOffset; bool cdOffset64 = cdOffset >= 0xFFFFFFFF; bool cdSize64 = cdSize >= 0xFFFFFFFF; bool items64 = items.Size() >= 0xFFFF; bool isZip64 = (cdOffset64 || cdSize64 || items64); if (isZip64) { WriteUInt32(NSignature::kZip64EndOfCentralDir); WriteUInt64(kZip64EcdSize); // ThisDiskNumber = 0; WriteUInt16(45); // version WriteUInt16(45); // version WriteUInt32(0); // ThisDiskNumber = 0; WriteUInt32(0); // StartCentralDirectoryDiskNumber;; WriteUInt64((UInt64)items.Size()); WriteUInt64((UInt64)items.Size()); WriteUInt64((UInt64)cdSize); WriteUInt64((UInt64)cdOffset); WriteUInt32(NSignature::kZip64EndOfCentralDirLocator); WriteUInt32(0); // number of the disk with the start of the zip64 end of central directory WriteUInt64(cd64EndOffset); WriteUInt32(1); // total number of disks } WriteUInt32(NSignature::kEndOfCentralDir); WriteUInt16(0); // ThisDiskNumber = 0; WriteUInt16(0); // StartCentralDirectoryDiskNumber; WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size())); WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size())); WriteUInt32(cdSize64 ? 0xFFFFFFFF: (UInt32)cdSize); WriteUInt32(cdOffset64 ? 0xFFFFFFFF: (UInt32)cdOffset); UInt16 commentSize = (UInt16)comment.GetCapacity(); WriteUInt16(commentSize); if (commentSize > 0) WriteBytes((const Byte *)comment, commentSize); m_OutBuffer.FlushWithCheck(); }
static bool ReadStream(CMyComPtr<IInStream> & inStream, Int64 offset, UINT32 seekOrigin, CByteBuffer & signature) { UInt64 savedPosition = 0; UInt64 newPosition = 0; #if MY_VER_MAJOR >= 15 UInt32 readCount = signature.Size(); #else UInt32 readCount = signature.GetCapacity(); #endif unsigned char * buf = signature; if (S_OK != inStream->Seek(0, FILE_CURRENT, &savedPosition)) return false; if (S_OK != inStream->Seek(offset, seekOrigin, &newPosition)) { inStream->Seek(savedPosition, FILE_BEGIN, &newPosition); //restore pos return false; } while (readCount > 0) { UInt32 processedCount = 0; if (S_OK != inStream->Read(buf, readCount, &processedCount)) { inStream->Seek(savedPosition, FILE_BEGIN, &newPosition); //restore pos return false; } if (processedCount == 0) break; readCount -= processedCount; buf += processedCount; } inStream->Seek(savedPosition, FILE_BEGIN, &newPosition); //restore pos return readCount == 0; }
void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) { Set(archive, byteBuffer, byteBuffer.GetCapacity()); }
HRESULT COutArchive::WriteBytes(const CByteBuffer &data) { return WriteBytes(data, data.GetCapacity()); }