Home | History | Annotate | Download | only in 7z
      1 // 7zOut.h
      2 
      3 #ifndef __7Z_OUT_H
      4 #define __7Z_OUT_H
      5 
      6 #include "7zCompressionMode.h"
      7 #include "7zEncode.h"
      8 #include "7zHeader.h"
      9 #include "7zItem.h"
     10 
     11 #include "../../Common/OutBuffer.h"
     12 #include "../../Common/StreamUtils.h"
     13 
     14 namespace NArchive {
     15 namespace N7z {
     16 
     17 class CWriteBufferLoc
     18 {
     19   Byte *_data;
     20   size_t _size;
     21   size_t _pos;
     22 public:
     23   CWriteBufferLoc(): _size(0), _pos(0) {}
     24   void Init(Byte *data, size_t size)
     25   {
     26     _data = data;
     27     _size = size;
     28     _pos = 0;
     29   }
     30   void WriteBytes(const void *data, size_t size)
     31   {
     32     if (size == 0)
     33       return;
     34     if (size > _size - _pos)
     35       throw 1;
     36     memcpy(_data + _pos, data, size);
     37     _pos += size;
     38   }
     39   void WriteByte(Byte b)
     40   {
     41     if (_size == _pos)
     42       throw 1;
     43     _data[_pos++] = b;
     44   }
     45   size_t GetPos() const { return _pos; }
     46 };
     47 
     48 struct CHeaderOptions
     49 {
     50   bool CompressMainHeader;
     51   /*
     52   bool WriteCTime;
     53   bool WriteATime;
     54   bool WriteMTime;
     55   */
     56 
     57   CHeaderOptions():
     58       CompressMainHeader(true)
     59       /*
     60       , WriteCTime(false)
     61       , WriteATime(false)
     62       , WriteMTime(true)
     63       */
     64       {}
     65 };
     66 
     67 
     68 struct CFileItem2
     69 {
     70   UInt64 CTime;
     71   UInt64 ATime;
     72   UInt64 MTime;
     73   UInt64 StartPos;
     74   bool CTimeDefined;
     75   bool ATimeDefined;
     76   bool MTimeDefined;
     77   bool StartPosDefined;
     78   bool IsAnti;
     79   // bool IsAux;
     80 
     81   void Init()
     82   {
     83     CTimeDefined = false;
     84     ATimeDefined = false;
     85     MTimeDefined = false;
     86     StartPosDefined = false;
     87     IsAnti = false;
     88     // IsAux = false;
     89   }
     90 };
     91 
     92 struct COutFolders
     93 {
     94   CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
     95 
     96   CRecordVector<CNum> NumUnpackStreamsVector;
     97   CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
     98 
     99   void OutFoldersClear()
    100   {
    101     FolderUnpackCRCs.Clear();
    102     NumUnpackStreamsVector.Clear();
    103     CoderUnpackSizes.Clear();
    104   }
    105 
    106   void OutFoldersReserveDown()
    107   {
    108     FolderUnpackCRCs.ReserveDown();
    109     NumUnpackStreamsVector.ReserveDown();
    110     CoderUnpackSizes.ReserveDown();
    111   }
    112 };
    113 
    114 struct CArchiveDatabaseOut: public COutFolders
    115 {
    116   CRecordVector<UInt64> PackSizes;
    117   CUInt32DefVector PackCRCs;
    118   CObjectVector<CFolder> Folders;
    119 
    120   CRecordVector<CFileItem> Files;
    121   UStringVector Names;
    122   CUInt64DefVector CTime;
    123   CUInt64DefVector ATime;
    124   CUInt64DefVector MTime;
    125   CUInt64DefVector StartPos;
    126   CRecordVector<bool> IsAnti;
    127 
    128   /*
    129   CRecordVector<bool> IsAux;
    130 
    131   CByteBuffer SecureBuf;
    132   CRecordVector<UInt32> SecureSizes;
    133   CRecordVector<UInt32> SecureIDs;
    134 
    135   void ClearSecure()
    136   {
    137     SecureBuf.Free();
    138     SecureSizes.Clear();
    139     SecureIDs.Clear();
    140   }
    141   */
    142 
    143   void Clear()
    144   {
    145     OutFoldersClear();
    146 
    147     PackSizes.Clear();
    148     PackCRCs.Clear();
    149     Folders.Clear();
    150 
    151     Files.Clear();
    152     Names.Clear();
    153     CTime.Clear();
    154     ATime.Clear();
    155     MTime.Clear();
    156     StartPos.Clear();
    157     IsAnti.Clear();
    158 
    159     /*
    160     IsAux.Clear();
    161     ClearSecure();
    162     */
    163   }
    164 
    165   void ReserveDown()
    166   {
    167     OutFoldersReserveDown();
    168 
    169     PackSizes.ReserveDown();
    170     PackCRCs.ReserveDown();
    171     Folders.ReserveDown();
    172 
    173     Files.ReserveDown();
    174     Names.ReserveDown();
    175     CTime.ReserveDown();
    176     ATime.ReserveDown();
    177     MTime.ReserveDown();
    178     StartPos.ReserveDown();
    179     IsAnti.ReserveDown();
    180 
    181     /*
    182     IsAux.ReserveDown();
    183     */
    184   }
    185 
    186   bool IsEmpty() const
    187   {
    188     return (
    189       PackSizes.IsEmpty() &&
    190       NumUnpackStreamsVector.IsEmpty() &&
    191       Folders.IsEmpty() &&
    192       Files.IsEmpty());
    193   }
    194 
    195   bool CheckNumFiles() const
    196   {
    197     unsigned size = Files.Size();
    198     return (
    199       CTime.CheckSize(size) &&
    200       ATime.CheckSize(size) &&
    201       MTime.CheckSize(size) &&
    202       StartPos.CheckSize(size) &&
    203       (size == IsAnti.Size() || IsAnti.Size() == 0));
    204   }
    205 
    206   bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
    207   // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
    208 
    209   void SetItem_Anti(unsigned index, bool isAnti)
    210   {
    211     while (index >= IsAnti.Size())
    212       IsAnti.Add(false);
    213     IsAnti[index] = isAnti;
    214   }
    215   /*
    216   void SetItem_Aux(unsigned index, bool isAux)
    217   {
    218     while (index >= IsAux.Size())
    219       IsAux.Add(false);
    220     IsAux[index] = isAux;
    221   }
    222   */
    223 
    224   void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
    225 };
    226 
    227 class COutArchive
    228 {
    229   UInt64 _prefixHeaderPos;
    230 
    231   HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); }
    232 
    233   UInt64 GetPos() const;
    234   void WriteBytes(const void *data, size_t size);
    235   void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); }
    236   void WriteByte(Byte b);
    237   void WriteUInt32(UInt32 value);
    238   void WriteUInt64(UInt64 value);
    239   void WriteNumber(UInt64 value);
    240   void WriteID(UInt64 value) { WriteNumber(value); }
    241 
    242   void WriteFolder(const CFolder &folder);
    243   HRESULT WriteFileHeader(const CFileItem &itemInfo);
    244   void WriteBoolVector(const CBoolVector &boolVector);
    245   void WritePropBoolVector(Byte id, const CBoolVector &boolVector);
    246 
    247   void WriteHashDigests(const CUInt32DefVector &digests);
    248 
    249   void WritePackInfo(
    250       UInt64 dataOffset,
    251       const CRecordVector<UInt64> &packSizes,
    252       const CUInt32DefVector &packCRCs);
    253 
    254   void WriteUnpackInfo(
    255       const CObjectVector<CFolder> &folders,
    256       const COutFolders &outFolders);
    257 
    258   void WriteSubStreamsInfo(
    259       const CObjectVector<CFolder> &folders,
    260       const COutFolders &outFolders,
    261       const CRecordVector<UInt64> &unpackSizes,
    262       const CUInt32DefVector &digests);
    263 
    264   void SkipAlign(unsigned pos, unsigned alignSize);
    265   void WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize);
    266   void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
    267 
    268   HRESULT EncodeStream(
    269       DECL_EXTERNAL_CODECS_LOC_VARS
    270       CEncoder &encoder, const CByteBuffer &data,
    271       CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders);
    272   void WriteHeader(
    273       const CArchiveDatabaseOut &db,
    274       // const CHeaderOptions &headerOptions,
    275       UInt64 &headerOffset);
    276 
    277   bool _countMode;
    278   bool _writeToStream;
    279   size_t _countSize;
    280   UInt32 _crc;
    281   COutBuffer _outByte;
    282   CWriteBufferLoc _outByte2;
    283 
    284   #ifdef _7Z_VOL
    285   bool _endMarker;
    286   #endif
    287 
    288   bool _useAlign;
    289 
    290   HRESULT WriteSignature();
    291   #ifdef _7Z_VOL
    292   HRESULT WriteFinishSignature();
    293   #endif
    294   HRESULT WriteStartHeader(const CStartHeader &h);
    295   #ifdef _7Z_VOL
    296   HRESULT WriteFinishHeader(const CFinishHeader &h);
    297   #endif
    298   CMyComPtr<IOutStream> Stream;
    299 public:
    300 
    301   COutArchive() { _outByte.Create(1 << 16); }
    302   CMyComPtr<ISequentialOutStream> SeqStream;
    303   HRESULT Create(ISequentialOutStream *stream, bool endMarker);
    304   void Close();
    305   HRESULT SkipPrefixArchiveHeader();
    306   HRESULT WriteDatabase(
    307       DECL_EXTERNAL_CODECS_LOC_VARS
    308       const CArchiveDatabaseOut &db,
    309       const CCompressionMethodMode *options,
    310       const CHeaderOptions &headerOptions);
    311 
    312   #ifdef _7Z_VOL
    313   static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);
    314   static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);
    315   #endif
    316 
    317 };
    318 
    319 }}
    320 
    321 #endif
    322