ZipCentralDir.h
Go to the documentation of this file.
1 
2 // This source file is part of the ZipArchive Library Open Source distribution
3 // and is Copyrighted 2000 - 2022 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: https://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 #pragma warning(suppress: 26495)
91  CInfo()
92  {
93  Init();
94  }
99  ZIP_SIZE_TYPE m_uEndOffset;
100 
105  ZIP_VOLUME_TYPE m_uLastVolume;
106  ZIP_VOLUME_TYPE m_uVolumeWithCD;
107  ZIP_INDEX_TYPE m_uVolumeEntriesNo;
108  ZIP_INDEX_TYPE m_uEntriesNumber;
109 
114  ZIP_SIZE_TYPE m_uSize;
115 
121  ZIP_SIZE_TYPE m_uOffset;
122 
123 
128 
129  private:
130  friend class CZipCentralDir;
131  void Init()
132  {
133  m_iReference = 1;
134 #ifdef _ZIP_USE_LOCKING
135  m_mutex.Open();
136 #endif
137  m_pCompare = GetCZipStrCompFunc(ZipPlatform::GetSystemCaseSensitivity());
138  m_bCaseSensitive = false;
139  m_bFindFastEnabled = false;
140  m_pszComment.Release();
141  // initialize ( necessary when using 64 bits - we are copying only 4 bytes in Read())
142  m_bInArchive = false;
143  m_uEndOffset = 0;
144  m_uLastVolume = 0;
145  m_uVolumeWithCD = 0;
146  m_uVolumeEntriesNo = 0;
147  m_uEntriesNumber = 0;
148  m_uSize = 0;
149  m_uOffset = 0;
150  m_iLastIndexAdded = ZIP_FILE_INDEX_UNSPECIFIED;
151  }
152  bool CheckIfOK_1()
153  {
154  return (m_uEndOffset >= m_uOffset + m_uSize);
155  }
156  ZIP_SIZE_TYPE CalculateBytesBeforeZip()
157  {
158  return m_uEndOffset - m_uSize - m_uOffset;
159  }
160  bool CheckIfOK_2()
161  {
162  return (m_uSize || !m_uEntriesNumber) && (m_uEntriesNumber || !m_uSize);
163  }
164 
174  bool NeedsZip64() const
175  {
176  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;
177  }
178 
179  CZipAutoBuffer m_pszComment;
180 
184  bool m_bCaseSensitive;
185 
189  bool m_bFindFastEnabled;
190 
194  ZIP_INDEX_TYPE m_iLastIndexAdded;
195 
196  private:
200  ZIPSTRINGCOMPARE m_pCompare;
201  int m_iReference;
202 #ifdef _ZIP_USE_LOCKING
203  ZipArchiveLib::CZipMutex m_mutex;
204 #endif
205  };
206 
207  CZipCentralDir();
208  virtual ~CZipCentralDir();
209 
210  static char m_gszSignature[];
211  static char m_gszSignature64Locator[];
213 
221  void InitOnCreate(CZipArchive* pArchive);
222 
231  void Init(CZipCentralDir* pSource = NULL);
232 
236  void Read();
237 
245  void OpenFile(ZIP_INDEX_TYPE uIndex);
246 
256  bool IsValidIndex(ZIP_INDEX_TYPE uIndex)const;
257 
272  void RemoveFile(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex = ZIP_FILE_INDEX_UNSPECIFIED, bool bShift = true);
273 
274 
285  void RemoveLastFile(CZipFileHeader* pHeader = NULL, ZIP_INDEX_TYPE uIndex = ZIP_FILE_INDEX_UNSPECIFIED);
286 
291  void RemoveAll();
292 
296  void Close();
297 
317  CZipFileHeader* AddNewFile(const CZipFileHeader & header, ZIP_INDEX_TYPE uReplaceIndex, int iLevel, bool bRichHeaderTemplateCopy = false);
318 
325  ZIP_INDEX_TYPE GetLastIndexAdded() const
326  {
327  return m_pInfo ? m_pInfo->m_iLastIndexAdded : ZIP_FILE_INDEX_UNSPECIFIED;
328  }
329 
334  void RemoveFromDisk();
335 
348  ZIP_SIZE_TYPE GetSize(bool bWhole = false) const;
349 
357  void CloseFile(bool skipCheckingDataDescriptor = false);
358 
363  void CloseNewFile();
364 
369  void Write();
370 
377  void EnableFindFast(bool bEnable, bool bCaseSensitive);
378 
385  ZIP_INDEX_TYPE FindFile(LPCTSTR lpszFileName, bool bCaseSensitive, bool bSporadically, bool bFileNameOnly);
386 
387 
394  ZIP_INDEX_TYPE GetFindFastIndex(ZIP_INDEX_TYPE uFindFastIndex)const
395  {
396  if (!IsValidIndex(uFindFastIndex) || !m_pInfo->m_bFindFastEnabled)
397  return ZIP_FILE_INDEX_NOT_FOUND;
398 
399  return (*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)uFindFastIndex]->m_uIndex;
400  }
401 
402 
409  CZipFileHeader* operator[](ZIP_INDEX_TYPE uIndex)
410  {
411  return (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uIndex];
412  }
413 
420  const CZipFileHeader* operator[](ZIP_INDEX_TYPE uIndex) const
421  {
422  return (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uIndex];
423  }
424 
432  ZIP_ARRAY_SIZE_TYPE GetCount() const
433  {
434  return m_pHeaders == NULL ? 0 : m_pHeaders->GetSize();
435  }
436 
443  void SetComment(LPCTSTR lpszComment, UINT codePage);
444 
451  void GetComment(CZipString& szComment) const;
452 
453 
454 
468  ZIP_INDEX_TYPE FindFileNameIndex(LPCTSTR lpszFileName) const;
469 
476  void GetInfo(CInfo& info) const {info = *m_pInfo;}
477 
484  bool IsFindFastEnabled(){return m_pInfo->m_bFindFastEnabled;}
485 
490  {
491  if (m_pInfo->m_bFindFastEnabled)
492  BuildFindFastArray(m_pInfo->m_bCaseSensitive);
493  }
494 
502 
510 
523  bool IsConsistencyCheckOn(int iLevel)
524  {
525  // check, if not ignored
526  return (m_iIgnoredChecks & iLevel) == 0;
527  }
528 
536 #ifdef _ZIP_UNICODE_CUSTOM
537 
544 #endif
545 
552  bool OnFileNameChange(CZipFileHeader* pHeader, bool bInCentralOnly);
553 
561  bool OnFileCentralChange();
562 
569  void SetUnicodeMode(int iMode) {m_iUnicodeMode = iMode;}
570 
577  int GetUnicodeMode() const {return m_iUnicodeMode;}
578 
588  bool IsAnyFileModified() const;
589 
593  void ThrowError(int err) const;
594 
595  CZipArchive* GetArchive()
596  {
597  return m_pArchive;
598  }
599 
600  ZIP_FILE_USIZE LocateSignature() ;
601 protected:
602 
607 
612 
613 
614 #if _MSC_VER > 1000
615  #pragma warning( push )
616  #pragma warning (disable : 4702) // unreachable code
617 #endif
618 
619 
624 
628  static int CompareHeaders(const void *pArg1, const void *pArg2)
629  {
630  CZipFileHeader* pHeader1 = *(CZipFileHeader**)pArg1;
631  CZipFileHeader* pHeader2 = *(CZipFileHeader**)pArg2;
632 
633  if (pHeader1 == pHeader2)
634  return 0;
635 
636  if (pHeader1->m_uVolumeStart == pHeader2->m_uVolumeStart)
637  {
638  if (pHeader1->m_uOffset < pHeader2->m_uOffset)
639  return -1;
640  else if (pHeader1->m_uOffset > pHeader2->m_uOffset)
641  return 1;
642  // if we have two headers with the same offset on the same volume,
643  // we want them to be next to each other so that we can throw an exception while verifying headers after sorting
644  else
645  return 0;
646  }
647  else if (pHeader1->m_uVolumeStart < pHeader2->m_uVolumeStart)
648  return -1;
649  else // if (pHeader1->m_uVolumeStart > pHeader2->m_uVolumeStart)
650  return 1;
651  }
652 
653 #if _MSC_VER > 1000
654  #pragma warning( pop )
655 #endif
656 
657  static int CompareFindFastCollate(const void* pArg1, const void* pArg2)
658  {
659  CZipFindFast* pHeader1 = *(CZipFindFast**)pArg1;
660  CZipFindFast* pHeader2 = *(CZipFindFast**)pArg2;
661  return pHeader1->m_pHeader->GetFileName().Collate(pHeader2->m_pHeader->GetFileName());
662  }
663 
664  static int CompareFindFastCollateNoCase(const void* pArg1, const void* pArg2)
665  {
666  CZipFindFast* pHeader1 = *(CZipFindFast**)pArg1;
667  CZipFindFast* pHeader2 = *(CZipFindFast**)pArg2;
668  return pHeader1->m_pHeader->GetFileName().CollateNoCase(pHeader2->m_pHeader->GetFileName());
669  }
670 
677  CZipArray<CZipFileHeader*>* m_pHeaders;
678 
679 
683  void BuildFindFastArray( bool bCaseSensitive );
684 
685  void ClearFindFastArray()
686  {
687  ZIP_ARRAY_SIZE_TYPE uCount = m_pFindArray->GetSize();
688  for (ZIP_ARRAY_SIZE_TYPE i = 0; i < uCount; i++)
689  delete (*m_pFindArray)[i];
690  m_pFindArray->RemoveAll();
691  }
692 
703  CZipArray<CZipFindFast*>* m_pFindArray;
704 
705 
721  int CompareElement(LPCTSTR lpszFileName, ZIP_INDEX_TYPE uIndex) const
722  {
723  return ((*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)uIndex]->m_pHeader->GetFileName().*(m_pInfo->m_pCompare))(lpszFileName);
724  }
725 
740  ZIP_INDEX_TYPE InsertFindFastElement(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex);
741 
751  ZIP_INDEX_TYPE RemoveFindFastElement(CZipFileHeader* pHeader, bool bShift);
752 
760 
764  void ReadHeaders();
765 
769  void RemoveHeaders();
770 
783  bool RemoveDataDescr(bool bFromBuffer);
784 
788  void WriteHeaders(bool bOneDisk);
789 
797  void WriteCentralEnd();
798 
799 
806  void CreateSharedData();
807 
816  void DestroySharedData();
817 
818 #ifdef _ZIP_USE_LOCKING
819 
828  void LockAccess()
829  {
830 
831  ASSERT(m_pInfo);
832  m_pInfo->m_mutex.Lock();
833  }
834 
844  void UnlockAccess()
845  {
846  if (m_pInfo)
847  m_pInfo->m_mutex.Unlock();
848  }
849 #endif
850 private:
851  void InitUnicode();
852 };
853 
854 #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL)
855  #pragma warning (pop)
856 #endif
857 
858 
859 #endif // !defined(ZIPARCHIVE_ZIPCENTRALDIR_DOT_H)

The ZipArchive Library Copyright © 2000 - 2022 Artpol Software - Tadeusz Dracz. Generated at Sat Dec 17 2022 19:57:03.