ZipStorage.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_ZIPSTORAGE_DOT_H)
22 #define ZIPARCHIVE_ZIPSTORAGE_DOT_H
23 
24 #if _MSC_VER > 1000
25  #pragma once
26  #if defined ZIP_HAS_DLL
27  #pragma warning (push)
28  #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class
29  #endif
30 #endif
31 
32 #include "ZipFile.h"
33 #include "ZipAutoBuffer.h"
34 #include "ZipString.h"
35 #include "ZipMemFile.h"
36 #include "ZipExport.h"
37 #include "ZipCallback.h"
38 #include "BitFlag.h"
39 #include "ZipSplitNamesHandler.h"
40 #include "ZipException.h"
41 #include "ZipCollections.h"
42 
46 class ZIP_API CZipStorage
47 {
48  friend class CZipArchive;
49  friend class CZipCentralDir;
50 public:
54  enum State
55  {
56  stateOpened = 0x0001,
57  stateReadOnly = 0x0002,
58  stateAutoClose = 0x0004,
59  stateExisting = 0x0008,
60  stateSegmented = 0x0010,
61  stateSplit = stateSegmented | 0x0020,
62  stateBinarySplit = stateSplit | 0x0040,
63  stateSpan = stateSegmented | 0x0080
64  };
65 
72  enum SeekType
73  {
76 
80  seekCurrent
81  };
82 
83  static const ZIP_FILE_USIZE SignatureNotFound;
84 
85  CZipStorage();
86  virtual ~CZipStorage();
87 
88  void Initialize();
93  void Open(CZipAbstractFile& af, int iMode, bool bAutoClose);
94 
100  void Open(LPCTSTR lpszPathName, int iMode, ZIP_SIZE_TYPE uVolumeSize);
101 
102 
115  CZipString GetSplitVolumeName(ZIP_VOLUME_TYPE uVolume, bool bLast)
116  {
117  if (m_pSplitNames == NULL)
118  {
120  return _T(""); // for Code Analysis
121  }
123  if (IsExisting())
125  return m_pSplitNames->GetVolumeName(m_szArchiveName, (ZIP_VOLUME_TYPE)(uVolume + 1), flags);
126  }
127 
133  void FinalizeSegm();
134 
135 
142  void UpdateSegmMode(ZIP_VOLUME_TYPE uLastVolume);
143 
154  ZIP_SIZE_TYPE AssureFree(ZIP_SIZE_TYPE uNeeded);
155 
170  void Write(const void *pBuf, DWORD iSize, bool bAtOnce);
171 
178  ZIP_SIZE_TYPE GetOccupiedSpace() const
179  {
180  return ZIP_SIZE_TYPE(m_pFile->GetLength() + m_uBytesInWriteBuffer);
181  }
182 
186  bool IsClosed(bool bArchive) const
187  {
188  if (bArchive)
189  return !m_state.IsSetAny(stateOpened);
190  else
191  // assume not auto-close files always opened
192  return !m_pFile || (m_state.IsSetAny(stateAutoClose) && m_pFile->IsClosed());
193  }
194 
209  DWORD Read(void* pBuf, DWORD iSize, bool bAtOnce);
210 
221  ZIP_SIZE_TYPE GetPosition() const
222  {
223  ZIP_SIZE_TYPE uPos = (ZIP_SIZE_TYPE)(m_pFile->GetPosition()) + m_uBytesInWriteBuffer;
224  if (m_uCurrentVolume == 0)
225  uPos -= m_uBytesBeforeZip;
226  else if (IsBinarySplit()) // not for the first volume
227  {
228  ZIP_VOLUME_TYPE uVolume = m_uCurrentVolume;
229  ASSERT(m_pCachedSizes->GetSize() > (ZIP_ARRAY_SIZE_TYPE)(uVolume - 1));
230  do
231  {
232  uVolume--;
233  uPos += (ZIP_SIZE_TYPE)m_pCachedSizes->GetAt((ZIP_ARRAY_SIZE_TYPE)uVolume);
234  }
235  while (uVolume > 0);
236  }
237  return uPos;
238  }
239 
240 
245  void Flush();
246 
247 
251  void FlushFile()
252  {
253  if (!IsReadOnly())
254  m_pFile->Flush();
255  }
256 
257  void FlushBuffers()
258  {
259  Flush();
260  FlushFile();
261  }
262 
270  void NextVolume(ZIP_SIZE_TYPE uNeeded);
271 
272 
276  ZIP_VOLUME_TYPE GetCurrentVolume() const {return m_uCurrentVolume;}
277 
278 
285  void ChangeVolume(ZIP_VOLUME_TYPE uNumber);
286 
290  void ChangeVolume()
291  {
292  ChangeVolume((ZIP_VOLUME_TYPE)(m_uCurrentVolume + 1));
293  }
294 
298  void ChangeVolumeDec()
299  {
300  if (m_uCurrentVolume == 0)
302  ChangeVolume((ZIP_VOLUME_TYPE)(m_uCurrentVolume - 1));
303  }
304 
311  bool IsSplit() const
312  {
313  return m_state.IsSetAll(stateSplit);
314  }
315 
322  bool IsBinarySplit() const
323  {
324  return m_state.IsSetAll(stateBinarySplit);
325  }
326 
333  bool IsRegularSplit() const
334  {
335  return m_state.IsSetAll(stateSplit) && !m_state.IsSetAll(stateBinarySplit);
336  }
337 
344  bool IsSpanned() const
345  {
346  return m_state.IsSetAll(stateSpan);
347  }
348 
352  bool IsReadOnly() const
353  {
354  return m_state.IsSetAny(stateReadOnly) || IsExistingSegmented();
355  }
356 
363  bool IsExistingSegmented() const
364  {
365  return m_state.IsSetAll(stateSegmented | stateExisting);
366  }
367 
374  bool IsNewSegmented() const
375  {
376  return m_state.IsSetAny(stateSegmented) && !IsExisting();
377  }
378 
385  bool IsSegmented() const
386  {
387  return m_state.IsSetAny(stateSegmented);
388  }
389 
396  bool IsExisting() const
397  {
398  return m_state.IsSetAny(stateExisting);
399  }
400 
409  bool SetSplitNamesHandler(CZipSplitNamesHandler* pNames, bool bAutoDelete)
410  {
411  if (m_state != 0)
412  {
413  ZIPTRACE("%s(%i) : The archive is already opened.\n");
414  return false;
415  }
416  ClearSplitNames();
417  m_pSplitNames = pNames;
418  m_bAutoDeleteSplitNames = bAutoDelete;
419  return true;
420  }
421 
430  CZipSplitNamesHandler* GetSplitNamesHandler()
431  {
432  return m_pSplitNames;
433  }
434 
443  const CZipSplitNamesHandler* GetSplitNamesHandler() const
444  {
445  return m_pSplitNames;
446  }
447 
458  ULONGLONG Seek(ULONGLONG lOff, SeekType iSeekType = seekFromBeginning);
459 
470  void SeekInBinary(ZIP_FILE_SIZE lOff, bool bSeekToBegin = false);
471 
478  ZIP_SIZE_TYPE VolumeLeft() const;
479 
493  CZipString Close(bool bWrite, bool bGetLastVolumeName = false);
494 
498  CZipAbstractFile* m_pFile;
499 
503  static char m_gszExtHeaderSignat[];
504 
505  ZipArchiveLib::CBitFlag& GetState()
506  {
507  return m_state;
508  }
509 
523  ZIP_FILE_USIZE LocateSignature(char* szSignature, ZIP_SIZE_TYPE uMaxDepth);
524 
525 protected:
526 
533  ZIP_SIZE_TYPE GetLastDataOffset()
534  {
535  return (ZIP_SIZE_TYPE)m_pFile->GetLength() - m_uBytesBeforeZip;
536  }
537 
541  void EmptyWriteBuffer()
542  {
543  m_uBytesInWriteBuffer = 0;
544  }
545 
561  bool OpenFile(LPCTSTR lpszName, UINT uFlags, bool bThrow = true);
562 
569  CZipString RenameLastFileInSplitArchive();
570 
581  void WriteInternalBuffer(const char *pBuf, DWORD uSize);
582 
589  ZIP_SIZE_TYPE GetFreeVolumeSpace() const;
590 
608  void CallCallback(ZIP_SIZE_TYPE uNeeded, int iCode, CZipString szTemp);
609 
613  CZipString ChangeSplitRead();
614 
618  CZipString ChangeSpannedRead();
619 
626  DWORD GetFreeInBuffer() const {return m_pWriteBuffer.GetSize() - m_uBytesInWriteBuffer;}
627 
635  ZIP_SIZE_TYPE m_uSplitData;
636 
641 
647  ZIP_SIZE_TYPE m_uCurrentVolSize;
648 
652  CZipAutoBuffer m_pWriteBuffer;
653 
658  ZIP_SIZE_TYPE m_uBytesWritten;
659 
664  ZIP_VOLUME_TYPE m_uCurrentVolume;
665 
671  ZIP_SIZE_TYPE m_uBytesBeforeZip;
672 
673 
681 
689 
698 
707 
708 private:
709  ZIP_FILE_USIZE LocateSignature(char* szSignature, ZIP_SIZE_TYPE uMaxDepth, int& leftToFind, bool& found, ZIP_FILE_USIZE uFileLength);
710 
711  CZipString GetSplitVolumeName(bool bLast)
712  {
713  return GetSplitVolumeName(m_uCurrentVolume, bLast);
714  }
715 
716  void ClearSplitNames()
717  {
718  if (m_pSplitNames)
719  {
720  if (m_bAutoDeleteSplitNames)
721  delete m_pSplitNames;
722  m_pSplitNames = NULL;
723  m_bAutoDeleteSplitNames = false;
724  }
725  }
726 
727  void ClearCachedSizes()
728  {
729  if (m_pCachedSizes)
730  {
731  delete m_pCachedSizes;
732  m_pCachedSizes = NULL;
733  }
734  }
735 
736  void EnsureSplitNames()
737  {
738  if (IsSplit())
739  {
740  if (m_pSplitNames == NULL)
741  {
742  m_bAutoDeleteSplitNames = true;
743  if (m_state.IsSetAll(stateBinarySplit))
744  m_pSplitNames = new CZipBinSplitNamesHandler();
745  else
746  m_pSplitNames = new CZipRegularSplitNamesHandler();
747  }
748  m_pSplitNames->Initialize(m_szArchiveName);
749  }
750  }
751 
752  ZIP_FILE_USIZE GetCachedSize(ZIP_VOLUME_TYPE uVolume)
753  {
754  ASSERT(m_pCachedSizes);
755  if (m_pCachedSizes->GetSize() > (ZIP_ARRAY_SIZE_TYPE)uVolume)
756  return m_pCachedSizes->GetAt((ZIP_ARRAY_SIZE_TYPE)uVolume);
758  // for a compiler
759  return 0;
760  }
761 
762  void CacheSizes();
763 
764  ZipArchiveLib::CBitFlag m_state;
765  CZipSegmCallback* m_pChangeVolumeFunc;
766  CZipString m_szArchiveName;
767  CZipFile m_internalfile;
768  CZipSplitNamesHandler* m_pSplitNames;
769  CZipArray<ZIP_FILE_USIZE>* m_pCachedSizes;
770  bool m_bAutoDeleteSplitNames;
771  void ThrowError(int err) const;
772 };
773 
774 #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL)
775  #pragma warning (pop)
776 #endif
777 
778 
779 #endif // !defined(ZIPARCHIVE_ZIPSTORAGE_DOT_H)

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