// @(#)root/io:$Id$
// Author: Fons Rademakers   30/6/04

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TZIPFile
#define ROOT_TZIPFile


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TZIPFile                                                             //
//                                                                      //
// This class describes a ZIP archive file containing multiple          //
// sub-files. Typically the sub-files are ROOT files. Notice that       //
// the ROOT files should not be compressed when being added to the      //
// ZIP file, since ROOT files are normally already compressed.          //
// Such a ZIP file should be created like:                              //
//                                                                      //
//    zip -n root multi file1.root file2.root                           //
//                                                                      //
// which creates a ZIP file multi.zip.                                  //
//                                                                      //
// For more on the ZIP file structure see TZIPFile.cxx.                 //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TArchiveFile
#include "TArchiveFile.h"
#endif

class TZIPMember;


class TZIPFile : public TArchiveFile {

protected:
   Long64_t    fDirPos;     // Central directory position
   Long64_t    fDirSize;    // Central directory size
   Long64_t    fDirOffset;  // Central directory offset (from the beginning of the archive)
   TString     fComment;    // Archive comment

   Long64_t   FindEndHeader();
   Int_t      ReadEndHeader(Long64_t pos);
   Long64_t   ReadZip64EndLocator(Long64_t pos);
   Int_t      ReadZip64EndRecord(Long64_t pos);
   Int_t      ReadDirectory();
   Int_t      ReadMemberHeader(TZIPMember *member);
   UInt_t     Get(const void *buffer, Int_t bytes);
   ULong64_t  Get64(const void *buffer, Int_t bytes);
   Int_t      DecodeZip64ExtendedExtraField(TZIPMember *m, Bool_t global = kTRUE);

   // ZIP archive constants
   enum EZIPConstants {
      // - Archive version required (and made)
      kARCHIVE_VERSION     = 45,

      // - Magic header constants
      kDIR_HEADER_MAGIC       = 0x02014b50,
      kENTRY_HEADER_MAGIC     = 0x04034b50,
      kEND_HEADER_MAGIC       = 0x06054b50,
      kZIP64_EDR_HEADER_MAGIC = 0x06064b50,
      kZIP64_EDL_HEADER_MAGIC = 0x07064b50,
      kZIP64_EXTENDED_MAGIC   = 0x0001,     // Zip64 Extended Information Extra Field
      kZIP_MAGIC_LEN          = 4,          // Length of magic's
      kMAX_VAR_LEN            = 0xffff,     // Max variable-width field length
      kMAX_SIZE               = 0xffffffff, // Max size of things

      // - Offsets into the central directory headers
      kDIR_MAGIC_OFF      = 0,
      kDIR_VMADE_OFF      = 4,    kDIR_VMADE_LEN          = 2,
      kDIR_VREQD_OFF      = 6,    kDIR_VREQD_LEN          = 2,
      kDIR_FLAG_OFF       = 8,    kDIR_FLAG_LEN           = 2,
      kDIR_METHOD_OFF     = 10,   kDIR_METHOD_LEN         = 2,
      kDIR_DATE_OFF       = 12,   kDIR_DATE_LEN           = 4,
      kDIR_CRC32_OFF      = 16,   kDIR_CRC32_LEN          = 4,
      kDIR_CSIZE_OFF      = 20,   kDIR_CSIZE_LEN          = 4,
      kDIR_USIZE_OFF      = 24,   kDIR_USIZE_LEN          = 4,
      kDIR_NAMELEN_OFF    = 28,   kDIR_NAMELEN_LEN        = 2,
      kDIR_EXTRALEN_OFF   = 30,   kDIR_EXTRALEN_LEN       = 2,
      kDIR_COMMENTLEN_OFF = 32,   kDIR_COMMENTLEN_LEN     = 2,
      kDIR_DISK_START_OFF = 34,   kDIR_DISK_START_LEN     = 2,
      kDIR_INT_ATTR_OFF   = 36,   kDIR_INT_ATTR_LEN       = 2,
      kDIR_EXT_ATTR_OFF   = 38,   kDIR_EXT_ATTR_LEN       = 4,
      kDIR_ENTRY_POS_OFF  = 42,   kDIR_ENTRY_POS_LEN      = 4,
      kDIR_HEADER_SIZE    = 46,
      
      // - Offsets into the Zip64 end of central directory record (EDR)
      kZIP64_EDR_MAGIC_OFF      = 0,
      kZIP64_EDR_SIZE_OFF       = 4,  kZIP64_EDR_SIZE_LEN       = 8,
      kZIP64_EDR_VERS_MADE_OFF  = 12, kZIP64_EDR_VERS_MADE_LEN  = 2,
      kZIP64_EDR_VERS_EXT_OFF   = 14, kZIP64_EDR_VERS_EXT_LEN   = 2,
      kZIP64_EDR_DISK_OFF       = 16, kZIP64_EDR_DISK_LEN       = 4,
      kZIP64_EDR_DIR_DISK_OFF   = 20, kZIP64_EDR_DIR_DISK_LEN   = 4,
      kZIP64_EDR_DISK_HDRS_OFF  = 24, kZIP64_EDR_DISK_HDRS_LEN  = 8,
      kZIP64_EDR_TOTAL_HDRS_OFF = 32, kZIP64_EDR_TOTAL_HDRS_LEN = 8,
      kZIP64_EDR_DIR_SIZE_OFF   = 40, kZIP64_EDR_DIR_SIZE_LEN   = 8,
      kZIP64_EDR_DIR_OFFSET_OFF = 48, kZIP64_EDR_DIR_OFFSET_LEN = 8,
      kZIP64_EDR_HEADER_SIZE    = 56,
      
      // - Offsets into the Zip64 end of central directory locator (EDL)
      kZIP64_EDL_MAGIC_OFF      = 0,
      kZIP64_EDL_DISK_OFF       = 4,  kZIP64_EDL_DISK_LEN       = 4,
      kZIP64_EDL_REC_OFFSET_OFF = 8,  kZIP64_EDL_REC_OFFSET_LEN = 8,
      kZIP64_EDL_TOTAL_DISK_OFF = 16, kZIP64_EDL_TOTAL_DISK_LEN = 4,
      kZIP64_EDL_HEADER_SIZE    = 20,

      // - Offsets into the end-of-archive header
      kEND_MAGIC_OFF      = 0,
      kEND_DISK_OFF       = 4,    kEND_DISK_LEN           = 2,
      kEND_DIR_DISK_OFF   = 6,    kEND_DIR_DISK_LEN       = 2,
      kEND_DISK_HDRS_OFF  = 8,    kEND_DISK_HDRS_LEN      = 2,
      kEND_TOTAL_HDRS_OFF = 10,   kEND_TOTAL_HDRS_LEN     = 2,
      kEND_DIR_SIZE_OFF   = 12,   kEND_DIR_SIZE_LEN       = 4,
      kEND_DIR_OFFSET_OFF = 16,   kEND_DIR_OFFSET_LEN     = 4,
      kEND_COMMENTLEN_OFF = 20,   kEND_COMMENTLEN_LEN     = 2,
      kEND_HEADER_SIZE    = 22,

      // - Offsets into the local entry headers
      kENTRY_MAGIC_OFF    = 0,
      kENTRY_VREQD_OFF    = 4,    kENTRY_VREQD_LEN        = 2,
      kENTRY_FLAG_OFF     = 6,    kENTRY_FLAG_LEN         = 2,
      kENTRY_METHOD_OFF   = 8,    kENTRY_METHOD_LEN       = 2,
      kENTRY_DATE_OFF     = 10,   kENTRY_DATE_LEN         = 4,
      kENTRY_CRC32_OFF    = 14,   kENTRY_CRC32_LEN        = 4,
      kENTRY_CSIZE_OFF    = 18,   kENTRY_CSIZE_LEN        = 4,
      kENTRY_USIZE_OFF    = 22,   kENTRY_USIZE_LEN        = 4,
      kENTRY_NAMELEN_OFF  = 26,   kENTRY_NAMELEN_LEN      = 2,
      kENTRY_EXTRALEN_OFF = 28,   kENTRY_EXTRALEN_LEN     = 2,
      kENTRY_HEADER_SIZE  = 30,
      
      // - Offsets into the Zip64 Extended Information Extra Field
      kZIP64_EXTENDED_MAGIC_OFF      = 0,  kZIP64_EXTENDED_MAGIC_LEN      = 2,
      kZIP64_EXTENDED_SIZE_OFF       = 2,  kZIP64_EXTENDED_SIZE_LEN       = 2,
      kZIP64_EXTENDED_USIZE_OFF      = 4,  kZIP64_EXTENDED_USIZE_LEN      = 8,
      kZIP64_EXTENTED_CSIZE_OFF      = 12, kZIP64_EXTENDED_CSIZE_LEN      = 8,
      kZIP64_EXTENDED_HDR_OFFSET_OFF = 20, kZIP64_EXTENDED_HDR_OFFSET_LEN = 8,
      kZIP64_EXTENDED_DISK_OFF       = 28, kZIP64_EXTENDED_DISK_LEN       = 4,
      kZIP64_EXTENDED_SIZE           = 32,

      // - Compression method and strategy
      kSTORED              = 0,            // Stored as is
      kDEFLATED            = 8             // Stored using deflate
   };

   TZIPFile(const TZIPFile&); // Not implemented
   TZIPFile& operator=(const TZIPFile&); // Not implemented

public:
   TZIPFile();
   TZIPFile(const char *archive, const char *member, TFile *file);
   virtual ~TZIPFile() { }

   virtual Int_t OpenArchive();
   virtual Int_t SetCurrentMember();

   void          Print(Option_t *option = "") const;

   ClassDef(TZIPFile,1)  //A ZIP archive file
};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TZIPMember                                                           //
//                                                                      //
// A ZIP archive consists of files compressed with the popular ZLIB     //
// compression algorithm; this class records the information about a    //
// single archive member.                                               //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TZIPMember : public TArchiveMember {

friend class TZIPFile;

private:
   void          *fLocal;     // Extra file header data
   UInt_t         fLocalLen;  // Length of extra file header data
   void          *fGlobal;    // Extra directory data
   UInt_t         fGlobalLen; // Length of extra directory data
   UInt_t         fCRC32;     // CRC-32 for all decompressed data
   UInt_t         fAttrInt;   // Internal file attributes
   UInt_t         fAttrExt;   // External file attributes
   UInt_t         fMethod;    // Compression type
   UInt_t         fLevel;     // Compression level

public:
   TZIPMember();
   TZIPMember(const char *name);
   TZIPMember(const TZIPMember &member);
   TZIPMember &operator=(const TZIPMember &rhs);
   virtual ~TZIPMember();

   void     *GetLocal() const { return fLocal; }
   UInt_t    GetLocalLen() const { return fLocalLen; }
   void     *GetGlobal() const { return fGlobal; }
   UInt_t    GetGlobalLen() const { return fGlobalLen; }
   UInt_t    GetCRC32() const { return fCRC32; }
   UInt_t    GetAttrInt() const { return fAttrInt; }
   UInt_t    GetAttrExt() const { return fAttrExt; }
   UInt_t    GetMethod() const { return fMethod; }
   UInt_t    GetLevel() const { return fLevel; }

   void      Print(Option_t *option = "") const;

   ClassDef(TZIPMember,2)  //A ZIP archive member file
};

#endif
 TZIPFile.h:1
 TZIPFile.h:2
 TZIPFile.h:3
 TZIPFile.h:4
 TZIPFile.h:5
 TZIPFile.h:6
 TZIPFile.h:7
 TZIPFile.h:8
 TZIPFile.h:9
 TZIPFile.h:10
 TZIPFile.h:11
 TZIPFile.h:12
 TZIPFile.h:13
 TZIPFile.h:14
 TZIPFile.h:15
 TZIPFile.h:16
 TZIPFile.h:17
 TZIPFile.h:18
 TZIPFile.h:19
 TZIPFile.h:20
 TZIPFile.h:21
 TZIPFile.h:22
 TZIPFile.h:23
 TZIPFile.h:24
 TZIPFile.h:25
 TZIPFile.h:26
 TZIPFile.h:27
 TZIPFile.h:28
 TZIPFile.h:29
 TZIPFile.h:30
 TZIPFile.h:31
 TZIPFile.h:32
 TZIPFile.h:33
 TZIPFile.h:34
 TZIPFile.h:35
 TZIPFile.h:36
 TZIPFile.h:37
 TZIPFile.h:38
 TZIPFile.h:39
 TZIPFile.h:40
 TZIPFile.h:41
 TZIPFile.h:42
 TZIPFile.h:43
 TZIPFile.h:44
 TZIPFile.h:45
 TZIPFile.h:46
 TZIPFile.h:47
 TZIPFile.h:48
 TZIPFile.h:49
 TZIPFile.h:50
 TZIPFile.h:51
 TZIPFile.h:52
 TZIPFile.h:53
 TZIPFile.h:54
 TZIPFile.h:55
 TZIPFile.h:56
 TZIPFile.h:57
 TZIPFile.h:58
 TZIPFile.h:59
 TZIPFile.h:60
 TZIPFile.h:61
 TZIPFile.h:62
 TZIPFile.h:63
 TZIPFile.h:64
 TZIPFile.h:65
 TZIPFile.h:66
 TZIPFile.h:67
 TZIPFile.h:68
 TZIPFile.h:69
 TZIPFile.h:70
 TZIPFile.h:71
 TZIPFile.h:72
 TZIPFile.h:73
 TZIPFile.h:74
 TZIPFile.h:75
 TZIPFile.h:76
 TZIPFile.h:77
 TZIPFile.h:78
 TZIPFile.h:79
 TZIPFile.h:80
 TZIPFile.h:81
 TZIPFile.h:82
 TZIPFile.h:83
 TZIPFile.h:84
 TZIPFile.h:85
 TZIPFile.h:86
 TZIPFile.h:87
 TZIPFile.h:88
 TZIPFile.h:89
 TZIPFile.h:90
 TZIPFile.h:91
 TZIPFile.h:92
 TZIPFile.h:93
 TZIPFile.h:94
 TZIPFile.h:95
 TZIPFile.h:96
 TZIPFile.h:97
 TZIPFile.h:98
 TZIPFile.h:99
 TZIPFile.h:100
 TZIPFile.h:101
 TZIPFile.h:102
 TZIPFile.h:103
 TZIPFile.h:104
 TZIPFile.h:105
 TZIPFile.h:106
 TZIPFile.h:107
 TZIPFile.h:108
 TZIPFile.h:109
 TZIPFile.h:110
 TZIPFile.h:111
 TZIPFile.h:112
 TZIPFile.h:113
 TZIPFile.h:114
 TZIPFile.h:115
 TZIPFile.h:116
 TZIPFile.h:117
 TZIPFile.h:118
 TZIPFile.h:119
 TZIPFile.h:120
 TZIPFile.h:121
 TZIPFile.h:122
 TZIPFile.h:123
 TZIPFile.h:124
 TZIPFile.h:125
 TZIPFile.h:126
 TZIPFile.h:127
 TZIPFile.h:128
 TZIPFile.h:129
 TZIPFile.h:130
 TZIPFile.h:131
 TZIPFile.h:132
 TZIPFile.h:133
 TZIPFile.h:134
 TZIPFile.h:135
 TZIPFile.h:136
 TZIPFile.h:137
 TZIPFile.h:138
 TZIPFile.h:139
 TZIPFile.h:140
 TZIPFile.h:141
 TZIPFile.h:142
 TZIPFile.h:143
 TZIPFile.h:144
 TZIPFile.h:145
 TZIPFile.h:146
 TZIPFile.h:147
 TZIPFile.h:148
 TZIPFile.h:149
 TZIPFile.h:150
 TZIPFile.h:151
 TZIPFile.h:152
 TZIPFile.h:153
 TZIPFile.h:154
 TZIPFile.h:155
 TZIPFile.h:156
 TZIPFile.h:157
 TZIPFile.h:158
 TZIPFile.h:159
 TZIPFile.h:160
 TZIPFile.h:161
 TZIPFile.h:162
 TZIPFile.h:163
 TZIPFile.h:164
 TZIPFile.h:165
 TZIPFile.h:166
 TZIPFile.h:167
 TZIPFile.h:168
 TZIPFile.h:169
 TZIPFile.h:170
 TZIPFile.h:171
 TZIPFile.h:172
 TZIPFile.h:173
 TZIPFile.h:174
 TZIPFile.h:175
 TZIPFile.h:176
 TZIPFile.h:177
 TZIPFile.h:178
 TZIPFile.h:179
 TZIPFile.h:180
 TZIPFile.h:181
 TZIPFile.h:182
 TZIPFile.h:183
 TZIPFile.h:184
 TZIPFile.h:185
 TZIPFile.h:186
 TZIPFile.h:187
 TZIPFile.h:188
 TZIPFile.h:189
 TZIPFile.h:190
 TZIPFile.h:191
 TZIPFile.h:192
 TZIPFile.h:193
 TZIPFile.h:194
 TZIPFile.h:195
 TZIPFile.h:196
 TZIPFile.h:197
 TZIPFile.h:198
 TZIPFile.h:199
 TZIPFile.h:200
 TZIPFile.h:201
 TZIPFile.h:202
 TZIPFile.h:203
 TZIPFile.h:204
 TZIPFile.h:205
 TZIPFile.h:206
 TZIPFile.h:207
 TZIPFile.h:208
 TZIPFile.h:209
 TZIPFile.h:210
 TZIPFile.h:211
 TZIPFile.h:212
 TZIPFile.h:213
 TZIPFile.h:214
 TZIPFile.h:215
 TZIPFile.h:216