Welcome to mirror list, hosted at ThFree Co, Russian Federation.

CabIn.h « Cab « Archive « 7zip « CPP - github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: baeeb7b2d2eba9b8d9a4ed7929364a9551ef9daa (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
162
163
164
165
166
167
168
169
170
171
// Archive/CabIn.h

#ifndef __ARCHIVE_CAB_IN_H
#define __ARCHIVE_CAB_IN_H

#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyCom.h"

#include "../../Common/InBuffer.h"

#include "CabItem.h"

namespace NArchive {
namespace NCab {

struct COtherArc
{
  AString FileName;
  AString DiskName;
  
  void Clear()
  {
    FileName.Empty();
    DiskName.Empty();
  }
};

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

  UInt16 PerCabinet_AreaSize; // (optional) size of per-cabinet reserved area
  Byte PerFolder_AreaSize;    // (optional) size of per-folder reserved area
  Byte PerDataBlock_AreaSize; // (optional) size of per-datablock reserved area

  COtherArc PrevArc; // prev link can skip some volumes !!!
  COtherArc NextArc;

  bool ReserveBlockPresent() const { return (Flags & NHeader::NArcFlags::kReservePresent) != 0; }
  bool IsTherePrev() const { return (Flags & NHeader::NArcFlags::kPrevCabinet) != 0; }
  bool IsThereNext() const { return (Flags & NHeader::NArcFlags::kNextCabinet) != 0; }
  Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlock_AreaSize : 0); }

  CArchInfo()
  {
    PerCabinet_AreaSize = 0;
    PerFolder_AreaSize = 0;
    PerDataBlock_AreaSize = 0;
  }

  void Clear()
  {
    PerCabinet_AreaSize = 0;
    PerFolder_AreaSize = 0;
    PerDataBlock_AreaSize = 0;

    PrevArc.Clear();
    NextArc.Clear();
  }
};

struct CInArcInfo: public CArchInfo
{
  UInt32 Size; // size of this cabinet file in bytes
  UInt32 FileHeadersOffset; // offset of the first CFFILE entry

  bool Parse(const Byte *p);
};


struct CDatabase
{
  CRecordVector<CFolder> Folders;
  CObjectVector<CItem> Items;
  UInt64 StartPosition;
  CInArcInfo ArcInfo;
  
  void Clear()
  {
    ArcInfo.Clear();
    Folders.Clear();
    Items.Clear();
  }
  
  bool IsTherePrevFolder() const
  {
    FOR_VECTOR (i, Items)
      if (Items[i].ContinuedFromPrev())
        return true;
    return false;
  }
  
  int GetNumberOfNewFolders() const
  {
    int res = Folders.Size();
    if (IsTherePrevFolder())
      res--;
    return res;
  }
};

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

struct CMvItem
{
  unsigned VolumeIndex;
  unsigned ItemIndex;
};

class CMvDatabaseEx
{
  bool AreItemsEqual(unsigned i1, unsigned i2);

public:
  CObjectVector<CDatabaseEx> Volumes;
  CRecordVector<CMvItem> Items;
  CRecordVector<int> StartFolderOfVol; // can be negative
  CRecordVector<unsigned> 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
{
  CInBufferBase _inBuffer;
  CByteBuffer _tempBuf;

  void Skip(unsigned size);
  void Read(Byte *data, unsigned size);
  void ReadName(AString &s);
  void ReadOtherArc(COtherArc &oa);
  HRESULT Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit);

public:
  bool IsArc;
  bool ErrorInNames;
  bool UnexpectedEnd;
  bool HeaderError;

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