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

📄 tarin.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
字号:
// Archive/TarIn.cpp#include "StdAfx.h"#include "TarIn.h"#include "TarHeader.h"#include "Common/StringToInt.h"#include "Windows/Defs.h"#include "../../Common/StreamUtils.h"namespace NArchive {namespace NTar { HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize){  RINOK(ReadStream(m_Stream, data, size, &processedSize));  m_Position += processedSize;  return S_OK;}HRESULT CInArchive::Open(IInStream *inStream){  RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));  m_Stream = inStream;  return S_OK;}static bool OctalToNumber(const char *srcString, int size, UInt64 &res){  char sz[32];  strncpy(sz, srcString, size);  sz[size] = 0;  const char *end;  int i;  for (i = 0; sz[i] == ' '; i++);  res = ConvertOctStringToUInt64(sz + i, &end);  return (*end == ' ' || *end == 0);}static bool OctalToNumber32(const char *srcString, int size, UInt32 &res){  UInt64 res64;  if (!OctalToNumber(srcString, size, res64))    return false;  res = (UInt32)res64;  return (res64 <= 0xFFFFFFFF);}#define RIF(x) { if (!(x)) return S_FALSE; }static bool IsRecordLast(const char *record){  for (int i = 0; i < NFileHeader::kRecordSize; i++)    if (record[i] != 0)      return false;  return true;}static void ReadString(const char *s, int size, AString &result){  if (size > NFileHeader::kRecordSize)    size = NFileHeader::kNameSize;  char tempString[NFileHeader::kRecordSize + 1];  strncpy(tempString, s, size);  tempString[size] = '\0';  result = tempString;}static char GetHex(Byte value){  return (value < 10) ? ('0' + value) : ('A' + (value - 10));}HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item){  item.LongLinkSize = 0;  // NFileHeader::CRecord record;  char record[NFileHeader::kRecordSize];  char *cur = record;  filled = false;  UInt32 processedSize;  item.HeaderPosition = m_Position;  RINOK(ReadBytes(record, NFileHeader::kRecordSize, processedSize));  if (processedSize == 0 ||       (processedSize == NFileHeader::kRecordSize && IsRecordLast(record)))    return S_OK;  if (processedSize < NFileHeader::kRecordSize)    return S_FALSE;    // NFileHeader::CHeader &header = record.Header;    AString name;  ReadString(cur, NFileHeader::kNameSize, name);  cur += NFileHeader::kNameSize;  item.Name.Empty();  int i;  for (i = 0; i < name.Length(); i++)  {    char c = name[i];    if (((Byte)c) < 0x08)    {      return S_FALSE;    }    if (((Byte)c) < 0x20)    {      item.Name += '[';      item.Name += GetHex(((Byte)c) >> 4);      item.Name += GetHex(((Byte)c) & 0xF);      item.Name += ']';    }    else      item.Name += c;  }  RIF(OctalToNumber32(cur, 8, item.Mode));  cur += 8;  if (!OctalToNumber32(cur, 8, item.UID))    item.UID = 0;  cur += 8;  if (!OctalToNumber32(cur, 8, item.GID))    item.GID = 0;  cur += 8;  RIF(OctalToNumber(cur, 12, item.Size));  cur += 12;  RIF(OctalToNumber32(cur, 12, item.ModificationTime));  cur += 12;    UInt32 checkSum;  RIF(OctalToNumber32(cur, 8, checkSum));  memmove(cur, NFileHeader::kCheckSumBlanks, 8);  cur += 8;  item.LinkFlag = *cur++;  ReadString(cur, NFileHeader::kNameSize, item.LinkName);  cur += NFileHeader::kNameSize;  memmove(item.Magic, cur, 8);  cur += 8;  ReadString(cur, NFileHeader::kUserNameSize, item.UserName);  cur += NFileHeader::kUserNameSize;  ReadString(cur, NFileHeader::kUserNameSize, item.GroupName);  cur += NFileHeader::kUserNameSize;  item.DeviceMajorDefined = (cur[0] != 0);  RIF(OctalToNumber32(cur, 8, item.DeviceMajor));  cur += 8;   item.DeviceMinorDefined = (cur[0] != 0);  RIF(OctalToNumber32(cur, 8, item.DeviceMinor));  cur += 8;  AString prefix;  ReadString(cur, NFileHeader::kPrefixSize, prefix);  cur += NFileHeader::kPrefixSize;  if (!prefix.IsEmpty() && item.IsMagic())    item.Name = prefix + AString('/') + item.Name;  if (item.LinkFlag == NFileHeader::NLinkFlag::kLink)    item.Size = 0;     UInt32 checkSumReal = 0;  for(i = 0; i < NFileHeader::kRecordSize; i++)    checkSumReal += Byte(record[i]);    if (checkSumReal != checkSum)    return S_FALSE;  filled = true;  return S_OK;}HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item){  RINOK(GetNextItemReal(filled, item));  if (!filled)    return S_OK;  // GNUtar extension  if (item.LinkFlag == 'L')  {    if (item.Name.Compare(NFileHeader::kLongLink) != 0)      return S_FALSE;    UInt64 headerPosition = item.HeaderPosition;    UInt32 processedSize;    AString fullName;    char *buffer = fullName.GetBuffer((UInt32)item.Size + 1);    RINOK(ReadBytes(buffer, (UInt32)item.Size, processedSize));    buffer[item.Size] = '\0';    fullName.ReleaseBuffer();    if (processedSize != item.Size)      return S_FALSE;    RINOK(Skeep((0 - item.Size) & 0x1FF));    RINOK(GetNextItemReal(filled, item));    item.Name = fullName;    item.LongLinkSize = item.HeaderPosition - headerPosition;    item.HeaderPosition = headerPosition;  }  else if (item.LinkFlag == 'g' || item.LinkFlag == 'x')  {    // pax Extended Header    return S_OK;  }  else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0))    return S_FALSE;  return S_OK;}HRESULT CInArchive::Skeep(UInt64 numBytes){  UInt64 newPostion;  RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));  m_Position += numBytes;  if (m_Position != newPostion)    return E_FAIL;  return S_OK;}HRESULT CInArchive::SkeepDataRecords(UInt64 dataSize){  return Skeep((dataSize + 0x1FF) & (~((UInt64)0x1FF)));}}}

⌨️ 快捷键说明

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