misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zItem.h
author nemo
Mon, 10 Apr 2017 12:06:43 -0400
changeset 12213 bb5522e88ab2
permissions -rw-r--r--
bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash

// 7zItem.h

#ifndef __7Z_ITEM_H
#define __7Z_ITEM_H

#include "../../../Common/Buffer.h"
#include "../../../Common/MyString.h"
#include "../../Common/MethodId.h"
#include "7zHeader.h"

namespace NArchive {
namespace N7z {

typedef UInt32 CNum;
const CNum kNumMax     = 0x7FFFFFFF;
const CNum kNumNoIndex = 0xFFFFFFFF;

struct CCoderInfo
{
  CMethodId MethodID;
  CByteBuffer Properties;
  CNum NumInStreams;
  CNum NumOutStreams;
  bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
};

struct CBindPair
{
  CNum InIndex;
  CNum OutIndex;
};

struct CFolder
{
  CObjectVector<CCoderInfo> Coders;
  CRecordVector<CBindPair> BindPairs;
  CRecordVector<CNum> PackStreams;
  CRecordVector<UInt64> UnPackSizes;
  UInt32 UnPackCRC;
  bool UnPackCRCDefined;

  CFolder(): UnPackCRCDefined(false) {}

  UInt64 GetUnPackSize() const // test it
  { 
    if (UnPackSizes.IsEmpty())
      return 0;
    for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
      if (FindBindPairForOutStream(i) < 0)
        return UnPackSizes[i];
    throw 1;
  }

  CNum GetNumOutStreams() const
  {
    CNum result = 0;
    for (int i = 0; i < Coders.Size(); i++)
      result += Coders[i].NumOutStreams;
    return result;
  }

  int FindBindPairForInStream(CNum inStreamIndex) const
  {
    for(int i = 0; i < BindPairs.Size(); i++)
      if (BindPairs[i].InIndex == inStreamIndex)
        return i;
    return -1;
  }
  int FindBindPairForOutStream(CNum outStreamIndex) const
  {
    for(int i = 0; i < BindPairs.Size(); i++)
      if (BindPairs[i].OutIndex == outStreamIndex)
        return i;
    return -1;
  }
  int FindPackStreamArrayIndex(CNum inStreamIndex) const
  {
    for(int i = 0; i < PackStreams.Size(); i++)
      if (PackStreams[i] == inStreamIndex)
        return i;
    return -1;
  }
};

typedef FILETIME CArchiveFileTime;

class CFileItem
{
public:
  CArchiveFileTime CreationTime;
  CArchiveFileTime LastWriteTime;
  CArchiveFileTime LastAccessTime;
  UInt64 UnPackSize;
  UInt64 StartPos;
  UInt32 Attributes;
  UInt32 FileCRC;
  UString Name;

  bool HasStream; // Test it !!! it means that there is 
                  // stream in some folder. It can be empty stream
  bool IsDirectory;
  bool IsAnti;
  bool IsFileCRCDefined;
  bool AreAttributesDefined;
  bool IsCreationTimeDefined;
  bool IsLastWriteTimeDefined;
  bool IsLastAccessTimeDefined;
  bool IsStartPosDefined;

  /*
  const bool HasStream() const { 
      return !IsDirectory && !IsAnti && UnPackSize != 0; }
  */
  CFileItem(): 
    HasStream(true),
    IsDirectory(false),
    IsAnti(false),
    IsFileCRCDefined(false),
    AreAttributesDefined(false), 
    IsCreationTimeDefined(false), 
    IsLastWriteTimeDefined(false), 
    IsLastAccessTimeDefined(false),
    IsStartPosDefined(false)
      {}
  void SetAttributes(UInt32 attributes) 
  { 
    AreAttributesDefined = true;
    Attributes = attributes;
  }
  void SetCreationTime(const CArchiveFileTime &creationTime) 
  { 
    IsCreationTimeDefined = true;
    CreationTime = creationTime;
  }
  void SetLastWriteTime(const CArchiveFileTime &lastWriteTime) 
  {
    IsLastWriteTimeDefined = true;
    LastWriteTime = lastWriteTime;
  }
  void SetLastAccessTime(const CArchiveFileTime &lastAccessTime) 
  { 
    IsLastAccessTimeDefined = true;
    LastAccessTime = lastAccessTime;
  }
};

struct CArchiveDatabase
{
  CRecordVector<UInt64> PackSizes;
  CRecordVector<bool> PackCRCsDefined;
  CRecordVector<UInt32> PackCRCs;
  CObjectVector<CFolder> Folders;
  CRecordVector<CNum> NumUnPackStreamsVector;
  CObjectVector<CFileItem> Files;
  void Clear()
  {
    PackSizes.Clear();
    PackCRCsDefined.Clear();
    PackCRCs.Clear();
    Folders.Clear();
    NumUnPackStreamsVector.Clear();
    Files.Clear();
  }
  bool IsEmpty() const
  {
    return (PackSizes.IsEmpty() && 
      PackCRCsDefined.IsEmpty() && 
      PackCRCs.IsEmpty() && 
      Folders.IsEmpty() && 
      NumUnPackStreamsVector.IsEmpty() && 
      Files.IsEmpty());
  }
  bool IsSolid() const
  {
    for (int i = 0; i < NumUnPackStreamsVector.Size(); i++)
      if (NumUnPackStreamsVector[i] > 1)
        return true;
    return false;
  }
};

}}

#endif