ZipCentralDir.h
Go to the documentation of this file.
1 
2 // This source file is part of the ZipArchive library source distribution and
3 // is Copyrighted 2000 - 2013 by Artpol Software - Tadeusz Dracz
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // For the licensing details refer to the License.txt file.
11 //
12 // Web Site: http://www.artpol-software.com
14 
21 #if !defined(ZIPARCHIVE_ZIPCENTRALDIR_DOT_H)
22 #define ZIPARCHIVE_ZIPCENTRALDIR_DOT_H
23 
24 #if _MSC_VER > 1000
25 #pragma once
26 #endif
27 
28 #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL)
29  #pragma warning (push)
30  #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class
31 #endif
32 
33 #include "ZipException.h"
34 #include "ZipFileHeader.h"
35 #include "ZipAutoBuffer.h"
36 #include "ZipCollections.h"
37 #include "ZipCompatibility.h"
38 #include "ZipExport.h"
39 #include "ZipCallbackProvider.h"
40 #include "ZipMutex.h"
41 
42 
43 class CZipArchive;
44 
48 class ZIP_API CZipCentralDir
49 {
50 public:
51 
63  struct ZIP_API CZipFindFast
64  {
65  CZipFindFast()
66  {
67  m_uIndex = 0;
68  m_pHeader= NULL;
69  }
70  CZipFindFast(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex):m_pHeader(pHeader), m_uIndex(uIndex){}
71 
76 
80  ZIP_INDEX_TYPE m_uIndex;
81  };
82 
83 
88  struct ZIP_API CInfo
89  {
90 
95  ZIP_SIZE_TYPE m_uEndOffset;
96 
101  ZIP_VOLUME_TYPE m_uLastVolume;
102  ZIP_VOLUME_TYPE m_uVolumeWithCD;
103  ZIP_INDEX_TYPE m_uVolumeEntriesNo;
104  ZIP_INDEX_TYPE m_uEntriesNumber;
105 
110  ZIP_SIZE_TYPE m_uSize;
111 
117  ZIP_SIZE_TYPE m_uOffset;
118 
119 
124 
125  private:
126  friend class CZipCentralDir;
127  void Init()
128  {
129  m_iReference = 1;
130 #ifdef _ZIP_USE_LOCKING
131  m_mutex.Open();
132 #endif
133  m_pCompare = GetCZipStrCompFunc(ZipPlatform::GetSystemCaseSensitivity());
134  m_bCaseSensitive = false;
135  m_bFindFastEnabled = false;
136  m_pszComment.Release();
137  // initialize ( necessary when using 64 bits - we are copying only 4 bytes in Read())
138  m_bInArchive = false;
139  m_uEndOffset = 0;
140  m_uLastVolume = 0;
141  m_uVolumeWithCD = 0;
142  m_uVolumeEntriesNo = 0;
143  m_uEntriesNumber = 0;
144  m_uSize = 0;
145  m_uOffset = 0;
146  m_iLastIndexAdded = ZIP_FILE_INDEX_UNSPECIFIED;
147  }
148  bool CheckIfOK_1()
149  {
150  return (m_uEndOffset >= m_uOffset + m_uSize);
151  }
152  ZIP_SIZE_TYPE CalculateBytesBeforeZip()
153  {
154  return m_uEndOffset - m_uSize - m_uOffset;
155  }
156  bool CheckIfOK_2()
157  {
158  return (m_uSize || !m_uEntriesNumber) && (m_uEntriesNumber || !m_uSize);
159  }
160 
170  bool NeedsZip64() const
171  {
172  return m_uLastVolume >= USHRT_MAX || m_uVolumeWithCD >= USHRT_MAX || m_uVolumeEntriesNo >= USHRT_MAX || m_uEntriesNumber >= USHRT_MAX || m_uSize >= UINT_MAX || m_uOffset >= UINT_MAX;
173  }
174 
175  CZipAutoBuffer m_pszComment;
176 
180  bool m_bCaseSensitive;
181 
185  bool m_bFindFastEnabled;
186 
190  ZIP_INDEX_TYPE m_iLastIndexAdded;
191 
192  private:
196  ZIPSTRINGCOMPARE m_pCompare;
197  int m_iReference;
198 #ifdef _ZIP_USE_LOCKING
199  ZipArchiveLib::CZipMutex m_mutex;
200 #endif
201  };
202 
203  CZipCentralDir();
204  virtual ~CZipCentralDir();
205 
206  static char m_gszSignature[];
207  static char m_gszSignature64Locator[];
209 
217  void InitOnCreate(CZipArchive* pArchive);
218 
227  void Init(CZipCentralDir* pSource = NULL);
228 
232  void Read();
233 
241  void OpenFile(ZIP_INDEX_TYPE uIndex);
242 
252  bool IsValidIndex(ZIP_INDEX_TYPE uIndex)const;
253 
268  void RemoveFile(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex = ZIP_FILE_INDEX_UNSPECIFIED, bool bShift = true);
269 
270 
281  void RemoveLastFile(CZipFileHeader* pHeader = NULL, ZIP_INDEX_TYPE uIndex = ZIP_FILE_INDEX_UNSPECIFIED);
282 
287  void RemoveAll();
288 
292  void Close();
293 
313  CZipFileHeader* AddNewFile(const CZipFileHeader & header, ZIP_INDEX_TYPE uReplaceIndex, int iLevel, bool bRichHeaderTemplateCopy = false);
314 
321  ZIP_INDEX_TYPE GetLastIndexAdded() const
322  {
323  return m_pInfo ? m_pInfo->m_iLastIndexAdded : ZIP_FILE_INDEX_UNSPECIFIED;
324  }
325 
330  void RemoveFromDisk();
331 
344  ZIP_SIZE_TYPE GetSize(bool bWhole = false) const;
345 
353  void CloseFile(bool skipCheckingDataDescriptor = false);
354 
359  void CloseNewFile();
360 
365  void Write();
366 
373  void EnableFindFast(bool bEnable, bool bCaseSensitive);
374 
381  ZIP_INDEX_TYPE FindFile(LPCTSTR lpszFileName, bool bCaseSensitive, bool bSporadically, bool bFileNameOnly);
382 
383 
390  ZIP_INDEX_TYPE GetFindFastIndex(ZIP_INDEX_TYPE uFindFastIndex)const
391  {
392  if (!IsValidIndex(uFindFastIndex) || !m_pInfo->m_bFindFastEnabled)
393  return ZIP_FILE_INDEX_NOT_FOUND;
394 
395  return (*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)uFindFastIndex]->m_uIndex;
396  }
397 
398 
405  CZipFileHeader* operator[](ZIP_INDEX_TYPE uIndex)
406  {
407  return (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uIndex];
408  }
409 
416  const CZipFileHeader* operator[](ZIP_INDEX_TYPE uIndex) const
417  {
418  return (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uIndex];
419  }
420 
428  ZIP_ARRAY_SIZE_TYPE GetCount() const
429  {
430  return m_pHeaders == NULL ? 0 : m_pHeaders->GetSize();
431  }
432 
439  void SetComment(LPCTSTR lpszComment, UINT codePage);
440 
447  void GetComment(CZipString& szComment) const;
448 
449 
450 
464  ZIP_INDEX_TYPE FindFileNameIndex(LPCTSTR lpszFileName) const;
465 
472  void GetInfo(CInfo& info) const {info = *m_pInfo;}
473 
480  bool IsFindFastEnabled(){return m_pInfo->m_bFindFastEnabled;}
481 
486  {
487  if (m_pInfo->m_bFindFastEnabled)
488  BuildFindFastArray(m_pInfo->m_bCaseSensitive);
489  }
490 
498 
506 
519  bool IsConsistencyCheckOn(int iLevel)
520  {
521  // check, if not ignored
522  return (m_iIgnoredChecks & iLevel) == 0;
523  }
524 
532 #ifdef _ZIP_UNICODE_CUSTOM
533 
540 #endif
541 
548  bool OnFileNameChange(CZipFileHeader* pHeader, bool bInCentralOnly);
549 
557  bool OnFileCentralChange();
558 
565  void SetUnicodeMode(int iMode) {m_iUnicodeMode = iMode;}
566 
573  int GetUnicodeMode() const {return m_iUnicodeMode;}
574 
584  bool IsAnyFileModified() const;
585 
589  void ThrowError(int err) const;
590 
591  CZipArchive* GetArchive()
592  {
593  return m_pArchive;
594  }
595 
596  ZIP_FILE_USIZE LocateSignature() ;
597 protected:
598 
603 
608 
609 
610 #if _MSC_VER > 1000
611  #pragma warning( push )
612  #pragma warning (disable : 4702) // unreachable code
613 #endif
614 
615 
620 
624  static int CompareHeaders(const void *pArg1, const void *pArg2)
625  {
626  CZipFileHeader* pw1 = *(CZipFileHeader**)pArg1;
627  CZipFileHeader* pw2 = *(CZipFileHeader**)pArg2;
628  if (pw1 == pw2)
629  return 0;
630 
631  if (pw1->m_uVolumeStart == pw2->m_uVolumeStart)
632  {
633  if (pw1->m_uOffset < pw2->m_uOffset)
634  return -1;
635  else if (pw1->m_uOffset > pw2->m_uOffset)
636  return 1;
637  ASSERT(FALSE);
638 
639 
640  // two files with the same offsets in the same volume???
642  return 0; // just for the compiler comfort (and discomfort of another)
643  }
644  else if (pw1->m_uVolumeStart < pw2->m_uVolumeStart)
645  return -1;
646  else // if (pw1->m_uVolumeStart > pw2->m_uVolumeStart)
647  return 1;
648  }
649 
650 #if _MSC_VER > 1000
651  #pragma warning( pop )
652 #endif
653 
654  static int CompareFindFastCollate(const void* pArg1, const void* pArg2)
655  {
656  CZipFindFast* pHeader1 = *(CZipFindFast**)pArg1;
657  CZipFindFast* pHeader2 = *(CZipFindFast**)pArg2;
658  return pHeader1->m_pHeader->GetFileName().Collate(pHeader2->m_pHeader->GetFileName());
659  }
660 
661  static int CompareFindFastCollateNoCase(const void* pArg1, const void* pArg2)
662  {
663  CZipFindFast* pHeader1 = *(CZipFindFast**)pArg1;
664  CZipFindFast* pHeader2 = *(CZipFindFast**)pArg2;
665  return pHeader1->m_pHeader->GetFileName().CollateNoCase(pHeader2->m_pHeader->GetFileName());
666  }
667 
674  CZipArray<CZipFileHeader*>* m_pHeaders;
675 
676 
680  void BuildFindFastArray( bool bCaseSensitive );
681 
682  void ClearFindFastArray()
683  {
684  ZIP_ARRAY_SIZE_TYPE uCount = m_pFindArray->GetSize();
685  for (ZIP_ARRAY_SIZE_TYPE i = 0; i < uCount; i++)
686  delete (*m_pFindArray)[i];
687  m_pFindArray->RemoveAll();
688  }
689 
700  CZipArray<CZipFindFast*>* m_pFindArray;
701 
702 
718  int CompareElement(LPCTSTR lpszFileName, ZIP_INDEX_TYPE uIndex) const
719  {
720  return ((*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)uIndex]->m_pHeader->GetFileName().*(m_pInfo->m_pCompare))(lpszFileName);
721  }
722 
737  ZIP_INDEX_TYPE InsertFindFastElement(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex);
738 
748  ZIP_INDEX_TYPE RemoveFindFastElement(CZipFileHeader* pHeader, bool bShift);
749 
757 
761  void ReadHeaders();
762 
766  void RemoveHeaders();
767 
780  bool RemoveDataDescr(bool bFromBuffer);
781 
785  void WriteHeaders(bool bOneDisk);
786 
794  void WriteCentralEnd();
795 
796 
803  void CreateSharedData();
804 
813  void DestroySharedData();
814 
815 #ifdef _ZIP_USE_LOCKING
816 
825  void LockAccess()
826  {
827 
828  ASSERT(m_pInfo);
829  m_pInfo->m_mutex.Lock();
830  }
831 
841  void UnlockAccess()
842  {
843  if (m_pInfo)
844  m_pInfo->m_mutex.Unlock();
845  }
846 #endif
847 private:
848  void InitUnicode();
849 };
850 
851 #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL)
852  #pragma warning (pop)
853 #endif
854 
855 
856 #endif // !defined(ZIPARCHIVE_ZIPCENTRALDIR_DOT_H)

The ZipArchive Library Copyright © 2000 - 2013 Artpol Software - Tadeusz Dracz. Generated at Mon Feb 25 2013 16:29:20.