⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zipin.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Archive/ZipIn.cpp#include "StdAfx.h"#include "ZipIn.h"#include "Windows/Defs.h"#include "Common/StringConvert.h"#include "Common/DynamicBuffer.h"#include "../../Common/LimitedStreams.h"#include "../../Common/StreamUtils.h"namespace NArchive {namespace NZip { // static const char kEndOfString = '\0';  bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit){  m_Stream = inStream;  if(m_Stream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK)    return false;  m_Position = m_StreamStartPosition;  return FindAndReadMarker(searchHeaderSizeLimit);}void CInArchive::Close(){  m_Stream.Release();}//////////////////////////////////////// Markersstatic inline bool TestMarkerCandidate(const Byte *p, UInt32 &value){  value = p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);  return (value == NSignature::kLocalFileHeader) ||    (value == NSignature::kEndOfCentralDir);}bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit){  m_ArchiveInfo.Clear();  m_ArchiveInfo.StartPosition = 0;  m_Position = m_StreamStartPosition;  if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)    return false;  Byte marker[NSignature::kMarkerSize];  UInt32 processedSize;   ReadBytes(marker, NSignature::kMarkerSize, &processedSize);  if(processedSize != NSignature::kMarkerSize)    return false;  if (TestMarkerCandidate(marker, m_Signature))    return true;  CByteDynamicBuffer dynamicBuffer;  static const UInt32 kSearchMarkerBufferSize = 0x10000;  dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize);  Byte *buffer = dynamicBuffer;  UInt32 numBytesPrev = NSignature::kMarkerSize - 1;  memmove(buffer, marker + 1, numBytesPrev);  UInt64 curTestPos = m_StreamStartPosition + 1;  while(true)  {    if (searchHeaderSizeLimit != NULL)      if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit)        return false;    UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;    ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);    UInt32 numBytesInBuffer = numBytesPrev + processedSize;    if (numBytesInBuffer < NSignature::kMarkerSize)      return false;    UInt32 numTests = numBytesInBuffer - NSignature::kMarkerSize + 1;    for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)    {       if (TestMarkerCandidate(buffer + pos, m_Signature))      {        m_ArchiveInfo.StartPosition = curTestPos;        m_Position = curTestPos + NSignature::kMarkerSize;        if(m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL) != S_OK)          return false;        return true;      }    }    numBytesPrev = numBytesInBuffer - numTests;    memmove(buffer, buffer + numTests, numBytesPrev);  }}HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize){  UInt32 realProcessedSize;  HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize);  if(processedSize != NULL)    *processedSize = realProcessedSize;  m_Position += realProcessedSize;  return result;}void CInArchive::IncreaseRealPosition(UInt64 addValue){  if(m_Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position) != S_OK)    throw CInArchiveException(CInArchiveException::kSeekStreamError);}bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size){  UInt32 realProcessedSize;  if(ReadBytes(data, size, &realProcessedSize) != S_OK)    throw CInArchiveException(CInArchiveException::kReadStreamError);  return (realProcessedSize == size);}void CInArchive::SafeReadBytes(void *data, UInt32 size){  if(!ReadBytesAndTestSize(data, size))    throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);}void CInArchive::ReadBuffer(CByteBuffer &buffer, UInt32 size){  buffer.SetCapacity(size);  if (size > 0)    SafeReadBytes(buffer, size);}Byte CInArchive::ReadByte(){  Byte b;  SafeReadBytes(&b, 1);  return b;}UInt16 CInArchive::ReadUInt16(){  UInt16 value = 0;  for (int i = 0; i < 2; i++)    value |= (((UInt16)ReadByte()) << (8 * i));  return value;}UInt32 CInArchive::ReadUInt32(){  UInt32 value = 0;  for (int i = 0; i < 4; i++)    value |= (((UInt32)ReadByte()) << (8 * i));  return value;}UInt64 CInArchive::ReadUInt64(){  UInt64 value = 0;  for (int i = 0; i < 8; i++)    value |= (((UInt64)ReadByte()) << (8 * i));  return value;}bool CInArchive::ReadUInt32(UInt32 &value){  value = 0;  for (int i = 0; i < 4; i++)  {    Byte b;    if (!ReadBytesAndTestSize(&b, 1))      return false;    value |= (UInt32(b) << (8 * i));  }  return true;}AString CInArchive::ReadFileName(UInt32 nameSize){  if (nameSize == 0)    return AString();  SafeReadBytes(m_NameBuffer.GetBuffer(nameSize), nameSize);  m_NameBuffer.ReleaseBuffer(nameSize);  return m_NameBuffer;}void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const{  archiveInfo = m_ArchiveInfo;}void CInArchive::ThrowIncorrectArchiveException(){  throw CInArchiveException(CInArchiveException::kIncorrectArchive);}static UInt32 GetUInt32(const Byte *data){  return       ((UInt32)(Byte)data[0]) |      (((UInt32)(Byte)data[1]) << 8) |      (((UInt32)(Byte)data[2]) << 16) |      (((UInt32)(Byte)data[3]) << 24);}void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock,     UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber){  extraBlock.Clear();  UInt32 remain = extraSize;  while(remain >= 4)  {    CExtraSubBlock subBlock;    subBlock.ID = ReadUInt16();    UInt32 dataSize = ReadUInt16();    remain -= 4;    if (dataSize > remain) // it's bug      dataSize = remain;    if (subBlock.ID == 0x1)    {      if (unpackSize == 0xFFFFFFFF)      {        if (dataSize < 8)          break;        unpackSize = ReadUInt64();        remain -= 8;        dataSize -= 8;      }      if (packSize == 0xFFFFFFFF)      {        if (dataSize < 8)          break;        packSize = ReadUInt64();        remain -= 8;        dataSize -= 8;      }      if (localHeaderOffset == 0xFFFFFFFF)      {        if (dataSize < 8)          break;        localHeaderOffset = ReadUInt64();        remain -= 8;        dataSize -= 8;      }      if (diskStartNumber == 0xFFFF)      {        if (dataSize < 4)          break;        diskStartNumber = ReadUInt32();        remain -= 4;        dataSize -= 4;      }      for (UInt32 i = 0; i < dataSize; i++)        ReadByte();    }    else    {      ReadBuffer(subBlock.Data, dataSize);      extraBlock.SubBlocks.Add(subBlock);    }    remain -= dataSize;  }  IncreaseRealPosition(remain);}HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress){  // m_Signature must be kLocalFileHeaderSignature or  // kEndOfCentralDirSignature  // m_Position points to next byte after signature  items.Clear();  if (progress != 0)  {    UInt64 numItems = items.Size();    RINOK(progress->SetCompleted(&numItems));  }  while(m_Signature == NSignature::kLocalFileHeader)  {    // FSeek points to next byte after signature    // NFileHeader::CLocalBlock localHeader;    CItemEx item;    item.LocalHeaderPosition = m_Position - m_StreamStartPosition - 4; // points to signature;        // SafeReadBytes(&localHeader, sizeof(localHeader));    item.ExtractVersion.Version = ReadByte();    item.ExtractVersion.HostOS = ReadByte();    item.Flags = ReadUInt16() & NFileHeader::NFlags::kUsedBitsMask;     item.CompressionMethod = ReadUInt16();    item.Time =  ReadUInt32();    item.FileCRC = ReadUInt32();    item.PackSize = ReadUInt32();    item.UnPackSize = ReadUInt32();    UInt32 fileNameSize = ReadUInt16();    item.LocalExtraSize = ReadUInt16();    item.Name = ReadFileName(fileNameSize);    /*    if (!NItemName::IsNameLegal(item.Name))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -