00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00014
00021 #if !defined(ZIPARCHIVE_ZIPCENTRALDIR_DOT_H)
00022 #define ZIPARCHIVE_ZIPCENTRALDIR_DOT_H
00023
00024 #if _MSC_VER > 1000
00025 #pragma once
00026 #endif
00027
00028 #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL)
00029 #pragma warning (push)
00030 #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class
00031 #endif
00032
00033 #include "ZipException.h"
00034 #include "ZipFileHeader.h"
00035 #include "ZipAutoBuffer.h"
00036 #include "ZipCollections.h"
00037 #include "ZipCompatibility.h"
00038 #include "ZipExport.h"
00039 #include "ZipCallbackProvider.h"
00040 #include "ZipMutex.h"
00041
00042
00043 class CZipArchive;
00044
00048 class ZIP_API CZipCentralDir
00049 {
00050 public:
00051
00063 struct ZIP_API CZipFindFast
00064 {
00065 CZipFindFast()
00066 {
00067 m_uIndex = 0;
00068 m_pHeader= NULL;
00069 }
00070 CZipFindFast(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex):m_pHeader(pHeader), m_uIndex(uIndex){}
00071
00075 CZipFileHeader* m_pHeader;
00076
00080 ZIP_INDEX_TYPE m_uIndex;
00081 };
00082
00083
00088 struct ZIP_API CInfo
00089 {
00090
00095 ZIP_SIZE_TYPE m_uEndOffset;
00096
00101 ZIP_VOLUME_TYPE m_uLastVolume;
00102 ZIP_VOLUME_TYPE m_uVolumeWithCD;
00103 ZIP_INDEX_TYPE m_uVolumeEntriesNo;
00104 ZIP_INDEX_TYPE m_uEntriesNumber;
00105
00110 ZIP_SIZE_TYPE m_uSize;
00111
00117 ZIP_SIZE_TYPE m_uOffset;
00118
00119
00123 bool m_bInArchive;
00124
00125 private:
00126 friend class CZipCentralDir;
00127 void Init()
00128 {
00129 m_iReference = 1;
00130 #ifdef _ZIP_USE_LOCKING
00131 m_mutex.Open();
00132 #endif
00133 m_pCompare = GetCZipStrCompFunc(ZipPlatform::GetSystemCaseSensitivity());
00134 m_bCaseSensitive = false;
00135 m_bFindFastEnabled = false;
00136 m_pszComment.Release();
00137
00138 m_bInArchive = false;
00139 m_uEndOffset = 0;
00140 m_uLastVolume = 0;
00141 m_uVolumeWithCD = 0;
00142 m_uVolumeEntriesNo = 0;
00143 m_uEntriesNumber = 0;
00144 m_uSize = 0;
00145 m_uOffset = 0;
00146 }
00147 bool CheckIfOK_1()
00148 {
00149 return (m_uEndOffset >= m_uOffset + m_uSize);
00150 }
00151 ZIP_SIZE_TYPE CalculateBytesBeforeZip()
00152 {
00153 return m_uEndOffset - m_uSize - m_uOffset;
00154 }
00155 bool CheckIfOK_2()
00156 {
00157 return (m_uSize || !m_uEntriesNumber) && (m_uEntriesNumber || !m_uSize);
00158 }
00159
00169 bool NeedsZip64() const
00170 {
00171 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;
00172 }
00173
00174 CZipAutoBuffer m_pszComment;
00175
00179 bool m_bCaseSensitive;
00180
00184 bool m_bFindFastEnabled;
00185
00186 private:
00190 ZIPSTRINGCOMPARE m_pCompare;
00191 int m_iReference;
00192 #ifdef _ZIP_USE_LOCKING
00193 ZipArchiveLib::CZipMutex m_mutex;
00194 #endif
00195 };
00196
00197 CZipCentralDir();
00198 virtual ~CZipCentralDir();
00199
00200 static char m_gszSignature[];
00201 static char m_gszSignature64Locator[];
00202 CZipFileHeader* m_pOpenedFile;
00203
00211 void InitOnCreate(CZipArchive* pArchive);
00212
00221 void Init(CZipCentralDir* pSource = NULL);
00222
00233 void Read(bool bExhaustiveRead);
00234
00242 void OpenFile(ZIP_INDEX_TYPE uIndex);
00243
00253 bool IsValidIndex(ZIP_INDEX_TYPE uIndex)const;
00254
00269 void RemoveFile(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex = ZIP_FILE_INDEX_UNSPECIFIED, bool bShift = true);
00270
00271
00282 void RemoveLastFile(CZipFileHeader* pHeader = NULL, ZIP_INDEX_TYPE uIndex = ZIP_FILE_INDEX_UNSPECIFIED);
00283
00288 void RemoveAll();
00289
00293 void Close();
00294
00314 CZipFileHeader* AddNewFile(const CZipFileHeader & header, ZIP_INDEX_TYPE uReplaceIndex, int iLevel, bool bRichHeaderTemplateCopy = false);
00315
00320 void RemoveFromDisk();
00321
00334 ZIP_SIZE_TYPE GetSize(bool bWhole = false) const;
00335
00343 void CloseFile(bool skipCheckingDataDescriptor = false);
00344
00349 void CloseNewFile();
00350
00355 void Write();
00356
00363 void EnableFindFast(bool bEnable, bool bCaseSensitive);
00364
00371 ZIP_INDEX_TYPE FindFile(LPCTSTR lpszFileName, bool bCaseSensitive, bool bSporadically, bool bFileNameOnly);
00372
00373
00380 ZIP_INDEX_TYPE GetFindFastIndex(ZIP_INDEX_TYPE uFindFastIndex)const
00381 {
00382 if (!IsValidIndex(uFindFastIndex) || !m_pInfo->m_bFindFastEnabled)
00383 return ZIP_FILE_INDEX_NOT_FOUND;
00384
00385 return (*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)uFindFastIndex]->m_uIndex;
00386 }
00387
00388
00395 CZipFileHeader* operator[](ZIP_INDEX_TYPE uIndex)
00396 {
00397 return (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uIndex];
00398 }
00399
00406 const CZipFileHeader* operator[](ZIP_INDEX_TYPE uIndex) const
00407 {
00408 return (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uIndex];
00409 }
00410
00418 ZIP_ARRAY_SIZE_TYPE GetCount() const
00419 {
00420 return m_pHeaders == NULL ? 0 : m_pHeaders->GetSize();
00421 }
00422
00429 void SetComment(LPCTSTR lpszComment, UINT codePage);
00430
00437 void GetComment(CZipString& szComment) const;
00438
00439
00440
00454 ZIP_INDEX_TYPE FindFileNameIndex(LPCTSTR lpszFileName) const;
00455
00462 void GetInfo(CInfo& info) const {info = *m_pInfo;}
00463
00470 bool IsFindFastEnabled(){return m_pInfo->m_bFindFastEnabled;}
00471
00475 void RebuildFindFastArray()
00476 {
00477 if (m_pInfo->m_bFindFastEnabled)
00478 BuildFindFastArray(m_pInfo->m_bCaseSensitive);
00479 }
00480
00487 int m_iIgnoredChecks;
00488
00501 bool IsConsistencyCheckOn(int iLevel)
00502 {
00503
00504 return (m_iIgnoredChecks & iLevel) == 0;
00505 }
00506
00513 CZipStorage* GetStorage() {return m_pStorage;}
00514 #ifdef _ZIP_UNICODE_CUSTOM
00515
00521 const CZipStringStoreSettings& GetStringStoreSettings() const;
00522 #endif
00523
00530 bool OnFileNameChange(CZipFileHeader* pHeader);
00531
00539 bool OnFileCentralChange();
00540
00547 void SetUnicodeMode(int iMode) {m_iUnicodeMode = iMode;}
00548
00555 int GetUnicodeMode() const {return m_iUnicodeMode;}
00556
00566 bool IsAnyFileModified() const;
00567
00571 void ThrowError(int err) const;
00572
00573 CZipArchive* GetArchive()
00574 {
00575 return m_pArchive;
00576 }
00577
00578 ZIP_FILE_USIZE LocateSignature() ;
00579 protected:
00580
00584 CZipArchive* m_pArchive;
00585
00589 CZipStorage* m_pStorage;
00590
00591
00592 #if _MSC_VER > 1000
00593 #pragma warning( push )
00594 #pragma warning (disable : 4702) // unreachable code
00595 #endif
00596
00600 int m_iUnicodeMode;
00601
00605 static int CompareHeaders(const void *pArg1, const void *pArg2)
00606 {
00607 CZipFileHeader* pw1 = *(CZipFileHeader**)pArg1;
00608 CZipFileHeader* pw2 = *(CZipFileHeader**)pArg2;
00609 if (pw1 == pw2)
00610 return 0;
00611
00612 if (pw1->m_uVolumeStart == pw2->m_uVolumeStart)
00613 {
00614 if (pw1->m_uOffset < pw2->m_uOffset)
00615 return -1;
00616 else if (pw1->m_uOffset > pw2->m_uOffset)
00617 return 1;
00618 ASSERT(FALSE);
00619
00620
00621
00622 CZipException::Throw(CZipException::badZipFile);
00623 return 0;
00624 }
00625 else if (pw1->m_uVolumeStart < pw2->m_uVolumeStart)
00626 return -1;
00627 else
00628 return 1;
00629 }
00630
00631 #if _MSC_VER > 1000
00632 #pragma warning( pop )
00633 #endif
00634
00635 static int CompareFindFastCollate(const void* pArg1, const void* pArg2)
00636 {
00637 CZipFindFast* pHeader1 = *(CZipFindFast**)pArg1;
00638 CZipFindFast* pHeader2 = *(CZipFindFast**)pArg2;
00639 return pHeader1->m_pHeader->GetFileName().Collate(pHeader2->m_pHeader->GetFileName());
00640 }
00641
00642 static int CompareFindFastCollateNoCase(const void* pArg1, const void* pArg2)
00643 {
00644 CZipFindFast* pHeader1 = *(CZipFindFast**)pArg1;
00645 CZipFindFast* pHeader2 = *(CZipFindFast**)pArg2;
00646 return pHeader1->m_pHeader->GetFileName().CollateNoCase(pHeader2->m_pHeader->GetFileName());
00647 }
00648
00655 CZipArray<CZipFileHeader*>* m_pHeaders;
00656
00657
00661 void BuildFindFastArray( bool bCaseSensitive );
00662
00663 void ClearFindFastArray()
00664 {
00665 ZIP_ARRAY_SIZE_TYPE uCount = m_pFindArray->GetSize();
00666 for (ZIP_ARRAY_SIZE_TYPE i = 0; i < uCount; i++)
00667 delete (*m_pFindArray)[i];
00668 m_pFindArray->RemoveAll();
00669 }
00670
00681 CZipArray<CZipFindFast*>* m_pFindArray;
00682
00683
00699 int CompareElement(LPCTSTR lpszFileName, ZIP_INDEX_TYPE uIndex) const
00700 {
00701 return ((*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)uIndex]->m_pHeader->GetFileName().*(m_pInfo->m_pCompare))(lpszFileName);
00702 }
00703
00718 ZIP_INDEX_TYPE InsertFindFastElement(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex);
00719
00729 ZIP_INDEX_TYPE RemoveFindFastElement(CZipFileHeader* pHeader, bool bShift);
00730
00737 CInfo* m_pInfo;
00738
00749 void ReadHeaders(bool bExhaustiveRead);
00750
00754 void RemoveHeaders();
00755
00768 bool RemoveDataDescr(bool bFromBuffer);
00769
00773 void WriteHeaders(bool bOneDisk);
00774
00782 void WriteCentralEnd();
00783
00784
00791 void CreateSharedData();
00792
00801 void DestroySharedData();
00802
00803 #ifdef _ZIP_USE_LOCKING
00804
00813 void LockAccess()
00814 {
00815
00816 ASSERT(m_pInfo);
00817 m_pInfo->m_mutex.Lock();
00818 }
00819
00829 void UnlockAccess()
00830 {
00831 if (m_pInfo)
00832 m_pInfo->m_mutex.Unlock();
00833 }
00834 #endif
00835 private:
00836 void InitUnicode();
00837 };
00838
00839 #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL)
00840 #pragma warning (pop)
00841 #endif
00842
00843
00844 #endif // !defined(ZIPARCHIVE_ZIPCENTRALDIR_DOT_H)