Logo ROOT  
Reference Guide
TZIPFile.cxx
Go to the documentation of this file.
1 // @(#)root/io:$Id$
2 // Author: Fons Rademakers and Lassi Tuura 30/6/04
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /**
13 \class TZIPFile
14 \ingroup IO
15 
16 Describes a ZIP archive file containing multiple sub-files.
17 
18 Typically the sub-files are ROOT files. Notice that
19 the ROOT files should not be compressed when being added to the
20 ZIP file, since ROOT files are normally already compressed.
21 Such a ZIP file should be created like:
22  zip -n root multi file1.root file2.root
23 which creates a ZIP file multi.zip.
24 A ZIP archive consists of files compressed with the popular ZLIB
25 compression algorithm. The archive format is used among others by
26 PKZip and Info-ZIP. The compression algorithm is also used by
27 GZIP and the PNG graphics standard. The format of the archives is
28 explained briefly below. This class provides an interface to read
29 such archives.
30 A ZIP archive contains a prefix, series of archive members
31 (sub-files), and a central directory. In theory the archive could
32 span multiple disks (or files) with the central directory of the
33 whole archive on the last disk, but this class does not support
34 such multi-part archives. The prefix is only used in self-extracting
35 executable archive files.
36 The members are stored in the archive sequentially, each with a
37 local header followed by the (optionally) compressed data; the local
38 header describes the member, including its file name and compressed
39 and real sizes. The central directory includes the member details
40 again, plus allows an extra member comment to be added. The last
41 member in the central directory is an end marker that can contain
42 a comment for the whole archive. Both the local header and the
43 central directory can also carry extra member-specific data; the
44 data in the local and global parts can be different.
45 The fact that the archive has a global directory makes it efficient
46 and allows for only the reading of the desired data, one does not
47 have to scan through the whole file to find the desired sub-file.
48 The Zip64 extensions are supported so files larger than 2GB can be
49 stored in archives larger than 4 GB.
50 Once the archive has been opened, the client can query the members
51 and read their contents by asking the archive for an offset where
52 the sub-file starts. The members can be accessed in any order.
53 */
54 
55 #include "TZIPFile.h"
56 #include "TFile.h"
57 #include "TObjArray.h"
58 
59 
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// Default ctor.
64 
66 {
67  fDirPos = 0;
68  fDirSize = 0;
69  fDirOffset = 0;
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Specify the archive name and member name. The member can be a decimal
74 /// number which allows to access the n-th member.
75 
76 TZIPFile::TZIPFile(const char *archive, const char *member, TFile *file)
77  : TArchiveFile(archive, member, file)
78 {
79  fDirPos = 0;
80  fDirSize = 0;
81  fDirOffset = 0;
82 }
83 
84 ////////////////////////////////////////////////////////////////////////////////
85 /// Open archive and read end-header and directory. Returns -1 in case
86 /// of error, 0 otherwise.
87 
89 {
90  if (ReadEndHeader(FindEndHeader()) == -1)
91  return -1;
92  return ReadDirectory();
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Find the end header of the ZIP archive. Returns 0 in case of error.
97 
99 {
100  const Int_t kBUFSIZE = 1024;
101  Long64_t size = fFile->GetSize();
102  Long64_t limit = TMath::Min(size, Long64_t(kMAX_VAR_LEN));
103  char buf[kBUFSIZE+4];
104 
105  // Note, this works correctly even if the signature straddles read
106  // boundaries since we always read an overlapped area of four
107  // bytes on the next read
108  for (Long64_t offset = 4; offset < limit; ) {
109  offset = TMath::Min(offset + kBUFSIZE, limit);
110 
111  Long64_t pos = size - offset;
112  Int_t n = TMath::Min(kBUFSIZE+4, Int_t(offset));
113 
114  fFile->Seek(pos);
115  if (fFile->ReadBuffer(buf, n)) {
116  Error("FindEndHeader", "error reading %d bytes at %lld", n, pos);
117  return 0;
118  }
119 
120  for (Int_t i = n - 4; i > 0; i--)
121  if (buf[i] == 0x50 && buf[i+1] == 0x4b &&
122  buf[i+2] == 0x05 && buf[i+3] == 0x06) {
123  return pos + i;
124  }
125  }
126 
127  Error("FindEndHeader", "did not find end header in %s", fArchiveName.Data());
128 
129  return 0;
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 /// Read the end header of the ZIP archive including the archive comment
134 /// at the current file position. Check that it really was a single-disk
135 /// archive with all the entries as expected. Most importantly, figure
136 /// out where the central directory begins. Returns -1 in case of error,
137 /// 0 otherwise.
138 
140 {
141  char buf[kEND_HEADER_SIZE];
142 
143  // read and validate first the end header magic
144  fFile->Seek(pos);
145  if (fFile->ReadBuffer(buf, kZIP_MAGIC_LEN) ||
147  Error("ReadEndHeader", "wrong end header magic in %s", fArchiveName.Data());
148  return -1;
149  }
150 
151  // read rest of the header
153  Error("ReadEndHeader", "error reading %d end header bytes from %s",
155  return -1;
156  }
157 
158  UInt_t disk = Get(buf + kEND_DISK_OFF, kEND_DISK_LEN);
159  UInt_t dirdisk = Get(buf + kEND_DIR_DISK_OFF, kEND_DIR_DISK_LEN);
165 
166  if (disk != 0 || dirdisk != 0) {
167  Error("ReadHeader", "only single disk archives are supported in %s",
168  fArchiveName.Data());
169  return -1;
170  }
171  if (dhdrs != thdrs) {
172  Error("ReadEndHeader", "inconsistency in end header data in %s",
173  fArchiveName.Data());
174  return -1;
175  }
176 
177  char *comment = new char[commlen+1];
178  if (fFile->ReadBuffer(comment, commlen)) {
179  Error("ReadEndHeader", "error reading %d end header comment bytes from %s",
180  commlen, fArchiveName.Data());
181  delete [] comment;
182  return -1;
183  }
184  comment[commlen] = '\0';
185 
186  fComment = comment;
187  fDirOffset = fDirPos = diroff;
188  fDirSize = dirsz;
189 
190  delete [] comment;
191 
192  // Try to read Zip64 end of central directory locator
194  if (recoff < 0) {
195  if (recoff == -1)
196  return -1;
197  return 0;
198  }
199 
200  if (ReadZip64EndRecord(recoff) < 0)
201  return -1;
202 
203  return 0;
204 }
205 
206 ////////////////////////////////////////////////////////////////////////////////
207 /// Read Zip64 end of central directory locator. Returns -1 in case of error,
208 /// -2 in case end locator magic is not found (i.e. not a zip64 file) and
209 /// offset of Zip64 end of central directory record in case of success.
210 
212 {
213  char buf[kZIP64_EDL_HEADER_SIZE];
214 
215  // read and validate first the end header magic
216  fFile->Seek(pos);
217  if (fFile->ReadBuffer(buf, kZIP_MAGIC_LEN) ||
219  return -2;
220  }
221 
222  // read rest of the header
224  Error("ReadZip64EndLocator", "error reading %d Zip64 end locator header bytes from %s",
226  return -1;
227  }
228 
232 
233  if (dirdisk != 0 || totdisk != 1) {
234  Error("ReadZip64EndLocator", "only single disk archives are supported in %s",
235  fArchiveName.Data());
236  return -1;
237  }
238 
239  return recoff;
240 }
241 
242 ////////////////////////////////////////////////////////////////////////////////
243 /// Read Zip64 end of central directory record. Returns -1 in case of error
244 /// and 0 in case of success.
245 
247 {
248  char buf[kZIP64_EDR_HEADER_SIZE];
249 
250  // read and validate first the end header magic
251  fFile->Seek(pos);
252  if (fFile->ReadBuffer(buf, kZIP_MAGIC_LEN) ||
254  Error("ReadZip64EndRecord", "no Zip64 end of directory record\n");
255  return -1;
256  }
257 
258  // read rest of the header
260  Error("ReadZip64EndRecord", "error reading %d Zip64 end record header bytes from %s",
262  return -1;
263  }
264 
267 
268  fDirOffset = fDirPos = diroff;
269  fDirSize = dirsz;
270 
271  return 0;
272 }
273 
274 ////////////////////////////////////////////////////////////////////////////////
275 /// Read the directory of the ZIP archive. Returns -1 in case of error,
276 /// 0 otherwise.
277 
279 {
280  char buf[kDIR_HEADER_SIZE];
281  UInt_t n, i;
282 
283  // read and validate first the header magic
284  fFile->Seek(fDirPos);
285  if (fFile->ReadBuffer(buf, kZIP_MAGIC_LEN) ||
286  (n = Get(buf, kZIP_MAGIC_LEN)) != kDIR_HEADER_MAGIC) {
287  Error("ReadDirectory", "wrong directory header magic in %s",
288  fArchiveName.Data());
289  return -1;
290  }
291 
292  // now read the full directory
293  for (i = 0; n == kDIR_HEADER_MAGIC; i++) {
294  // read the rest of the header
296  Error("ReadDirectory", "error reading %d directory bytes from %s",
298  return -1;
299  }
300 
301  UInt_t version = Get(buf + kDIR_VREQD_OFF, kDIR_VREQD_LEN);
302  UInt_t flags = Get(buf + kDIR_FLAG_OFF, kDIR_FLAG_LEN);
303  UInt_t method = Get(buf + kDIR_METHOD_OFF, kDIR_METHOD_LEN);
304  UInt_t time = Get(buf + kDIR_DATE_OFF, kDIR_DATE_LEN);
305  UInt_t crc32 = Get(buf + kDIR_CRC32_OFF, kDIR_CRC32_LEN);
306  Long64_t csize = Get(buf + kDIR_CSIZE_OFF, kDIR_CSIZE_LEN);
307  Long64_t usize = Get(buf + kDIR_USIZE_OFF, kDIR_USIZE_LEN);
308  Int_t namelen = Get(buf + kDIR_NAMELEN_OFF, kDIR_NAMELEN_LEN);
309  Int_t extlen = Get(buf + kDIR_EXTRALEN_OFF, kDIR_EXTRALEN_LEN);
315 
316  // check value sanity and the variable-length fields
318  version > kARCHIVE_VERSION ||
319  flags & 8 ||
320  (method != kSTORED && method != kDEFLATED) ||
321  disk != 0 ||
322  csize < 0 ||
323  usize < 0 ||
324  csize > kMaxUInt ||
325  usize > kMaxUInt) {
326  Error("ReadDirectory", "inconsistency in directory data in %s",
327  fArchiveName.Data());
328  return -1;
329  }
330 
331  char *name = new char[namelen+1];
332  char *extra = new char[extlen];
333  char *comment = new char[commlen+1];
334  if (fFile->ReadBuffer(name, namelen) ||
335  fFile->ReadBuffer(extra, extlen) ||
336  fFile->ReadBuffer(comment, commlen)) {
337  Error("ReadDirectory", "error reading additional directory data from %s",
338  fArchiveName.Data());
339  delete [] name;
340  delete [] extra;
341  delete [] comment;
342  return -1;
343  }
344  name[namelen] = '\0';
345  comment[commlen] = '\0';
346 
347  // create a new archive member and store the fields
348  TZIPMember *m = new TZIPMember(name);
349  fMembers->Add(m);
350 
351  m->fMethod = method;
352  m->fLevel = method == kSTORED ? 0
353  : (flags & 6)/2 == 0 ? 3 // default (:N)
354  : (flags & 6)/2 == 1 ? 9 // best (:X)
355  : (flags & 6)/2 == 2 ? 2 // fast (:F)
356  : (flags & 6)/2 == 3 ? 1 // fastest (:F)
357  : 3; // unreached
358  m->fCsize = csize;
359  m->fDsize = usize;
360  m->fCRC32 = crc32;
361  m->fModTime.Set(time, kTRUE); // DOS date/time format
362  m->fGlobalLen = extlen;
363  m->fGlobal = extra;
364  m->fComment = comment;
365  m->fAttrInt = iattr;
366  m->fAttrExt = xattr;
367  m->fPosition = offset;
368 
369  delete [] name;
370  delete [] comment;
371  // extra is adopted be the TZIPMember
372 
373  if (DecodeZip64ExtendedExtraField(m) == -1)
374  return -1;
375 
376  if (gDebug)
377  Info("ReadDirectory", "%lld %lld %s %s",
378  m->GetDecompressedSize(), m->GetCompressedSize(),
379  m->GetModTime().AsSQLString(), m->GetName());
380 
381  // done, read the next magic
382  if (fFile->ReadBuffer(buf, kZIP_MAGIC_LEN)) {
383  Error("ReadDirectory", "error reading %d directory bytes from %s",
385  return -1;
386  }
387  n = Get(buf, kZIP_MAGIC_LEN);
388  }
389 
390  // should now see end of archive
392  Error("ReadDirectory", "wrong end header magic in %s", fArchiveName.Data());
393  return -1;
394  }
395 
396  return 0;
397 }
398 
399 ////////////////////////////////////////////////////////////////////////////////
400 /// Read the member header of the ZIP archive. Sets the position where
401 /// the data starts in the member object. Returns -1 in case of error,
402 /// 0 otherwise.
403 
405 {
406  // read file header to find start of data, since extra len might be
407  // different we cannot take it from the directory data
408  char buf[kENTRY_HEADER_SIZE];
409 
410  // read and validate first the entry header magic
411  fFile->Seek(member->fPosition);
412  if (fFile->ReadBuffer(buf, kZIP_MAGIC_LEN) ||
414  Error("ReadMemberHeader", "wrong entry header magic in %s",
415  fArchiveName.Data());
416  return -1;
417  }
418 
419  // read rest of the header
421  Error("ReadMemberHeader", "error reading %d member header bytes from %s",
423  return -1;
424  }
427 
428  member->fFilePosition = member->fPosition + kENTRY_HEADER_SIZE +
429  namelen + extlen;
430 
431  return 0;
432 }
433 
434 ////////////////////////////////////////////////////////////////////////////////
435 /// Decode the Zip64 extended extra field. If global is true, decode the
436 /// extra field coming from the central directory, if false decode the
437 /// extra field coming from the local file header. Returns -1 in case of
438 /// error, -2 in case Zip64 extra block was not found and 0 in case of
439 /// success.
440 
442 {
443  char *buf;
444  Int_t len;
445  Int_t ret = -2;
446 
447  if (global) {
448  buf = (char *) m->fGlobal;
449  len = m->fGlobalLen;
450  } else {
451  buf = (char *) m->fLocal;
452  len = m->fLocalLen;
453  }
454 
455  if (!buf || !len) {
456  return ret;
457  }
458 
459  Int_t off = 0;
460  while (len > 0) {
463  if (tag == kZIP64_EXTENDED_MAGIC) {
466  m->fDsize = usize;
467  m->fCsize = csize;
468  if (size >= 24) {
470  m->fPosition = offset;
471  }
472 
473  ret = 0;
474  }
477  }
478 
479  return ret;
480 }
481 
482 ////////////////////////////////////////////////////////////////////////////////
483 /// Find the desired member in the member array and make it the
484 /// current member. Returns -1 in case member is not found, 0 otherwise.
485 
487 {
488  fCurMember = 0;
489 
490  if (fMemberIndex > -1) {
492  if (!fCurMember)
493  return -1;
495  } else {
496  for (int i = 0; i < fMembers->GetEntriesFast(); i++) {
497  TZIPMember *m = (TZIPMember *) fMembers->At(i);
498  if (fMemberName == m->fName) {
499  fCurMember = m;
500  fMemberIndex = i;
501  break;
502  }
503  }
504  if (!fCurMember)
505  return -1;
506  }
507 
509 }
510 
511 ////////////////////////////////////////////////////////////////////////////////
512 /// Read a "bytes" long little-endian integer value from "buffer".
513 
514 UInt_t TZIPFile::Get(const void *buffer, Int_t bytes)
515 {
516  UInt_t value = 0;
517 
518  if (bytes > 4) {
519  Error("Get", "can not read > 4 byte integers, use Get64");
520  return value;
521  }
522 #ifdef R__BYTESWAP
523  memcpy(&value, buffer, bytes);
524 #else
525  const UChar_t *buf = static_cast<const unsigned char *>(buffer);
526  for (UInt_t shift = 0; bytes; shift += 8, --bytes, ++buf)
527  value += *buf << shift;
528 #endif
529  return value;
530 }
531 
532 ////////////////////////////////////////////////////////////////////////////////
533 /// Read a 8 byte long little-endian integer value from "buffer".
534 
535 ULong64_t TZIPFile::Get64(const void *buffer, Int_t bytes)
536 {
537  ULong64_t value = 0;
538 
539  if (bytes != 8) {
540  Error("Get64", "bytes must be 8 (asked for %d)", bytes);
541  return value;
542  }
543 
544 #ifdef R__BYTESWAP
545  memcpy(&value, buffer, bytes);
546 #else
547  const UChar_t *buf = static_cast<const unsigned char *>(buffer);
548  for (UInt_t shift = 0; bytes; shift += 8, --bytes, ++buf)
549  value += *buf << shift;
550 #endif
551  return value;
552 }
553 
554 ////////////////////////////////////////////////////////////////////////////////
555 /// Pretty print ZIP archive members.
556 
558 {
559  if (fMembers)
560  fMembers->Print();
561 }
562 
563 
565 
566 ////////////////////////////////////////////////////////////////////////////////
567 /// Default ctor.
568 
570 {
571  fLocal = 0;
572  fLocalLen = 0;
573  fGlobal = 0;
574  fGlobalLen = 0;
575  fCRC32 = 0;
576  fAttrInt = 0;
577  fAttrExt = 0;
578  fMethod = 0;
579  fLevel = 0;
580 }
581 
582 ////////////////////////////////////////////////////////////////////////////////
583 /// Create ZIP member file.
584 
587 {
588  fLocal = 0;
589  fLocalLen = 0;
590  fGlobal = 0;
591  fGlobalLen = 0;
592  fCRC32 = 0;
593  fAttrInt = 0;
594  fAttrExt = 0;
595  fMethod = 0;
596  fLevel = 0;
597 }
598 
599 ////////////////////////////////////////////////////////////////////////////////
600 /// Copy ctor.
601 
603  : TArchiveMember(member)
604 {
605  fLocal = 0;
606  fLocalLen = member.fLocalLen;
607  fGlobal = 0;
608  fGlobalLen = member.fGlobalLen;
609  fCRC32 = member.fCRC32;
610  fAttrInt = member.fAttrInt;
611  fAttrExt = member.fAttrExt;
612  fMethod = member.fMethod;
613  fLevel = member.fLevel;
614 
615  if (member.fLocal) {
616  fLocal = new char [fLocalLen];
617  memcpy(fLocal, member.fLocal, fLocalLen);
618  }
619  if (member.fGlobal) {
620  fGlobal = new char [fGlobalLen];
621  memcpy(fGlobal, member.fGlobal, fGlobalLen);
622  }
623 }
624 
625 ////////////////////////////////////////////////////////////////////////////////
626 /// Assignment operator.
627 
629 {
630  if (this != &rhs) {
632 
633  delete [] (char*) fLocal;
634  delete [] (char*) fGlobal;
635 
636  fLocal = 0;
637  fLocalLen = rhs.fLocalLen;
638  fGlobal = 0;
639  fGlobalLen = rhs.fGlobalLen;
640  fCRC32 = rhs.fCRC32;
641  fAttrInt = rhs.fAttrInt;
642  fAttrExt = rhs.fAttrExt;
643  fMethod = rhs.fMethod;
644  fLevel = rhs.fLevel;
645 
646  if (rhs.fLocal) {
647  fLocal = new char [fLocalLen];
648  memcpy(fLocal, rhs.fLocal, fLocalLen);
649  }
650  if (rhs.fGlobal) {
651  fGlobal = new char [fGlobalLen];
652  memcpy(fGlobal, rhs.fGlobal, fGlobalLen);
653  }
654  }
655  return *this;
656 }
657 
658 ////////////////////////////////////////////////////////////////////////////////
659 /// Cleanup.
660 
662 {
663  delete [] (char*) fLocal;
664  delete [] (char*) fGlobal;
665 }
666 
667 ////////////////////////////////////////////////////////////////////////////////
668 /// Pretty print basic ZIP member info.
669 
671 {
672  printf("%-20lld", fDsize);
673  printf(" %s %s\n", fModTime.AsSQLString(), fName.Data());
674 }
TZIPFile::kZIP64_EDR_DIR_OFFSET_LEN
@ kZIP64_EDR_DIR_OFFSET_LEN
Definition: TZIPFile.h:83
m
auto * m
Definition: textangle.C:8
TZIPMember::fGlobalLen
UInt_t fGlobalLen
Length of extra directory data.
Definition: TZIPFile.h:164
kMaxUInt
const UInt_t kMaxUInt
Definition: RtypesCore.h:102
n
const Int_t n
Definition: legend1.C:16
TZIPFile::kEND_DIR_OFFSET_OFF
@ kEND_DIR_OFFSET_OFF
Definition: TZIPFile.h:100
TZIPFile::Get
UInt_t Get(const void *buffer, Int_t bytes)
Read a "bytes" long little-endian integer value from "buffer".
Definition: TZIPFile.cxx:514
TZIPFile::kEND_DIR_SIZE_OFF
@ kEND_DIR_SIZE_OFF
Definition: TZIPFile.h:99
TArchiveFile
Class describing an archive file containing multiple sub-files, like a ZIP or TAR archive.
Definition: TArchiveFile.h:24
TZIPFile::kZIP64_EDR_DIR_SIZE_LEN
@ kZIP64_EDR_DIR_SIZE_LEN
Definition: TZIPFile.h:82
TZIPFile::kZIP64_EXTENDED_MAGIC
@ kZIP64_EXTENDED_MAGIC
Zip64 Extended Information Extra Field.
Definition: TZIPFile.h:49
TZIPFile::kEND_HEADER_SIZE
@ kEND_HEADER_SIZE
Definition: TZIPFile.h:102
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TZIPFile.h
TCollection::Print
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
Definition: TCollection.cxx:476
TZIPFile::kZIP64_EDL_TOTAL_DISK_OFF
@ kZIP64_EDL_TOTAL_DISK_OFF
Definition: TZIPFile.h:90
TZIPFile::fComment
TString fComment
Archive comment.
Definition: TZIPFile.h:26
TZIPFile::kZIP64_EXTENTED_CSIZE_OFF
@ kZIP64_EXTENTED_CSIZE_OFF
Definition: TZIPFile.h:121
TZIPFile::kDIR_VREQD_OFF
@ kDIR_VREQD_OFF
Definition: TZIPFile.h:57
TZIPFile::kDIR_EXT_ATTR_LEN
@ kDIR_EXT_ATTR_LEN
Definition: TZIPFile.h:69
TZIPFile::kDIR_DISK_START_LEN
@ kDIR_DISK_START_LEN
Definition: TZIPFile.h:67
TZIPFile::kDIR_EXTRALEN_OFF
@ kDIR_EXTRALEN_OFF
Definition: TZIPFile.h:65
Option_t
const char Option_t
Definition: RtypesCore.h:66
TZIPFile::kZIP64_EDL_REC_OFFSET_OFF
@ kZIP64_EDL_REC_OFFSET_OFF
Definition: TZIPFile.h:89
TArchiveMember::GetName
const char * GetName() const
Returns name of object.
Definition: TArchiveFile.h:86
TZIPFile::kDIR_METHOD_LEN
@ kDIR_METHOD_LEN
Definition: TZIPFile.h:59
TFile::Seek
virtual void Seek(Long64_t offset, ERelativeTo pos=kBeg)
Seek to a specific position in the file. Pos it either kBeg, kCur or kEnd.
Definition: TFile.cxx:2187
TZIPFile::kZIP_MAGIC_LEN
@ kZIP_MAGIC_LEN
Length of magic's.
Definition: TZIPFile.h:50
TArchiveMember::fFilePosition
Long64_t fFilePosition
Byte position in archive where member data starts.
Definition: TArchiveFile.h:74
TZIPMember
A ZIP archive consists of files compressed with the popular ZLIB compression algorithm; this class re...
Definition: TZIPFile.h:156
TZIPFile::kEND_DIR_OFFSET_LEN
@ kEND_DIR_OFFSET_LEN
Definition: TZIPFile.h:100
TString::Data
const char * Data() const
Definition: TString.h:369
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TZIPFile::kMAX_VAR_LEN
@ kMAX_VAR_LEN
Max variable-width field length.
Definition: TZIPFile.h:51
TZIPFile::SetCurrentMember
virtual Int_t SetCurrentMember()
Find the desired member in the member array and make it the current member.
Definition: TZIPFile.cxx:486
TZIPFile::kENTRY_HEADER_SIZE
@ kENTRY_HEADER_SIZE
Definition: TZIPFile.h:115
TZIPFile::kEND_COMMENTLEN_OFF
@ kEND_COMMENTLEN_OFF
Definition: TZIPFile.h:101
TObject::Info
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:864
Long64_t
long long Long64_t
Definition: RtypesCore.h:73
TZIPFile::kZIP64_EXTENDED_SIZE_LEN
@ kZIP64_EXTENDED_SIZE_LEN
Definition: TZIPFile.h:119
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:890
TZIPFile::kDIR_HEADER_SIZE
@ kDIR_HEADER_SIZE
Definition: TZIPFile.h:71
TArchiveMember
Definition: TArchiveFile.h:65
TZIPFile::kDIR_EXT_ATTR_OFF
@ kDIR_EXT_ATTR_OFF
Definition: TZIPFile.h:69
TZIPFile::ReadMemberHeader
Int_t ReadMemberHeader(TZIPMember *member)
Read the member header of the ZIP archive.
Definition: TZIPFile.cxx:404
TZIPMember::fMethod
UInt_t fMethod
Compression type.
Definition: TZIPFile.h:168
TZIPFile::kDIR_INT_ATTR_OFF
@ kDIR_INT_ATTR_OFF
Definition: TZIPFile.h:68
TZIPFile::kDIR_CRC32_OFF
@ kDIR_CRC32_OFF
Definition: TZIPFile.h:61
TZIPMember::~TZIPMember
virtual ~TZIPMember()
Cleanup.
Definition: TZIPFile.cxx:661
TZIPFile::kZIP64_EDL_REC_OFFSET_LEN
@ kZIP64_EDL_REC_OFFSET_LEN
Definition: TZIPFile.h:89
TZIPFile::kZIP64_EDL_HEADER_MAGIC
@ kZIP64_EDL_HEADER_MAGIC
Definition: TZIPFile.h:48
Int_t
int Int_t
Definition: RtypesCore.h:45
TZIPMember::fAttrExt
UInt_t fAttrExt
External file attributes.
Definition: TZIPFile.h:167
TArchiveMember::fDsize
Long64_t fDsize
Decompressed size.
Definition: TArchiveFile.h:76
TZIPFile::kDIR_EXTRALEN_LEN
@ kDIR_EXTRALEN_LEN
Definition: TZIPFile.h:65
TZIPFile::kSTORED
@ kSTORED
Stored as is.
Definition: TZIPFile.h:127
TZIPFile::ReadEndHeader
Int_t ReadEndHeader(Long64_t pos)
Read the end header of the ZIP archive including the archive comment at the current file position.
Definition: TZIPFile.cxx:139
TZIPFile::kEND_DISK_HDRS_OFF
@ kEND_DISK_HDRS_OFF
Definition: TZIPFile.h:97
TObjArray::At
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
TZIPFile::kEND_DIR_DISK_LEN
@ kEND_DIR_DISK_LEN
Definition: TZIPFile.h:96
TFile::ReadBuffer
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read a buffer from the file.
Definition: TFile.cxx:1683
TZIPFile::kEND_HEADER_MAGIC
@ kEND_HEADER_MAGIC
Definition: TZIPFile.h:46
TZIPFile::kDIR_MAGIC_OFF
@ kDIR_MAGIC_OFF
Definition: TZIPFile.h:55
TZIPFile::kDIR_METHOD_OFF
@ kDIR_METHOD_OFF
Definition: TZIPFile.h:59
TZIPFile::fDirSize
Long64_t fDirSize
Central directory size.
Definition: TZIPFile.h:24
TZIPFile::kDIR_USIZE_LEN
@ kDIR_USIZE_LEN
Definition: TZIPFile.h:63
TZIPFile::FindEndHeader
Long64_t FindEndHeader()
Find the end header of the ZIP archive. Returns 0 in case of error.
Definition: TZIPFile.cxx:98
TArchiveFile::fFile
TFile * fFile
File stream used to access the archive.
Definition: TArchiveFile.h:34
TZIPMember::fLevel
UInt_t fLevel
Compression level.
Definition: TZIPFile.h:169
TFile.h
TZIPFile::kDIR_COMMENTLEN_LEN
@ kDIR_COMMENTLEN_LEN
Definition: TZIPFile.h:66
TZIPFile::kZIP64_EXTENDED_CSIZE_LEN
@ kZIP64_EXTENDED_CSIZE_LEN
Definition: TZIPFile.h:121
TZIPFile::kDIR_DISK_START_OFF
@ kDIR_DISK_START_OFF
Definition: TZIPFile.h:67
TZIPMember::fGlobal
void * fGlobal
Extra directory data.
Definition: TZIPFile.h:163
bool
TZIPFile::kENTRY_NAMELEN_OFF
@ kENTRY_NAMELEN_OFF
Definition: TZIPFile.h:113
TZIPFile::kZIP64_EDL_DISK_LEN
@ kZIP64_EDL_DISK_LEN
Definition: TZIPFile.h:88
TZIPFile::ReadDirectory
Int_t ReadDirectory()
Read the directory of the ZIP archive.
Definition: TZIPFile.cxx:278
TObjArray::Add
void Add(TObject *obj)
Definition: TObjArray.h:74
TZIPFile::kZIP64_EDL_TOTAL_DISK_LEN
@ kZIP64_EDL_TOTAL_DISK_LEN
Definition: TZIPFile.h:90
TZIPFile::ReadZip64EndRecord
Int_t ReadZip64EndRecord(Long64_t pos)
Read Zip64 end of central directory record.
Definition: TZIPFile.cxx:246
TZIPFile::kZIP64_EDR_HEADER_MAGIC
@ kZIP64_EDR_HEADER_MAGIC
Definition: TZIPFile.h:47
TZIPFile::kEND_DIR_SIZE_LEN
@ kEND_DIR_SIZE_LEN
Definition: TZIPFile.h:99
TArchiveFile::fCurMember
TArchiveMember * fCurMember
Current archive member.
Definition: TArchiveFile.h:36
TZIPFile::kDIR_DATE_OFF
@ kDIR_DATE_OFF
Definition: TZIPFile.h:60
TZIPFile::kZIP64_EXTENDED_HDR_OFFSET_OFF
@ kZIP64_EXTENDED_HDR_OFFSET_OFF
Definition: TZIPFile.h:122
TZIPFile::kZIP64_EDL_HEADER_SIZE
@ kZIP64_EDL_HEADER_SIZE
Definition: TZIPFile.h:91
TZIPFile::kDIR_VREQD_LEN
@ kDIR_VREQD_LEN
Definition: TZIPFile.h:57
TZIPMember::fLocalLen
UInt_t fLocalLen
Length of extra file header data.
Definition: TZIPFile.h:162
TZIPFile::kEND_COMMENTLEN_LEN
@ kEND_COMMENTLEN_LEN
Definition: TZIPFile.h:101
TZIPFile::kEND_DISK_LEN
@ kEND_DISK_LEN
Definition: TZIPFile.h:95
TZIPFile::kDIR_CSIZE_LEN
@ kDIR_CSIZE_LEN
Definition: TZIPFile.h:62
TZIPMember::fAttrInt
UInt_t fAttrInt
Internal file attributes.
Definition: TZIPFile.h:166
TZIPFile::kEND_DISK_OFF
@ kEND_DISK_OFF
Definition: TZIPFile.h:95
TZIPFile::kZIP64_EXTENDED_MAGIC_LEN
@ kZIP64_EXTENDED_MAGIC_LEN
Definition: TZIPFile.h:118
TArchiveMember::fPosition
Long64_t fPosition
Byte position in archive.
Definition: TArchiveFile.h:73
TDatime::AsSQLString
const char * AsSQLString() const
Return the date & time in SQL compatible string format, like: 1997-01-15 20:16:28.
Definition: TDatime.cxx:152
TZIPFile::kDIR_NAMELEN_OFF
@ kDIR_NAMELEN_OFF
Definition: TZIPFile.h:64
TObjArray::GetEntriesFast
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
TZIPFile::kDIR_CSIZE_OFF
@ kDIR_CSIZE_OFF
Definition: TZIPFile.h:62
TZIPMember::fCRC32
UInt_t fCRC32
CRC-32 for all decompressed data.
Definition: TZIPFile.h:165
TZIPMember::Print
void Print(Option_t *option="") const
Pretty print basic ZIP member info.
Definition: TZIPFile.cxx:670
TZIPMember::fLocal
void * fLocal
Extra file header data.
Definition: TZIPFile.h:161
TZIPFile::kENTRY_EXTRALEN_OFF
@ kENTRY_EXTRALEN_OFF
Definition: TZIPFile.h:114
TFile::GetSize
virtual Long64_t GetSize() const
Returns the current file size.
Definition: TFile.cxx:1262
TZIPMember::TZIPMember
TZIPMember()
Default ctor.
Definition: TZIPFile.cxx:569
gDebug
Int_t gDebug
Definition: TROOT.cxx:590
TZIPFile::kEND_TOTAL_HDRS_OFF
@ kEND_TOTAL_HDRS_OFF
Definition: TZIPFile.h:98
TZIPMember::operator=
TZIPMember & operator=(const TZIPMember &rhs)
Assignment operator.
Definition: TZIPFile.cxx:628
TArchiveMember::fModTime
TDatime fModTime
Modification time.
Definition: TArchiveFile.h:72
TZIPFile::kENTRY_HEADER_MAGIC
@ kENTRY_HEADER_MAGIC
Definition: TZIPFile.h:45
TZIPFile::kZIP64_EXTENDED_USIZE_LEN
@ kZIP64_EXTENDED_USIZE_LEN
Definition: TZIPFile.h:120
TZIPFile::fDirOffset
Long64_t fDirOffset
Central directory offset (from the beginning of the archive)
Definition: TZIPFile.h:25
TZIPFile::kENTRY_NAMELEN_LEN
@ kENTRY_NAMELEN_LEN
Definition: TZIPFile.h:113
TZIPFile::Get64
ULong64_t Get64(const void *buffer, Int_t bytes)
Read a 8 byte long little-endian integer value from "buffer".
Definition: TZIPFile.cxx:535
TZIPFile::kDIR_CRC32_LEN
@ kDIR_CRC32_LEN
Definition: TZIPFile.h:61
TArchiveMember::operator=
TArchiveMember & operator=(const TArchiveMember &rhs)
Assignment operator.
Definition: TArchiveFile.cxx:255
TFile
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:54
TZIPFile::kEND_TOTAL_HDRS_LEN
@ kEND_TOTAL_HDRS_LEN
Definition: TZIPFile.h:98
TMath::Min
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
TZIPFile::kDIR_ENTRY_POS_LEN
@ kDIR_ENTRY_POS_LEN
Definition: TZIPFile.h:70
unsigned int
TZIPFile::ReadZip64EndLocator
Long64_t ReadZip64EndLocator(Long64_t pos)
Read Zip64 end of central directory locator.
Definition: TZIPFile.cxx:211
TZIPFile::kZIP64_EDL_DISK_OFF
@ kZIP64_EDL_DISK_OFF
Definition: TZIPFile.h:88
TArchiveMember::fName
TString fName
Name of member.
Definition: TArchiveFile.h:70
TZIPFile::kDIR_FLAG_OFF
@ kDIR_FLAG_OFF
Definition: TZIPFile.h:58
ULong64_t
unsigned long long ULong64_t
Definition: RtypesCore.h:74
TZIPFile::kENTRY_EXTRALEN_LEN
@ kENTRY_EXTRALEN_LEN
Definition: TZIPFile.h:114
TArchiveFile::fArchiveName
TString fArchiveName
Archive file name.
Definition: TArchiveFile.h:31
TZIPFile::fDirPos
Long64_t fDirPos
Central directory position.
Definition: TZIPFile.h:23
TZIPFile::kDIR_NAMELEN_LEN
@ kDIR_NAMELEN_LEN
Definition: TZIPFile.h:64
TZIPFile::kZIP64_EXTENDED_MAGIC_OFF
@ kZIP64_EXTENDED_MAGIC_OFF
Definition: TZIPFile.h:118
TObjArray.h
TZIPFile::kZIP64_EDR_HEADER_SIZE
@ kZIP64_EDR_HEADER_SIZE
Definition: TZIPFile.h:84
TZIPFile::kDIR_INT_ATTR_LEN
@ kDIR_INT_ATTR_LEN
Definition: TZIPFile.h:68
TZIPFile::kZIP64_EDR_DIR_SIZE_OFF
@ kZIP64_EDR_DIR_SIZE_OFF
Definition: TZIPFile.h:82
TZIPFile::kDIR_DATE_LEN
@ kDIR_DATE_LEN
Definition: TZIPFile.h:60
file
Definition: file.py:1
UChar_t
unsigned char UChar_t
Definition: RtypesCore.h:38
TZIPFile::kDIR_COMMENTLEN_OFF
@ kDIR_COMMENTLEN_OFF
Definition: TZIPFile.h:66
TZIPFile::Print
void Print(Option_t *option="") const
Pretty print ZIP archive members.
Definition: TZIPFile.cxx:557
TArchiveFile::fMemberName
TString fMemberName
Sub-file name.
Definition: TArchiveFile.h:32
TZIPFile::kZIP64_EXTENDED_SIZE_OFF
@ kZIP64_EXTENDED_SIZE_OFF
Definition: TZIPFile.h:119
name
char name[80]
Definition: TGX11.cxx:110
TArchiveFile::fMemberIndex
Int_t fMemberIndex
Index of sub-file in archive.
Definition: TArchiveFile.h:33
TZIPFile::kEND_DISK_HDRS_LEN
@ kEND_DISK_HDRS_LEN
Definition: TZIPFile.h:97
TZIPFile::kDIR_HEADER_MAGIC
@ kDIR_HEADER_MAGIC
Definition: TZIPFile.h:44
TZIPFile
Describes a ZIP archive file containing multiple sub-files.
Definition: TZIPFile.h:20
TArchiveFile::fMembers
TObjArray * fMembers
Members in this archive.
Definition: TArchiveFile.h:35
ROOT::TMetaUtils::propNames::comment
static const std::string comment("comment")
TZIPFile::OpenArchive
virtual Int_t OpenArchive()
Open archive and read end-header and directory.
Definition: TZIPFile.cxx:88
TZIPFile::kEND_DIR_DISK_OFF
@ kEND_DIR_DISK_OFF
Definition: TZIPFile.h:96
TZIPFile::TZIPFile
TZIPFile()
Default ctor.
Definition: TZIPFile.cxx:65
TZIPFile::kDIR_USIZE_OFF
@ kDIR_USIZE_OFF
Definition: TZIPFile.h:63
TZIPFile::kDIR_ENTRY_POS_OFF
@ kDIR_ENTRY_POS_OFF
Definition: TZIPFile.h:70
TZIPFile::kZIP64_EXTENDED_HDR_OFFSET_LEN
@ kZIP64_EXTENDED_HDR_OFFSET_LEN
Definition: TZIPFile.h:122
TZIPFile::kDIR_FLAG_LEN
@ kDIR_FLAG_LEN
Definition: TZIPFile.h:58
TZIPFile::DecodeZip64ExtendedExtraField
Int_t DecodeZip64ExtendedExtraField(TZIPMember *m, Bool_t global=kTRUE)
Decode the Zip64 extended extra field.
Definition: TZIPFile.cxx:441
TZIPFile::kARCHIVE_VERSION
@ kARCHIVE_VERSION
Definition: TZIPFile.h:41
TZIPFile::kDEFLATED
@ kDEFLATED
Stored using deflate.
Definition: TZIPFile.h:128
TZIPFile::kZIP64_EXTENDED_USIZE_OFF
@ kZIP64_EXTENDED_USIZE_OFF
Definition: TZIPFile.h:120
int
TZIPFile::kZIP64_EDR_DIR_OFFSET_OFF
@ kZIP64_EDR_DIR_OFFSET_OFF
Definition: TZIPFile.h:83