diff options
Diffstat (limited to 'zip/ZipArchive/ZipFileHeader.h')
| -rw-r--r-- | zip/ZipArchive/ZipFileHeader.h | 632 |
1 files changed, 487 insertions, 145 deletions
diff --git a/zip/ZipArchive/ZipFileHeader.h b/zip/ZipArchive/ZipFileHeader.h index c8a013a..876a244 100644 --- a/zip/ZipArchive/ZipFileHeader.h +++ b/zip/ZipArchive/ZipFileHeader.h @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////////
-// This source file is part of the ZipArchive library source distribution and
-// is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz
+// This source file is part of the ZipArchive Library Open Source distribution
+// and is Copyrighted 2000 - 2022 by Artpol Software - Tadeusz Dracz
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -9,7 +9,7 @@ //
// For the licensing details refer to the License.txt file.
//
-// Web Site: http://www.artpol-software.com
+// Web Site: https://www.artpol-software.com
////////////////////////////////////////////////////////////////////////////////
/**
@@ -17,7 +17,6 @@ * Includes the CZipFileHeader class.
*
*/
-
#if !defined(ZIPARCHIVE_ZIPFILEHEADER_DOT_H)
#define ZIPARCHIVE_ZIPFILEHEADER_DOT_H
@@ -34,6 +33,7 @@ #include "ZipExtraField.h"
#include "ZipStringStoreSettings.h"
#include "ZipCryptograph.h"
+#include "BitFlag.h"
class CZipCentralDir;
@@ -45,8 +45,26 @@ class ZIP_API CZipFileHeader {
friend class CZipCentralDir;
friend class CZipArchive;
+protected:
+ CZipFileHeader(CZipCentralDir* pCentralDir);
public:
+ /**
+ File header state flags.
+
+ \see
+ CZipArchive::UnicodeMode
+ */
+ enum StateFlags
+ {
+ sfNone = 0x00, ///< No special flags set.
+#ifdef _ZIP_UNICODE_CUSTOM
+ sfCustomUnicode = 0x10, ///< The header uses custom Unicode functionality.
+#endif
+ sfModified = 0x20 ///< The file has been modified.
+ };
+
CZipFileHeader();
+#pragma warning(suppress: 26495)
CZipFileHeader(const CZipFileHeader& header)
{
*this = header;
@@ -62,24 +80,35 @@ public: */
int PredictFileNameSize() const
{
- if (m_pszFileNameBuffer.IsAllocated())
- return m_pszFileNameBuffer.GetSize();
+ if (m_fileName.HasBuffer())
+ {
+ return m_fileName.GetBufferSize();
+ }
CZipAutoBuffer buffer;
ConvertFileName(buffer);
return buffer.GetSize();
}
-
+
/**
- Gets the comment size.
+ Predicts a file comment size.
\return
The number of characters in the comment not including a terminating \c NULL character.
*/
- WORD GetCommentSize() const {return (WORD)m_pszComment.GetSize();}
+ int PredictCommentSize() const
+ {
+ if (m_comment.HasBuffer())
+ {
+ return m_comment.GetBufferSize();
+ }
+ CZipAutoBuffer buffer;
+ ConvertComment(buffer);
+ return buffer.GetSize();
+ }
/**
- Gets the filename. If necessary, performs the conversion using the current filename code page.
+ Returns the filename. If necessary, performs the conversion using the current filename code page.
Caches the result of conversion for faster access the next time.
\param bClearBuffer
@@ -93,39 +122,147 @@ public: \see
<a href="kb">0610051525</a>
+ \see
+ SetFileName
+ \see
+ GetFileTitle
+ \see
+ GetFileExtension
+ \see
+ GetStringStoreSettings
+ \see
+ CZipStringStoreSettings::m_uNameCodePage
+ */
+ const CZipString& GetFileName(bool bClearBuffer = true);
+
+ /**
+ Returns the filename without the extension. If necessary, performs the conversion using the current filename code page.
+ Caches the result of conversion for faster access the next time.
+
+ \param bLowerCase
+ If \c true, the returned string will be lower-cased (for string comparison purposes).
+ \param bClearBuffer
+ If \c true, releases the internal buffer after performing the filename conversion.
+ If \c false, the internal buffer is not released and both representations of the
+ filename are kept in memory (converted and not converted). This takes more memory, but the
+ conversion does not take place again when the central directory is written back to the archive.
+
+ \return
+ The filename title.
+
+ \see
+ <a href="kb">0610051525</a>
+ \see
+ GetFileName
+ \see
+ SetFileName
+ \see
+ GetFileExtension
+ \see
+ GetStringStoreSettings
+ \see
+ CZipStringStoreSettings::m_uNameCodePage
+ */
+ CZipString GetFileTitle(bool bLowerCase = false, bool bClearBuffer = true);
+
+
+ /**
+ Returns the extension of the filename. If necessary, performs the conversion using the current filename code page.
+ Caches the result of conversion for faster access the next time.
+
+ \param bLowerCase
+ If \c true, the returned string will be lower-cased (for string comparison purposes).
+ \param bClearBuffer
+ If \c true, releases the internal buffer after performing the filename conversion.
+ If \c false, the internal buffer is not released and both representations of the
+ filename are kept in memory (converted and not converted). This takes more memory, but the
+ conversion does not take place again when the central directory is written back to the archive.
+
+ \return
+ The filename extension.
+
+ \see
+ <a href="kb">0610051525</a>
+ \see
+ GetFileName
+ \see
+ SetFileName
+ \see
+ GetFileTitle
\see
GetStringStoreSettings
\see
CZipStringStoreSettings::m_uNameCodePage
*/
- CZipString& GetFileName(bool bClearBuffer = true);
+ CZipString GetFileExtension(bool bLowerCase = false, bool bClearBuffer = true);
/**
Sets the filename.
+ The actual renaming of the file inside of the archive depends on the current commit mode.
+
\param lpszFileName
The filename to set.
+ \param bInCentralOnly
+ If set to \c true, rename the file in the central directory only. The local header will not be changed.
+ This way a file can be renamed quickly and safer. Most of the software (excluding XCeed) usually doesn't pay an attention to the information in the local header.
+
+ \return
+ \c true, if the method succeeded; \c false, if the current state of the archive is invalid for this method to be called.
+
+ \note
+ Leading path separators are removed from the filename unless the header is a directory and the filename contains of only one path separator (indicating a root path).
+
+ \see
+ <a href="kb">0610231944|rename</a>
+ \see
+ GetFileName
+ \see
+ GetFileTitle
+ \see
+ GetFileExtension
+ \see
+ CZipArchive::CommitChanges
*/
- void SetFileName(LPCTSTR lpszFileName);
+ bool SetFileName(LPCTSTR lpszFileName, bool bInCentralOnly = false);
/**
- Gets the file comment.
+ Returns the file comment.
+
+ \param bClearBuffer
+ If \c true, releases the internal buffer after performing the comment conversion.
+ If \c false, the internal buffer is not released and both representations of the
+ comment are kept in memory (converted and not converted). This takes more memory, but the
+ conversion does not take place again when the central directory is written back to the archive.
\return
The file comment.
+
+ \see
+ <a href="kb">0610231944|comment</a>
+ \see
+ SetComment
*/
- CZipString GetComment() const;
+ const CZipString& GetComment(bool bClearBuffer = false);
/**
Sets the file comment.
\param lpszComment
The file comment.
+
+ \return
+ \c true, if the method succeeded; \c false, if the current state of the archive is invalid for this method to be called.
+
+ \see
+ <a href="kb">0610231944|comment</a>
+ \see
+ GetComment
*/
- void SetComment(LPCTSTR lpszComment);
+ bool SetComment(LPCTSTR lpszComment);
/**
- Gets a value indicating whether the data descriptor is present or not.
+ Returns the value indicating whether the data descriptor is present.
\return
\c true, if the data descriptor is present; \c false otherwise.
@@ -133,12 +270,12 @@ public: bool IsDataDescriptor()const { return (m_uFlag & (WORD) 8) != 0;}
/**
- Gets the data descriptor size as it is required for the current file.
+ Returns the data descriptor size as it is required for the current file.
Takes into account various factors, such as the archive segmentation type,
encryption and the need for the Zip64 format.
\param pStorage
- The storage to test for segmentation type.
+ The storage to test for the segmentation type.
\return
The required data descriptor size in bytes.
@@ -149,7 +286,7 @@ public: }
/**
- Gets the data descriptor size as it is required for the current file.
+ Returns the data descriptor size as it is required for the current file.
Takes into account various factors, such as the need for the data descriptor signature
or for the Zip64 format.
@@ -159,19 +296,14 @@ public: \return
The required data descriptor size in bytes.
*/
- WORD GetDataDescriptorSize(bool bConsiderSignature = false) const;
-
+ WORD GetDataDescriptorSize(bool bConsiderSignature = false) const;
/**
- Gets the size of the compressed data.
-
- \param bUseLocal
- If \c true, uses #m_uLocalComprSize; otherwise uses #m_uComprSize;
+ Returns the size of the compressed data.
\param bReal
- If \c true, the returned value does not include the encrypted information size, only the data size.
- If \c false, the encrypted information size is added (you should not use this value
- when the file exists in the archive).
+ Set to \c true when calling for a file already in an archive.
+ Set to \c false when the header is not a part of the archive.
\return
The compressed data size in bytes.
@@ -179,15 +311,14 @@ public: \see
GetEncryptedInfoSize
*/
- ZIP_SIZE_TYPE GetDataSize(bool bUseLocal = false, bool bReal = true) const
+ ZIP_SIZE_TYPE GetDataSize(bool bReal) const
{
- ZIP_SIZE_TYPE uSize = bUseLocal ? m_uLocalComprSize : m_uComprSize;
DWORD uEncrSize = GetEncryptedInfoSize();
- return bReal ? (uSize - uEncrSize) : (uSize + uEncrSize);
+ return bReal ? (m_uComprSize - uEncrSize) : (m_uComprSize + uEncrSize);
}
/**
- Gets the encrypted information size. The returned value depends on the used encryption method.
+ Returns the encrypted information size. The returned value depends on the used encryption method.
\return
The encrypted information size in bytes.
@@ -198,15 +329,15 @@ public: }
/**
- Gets the total size of the structure in the central directory.
+ Returns the total size of this structure in the central directory.
\return
The total size in bytes.
*/
- DWORD GetSize()const;
+ DWORD GetSize() const;
/**
- Gets the local header size. Before calling this method, the local information must be up-to-date
+ Returns the local header size. Before calling this method, the local information must be up-to-date
(see <a href="kb">0610242128|local</a> for more information).
\param bReal
@@ -219,7 +350,7 @@ public: DWORD GetLocalSize(bool bReal) const;
/**
- Gets a value indicating if the compression is efficient.
+ Returns the value indicating whether the compression is efficient.
\return
\c true if the compression is efficient; \c false if the file should be
@@ -229,19 +360,19 @@ public: {
ZIP_SIZE_TYPE uBefore = m_uUncomprSize;
// ignore the length of encryption info
- ZIP_SIZE_TYPE uAfter = GetDataSize(false, true);
+ ZIP_SIZE_TYPE uAfter = GetDataSize(true);
return uAfter <= uBefore;
}
/**
- Gets the compression ratio.
+ Returns the compression ratio.
\return
The compression ratio of the file.
*/
float GetCompressionRatio()
{
-#if _MSC_VER >= 1300 || !defined(_ZIP64)
+#if _MSC_VER >= 1300 || !defined(_ZIP_ZIP64)
return m_uUncomprSize ? ((float)m_uComprSize * 100 ) / m_uUncomprSize: 0;
#else
return m_uUncomprSize ? ((float)(__int64)(m_uComprSize) / (float)(__int64)m_uUncomprSize) * 100: 0;
@@ -249,35 +380,99 @@ public: }
/**
- Sets the file modification date.
+ Sets the file creation time. The time will be stored in a dedicated extra header.
\param ttime
- The date to set. If this value is incorrect, the date defaults to January 1, 1980.
+ The time to set.
+
+ \see
+ GetCreationTime
+ \see
+ SetModificationTime
+ \see
+ <a href="kb">0610231944|filetimes</a>
+ */
+ void SetCreationTime(const time_t& ttime){m_tCreationTime = ttime;}
+
+ /**
+ Returns the file creation time.
+
+ \return
+ The creation time.
+ \see
+ SetCreationTime
+ \see
+ <a href="kb">0610231944|filetimes</a>
+ */
+ time_t GetCreationTime()const{return m_tCreationTime;}
+
+ /**
+ Sets the file modification time.
+ \param ttime
+ The time to set.
+ \param bFullResolution
+ If \c true, file time will be additionally stored as 64-bit Windows file time in a dedicated extra header.
+ Regular PKZIP format will be preserved allowing proper extraction of the archive by software that do not support this extension.
+ If \c false, the extra header will not be used and creation and last access time will be cleared.
+ \param bUseUtcTime
+ If \c true, UTC time will be used.
+ If \c false, local time will be used.
+ \see
+ CZipArchive::SetFullFileTimes
\see
- GetTime
+ GetModificationTime
+ \see
+ <a href="kb">0610231944|filetimes</a>
*/
- void SetTime(const time_t& ttime);
+ void SetModificationTime(const time_t& ttime, bool bFullResolution = false, bool bUseUtcTime = false );
/**
- Gets the file modification time.
+ Returns the file modification time.
\return
The modification time.
\see
- SetTime
+ SetModificationTime
+ */
+ time_t GetModificationTime()const;
+
+ /**
+ Returns the file last access time.
+
+ \return
+ The last access time.
+ \see
+ SetLastAccessTime
+ \see
+ <a href="kb">0610231944|filetimes</a>
+ */
+ time_t GetLastAccessTime()const{return m_tLastAccessTime;}
+
+ /**
+ Sets the file last access time. The time will be stored in a dedicated extra header.
+
+ \param ttime
+ The time to set.
+
+ \see
+ GetLastAccessTime
+ \see
+ SetModificationTime
+ \see
+ <a href="kb">0610231944|filetimes</a>
*/
- time_t GetTime()const;
+ void SetLastAccessTime(const time_t& ttime){m_tLastAccessTime = ttime;}
/**
- Gets the file system compatibility.
+ Returns the file system compatibility.
External software can use this information e.g. to determine end-of-line
format for text files etc.
The ZipArchive Library uses it to perform a proper file attributes conversion.
\return
- The file system compatibility. Can be one of the ZipCompatibility::ZipPlatforms values.
+ The file system compatibility. It can be one of the ZipCompatibility::ZipPlatforms values.
\see
CZipArchive::GetSystemComatibility
\see
@@ -285,11 +480,11 @@ public: */
int GetSystemCompatibility()const
{
- return (m_uVersionMadeBy & 0xFF00) >> 8;
+ return (int)m_iSystemCompatibility;
}
/**
- Gets the file attributes.
+ Returns the file attributes.
\return
The file attributes, converted if necessary to be compatible with the current system.
@@ -303,8 +498,23 @@ public: */
DWORD GetSystemAttr();
+
+ /**
+ Sets the file attributes.
+
+ \param uAttr
+ The attributes to set. The high-word should no be set in attributes, it will be overwritten by Unix attributes, which are stored in high-word.
+
+ \note
+ Throws an exception, if the archive system or the current system is not supported by the ZipArchive Library.
+
+ \see
+ GetSystemAttr
+ */
+ bool SetSystemAttr(DWORD uAttr);
+
/**
- Gets the file attributes exactly as they are stored in the archive.
+ Returns the file attributes exactly as they are stored in the archive.
\return
The file attributes as they are stored in the archive.
@@ -318,7 +528,7 @@ public: DWORD GetOriginalAttributes() const {return m_uExternalAttr;}
/**
- Gets a value indicating whether the file represents a directory or not.
+ Returns the value indicating whether the file represents a directory.
This method checks the file attributes. If the attributes value is zero,
the method checks for the presence of a path
separator at the end of the filename. If the path separator is present,
@@ -329,15 +539,15 @@ public: */
bool IsDirectory();
-
+#ifdef _ZIP_UNICODE_CUSTOM
/**
- Gets the string store settings for the file.
+ Returns the current string store settings.
\return
The string store settings.
\see
- <a href="kb">0610051525</a>
+ <a href="kb">0610051525|custom</a>
\see
CZipArchive::GetStringStoreSettings
*/
@@ -345,9 +555,10 @@ public: {
return m_stringSettings;
}
+#endif
/**
- Gets a value indicating if the file is encrypted or not.
+ Returns the value indicating whether the file is encrypted.
If the file is encrypted, you need to set the password with the
CZipArchive::SetPassword method before decompressing the file.
@@ -360,15 +571,15 @@ public: bool IsEncrypted()const { return m_uEncryptionMethod != CZipCryptograph::encNone;}
/**
- Gets the encryption method of the file.
+ Returns the encryption method of the file.
\return
- The file encryption method. Can be one of the CZipCryptograph::EncryptionMethod values.
+ The file encryption method. It can be one of the CZipCryptograph::EncryptionMethod values.
*/
int GetEncryptionMethod() const {return m_uEncryptionMethod;}
/**
- Gets a value indicating if the file is encrypted using WinZip AES encryption method or not.
+ Returns the value indicating whether the file is encrypted using WinZip AES encryption method.
\return
\c true, if the file is encrypted using WinZip AES encryption method; \c false otherwise.
@@ -379,7 +590,7 @@ public: }
/**
- Gets an approximate file compression level.
+ Returns an approximate file compression level.
\return
The compression level. May not be the real value used when compressing the file.
@@ -387,24 +598,50 @@ public: int GetCompressionLevel() const;
/**
- Returns the value indicating whether the current CZipFileHeader object has the time set or not.
+ Returns the value indicating whether the current CZipFileHeader object has the time set.
\return
\c true, if the time is set; \c false otherwise.
*/
- bool HasTime()
+ bool HasTime() const
{
return m_uModTime != 0 || m_uModDate != 0;
}
+ /**
+ Returns the value indicating whether the file was modified.
+
+ \return
+ \c true, if the file was modified; \c false otherwise.
+
+ \see
+ CZipArchive::CommitChanges
+ */
+ bool IsModified() const
+ {
+ return m_state.IsSetAny(sfModified);
+ }
+
+
+ /**
+ Returns the state flags.
+
+ \return
+ State flags. It can be one or more of #StateFlags values.
+ */
+ const ZipArchiveLib::CBitFlag& GetState() const
+ {
+ return m_state;
+ }
+
static char m_gszSignature[]; ///< The central file header signature.
static char m_gszLocalSignature[]; ///< The local file header signature.
- WORD m_uVersionMadeBy; ///< The "made by" version and the system compatibility.
+ unsigned char m_uVersionMadeBy; ///< The version of the software that created the archive.
WORD m_uVersionNeeded; ///< The version needed to extract the file.
WORD m_uFlag; ///< A general purpose bit flag.
- WORD m_uMethod; ///< The compression method. Can be one of the CZipCompressor::CompressionMethod values.
- WORD m_uModTime; ///< The file last modification time.
- WORD m_uModDate; ///< The file last modification date.
+ WORD m_uMethod; ///< The compression method. It can be one of the CZipCompressor::CompressionMethod values.
+ WORD m_uModTime; ///< The file last modification time. Don't set directly, but rather use CZipFileHeader::SetModificationTime method.
+ WORD m_uModDate; ///< The file last modification date. Don't set directly, but rather use CZipFileHeader::SetModificationTime method.
DWORD m_uCrc32; ///< The crc-32 value.
ZIP_SIZE_TYPE m_uComprSize; ///< The compressed size.
ZIP_SIZE_TYPE m_uUncomprSize; ///< The uncompressed size.
@@ -413,13 +650,20 @@ public: ZIP_SIZE_TYPE m_uLocalComprSize; ///< The compressed size written in the local header.
ZIP_SIZE_TYPE m_uLocalUncomprSize; ///< The uncompressed size written in the local header.
ZIP_SIZE_TYPE m_uOffset; ///< Relative offset of the local header with respect to CZipFileHeader::m_uVolumeStart.
- CZipExtraField m_aLocalExtraData; ///< The local extra field. Do not modify after you have started compressing the file.
+ CZipExtraField m_aLocalExtraData; ///< The local extra field. Do not modify it after you started compressing the file.
CZipExtraField m_aCentralExtraData; ///< The central extra field.
protected:
+ time_t m_tModificationTime; ///< The file modification time (stored in the NTFS extra field).
+ time_t m_tCreationTime; ///< The file creation time (stored in the NTFS extra field).
+ time_t m_tLastAccessTime; ///< The file last access time (stored in the NTFS extra field).
+
DWORD m_uExternalAttr; ///< External file attributes.
WORD m_uLocalFileNameSize; ///< The local filename length.
- BYTE m_uEncryptionMethod; ///< The file encryption method. Can be one of the CZipCryptograph::EncryptionMethod values.
- bool m_bIgnoreCrc32; ///< A value indicating whether to ignore Crc32 checking or not.
+ BYTE m_uEncryptionMethod; ///< The file encryption method. It can be one of the CZipCryptograph::EncryptionMethod values.
+ bool m_bIgnoreCrc32; ///< The value indicating whether to ignore Crc32 checking.
+ DWORD m_uLocalHeaderSize;
+
+ CZipCentralDir* m_pCentralDir; ///< The parent central directory. It can be \c NULL when the header is not a part of central directory.
@@ -427,43 +671,42 @@ protected: Sets the file system compatibility.
\param iSystemID
- The file system compatibility. Can be one of the ZipCompatibility::ZipPlatforms values.
+ The file system compatibility. It can be one of the ZipCompatibility::ZipPlatforms values.
+
+ \param bUpdateAttr
+ If \c true, the attributes will be converted to the new system; \c false otherwise.
\see
GetSystemCompatibility
*/
- void SetSystemCompatibility(int iSystemID)
+ void SetSystemCompatibility(int iSystemID, bool bUpdateAttr = false)
{
- m_uVersionMadeBy &= 0x00FF;
- m_uVersionMadeBy |= (WORD)(iSystemID << 8);
+ if (bUpdateAttr)
+ {
+ if ((int)m_iSystemCompatibility != iSystemID)
+ {
+ DWORD uAttr = GetSystemAttr();
+ m_iSystemCompatibility = (char)(iSystemID & 0xFF);
+ SetSystemAttr(uAttr & 0xFFFF);
+ }
+ return;
+ }
+ m_iSystemCompatibility = (char)(iSystemID & 0xFF);
}
-
- /**
- Sets the file attributes.
- To set the attributes of this structure use the CZipArchive::SetFileHeaderAttr method.
-
- \param uAttr
- The attributes to set.
-
- \note
- Throws exceptions, if the archive system or the current system
- is not supported by the ZipArchive Library.
-
- \see
- CZipArchive::SetFileHeaderAttr
- \see
- GetSystemAttr
- */
- void SetSystemAttr(DWORD uAttr);
/**
Prepares the filename for writing to the archive.
*/
- void PrepareFileName()
+ void PrepareStringBuffers()
{
- if (m_pszFileNameBuffer.IsAllocated() || m_pszFileName == NULL)
- return;
- ConvertFileName(m_pszFileNameBuffer);
+ if (!m_fileName.HasBuffer())
+ {
+ ConvertFileName(m_fileName.m_buffer);
+ }
+ if (!m_comment.HasBuffer())
+ {
+ ConvertComment(m_comment.m_buffer);
+ }
}
/**
@@ -497,48 +740,39 @@ protected: \param pStorage
The storage to write the local file header to.
- \note
- Throws exceptions.
*/
void WriteLocal(CZipStorage *pStorage);
/**
- Reads the local file header from an archive and validates the read data.
+ Reads the local file header from the archive and validates the read data.
- \param centralDir
- The current central directory.
+ \param pCentralDir
+ Used when the archive was opened with CZipArchive::OpenFrom method. Points to the original central directory.
\return
- \c true, if read data is consistent; \c false otherwise.
-
- \note
- Throws exceptions.
+ \c true, if the data read is consistent; \c false otherwise.
+
\see
CZipArchive::SetIgnoredConsistencyChecks
*/
- bool ReadLocal(CZipCentralDir& centralDir);
+ bool ReadLocal(CZipCentralDir* pCentralDir);
/**
Writes the central file header to \a pStorage.
- \param pStorage
- The storage to write the central file header to.
+ \param pCentralDir
+ The central directory the header belongs to.
\return
The size of the file header.
- \note
- Throws exceptions.
*/
- DWORD Write(CZipStorage *pStorage);
+ DWORD Write(CZipCentralDir* pCentralDir);
/**
Reads the central file header from \a pStorage and validates the read data.
- \param centralDir
- The current central directory.
-
\param bReadSignature
\c true, if the the central header signature should be read; \c false otherwise.
@@ -546,10 +780,8 @@ protected: \return
\c true, if the read data is consistent; \c false otherwise.
- \note
- Throws exceptions.
*/
- bool Read(CZipCentralDir& centralDir, bool bReadSignature);
+ bool Read(bool bReadSignature);
/**
@@ -561,7 +793,7 @@ protected: */
bool CheckLengths(bool local) const
{
- if (m_pszComment.GetSize() > USHRT_MAX || m_pszFileNameBuffer.GetSize() > USHRT_MAX)
+ if (m_comment.GetBufferSize() > (int)USHRT_MAX || m_fileName.GetBufferSize() > (int)USHRT_MAX)
return false;
else if (local)
return m_aLocalExtraData.Validate();
@@ -579,7 +811,7 @@ protected: /**
- Gets a value indicating whether the file needs the data descriptor.
+ Returns the value indicating whether the file needs the data descriptor.
The data descriptor is needed when a file is encrypted or the Zip64 format needs to be used.
\return
@@ -607,9 +839,18 @@ protected: */
void WriteDataDescriptor(CZipStorage* pStorage);
+ /**
+ Returns the value indicating whether the signature in the data descriptor is needed.
+
+ \param pStorage
+ The current storage.
+
+ \return
+ \c true, if the signature is needed; \c false otherwise.
+ */
bool NeedsSignatureInDataDescriptor(const CZipStorage* pStorage) const
{
- return pStorage->IsSegmented() != 0 || IsEncrypted();
+ return pStorage->IsSegmented() || IsEncrypted();
}
/**
@@ -621,6 +862,25 @@ protected: void UpdateLocalHeader(CZipStorage* pStorage);
/**
+ Adjusts the local compressed size.
+ */
+ void AdjustLocalComprSize()
+ {
+ AdjustLocalComprSize(m_uLocalComprSize);
+ }
+
+ /**
+ Adjusts the local compressed size.
+
+ \param uLocalComprSize
+ The value to adjust.
+ */
+ void AdjustLocalComprSize(ZIP_SIZE_TYPE& uLocalComprSize)
+ {
+ uLocalComprSize += GetEncryptedInfoSize();
+ }
+
+ /**
Verifies the central header signature.
\param buf
@@ -649,39 +909,119 @@ protected: m_uFlag |= 1; // encrypted file
}
+
+private:
-private:
+ struct StringWithBuffer
+ {
+ StringWithBuffer()
+ {
+ m_pString = NULL;
+ }
+ CZipAutoBuffer m_buffer;
+ StringWithBuffer& operator = (const StringWithBuffer& original)
+ {
+ if (original.HasString())
+ {
+ SetString(original.GetString());
+ }
+ else
+ {
+ ClearString();
+ }
+ m_buffer = original.m_buffer;
+ return *this;
+ }
+ void AllocateString()
+ {
+ ClearString();
+ m_pString = new CZipString(_T(""));
+ }
+ bool HasString() const
+ {
+ return m_pString != NULL;
+ }
+ bool HasBuffer() const
+ {
+ return m_buffer.IsAllocated() && m_buffer.GetSize() > 0;
+ }
+ void ClearString()
+ {
+ if (HasString())
+ {
+ delete m_pString;
+ m_pString = NULL;
+ }
+ }
+ void ClearBuffer()
+ {
+ m_buffer.Release();
+ }
- /**
- Sets the "made by" version.
+ const CZipString& GetString() const
+ {
+ ASSERT(HasString());
+ return *m_pString;
+ }
- \param uVersion
- The version to set.
- */
- void SetVersion(WORD uVersion)
- {
- if ((m_uVersionMadeBy & 0x00FF) != (uVersion & 0x00FF))
+ CZipString& GetString()
{
- m_uVersionMadeBy &= 0xFF00;
- m_uVersionMadeBy |= (WORD)(uVersion & 0x00FF);
+ ASSERT(HasString());
+ return *m_pString;
}
+
+ void SetString(LPCTSTR value)
+ {
+ if (!HasString())
+ AllocateString();
+ *m_pString = value;
+ }
+
+ int GetBufferSize() const
+ {
+ return m_buffer.GetSize();
+ }
+ ~StringWithBuffer()
+ {
+ ClearString();
+ }
+ protected:
+ CZipString* m_pString;
+ };
+
+ ZipArchiveLib::CBitFlag m_state;
+
+ void Initialize(CZipCentralDir* pCentralDir);
+
+ void SetModified(bool bModified = true)
+ {
+ m_state.Change(sfModified, bModified);
}
void ConvertFileName(CZipAutoBuffer& buffer) const;
void ConvertFileName(CZipString& szFileName) const;
+ void ConvertComment(CZipAutoBuffer& buffer) const;
+ void ConvertComment(CZipString& szComment) const;
- void ClearFileName()
+ bool UpdateFileNameFlags(const CZipString* szNewFileName, bool bAllowRemoveCDir);
+ bool UpdateCommentFlags(const CZipString* szNewComment);
+ bool UpdateStringsFlags(bool bAllowRemoveCDir)
{
- if (m_stringSettings.m_bStoreNameInExtraData)
- // we are keeping m_pszFileName, clear the buffer, we need the original, when writing extra header and when accessing the filename
- m_pszFileNameBuffer.Release();
- else if (m_pszFileName != NULL)
- {
- delete m_pszFileName;
- m_pszFileName = NULL;
- }
+ return UpdateFileNameFlags(NULL, bAllowRemoveCDir) | UpdateCommentFlags(NULL);
+ }
+
+ UINT GetDefaultFileNameCodePage() const
+ {
+ return ZipCompatibility::GetDefaultNameCodePage(GetSystemCompatibility());
}
+ UINT GetDefaultCommentCodePage() const
+ {
+ return ZipCompatibility::GetDefaultCommentCodePage(GetSystemCompatibility());
+ }
+
+ void ClearFileName();
+
void GetCrcAndSizes(char* pBuffer)const;
bool NeedsZip64() const
@@ -689,6 +1029,9 @@ private: return m_uComprSize >= UINT_MAX || m_uUncomprSize >= UINT_MAX || m_uVolumeStart >= USHRT_MAX || m_uOffset >= UINT_MAX;
}
+ time_t ReadFileTime(const char* buffer);
+ void WriteFileTime(const time_t& ttime, char* buffer, bool bUseUtcTime);
+
void OnNewFileClose(CZipStorage* pStorage)
{
@@ -697,13 +1040,12 @@ private: pStorage->Flush();
}
- CZipAutoBuffer m_pszFileNameBuffer;
-
- CZipString* m_pszFileName;
-
+#ifdef _ZIP_UNICODE_CUSTOM
CZipStringStoreSettings m_stringSettings;
-
- CZipAutoBuffer m_pszComment;
+#endif
+ StringWithBuffer m_fileName;
+ StringWithBuffer m_comment;
+ char m_iSystemCompatibility;
};
#endif // !defined(ZIPARCHIVE_ZIPFILEHEADER_DOT_H)
|
