summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/unix/CPP/7zip/Archive/Com/ComIn.h
blob: 429d3796ea53acc0554583f45faad92f96f10a79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Archive/ComIn.h

#ifndef __ARCHIVE_COM_IN_H
#define __ARCHIVE_COM_IN_H

#include "Common/MyString.h"
#include "Common/Buffer.h"

namespace NArchive {
namespace NCom {

struct CUInt32Buf
{
  UInt32 *_buf;
public:
  CUInt32Buf(): _buf(0) {}
  ~CUInt32Buf() { Free(); }
  void Free();
  bool Allocate(UInt32 numItems);
  operator UInt32 *() const { return _buf; };
};

namespace NFatID
{
  const UInt32 kFree       = 0xFFFFFFFF;
  const UInt32 kEndOfChain = 0xFFFFFFFE;
  const UInt32 kFatSector  = 0xFFFFFFFD;
  const UInt32 kMatSector  = 0xFFFFFFFC;
  const UInt32 kMaxValue   = 0xFFFFFFFA;
}

namespace NItemType
{
  const Byte kEmpty = 0;
  const Byte kStorage = 1;
  const Byte kStream = 2;
  const Byte kLockBytes = 3;
  const Byte kProperty = 4;
  const Byte kRootStorage = 5;
}

const UInt32 kNameSizeMax = 64;

struct CItem
{
  Byte Name[kNameSizeMax];
  // UInt16 NameSize;
  // UInt32 Flags;
  FILETIME CTime;
  FILETIME MTime;
  UInt64 Size;
  UInt32 LeftDid;
  UInt32 RightDid;
  UInt32 SonDid;
  UInt32 Sid;
  Byte Type;

  bool IsEmpty() const { return Type == NItemType::kEmpty; }
  bool IsDir() const { return Type == NItemType::kStorage || Type == NItemType::kRootStorage; }

  void Parse(const Byte *p, bool mode64bit);
};

struct CRef
{
  int Parent;
  UInt32 Did;
};

class CDatabase
{
  UInt32 NumSectorsInMiniStream;
  CUInt32Buf MiniSids;

  HRESULT AddNode(int parent, UInt32 did);
public:

  CUInt32Buf Fat;
  UInt32 FatSize;
  
  CUInt32Buf Mat;
  UInt32 MatSize;

  CObjectVector<CItem> Items;
  CRecordVector<CRef> Refs;

  UInt32 LongStreamMinSize;
  int SectorSizeBits;
  int MiniSectorSizeBits;

  Int32 MainSubfile;

  void Clear();
  bool IsLargeStream(UInt64 size) const { return size >= LongStreamMinSize; }
  UString GetItemPath(UInt32 index) const;

  UInt64 GetItemPackSize(UInt64 size) const
  {
    UInt64 mask = ((UInt64)1 << (IsLargeStream(size) ? SectorSizeBits : MiniSectorSizeBits)) - 1;
    return (size + mask) & ~mask;
  }

  bool GetMiniCluster(UInt32 sid, UInt64 &res) const
  {
    int subBits = SectorSizeBits - MiniSectorSizeBits;
    UInt32 fid = sid >> subBits;
    if (fid >= NumSectorsInMiniStream)
      return false;
    res = (((UInt64)MiniSids[fid] + 1) << subBits) + (sid & ((1 << subBits) - 1));
    return true;
  }

  HRESULT Open(IInStream *inStream);
};


}}
  
#endif