summaryrefslogtreecommitdiffstats
path: root/installerbuilder/libinstaller/3rdparty/7zip/unix/CPP/7zip/Archive/Cab/CabIn.h
blob: 1e9b188b561310d3e49da02da56504e3efba12dd (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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Archive/CabIn.h

#ifndef __ARCHIVE_CAB_IN_H
#define __ARCHIVE_CAB_IN_H

#include "../../IStream.h"
#include "../../Common/InBuffer.h"
#include "CabHeader.h"
#include "CabItem.h"

namespace NArchive {
namespace NCab {

class CInArchiveException
{
public:
  enum CCauseType
  {
    kUnexpectedEndOfArchive = 0,
    kIncorrectArchive,
    kUnsupported
  } Cause;
  CInArchiveException(CCauseType cause) : Cause(cause) {}
};

struct COtherArchive
{
  AString FileName;
  AString DiskName;
};

struct CArchiveInfo
{
  Byte VersionMinor; /* cabinet file format version, minor */
  Byte VersionMajor; /* cabinet file format version, major */
  UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */
  UInt16 NumFiles;   /* number of CFFILE entries in this cabinet */
  UInt16 Flags;      /* cabinet file option indicators */
  UInt16 SetID;      /* must be the same for all cabinets in a set */
  UInt16 CabinetNumber; /* number of this cabinet file in a set */

  bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; }

  bool IsTherePrev() const { return (Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0; }
  bool IsThereNext() const { return (Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0; }

  UInt16 PerCabinetAreaSize; // (optional) size of per-cabinet reserved area
  Byte PerFolderAreaSize;    // (optional) size of per-folder reserved area
  Byte PerDataBlockAreaSize; // (optional) size of per-datablock reserved area

  Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlockAreaSize : 0); }

  COtherArchive PrevArc;
  COtherArchive NextArc;

  CArchiveInfo()
  {
    Clear();
  }

  void Clear()
  {
    PerCabinetAreaSize = 0;
    PerFolderAreaSize = 0;
    PerDataBlockAreaSize = 0;
  }
};

struct CInArchiveInfo: public CArchiveInfo
{
  UInt32 Size; /* size of this cabinet file in bytes */
  UInt32 FileHeadersOffset; // offset of the first CFFILE entry
};


struct CDatabase
{
  UInt64 StartPosition;
  CInArchiveInfo ArchiveInfo;
  CObjectVector<CFolder> Folders;
  CObjectVector<CItem> Items;
  
  void Clear()
  {
    ArchiveInfo.Clear();
    Folders.Clear();
    Items.Clear();
  }
  bool IsTherePrevFolder() const
  {
    for (int i = 0; i < Items.Size(); i++)
      if (Items[i].ContinuedFromPrev())
        return true;
    return false;
  }
  int GetNumberOfNewFolders() const
  {
    int res = Folders.Size();
    if (IsTherePrevFolder())
      res--;
    return res;
  }
  UInt32 GetFileOffset(int index) const { return Items[index].Offset; }
  UInt32 GetFileSize(int index) const { return Items[index].Size; }
};

struct CDatabaseEx: public CDatabase
{
  CMyComPtr<IInStream> Stream;
};

struct CMvItem
{
  int VolumeIndex;
  int ItemIndex;
};

class CMvDatabaseEx
{
  bool AreItemsEqual(int i1, int i2);
public:
  CObjectVector<CDatabaseEx> Volumes;
  CRecordVector<CMvItem> Items;
  CRecordVector<int> StartFolderOfVol;
  CRecordVector<int> FolderStartFileIndex;
  
  int GetFolderIndex(const CMvItem *mvi) const
  {
    const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
    return StartFolderOfVol[mvi->VolumeIndex] +
        db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size());
  }
  void Clear()
  {
    Volumes.Clear();
    Items.Clear();
    StartFolderOfVol.Clear();
    FolderStartFileIndex.Clear();
  }
  void FillSortAndShrink();
  bool Check();
};

class CInArchive
{
  CInBuffer inBuffer;

  Byte Read8();
  UInt16 Read16();
  UInt32 Read32();
  AString SafeReadName();
  void Skip(UInt32 size);
  void ReadOtherArchive(COtherArchive &oa);

public:
  HRESULT Open(const UInt64 *searchHeaderSizeLimit, CDatabaseEx &db);
};
  
}}
  
#endif