1 // RarHandler.h
2 
3 #ifndef __RAR_HANDLER_H
4 #define __RAR_HANDLER_H
5 
6 #include "../IArchive.h"
7 
8 #include "../../Common/CreateCoder.h"
9 
10 #include "RarItem.h"
11 
12 namespace NArchive {
13 namespace NRar {
14 
15 struct CInArcInfo
16 {
17   UInt32 Flags;
18   Byte EncryptVersion;
19 
20   UInt64 StartPos;
21   UInt64 EndPos;
22   UInt64 FileSize;
23 
24   UInt32 EndFlags;
25   UInt32 VolNumber;
26   UInt32 DataCRC;
27   bool EndOfArchive_was_Read;
28 
CInArcInfoCInArcInfo29   CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false) {}
30 
GetPhySizeCInArcInfo31   UInt64 GetPhySize() const { return EndPos - StartPos; }
32 
ExtraZeroTail_is_PossibleCInArcInfo33   bool ExtraZeroTail_is_Possible() const { return IsVolume() && IsRecovery() && EndOfArchive_was_Read; }
34 
IsVolumeCInArcInfo35   bool IsVolume()           const { return (Flags & NHeader::NArchive::kVolume) != 0; }
IsCommentedCInArcInfo36   bool IsCommented()        const { return (Flags & NHeader::NArchive::kComment) != 0; }
37   // kLock
IsSolidCInArcInfo38   bool IsSolid()            const { return (Flags & NHeader::NArchive::kSolid) != 0; }
HaveNewVolumeNameCInArcInfo39   bool HaveNewVolumeName()  const { return (Flags & NHeader::NArchive::kNewVolName) != 0; }
40   // kAuthenticity
IsRecoveryCInArcInfo41   bool IsRecovery()         const { return (Flags & NHeader::NArchive::kRecovery) != 0; }
IsEncryptedCInArcInfo42   bool IsEncrypted()        const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; }
IsFirstVolumeCInArcInfo43   bool IsFirstVolume()      const { return (Flags & NHeader::NArchive::kFirstVolume) != 0; }
44 
45   // bool IsThereEncryptVer()  const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; }
46   // bool IsEncryptOld()       const { return (!IsThereEncryptVer() || EncryptVersion < 36); }
47 
AreMoreVolumesCInArcInfo48   bool AreMoreVolumes()       const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_NextVol) != 0; }
Is_VolNumber_DefinedCInArcInfo49   bool Is_VolNumber_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) != 0; }
Is_DataCRC_DefinedCInArcInfo50   bool Is_DataCRC_Defined()   const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) != 0; }
51 };
52 
53 struct CArc
54 {
55   CMyComPtr<IInStream> Stream;
56   UInt64 PhySize;
57   // CByteBuffer Comment;
58 
CArcCArc59   CArc(): PhySize(0) {}
60   ISequentialInStream *CreateLimitedStream(UInt64 offset, UInt64 size) const;
61 };
62 
63 struct CRefItem
64 {
65   unsigned VolumeIndex;
66   unsigned ItemIndex;
67   unsigned NumItems;
68 };
69 
70 class CHandler:
71   public IInArchive,
72   PUBLIC_ISetCompressCodecsInfo
73   public CMyUnknownImp
74 {
75   CRecordVector<CRefItem> _refItems;
76   CObjectVector<CItem> _items;
77   CObjectVector<CArc> _arcs;
78   NArchive::NRar::CInArcInfo _arcInfo;
79   // AString _errorMessage;
80   UInt32 _errorFlags;
81   UInt32 _warningFlags;
82   bool _isArc;
83   UString _missingVolName;
84 
85   DECL_EXTERNAL_CODECS_VARS
86 
87   UInt64 GetPackSize(unsigned refIndex) const;
88   bool IsSolid(unsigned refIndex) const;
89 
90   /*
91   void AddErrorMessage(const AString &s)
92   {
93     if (!_errorMessage.IsEmpty())
94       _errorMessage += '\n';
95     _errorMessage += s;
96   }
97   */
98 
99   HRESULT Open2(IInStream *stream,
100       const UInt64 *maxCheckStartPosition,
101       IArchiveOpenCallback *openCallback);
102 
103 public:
104   MY_QUERYINTERFACE_BEGIN2(IInArchive)
105   QUERY_ENTRY_ISetCompressCodecsInfo
106   MY_QUERYINTERFACE_END
107   MY_ADDREF_RELEASE
108 
109   INTERFACE_IInArchive(;)
110 
111   DECL_ISetCompressCodecsInfo
112 };
113 
114 }}
115 
116 #endif
117