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

📄 gzipin.cpp

📁 7-Zip 3.11的源码
💻 CPP
字号:
// Archive/GZipIn.cpp

#include "StdAfx.h"

#include "GZipIn.h"

#include "Common/Defs.h"
#include "Common/MyCom.h"
#include "Windows/Defs.h"

namespace NArchive {
namespace NGZip {
 
HRESULT CInArchive::ReadBytes(IInStream *inStream, void *data, UINT32 size)
{
  UINT32 realProcessedSize;
  RINOK(inStream->Read(data, size, &realProcessedSize));
  m_Position += realProcessedSize;
  if(realProcessedSize != size)
    return S_FALSE;
  return S_OK;
}

HRESULT CInArchive::UpdateCRCBytes(IInStream *inStream, 
    UINT32 numBytesToSkeep, CCRC &crc)
{
  while (numBytesToSkeep > 0)
  {
    const UINT32 kBufferSize = (1 << 12);
    BYTE buffer[kBufferSize];
    UINT32 currentSize = MyMin(numBytesToSkeep, kBufferSize);
    RINOK(ReadBytes(inStream, buffer, currentSize));
    crc.Update(buffer, currentSize);
    numBytesToSkeep -= currentSize;
  }
  return S_OK;
}

HRESULT CInArchive::ReadZeroTerminatedString(IInStream *inStream, AString &resString)
{
  resString.Empty();
  while(true)
  {
    char c;
    RINOK(ReadBytes(inStream, &c, sizeof(c)));
    if (c == 0)
      return S_OK;
    resString += c;
  }
}

HRESULT CInArchive::ReadHeader(IInStream *inStream, CItemEx &item)
{
  RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition));

  m_Position = m_StreamStartPosition;
  NFileHeader::CBlock fileHeader;

  RINOK(ReadBytes(inStream, &fileHeader, sizeof(fileHeader)));

  if (fileHeader.Id != kSignature)
    return S_FALSE;

  item.CompressionMethod = fileHeader.CompressionMethod;
  item.Flags = fileHeader.Flags;
  item.Time = fileHeader.Time;
  item.ExtraFlags = fileHeader.ExtraFlags;
  item.HostOS = fileHeader.HostOS;

  CCRC crc;
  crc.Update(&fileHeader, sizeof(fileHeader));
  if (item.ExtraFieldIsPresent())
  {
    item.ExtraPosition = m_Position;
    RINOK(ReadBytes(inStream, &item.ExtraFieldSize, 
        sizeof(item.ExtraFieldSize)));
    crc.Update(&item.ExtraFieldSize, sizeof(item.ExtraFieldSize));
    RINOK(UpdateCRCBytes(inStream, item.ExtraFieldSize, crc));
  }
  item.Name.Empty();
  if (item.NameIsPresent())
    RINOK(ReadZeroTerminatedString(inStream, item.Name));
  AString comment;
  if (item.CommentIsPresent())
  {
    item.CommentPosition = m_Position;
    RINOK(ReadZeroTerminatedString(inStream, comment));
    item.CommentSize = comment.Length() + 1;
  }
  if (item.HeaderCRCIsPresent())
  {
    UINT16 headerCRC;
    RINOK(ReadBytes(inStream, &headerCRC, sizeof(headerCRC)));
    if (item.NameIsPresent())
    {
      crc.Update((const char *)item.Name, item.Name.Length());
      BYTE zeroByte = 0;;
      crc.Update(&zeroByte, sizeof(zeroByte));
    }
    if (item.CommentIsPresent())
    {
      crc.Update((const char *)comment, comment.Length());
      BYTE zeroByte = 0;;
      crc.Update(&zeroByte, sizeof(zeroByte));
    }
    if ((UINT16)crc.GetDigest() != headerCRC)
      return S_FALSE;
  }

  item.DataPosition = m_Position;

  item.UnPackSize32 = 0;
  item.PackSize = 0;

  /*
  UINT64 newPosition;
  RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition));
  item.PackSize = newPosition - item.DataPosition;

  RINOK(ReadBytes(inStream, &item.FileCRC, sizeof(item.FileCRC)));
  RINOK(ReadBytes(inStream, &item.UnPackSize32, sizeof(item.UnPackSize32)));
  */
  return S_OK;
}

HRESULT CInArchive::ReadPostInfo(IInStream *inStream, UINT32 &crc, UINT32 &unpackSize32)
{
  RINOK(ReadBytes(inStream, &crc, sizeof(crc)));
  return ReadBytes(inStream, &unpackSize32, sizeof(unpackSize32));
}

}}

⌨️ 快捷键说明

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