diff options
author | Karsten Heimrich <karsten.heimrich@theqtcompany.com> | 2015-06-09 16:04:24 +0200 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@theqtcompany.com> | 2015-06-10 08:15:38 +0000 |
commit | 4677d362982a38c6e2aabb667e33aaa7f921f018 (patch) | |
tree | fe3b676288f05a87cdbb53a170e815427e3d9380 /src/libs/7zip/win | |
parent | 22ec6aa53e44069c03c7baf94881949c7a4facff (diff) |
Update source tree with version 9.38.beta of LZMA SDK.
- Remove unused files.
- Split in .pri files.
- Add HEADERS section.
- Adjust lib7z_facade.
Change-Id: I31e7bafbfe1a9346364bd58c391601955f98ad3a
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
Diffstat (limited to 'src/libs/7zip/win')
344 files changed, 24877 insertions, 21082 deletions
diff --git a/src/libs/7zip/win/7zC.txt b/src/libs/7zip/win/7zC.txt deleted file mode 100644 index 5d5d06d7b..000000000 --- a/src/libs/7zip/win/7zC.txt +++ /dev/null @@ -1,194 +0,0 @@ -7z ANSI-C Decoder 4.62 ----------------------- - -7z ANSI-C provides 7z/LZMA decoding. -7z ANSI-C version is simplified version ported from C++ code. - -LZMA is default and general compression method of 7z format -in 7-Zip compression program (www.7-zip.org). LZMA provides high -compression ratio and very fast decompression. - - -LICENSE -------- - -7z ANSI-C Decoder is part of the LZMA SDK. -LZMA SDK is written and placed in the public domain by Igor Pavlov. - -Files ---------------------- - -7zDecode.* - Low level 7z decoding -7zExtract.* - High level 7z decoding -7zHeader.* - .7z format constants -7zIn.* - .7z archive opening -7zItem.* - .7z structures -7zMain.c - Test application - - -How To Use ----------- - -You must download 7-Zip program from www.7-zip.org. - -You can create .7z archive with 7z.exe or 7za.exe: - - 7za.exe a archive.7z *.htm -r -mx -m0fb=255 - -If you have big number of files in archive, and you need fast extracting, -you can use partly-solid archives: - - 7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K - -In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only -512KB for extracting one file from such archive. - - -Limitations of current version of 7z ANSI-C Decoder ---------------------------------------------------- - - - It reads only "FileName", "Size", "LastWriteTime" and "CRC" information for each file in archive. - - It supports only LZMA and Copy (no compression) methods with BCJ or BCJ2 filters. - - It converts original UTF-16 Unicode file names to UTF-8 Unicode file names. - -These limitations will be fixed in future versions. - - -Using 7z ANSI-C Decoder Test application: ------------------------------------------ - -Usage: 7zDec <command> <archive_name> - -<Command>: - e: Extract files from archive - l: List contents of archive - t: Test integrity of archive - -Example: - - 7zDec l archive.7z - -lists contents of archive.7z - - 7zDec e archive.7z - -extracts files from archive.7z to current folder. - - -How to use .7z Decoder ----------------------- - -Memory allocation -~~~~~~~~~~~~~~~~~ - -7z Decoder uses two memory pools: -1) Temporary pool -2) Main pool -Such scheme can allow you to avoid fragmentation of allocated blocks. - - -Steps for using 7z decoder --------------------------- - -Use code at 7zMain.c as example. - -1) Declare variables: - inStream /* implements ILookInStream interface */ - CSzArEx db; /* 7z archive database structure */ - ISzAlloc allocImp; /* memory functions for main pool */ - ISzAlloc allocTempImp; /* memory functions for temporary pool */ - -2) call CrcGenerateTable(); function to initialize CRC structures. - -3) call SzArEx_Init(&db); function to initialize db structures. - -4) call SzArEx_Open(&db, inStream, &allocMain, &allocTemp) to open archive - -This function opens archive "inStream" and reads headers to "db". -All items in "db" will be allocated with "allocMain" functions. -SzArEx_Open function allocates and frees temporary structures by "allocTemp" functions. - -5) List items or Extract items - - Listing code: - ~~~~~~~~~~~~~ - { - UInt32 i; - for (i = 0; i < db.db.NumFiles; i++) - { - CFileItem *f = db.db.Files + i; - printf("%10d %s\n", (int)f->Size, f->Name); - } - } - - Extracting code: - ~~~~~~~~~~~~~~~~ - - SZ_RESULT SzAr_Extract( - CArchiveDatabaseEx *db, - ILookInStream *inStream, - UInt32 fileIndex, /* index of file */ - UInt32 *blockIndex, /* index of solid block */ - Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ - size_t *outBufferSize, /* buffer size for output buffer */ - size_t *offset, /* offset of stream for required file in *outBuffer */ - size_t *outSizeProcessed, /* size of file in *outBuffer */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp); - - If you need to decompress more than one file, you can send these values from previous call: - blockIndex, - outBuffer, - outBufferSize, - You can consider "outBuffer" as cache of solid block. If your archive is solid, - it will increase decompression speed. - - After decompressing you must free "outBuffer": - allocImp.Free(outBuffer); - -6) call SzArEx_Free(&db, allocImp.Free) to free allocated items in "db". - - - - -Memory requirements for .7z decoding ------------------------------------- - -Memory usage for Archive opening: - - Temporary pool: - - Memory for uncompressed .7z headers - - some other temporary blocks - - Main pool: - - Memory for database: - Estimated size of one file structures in solid archive: - - Size (4 or 8 Bytes) - - CRC32 (4 bytes) - - LastWriteTime (8 bytes) - - Some file information (4 bytes) - - File Name (variable length) + pointer + allocation structures - -Memory usage for archive Decompressing: - - Temporary pool: - - Memory for LZMA decompressing structures - - Main pool: - - Memory for decompressed solid block - - Memory for temprorary buffers, if BCJ2 fileter is used. Usually these - temprorary buffers can be about 15% of solid block size. - - -7z Decoder doesn't allocate memory for compressed blocks. -Instead of this, you must allocate buffer with desired -size before calling 7z Decoder. Use 7zMain.c as example. - - -Defines -------- - -_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr. - - ---- - -http://www.7-zip.org -http://www.7-zip.org/sdk.html -http://www.7-zip.org/support.html diff --git a/src/libs/7zip/win/7zFormat.txt b/src/libs/7zip/win/7zFormat.txt deleted file mode 100644 index e1cf7380d..000000000 --- a/src/libs/7zip/win/7zFormat.txt +++ /dev/null @@ -1,471 +0,0 @@ -7z Format description (2.30 Beta 25) ------------------------------------ - -This file contains description of 7z archive format. -7z archive can contain files compressed with any method. -See "Methods.txt" for description for defined compressing methods. - - -Format structure Overview -------------------------- - -Some fields can be optional. - -Archive structure -~~~~~~~~~~~~~~~~~ -SignatureHeader -[PackedStreams] -[PackedStreamsForHeaders] -[ - Header - or - { - Packed Header - HeaderInfo - } -] - - - -Header structure -~~~~~~~~~~~~~~~~ -{ - ArchiveProperties - AdditionalStreams - { - PackInfo - { - PackPos - NumPackStreams - Sizes[NumPackStreams] - CRCs[NumPackStreams] - } - CodersInfo - { - NumFolders - Folders[NumFolders] - { - NumCoders - CodersInfo[NumCoders] - { - ID - NumInStreams; - NumOutStreams; - PropertiesSize - Properties[PropertiesSize] - } - NumBindPairs - BindPairsInfo[NumBindPairs] - { - InIndex; - OutIndex; - } - PackedIndices - } - UnPackSize[Folders][Folders.NumOutstreams] - CRCs[NumFolders] - } - SubStreamsInfo - { - NumUnPackStreamsInFolders[NumFolders]; - UnPackSizes[] - CRCs[] - } - } - MainStreamsInfo - { - (Same as in AdditionalStreams) - } - FilesInfo - { - NumFiles - Properties[] - { - ID - Size - Data - } - } -} - -HeaderInfo structure -~~~~~~~~~~~~~~~~~~~~ -{ - (Same as in AdditionalStreams) -} - - - -Notes about Notation and encoding ---------------------------------- - -7z uses little endian encoding. - -7z archive format has optional headers that are marked as -[] -Header -[] - -REAL_UINT64 means real UINT64. - -UINT64 means real UINT64 encoded with the following scheme: - - Size of encoding sequence depends from first byte: - First_Byte Extra_Bytes Value - (binary) - 0xxxxxxx : ( xxxxxxx ) - 10xxxxxx BYTE y[1] : ( xxxxxx << (8 * 1)) + y - 110xxxxx BYTE y[2] : ( xxxxx << (8 * 2)) + y - ... - 1111110x BYTE y[6] : ( x << (8 * 6)) + y - 11111110 BYTE y[7] : y - 11111111 BYTE y[8] : y - - - -Property IDs ------------- - -0x00 = kEnd, - -0x01 = kHeader, - -0x02 = kArchiveProperties, - -0x03 = kAdditionalStreamsInfo, -0x04 = kMainStreamsInfo, -0x05 = kFilesInfo, - -0x06 = kPackInfo, -0x07 = kUnPackInfo, -0x08 = kSubStreamsInfo, - -0x09 = kSize, -0x0A = kCRC, - -0x0B = kFolder, - -0x0C = kCodersUnPackSize, -0x0D = kNumUnPackStream, - -0x0E = kEmptyStream, -0x0F = kEmptyFile, -0x10 = kAnti, - -0x11 = kName, -0x12 = kCreationTime, -0x13 = kLastAccessTime, -0x14 = kLastWriteTime, -0x15 = kWinAttributes, -0x16 = kComment, - -0x17 = kEncodedHeader, - - -7z format headers ------------------ - -SignatureHeader -~~~~~~~~~~~~~~~ - BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; - - ArchiveVersion - { - BYTE Major; // now = 0 - BYTE Minor; // now = 2 - }; - - UINT32 StartHeaderCRC; - - StartHeader - { - REAL_UINT64 NextHeaderOffset - REAL_UINT64 NextHeaderSize - UINT32 NextHeaderCRC - } - - -........................... - - -ArchiveProperties -~~~~~~~~~~~~~~~~~ -BYTE NID::kArchiveProperties (0x02) -for (;;) -{ - BYTE PropertyType; - if (aType == 0) - break; - UINT64 PropertySize; - BYTE PropertyData[PropertySize]; -} - - -Digests (NumStreams) -~~~~~~~~~~~~~~~~~~~~~ - BYTE AllAreDefined - if (AllAreDefined == 0) - { - for(NumStreams) - BIT Defined - } - UINT32 CRCs[NumDefined] - - -PackInfo -~~~~~~~~~~~~ - BYTE NID::kPackInfo (0x06) - UINT64 PackPos - UINT64 NumPackStreams - - [] - BYTE NID::kSize (0x09) - UINT64 PackSizes[NumPackStreams] - [] - - [] - BYTE NID::kCRC (0x0A) - PackStreamDigests[NumPackStreams] - [] - - BYTE NID::kEnd - - -Folder -~~~~~~ - UINT64 NumCoders; - for (NumCoders) - { - BYTE - { - 0:3 DecompressionMethod.IDSize - 4: - 0 - IsSimple - 1 - Is not simple - 5: - 0 - No Attributes - 1 - There Are Attributes - 7: - 0 - Last Method in Alternative_Method_List - 1 - There are more alternative methods - } - BYTE DecompressionMethod.ID[DecompressionMethod.IDSize] - if (!IsSimple) - { - UINT64 NumInStreams; - UINT64 NumOutStreams; - } - if (DecompressionMethod[0] != 0) - { - UINT64 PropertiesSize - BYTE Properties[PropertiesSize] - } - } - - NumBindPairs = NumOutStreamsTotal - 1; - - for (NumBindPairs) - { - UINT64 InIndex; - UINT64 OutIndex; - } - - NumPackedStreams = NumInStreamsTotal - NumBindPairs; - if (NumPackedStreams > 1) - for(NumPackedStreams) - { - UINT64 Index; - }; - - - - -Coders Info -~~~~~~~~~~~ - - BYTE NID::kUnPackInfo (0x07) - - - BYTE NID::kFolder (0x0B) - UINT64 NumFolders - BYTE External - switch(External) - { - case 0: - Folders[NumFolders] - case 1: - UINT64 DataStreamIndex - } - - - BYTE ID::kCodersUnPackSize (0x0C) - for(Folders) - for(Folder.NumOutStreams) - UINT64 UnPackSize; - - - [] - BYTE NID::kCRC (0x0A) - UnPackDigests[NumFolders] - [] - - - - BYTE NID::kEnd - - - -SubStreams Info -~~~~~~~~~~~~~~ - BYTE NID::kSubStreamsInfo; (0x08) - - [] - BYTE NID::kNumUnPackStream; (0x0D) - UINT64 NumUnPackStreamsInFolders[NumFolders]; - [] - - - [] - BYTE NID::kSize (0x09) - UINT64 UnPackSizes[] - [] - - - [] - BYTE NID::kCRC (0x0A) - Digests[Number of streams with unknown CRC] - [] - - - BYTE NID::kEnd - - -Streams Info -~~~~~~~~~~~~ - - [] - PackInfo - [] - - - [] - CodersInfo - [] - - - [] - SubStreamsInfo - [] - - BYTE NID::kEnd - - -FilesInfo -~~~~~~~~~ - BYTE NID::kFilesInfo; (0x05) - UINT64 NumFiles - - for (;;) - { - BYTE PropertyType; - if (aType == 0) - break; - - UINT64 Size; - - switch(PropertyType) - { - kEmptyStream: (0x0E) - for(NumFiles) - BIT IsEmptyStream - - kEmptyFile: (0x0F) - for(EmptyStreams) - BIT IsEmptyFile - - kAnti: (0x10) - for(EmptyStreams) - BIT IsAntiFile - - case kCreationTime: (0x12) - case kLastAccessTime: (0x13) - case kLastWriteTime: (0x14) - BYTE AllAreDefined - if (AllAreDefined == 0) - { - for(NumFiles) - BIT TimeDefined - } - BYTE External; - if(External != 0) - UINT64 DataIndex - [] - for(Definded Items) - UINT32 Time - [] - - kNames: (0x11) - BYTE External; - if(External != 0) - UINT64 DataIndex - [] - for(Files) - { - wchar_t Names[NameSize]; - wchar_t 0; - } - [] - - kAttributes: (0x15) - BYTE AllAreDefined - if (AllAreDefined == 0) - { - for(NumFiles) - BIT AttributesAreDefined - } - BYTE External; - if(External != 0) - UINT64 DataIndex - [] - for(Definded Attributes) - UINT32 Attributes - [] - } - } - - -Header -~~~~~~ - BYTE NID::kHeader (0x01) - - [] - ArchiveProperties - [] - - [] - BYTE NID::kAdditionalStreamsInfo; (0x03) - StreamsInfo - [] - - [] - BYTE NID::kMainStreamsInfo; (0x04) - StreamsInfo - [] - - [] - FilesInfo - [] - - BYTE NID::kEnd - - -HeaderInfo -~~~~~~~~~~ - [] - BYTE NID::kEncodedHeader; (0x17) - StreamsInfo for Encoded Header - [] - - ---- -End of document diff --git a/src/libs/7zip/win/C/7z.h b/src/libs/7zip/win/C/7z.h deleted file mode 100644 index 01c4cac6a..000000000 --- a/src/libs/7zip/win/C/7z.h +++ /dev/null @@ -1,203 +0,0 @@ -/* 7z.h -- 7z interface -2010-03-11 : Igor Pavlov : Public domain */ - -#ifndef __7Z_H -#define __7Z_H - -#include "7zBuf.h" - -EXTERN_C_BEGIN - -#define k7zStartHeaderSize 0x20 -#define k7zSignatureSize 6 -extern Byte k7zSignature[k7zSignatureSize]; -#define k7zMajorVersion 0 - -enum EIdEnum -{ - k7zIdEnd, - k7zIdHeader, - k7zIdArchiveProperties, - k7zIdAdditionalStreamsInfo, - k7zIdMainStreamsInfo, - k7zIdFilesInfo, - k7zIdPackInfo, - k7zIdUnpackInfo, - k7zIdSubStreamsInfo, - k7zIdSize, - k7zIdCRC, - k7zIdFolder, - k7zIdCodersUnpackSize, - k7zIdNumUnpackStream, - k7zIdEmptyStream, - k7zIdEmptyFile, - k7zIdAnti, - k7zIdName, - k7zIdCTime, - k7zIdATime, - k7zIdMTime, - k7zIdWinAttributes, - k7zIdComment, - k7zIdEncodedHeader, - k7zIdStartPos, - k7zIdDummy -}; - -typedef struct -{ - UInt32 NumInStreams; - UInt32 NumOutStreams; - UInt64 MethodID; - CBuf Props; -} CSzCoderInfo; - -void SzCoderInfo_Init(CSzCoderInfo *p); -void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); - -typedef struct -{ - UInt32 InIndex; - UInt32 OutIndex; -} CSzBindPair; - -typedef struct -{ - CSzCoderInfo *Coders; - CSzBindPair *BindPairs; - UInt32 *PackStreams; - UInt64 *UnpackSizes; - UInt32 NumCoders; - UInt32 NumBindPairs; - UInt32 NumPackStreams; - int UnpackCRCDefined; - UInt32 UnpackCRC; - - UInt32 NumUnpackStreams; -} CSzFolder; - -void SzFolder_Init(CSzFolder *p); -UInt64 SzFolder_GetUnpackSize(CSzFolder *p); -int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); -UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); -UInt64 SzFolder_GetUnpackSize(CSzFolder *p); - -SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, - ILookInStream *stream, UInt64 startPos, - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); - -typedef struct -{ - UInt32 Low; - UInt32 High; -} CNtfsFileTime; - -typedef struct -{ - CNtfsFileTime MTime; - UInt64 Size; - UInt32 Crc; - UInt32 Attrib; - Byte HasStream; - Byte IsDir; - Byte IsAnti; - Byte CrcDefined; - Byte MTimeDefined; - Byte AttribDefined; -} CSzFileItem; - -void SzFile_Init(CSzFileItem *p); - -typedef struct -{ - UInt64 *PackSizes; - Byte *PackCRCsDefined; - UInt32 *PackCRCs; - CSzFolder *Folders; - CSzFileItem *Files; - UInt32 NumPackStreams; - UInt32 NumFolders; - UInt32 NumFiles; -} CSzAr; - -void SzAr_Init(CSzAr *p); -void SzAr_Free(CSzAr *p, ISzAlloc *alloc); - - -/* - SzExtract extracts file from archive - - *outBuffer must be 0 before first call for each new archive. - - Extracting cache: - If you need to decompress more than one file, you can send - these values from previous call: - *blockIndex, - *outBuffer, - *outBufferSize - You can consider "*outBuffer" as cache of solid block. If your archive is solid, - it will increase decompression speed. - - If you use external function, you can declare these 3 cache variables - (blockIndex, outBuffer, outBufferSize) as static in that external function. - - Free *outBuffer and set *outBuffer to 0, if you want to flush cache. -*/ - -typedef struct -{ - CSzAr db; - - UInt64 startPosAfterHeader; - UInt64 dataPos; - - UInt32 *FolderStartPackStreamIndex; - UInt64 *PackStreamStartPositions; - UInt32 *FolderStartFileIndex; - UInt32 *FileIndexToFolderIndexMap; - - size_t *FileNameOffsets; /* in 2-byte steps */ - CBuf FileNames; /* UTF-16-LE */ -} CSzArEx; - -void SzArEx_Init(CSzArEx *p); -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); -UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); -int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); - -/* -if dest == NULL, the return value specifies the required size of the buffer, - in 16-bit characters, including the null-terminating character. -if dest != NULL, the return value specifies the number of 16-bit characters that - are written to the dest, including the null-terminating character. */ - -size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); - -SRes SzArEx_Extract( - const CSzArEx *db, - ILookInStream *inStream, - UInt32 fileIndex, /* index of file */ - UInt32 *blockIndex, /* index of solid block */ - Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ - size_t *outBufferSize, /* buffer size for output buffer */ - size_t *offset, /* offset of stream for required file in *outBuffer */ - size_t *outSizeProcessed, /* size of file in *outBuffer */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp); - - -/* -SzArEx_Open Errors: -SZ_ERROR_NO_ARCHIVE -SZ_ERROR_ARCHIVE -SZ_ERROR_UNSUPPORTED -SZ_ERROR_MEM -SZ_ERROR_CRC -SZ_ERROR_INPUT_EOF -SZ_ERROR_FAIL -*/ - -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); - -EXTERN_C_END - -#endif diff --git a/src/libs/7zip/win/C/7zAlloc.c b/src/libs/7zip/win/C/7zAlloc.c deleted file mode 100644 index 964b28db3..000000000 --- a/src/libs/7zip/win/C/7zAlloc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* 7zAlloc.c -- Allocation functions -2010-10-29 : Igor Pavlov : Public domain */ - -#include "7zAlloc.h" - -/* #define _SZ_ALLOC_DEBUG */ -/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ - -#ifdef _SZ_ALLOC_DEBUG - -#ifdef _WIN32 -#include <windows.h> -#endif - -#include <stdio.h> -int g_allocCount = 0; -int g_allocCountTemp = 0; - -#endif - -void *SzAlloc(void *p, size_t size) -{ - p = p; - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); - g_allocCount++; - #endif - return malloc(size); -} - -void SzFree(void *p, void *address) -{ - p = p; - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - { - g_allocCount--; - fprintf(stderr, "\nFree; count = %10d", g_allocCount); - } - #endif - free(address); -} - -void *SzAllocTemp(void *p, size_t size) -{ - p = p; - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); - g_allocCountTemp++; - #ifdef _WIN32 - return HeapAlloc(GetProcessHeap(), 0, size); - #endif - #endif - return malloc(size); -} - -void SzFreeTemp(void *p, void *address) -{ - p = p; - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - { - g_allocCountTemp--; - fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); - } - #ifdef _WIN32 - HeapFree(GetProcessHeap(), 0, address); - return; - #endif - #endif - free(address); -} diff --git a/src/libs/7zip/win/C/7zAlloc.h b/src/libs/7zip/win/C/7zAlloc.h deleted file mode 100644 index 3344e9373..000000000 --- a/src/libs/7zip/win/C/7zAlloc.h +++ /dev/null @@ -1,15 +0,0 @@ -/* 7zAlloc.h -- Allocation functions -2010-10-29 : Igor Pavlov : Public domain */ - -#ifndef __7Z_ALLOC_H -#define __7Z_ALLOC_H - -#include <stdlib.h> - -void *SzAlloc(void *p, size_t size); -void SzFree(void *p, void *address); - -void *SzAllocTemp(void *p, size_t size); -void SzFreeTemp(void *p, void *address); - -#endif diff --git a/src/libs/7zip/win/C/7zBuf.c b/src/libs/7zip/win/C/7zBuf.c deleted file mode 100644 index 14e7f4e2b..000000000 --- a/src/libs/7zip/win/C/7zBuf.c +++ /dev/null @@ -1,36 +0,0 @@ -/* 7zBuf.c -- Byte Buffer -2008-03-28 -Igor Pavlov -Public domain */ - -#include "7zBuf.h" - -void Buf_Init(CBuf *p) -{ - p->data = 0; - p->size = 0; -} - -int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) -{ - p->size = 0; - if (size == 0) - { - p->data = 0; - return 1; - } - p->data = (Byte *)alloc->Alloc(alloc, size); - if (p->data != 0) - { - p->size = size; - return 1; - } - return 0; -} - -void Buf_Free(CBuf *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->data); - p->data = 0; - p->size = 0; -} diff --git a/src/libs/7zip/win/C/7zBuf.h b/src/libs/7zip/win/C/7zBuf.h deleted file mode 100644 index e9f2f316d..000000000 --- a/src/libs/7zip/win/C/7zBuf.h +++ /dev/null @@ -1,39 +0,0 @@ -/* 7zBuf.h -- Byte Buffer -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __7Z_BUF_H -#define __7Z_BUF_H - -#include "Types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct -{ - Byte *data; - size_t size; -} CBuf; - -void Buf_Init(CBuf *p); -int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); -void Buf_Free(CBuf *p, ISzAlloc *alloc); - -typedef struct -{ - Byte *data; - size_t size; - size_t pos; -} CDynBuf; - -void DynBuf_Construct(CDynBuf *p); -void DynBuf_SeekToBeg(CDynBuf *p); -int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); -void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libs/7zip/win/C/7zBuf2.c b/src/libs/7zip/win/C/7zBuf2.c deleted file mode 100644 index 8d17e0dcf..000000000 --- a/src/libs/7zip/win/C/7zBuf2.c +++ /dev/null @@ -1,45 +0,0 @@ -/* 7zBuf2.c -- Byte Buffer -2008-10-04 : Igor Pavlov : Public domain */ - -#include <string.h> -#include "7zBuf.h" - -void DynBuf_Construct(CDynBuf *p) -{ - p->data = 0; - p->size = 0; - p->pos = 0; -} - -void DynBuf_SeekToBeg(CDynBuf *p) -{ - p->pos = 0; -} - -int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc) -{ - if (size > p->size - p->pos) - { - size_t newSize = p->pos + size; - Byte *data; - newSize += newSize / 4; - data = (Byte *)alloc->Alloc(alloc, newSize); - if (data == 0) - return 0; - p->size = newSize; - memcpy(data, p->data, p->pos); - alloc->Free(alloc, p->data); - p->data = data; - } - memcpy(p->data + p->pos, buf, size); - p->pos += size; - return 1; -} - -void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->data); - p->data = 0; - p->size = 0; - p->pos = 0; -} diff --git a/src/libs/7zip/win/C/7zCrc.c b/src/libs/7zip/win/C/7zCrc.c index a92084961..5f32380dd 100644 --- a/src/libs/7zip/win/C/7zCrc.c +++ b/src/libs/7zip/win/C/7zCrc.c @@ -1,41 +1,33 @@ -/* 7zCrc.c -- CRC32 calculation -2009-11-23 : Igor Pavlov : Public domain */ +/* 7zCrc.c -- CRC32 init +2013-11-12 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include "7zCrc.h" #include "CpuArch.h" #define kCrcPoly 0xEDB88320 -#ifdef MY_CPU_LE -#define CRC_NUM_TABLES 8 +#ifdef MY_CPU_X86_OR_AMD64 + #define CRC_NUM_TABLES 8 + UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); +#elif defined(MY_CPU_LE) + #define CRC_NUM_TABLES 4 #else -#define CRC_NUM_TABLES 1 + #define CRC_NUM_TABLES 5 + #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) + UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); +#endif + +#ifndef MY_CPU_BE + UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); #endif typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); -static CRC_FUNC g_CrcUpdate; +CRC_FUNC g_CrcUpdate; UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; -#if CRC_NUM_TABLES == 1 - -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -#else - -UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); -UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); - -#endif - UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) { return g_CrcUpdate(v, data, size, g_CrcTable); @@ -57,18 +49,37 @@ void MY_FAST_CALL CrcGenerateTable() r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); g_CrcTable[i] = r; } - #if CRC_NUM_TABLES == 1 - g_CrcUpdate = CrcUpdateT1; - #else for (; i < 256 * CRC_NUM_TABLES; i++) { UInt32 r = g_CrcTable[i - 256]; g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); } + + #ifdef MY_CPU_LE + g_CrcUpdate = CrcUpdateT4; - #ifdef MY_CPU_X86_OR_AMD64 + + #if CRC_NUM_TABLES == 8 if (!CPU_Is_InOrder()) g_CrcUpdate = CrcUpdateT8; #endif + + #else + { + #ifndef MY_CPU_BE + UInt32 k = 1; + if (*(const Byte *)&k == 1) + g_CrcUpdate = CrcUpdateT4; + else + #endif + { + for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) + { + UInt32 x = g_CrcTable[i - 256]; + g_CrcTable[i] = CRC_UINT32_SWAP(x); + } + g_CrcUpdate = CrcUpdateT1_BeT4; + } + } #endif } diff --git a/src/libs/7zip/win/C/7zCrc.h b/src/libs/7zip/win/C/7zCrc.h index 38e3e5fbc..8fd579587 100644 --- a/src/libs/7zip/win/C/7zCrc.h +++ b/src/libs/7zip/win/C/7zCrc.h @@ -1,10 +1,10 @@ /* 7zCrc.h -- CRC32 calculation -2009-11-21 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __7Z_CRC_H #define __7Z_CRC_H -#include "Types.h" +#include "7zTypes.h" EXTERN_C_BEGIN diff --git a/src/libs/7zip/win/C/7zCrcOpt.c b/src/libs/7zip/win/C/7zCrcOpt.c index 6c766a209..ce132b5d4 100644 --- a/src/libs/7zip/win/C/7zCrcOpt.c +++ b/src/libs/7zip/win/C/7zCrcOpt.c @@ -1,12 +1,14 @@ -/* 7zCrcOpt.c -- CRC32 calculation : optimized version -2009-11-23 : Igor Pavlov : Public domain */ +/* 7zCrcOpt.c -- CRC32 calculation +2013-11-12 : Igor Pavlov : Public domain */ -#include "CpuArch.h" +#include "Precomp.h" -#ifdef MY_CPU_LE +#include "CpuArch.h" #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) +#ifndef MY_CPU_BE + UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) { const Byte *p = (const Byte *)data; @@ -32,3 +34,33 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U } #endif + + +#ifndef MY_CPU_LE + +#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) + +UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + v = CRC_UINT32_SWAP(v); + table += 0x100; + for (; size >= 4; size -= 4, p += 4) + { + v ^= *(const UInt32 *)p; + v = + table[0x000 + (v & 0xFF)] ^ + table[0x100 + ((v >> 8) & 0xFF)] ^ + table[0x200 + ((v >> 16) & 0xFF)] ^ + table[0x300 + ((v >> 24))]; + } + table -= 0x100; + v = CRC_UINT32_SWAP(v); + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +#endif diff --git a/src/libs/7zip/win/C/7zDec.c b/src/libs/7zip/win/C/7zDec.c deleted file mode 100644 index b6d809956..000000000 --- a/src/libs/7zip/win/C/7zDec.c +++ /dev/null @@ -1,470 +0,0 @@ -/* 7zDec.c -- Decoding from 7z folder -2010-11-02 : Igor Pavlov : Public domain */ - -#include <string.h> - -/* #define _7ZIP_PPMD_SUPPPORT */ - -#include "7z.h" - -#include "Bcj2.h" -#include "Bra.h" -#include "CpuArch.h" -#include "LzmaDec.h" -#include "Lzma2Dec.h" -#ifdef _7ZIP_PPMD_SUPPPORT -#include "Ppmd7.h" -#endif - -#define k_Copy 0 -#define k_LZMA2 0x21 -#define k_LZMA 0x30101 -#define k_BCJ 0x03030103 -#define k_PPC 0x03030205 -#define k_ARM 0x03030501 -#define k_ARMT 0x03030701 -#define k_SPARC 0x03030805 -#define k_BCJ2 0x0303011B - -#ifdef _7ZIP_PPMD_SUPPPORT - -#define k_PPMD 0x30401 - -typedef struct -{ - IByteIn p; - const Byte *cur; - const Byte *end; - const Byte *begin; - UInt64 processed; - Bool extra; - SRes res; - ILookInStream *inStream; -} CByteInToLook; - -static Byte ReadByte(void *pp) -{ - CByteInToLook *p = (CByteInToLook *)pp; - if (p->cur != p->end) - return *p->cur++; - if (p->res == SZ_OK) - { - size_t size = p->cur - p->begin; - p->processed += size; - p->res = p->inStream->Skip(p->inStream, size); - size = (1 << 25); - p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size); - p->cur = p->begin; - p->end = p->begin + size; - if (size != 0) - return *p->cur++;; - } - p->extra = True; - return 0; -} - -static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) -{ - CPpmd7 ppmd; - CByteInToLook s; - SRes res = SZ_OK; - - s.p.Read = ReadByte; - s.inStream = inStream; - s.begin = s.end = s.cur = NULL; - s.extra = False; - s.res = SZ_OK; - s.processed = 0; - - if (coder->Props.size != 5) - return SZ_ERROR_UNSUPPORTED; - - { - unsigned order = coder->Props.data[0]; - UInt32 memSize = GetUi32(coder->Props.data + 1); - if (order < PPMD7_MIN_ORDER || - order > PPMD7_MAX_ORDER || - memSize < PPMD7_MIN_MEM_SIZE || - memSize > PPMD7_MAX_MEM_SIZE) - return SZ_ERROR_UNSUPPORTED; - Ppmd7_Construct(&ppmd); - if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) - return SZ_ERROR_MEM; - Ppmd7_Init(&ppmd, order); - } - { - CPpmd7z_RangeDec rc; - Ppmd7z_RangeDec_CreateVTable(&rc); - rc.Stream = &s.p; - if (!Ppmd7z_RangeDec_Init(&rc)) - res = SZ_ERROR_DATA; - else if (s.extra) - res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); - else - { - SizeT i; - for (i = 0; i < outSize; i++) - { - int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); - if (s.extra || sym < 0) - break; - outBuffer[i] = (Byte)sym; - } - if (i != outSize) - res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); - else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc)) - res = SZ_ERROR_DATA; - } - } - Ppmd7_Free(&ppmd, allocMain); - return res; -} - -#endif - - -static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) -{ - CLzmaDec state; - SRes res = SZ_OK; - - LzmaDec_Construct(&state); - RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); - state.dic = outBuffer; - state.dicBufSize = outSize; - LzmaDec_Init(&state); - - for (;;) - { - Byte *inBuf = NULL; - size_t lookahead = (1 << 18); - if (lookahead > inSize) - lookahead = (size_t)inSize; - res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); - if (res != SZ_OK) - break; - - { - SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; - ELzmaStatus status; - res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); - lookahead -= inProcessed; - inSize -= inProcessed; - if (res != SZ_OK) - break; - if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) - { - if (state.dicBufSize != outSize || lookahead != 0 || - (status != LZMA_STATUS_FINISHED_WITH_MARK && - status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) - res = SZ_ERROR_DATA; - break; - } - res = inStream->Skip((void *)inStream, inProcessed); - if (res != SZ_OK) - break; - } - } - - LzmaDec_FreeProbs(&state, allocMain); - return res; -} - -static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) -{ - CLzma2Dec state; - SRes res = SZ_OK; - - Lzma2Dec_Construct(&state); - if (coder->Props.size != 1) - return SZ_ERROR_DATA; - RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain)); - state.decoder.dic = outBuffer; - state.decoder.dicBufSize = outSize; - Lzma2Dec_Init(&state); - - for (;;) - { - Byte *inBuf = NULL; - size_t lookahead = (1 << 18); - if (lookahead > inSize) - lookahead = (size_t)inSize; - res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); - if (res != SZ_OK) - break; - - { - SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; - ELzmaStatus status; - res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); - lookahead -= inProcessed; - inSize -= inProcessed; - if (res != SZ_OK) - break; - if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos)) - { - if (state.decoder.dicBufSize != outSize || lookahead != 0 || - (status != LZMA_STATUS_FINISHED_WITH_MARK)) - res = SZ_ERROR_DATA; - break; - } - res = inStream->Skip((void *)inStream, inProcessed); - if (res != SZ_OK) - break; - } - } - - Lzma2Dec_FreeProbs(&state, allocMain); - return res; -} - -static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) -{ - while (inSize > 0) - { - void *inBuf; - size_t curSize = (1 << 18); - if (curSize > inSize) - curSize = (size_t)inSize; - RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); - if (curSize == 0) - return SZ_ERROR_INPUT_EOF; - memcpy(outBuffer, inBuf, curSize); - outBuffer += curSize; - inSize -= curSize; - RINOK(inStream->Skip((void *)inStream, curSize)); - } - return SZ_OK; -} - -static Bool IS_MAIN_METHOD(UInt32 m) -{ - switch(m) - { - case k_Copy: - case k_LZMA: - case k_LZMA2: - #ifdef _7ZIP_PPMD_SUPPPORT - case k_PPMD: - #endif - return True; - } - return False; -} - -static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) -{ - return - c->NumInStreams == 1 && - c->NumOutStreams == 1 && - c->MethodID <= (UInt32)0xFFFFFFFF && - IS_MAIN_METHOD((UInt32)c->MethodID); -} - -#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1) - -static SRes CheckSupportedFolder(const CSzFolder *f) -{ - if (f->NumCoders < 1 || f->NumCoders > 4) - return SZ_ERROR_UNSUPPORTED; - if (!IS_SUPPORTED_CODER(&f->Coders[0])) - return SZ_ERROR_UNSUPPORTED; - if (f->NumCoders == 1) - { - if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - if (f->NumCoders == 2) - { - CSzCoderInfo *c = &f->Coders[1]; - if (c->MethodID > (UInt32)0xFFFFFFFF || - c->NumInStreams != 1 || - c->NumOutStreams != 1 || - f->NumPackStreams != 1 || - f->PackStreams[0] != 0 || - f->NumBindPairs != 1 || - f->BindPairs[0].InIndex != 1 || - f->BindPairs[0].OutIndex != 0) - return SZ_ERROR_UNSUPPORTED; - switch ((UInt32)c->MethodID) - { - case k_BCJ: - case k_ARM: - break; - default: - return SZ_ERROR_UNSUPPORTED; - } - return SZ_OK; - } - if (f->NumCoders == 4) - { - if (!IS_SUPPORTED_CODER(&f->Coders[1]) || - !IS_SUPPORTED_CODER(&f->Coders[2]) || - !IS_BCJ2(&f->Coders[3])) - return SZ_ERROR_UNSUPPORTED; - if (f->NumPackStreams != 4 || - f->PackStreams[0] != 2 || - f->PackStreams[1] != 6 || - f->PackStreams[2] != 1 || - f->PackStreams[3] != 0 || - f->NumBindPairs != 3 || - f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || - f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || - f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - return SZ_ERROR_UNSUPPORTED; -} - -static UInt64 GetSum(const UInt64 *values, UInt32 index) -{ - UInt64 sum = 0; - UInt32 i; - for (i = 0; i < index; i++) - sum += values[i]; - return sum; -} - -#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; - -static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes, - ILookInStream *inStream, UInt64 startPos, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, - Byte *tempBuf[]) -{ - UInt32 ci; - SizeT tempSizes[3] = { 0, 0, 0}; - SizeT tempSize3 = 0; - Byte *tempBuf3 = 0; - - RINOK(CheckSupportedFolder(folder)); - - for (ci = 0; ci < folder->NumCoders; ci++) - { - CSzCoderInfo *coder = &folder->Coders[ci]; - - if (IS_MAIN_METHOD((UInt32)coder->MethodID)) - { - UInt32 si = 0; - UInt64 offset; - UInt64 inSize; - Byte *outBufCur = outBuffer; - SizeT outSizeCur = outSize; - if (folder->NumCoders == 4) - { - UInt32 indices[] = { 3, 2, 0 }; - UInt64 unpackSize = folder->UnpackSizes[ci]; - si = indices[ci]; - if (ci < 2) - { - Byte *temp; - outSizeCur = (SizeT)unpackSize; - if (outSizeCur != unpackSize) - return SZ_ERROR_MEM; - temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); - if (temp == 0 && outSizeCur != 0) - return SZ_ERROR_MEM; - outBufCur = tempBuf[1 - ci] = temp; - tempSizes[1 - ci] = outSizeCur; - } - else if (ci == 2) - { - if (unpackSize > outSize) /* check it */ - return SZ_ERROR_PARAM; - tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); - tempSize3 = outSizeCur = (SizeT)unpackSize; - } - else - return SZ_ERROR_UNSUPPORTED; - } - offset = GetSum(packSizes, si); - inSize = packSizes[si]; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - - if (coder->MethodID == k_Copy) - { - if (inSize != outSizeCur) /* check it */ - return SZ_ERROR_DATA; - RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); - } - else if (coder->MethodID == k_LZMA) - { - RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); - } - else if (coder->MethodID == k_LZMA2) - { - RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); - } - else - { - #ifdef _7ZIP_PPMD_SUPPPORT - RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); - #else - return SZ_ERROR_UNSUPPORTED; - #endif - } - } - else if (coder->MethodID == k_BCJ2) - { - UInt64 offset = GetSum(packSizes, 1); - UInt64 s3Size = packSizes[1]; - SRes res; - if (ci != 3) - return SZ_ERROR_UNSUPPORTED; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - tempSizes[2] = (SizeT)s3Size; - if (tempSizes[2] != s3Size) - return SZ_ERROR_MEM; - tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); - if (tempBuf[2] == 0 && tempSizes[2] != 0) - return SZ_ERROR_MEM; - res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); - RINOK(res) - - res = Bcj2_Decode( - tempBuf3, tempSize3, - tempBuf[0], tempSizes[0], - tempBuf[1], tempSizes[1], - tempBuf[2], tempSizes[2], - outBuffer, outSize); - RINOK(res) - } - else - { - if (ci != 1) - return SZ_ERROR_UNSUPPORTED; - switch(coder->MethodID) - { - case k_BCJ: - { - UInt32 state; - x86_Convert_Init(state); - x86_Convert(outBuffer, outSize, 0, &state, 0); - break; - } - CASE_BRA_CONV(ARM) - default: - return SZ_ERROR_UNSUPPORTED; - } - } - } - return SZ_OK; -} - -SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, - ILookInStream *inStream, UInt64 startPos, - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) -{ - Byte *tempBuf[3] = { 0, 0, 0}; - int i; - SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos, - outBuffer, (SizeT)outSize, allocMain, tempBuf); - for (i = 0; i < 3; i++) - IAlloc_Free(allocMain, tempBuf[i]); - return res; -} diff --git a/src/libs/7zip/win/C/7zFile.c b/src/libs/7zip/win/C/7zFile.c deleted file mode 100644 index a66c9e9d0..000000000 --- a/src/libs/7zip/win/C/7zFile.c +++ /dev/null @@ -1,284 +0,0 @@ -/* 7zFile.c -- File IO -2009-11-24 : Igor Pavlov : Public domain */ - -#include "7zFile.h" - -#ifndef USE_WINDOWS_FILE - -#ifndef UNDER_CE -#include <errno.h> -#endif - -#else - -/* - ReadFile and WriteFile functions in Windows have BUG: - If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) - from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES - (Insufficient system resources exist to complete the requested service). - Probably in some version of Windows there are problems with other sizes: - for 32 MB (maybe also for 16 MB). - And message can be "Network connection was lost" -*/ - -#define kChunkSizeMax (1 << 22) - -#endif - -void File_Construct(CSzFile *p) -{ - #ifdef USE_WINDOWS_FILE - p->handle = INVALID_HANDLE_VALUE; - #else - p->file = NULL; - #endif -} - -#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) -static WRes File_Open(CSzFile *p, const char *name, int writeMode) -{ - #ifdef USE_WINDOWS_FILE - p->handle = CreateFileA(name, - writeMode ? GENERIC_WRITE : GENERIC_READ, - FILE_SHARE_READ, NULL, - writeMode ? CREATE_ALWAYS : OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); - #else - p->file = fopen(name, writeMode ? "wb+" : "rb"); - return (p->file != 0) ? 0 : - #ifdef UNDER_CE - 2; /* ENOENT */ - #else - errno; - #endif - #endif -} - -WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } -WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } -#endif - -#ifdef USE_WINDOWS_FILE -static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) -{ - p->handle = CreateFileW(name, - writeMode ? GENERIC_WRITE : GENERIC_READ, - FILE_SHARE_READ, NULL, - writeMode ? CREATE_ALWAYS : OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); -} -WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } -WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } -#endif - -WRes File_Close(CSzFile *p) -{ - #ifdef USE_WINDOWS_FILE - if (p->handle != INVALID_HANDLE_VALUE) - { - if (!CloseHandle(p->handle)) - return GetLastError(); - p->handle = INVALID_HANDLE_VALUE; - } - #else - if (p->file != NULL) - { - int res = fclose(p->file); - if (res != 0) - return res; - p->file = NULL; - } - #endif - return 0; -} - -WRes File_Read(CSzFile *p, void *data, size_t *size) -{ - size_t originalSize = *size; - if (originalSize == 0) - return 0; - - #ifdef USE_WINDOWS_FILE - - *size = 0; - do - { - DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; - DWORD processed = 0; - BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); - data = (void *)((Byte *)data + processed); - originalSize -= processed; - *size += processed; - if (!res) - return GetLastError(); - if (processed == 0) - break; - } - while (originalSize > 0); - return 0; - - #else - - *size = fread(data, 1, originalSize, p->file); - if (*size == originalSize) - return 0; - return ferror(p->file); - - #endif -} - -WRes File_Write(CSzFile *p, const void *data, size_t *size) -{ - size_t originalSize = *size; - if (originalSize == 0) - return 0; - - #ifdef USE_WINDOWS_FILE - - *size = 0; - do - { - DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; - DWORD processed = 0; - BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); - data = (void *)((Byte *)data + processed); - originalSize -= processed; - *size += processed; - if (!res) - return GetLastError(); - if (processed == 0) - break; - } - while (originalSize > 0); - return 0; - - #else - - *size = fwrite(data, 1, originalSize, p->file); - if (*size == originalSize) - return 0; - return ferror(p->file); - - #endif -} - -WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) -{ - #ifdef USE_WINDOWS_FILE - - LARGE_INTEGER value; - DWORD moveMethod; - value.LowPart = (DWORD)*pos; - value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ - switch (origin) - { - case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; - case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; - case SZ_SEEK_END: moveMethod = FILE_END; break; - default: return ERROR_INVALID_PARAMETER; - } - value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); - if (value.LowPart == 0xFFFFFFFF) - { - WRes res = GetLastError(); - if (res != NO_ERROR) - return res; - } - *pos = ((Int64)value.HighPart << 32) | value.LowPart; - return 0; - - #else - - int moveMethod; - int res; - switch (origin) - { - case SZ_SEEK_SET: moveMethod = SEEK_SET; break; - case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; - case SZ_SEEK_END: moveMethod = SEEK_END; break; - default: return 1; - } - res = fseek(p->file, (long)*pos, moveMethod); - *pos = ftell(p->file); - return res; - - #endif -} - -WRes File_GetLength(CSzFile *p, UInt64 *length) -{ - #ifdef USE_WINDOWS_FILE - - DWORD sizeHigh; - DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); - if (sizeLow == 0xFFFFFFFF) - { - DWORD res = GetLastError(); - if (res != NO_ERROR) - return res; - } - *length = (((UInt64)sizeHigh) << 32) + sizeLow; - return 0; - - #else - - long pos = ftell(p->file); - int res = fseek(p->file, 0, SEEK_END); - *length = ftell(p->file); - fseek(p->file, pos, SEEK_SET); - return res; - - #endif -} - - -/* ---------- FileSeqInStream ---------- */ - -static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) -{ - CFileSeqInStream *p = (CFileSeqInStream *)pp; - return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; -} - -void FileSeqInStream_CreateVTable(CFileSeqInStream *p) -{ - p->s.Read = FileSeqInStream_Read; -} - - -/* ---------- FileInStream ---------- */ - -static SRes FileInStream_Read(void *pp, void *buf, size_t *size) -{ - CFileInStream *p = (CFileInStream *)pp; - return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; -} - -static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) -{ - CFileInStream *p = (CFileInStream *)pp; - return File_Seek(&p->file, pos, origin); -} - -void FileInStream_CreateVTable(CFileInStream *p) -{ - p->s.Read = FileInStream_Read; - p->s.Seek = FileInStream_Seek; -} - - -/* ---------- FileOutStream ---------- */ - -static size_t FileOutStream_Write(void *pp, const void *data, size_t size) -{ - CFileOutStream *p = (CFileOutStream *)pp; - File_Write(&p->file, data, &size); - return size; -} - -void FileOutStream_CreateVTable(CFileOutStream *p) -{ - p->s.Write = FileOutStream_Write; -} diff --git a/src/libs/7zip/win/C/7zFile.h b/src/libs/7zip/win/C/7zFile.h deleted file mode 100644 index 84538c03f..000000000 --- a/src/libs/7zip/win/C/7zFile.h +++ /dev/null @@ -1,83 +0,0 @@ -/* 7zFile.h -- File IO -2009-11-24 : Igor Pavlov : Public domain */ - -#ifndef __7Z_FILE_H -#define __7Z_FILE_H - -#ifdef _WIN32 -#define USE_WINDOWS_FILE -#endif - -#ifdef USE_WINDOWS_FILE -#include <windows.h> -#else -#include <stdio.h> -#endif - -#include "Types.h" - -EXTERN_C_BEGIN - -/* ---------- File ---------- */ - -typedef struct -{ - #ifdef USE_WINDOWS_FILE - HANDLE handle; - #else - FILE *file; - #endif -} CSzFile; - -void File_Construct(CSzFile *p); -#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) -WRes InFile_Open(CSzFile *p, const char *name); -WRes OutFile_Open(CSzFile *p, const char *name); -#endif -#ifdef USE_WINDOWS_FILE -WRes InFile_OpenW(CSzFile *p, const WCHAR *name); -WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); -#endif -WRes File_Close(CSzFile *p); - -/* reads max(*size, remain file's size) bytes */ -WRes File_Read(CSzFile *p, void *data, size_t *size); - -/* writes *size bytes */ -WRes File_Write(CSzFile *p, const void *data, size_t *size); - -WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); -WRes File_GetLength(CSzFile *p, UInt64 *length); - - -/* ---------- FileInStream ---------- */ - -typedef struct -{ - ISeqInStream s; - CSzFile file; -} CFileSeqInStream; - -void FileSeqInStream_CreateVTable(CFileSeqInStream *p); - - -typedef struct -{ - ISeekInStream s; - CSzFile file; -} CFileInStream; - -void FileInStream_CreateVTable(CFileInStream *p); - - -typedef struct -{ - ISeqOutStream s; - CSzFile file; -} CFileOutStream; - -void FileOutStream_CreateVTable(CFileOutStream *p); - -EXTERN_C_END - -#endif diff --git a/src/libs/7zip/win/C/7zIn.c b/src/libs/7zip/win/C/7zIn.c deleted file mode 100644 index ec93a43ff..000000000 --- a/src/libs/7zip/win/C/7zIn.c +++ /dev/null @@ -1,1402 +0,0 @@ -/* 7zIn.c -- 7z Input functions -2010-10-29 : Igor Pavlov : Public domain */ - -#include <string.h> - -#include "7z.h" -#include "7zCrc.h" -#include "CpuArch.h" - -Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; - -#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } - -#define NUM_FOLDER_CODERS_MAX 32 -#define NUM_CODER_STREAMS_MAX 32 - -void SzCoderInfo_Init(CSzCoderInfo *p) -{ - Buf_Init(&p->Props); -} - -void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) -{ - Buf_Free(&p->Props, alloc); - SzCoderInfo_Init(p); -} - -void SzFolder_Init(CSzFolder *p) -{ - p->Coders = 0; - p->BindPairs = 0; - p->PackStreams = 0; - p->UnpackSizes = 0; - p->NumCoders = 0; - p->NumBindPairs = 0; - p->NumPackStreams = 0; - p->UnpackCRCDefined = 0; - p->UnpackCRC = 0; - p->NumUnpackStreams = 0; -} - -void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) -{ - UInt32 i; - if (p->Coders) - for (i = 0; i < p->NumCoders; i++) - SzCoderInfo_Free(&p->Coders[i], alloc); - IAlloc_Free(alloc, p->Coders); - IAlloc_Free(alloc, p->BindPairs); - IAlloc_Free(alloc, p->PackStreams); - IAlloc_Free(alloc, p->UnpackSizes); - SzFolder_Init(p); -} - -UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) -{ - UInt32 result = 0; - UInt32 i; - for (i = 0; i < p->NumCoders; i++) - result += p->Coders[i].NumOutStreams; - return result; -} - -int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) -{ - UInt32 i; - for (i = 0; i < p->NumBindPairs; i++) - if (p->BindPairs[i].InIndex == inStreamIndex) - return i; - return -1; -} - - -int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) -{ - UInt32 i; - for (i = 0; i < p->NumBindPairs; i++) - if (p->BindPairs[i].OutIndex == outStreamIndex) - return i; - return -1; -} - -UInt64 SzFolder_GetUnpackSize(CSzFolder *p) -{ - int i = (int)SzFolder_GetNumOutStreams(p); - if (i == 0) - return 0; - for (i--; i >= 0; i--) - if (SzFolder_FindBindPairForOutStream(p, i) < 0) - return p->UnpackSizes[i]; - /* throw 1; */ - return 0; -} - -void SzFile_Init(CSzFileItem *p) -{ - p->HasStream = 1; - p->IsDir = 0; - p->IsAnti = 0; - p->CrcDefined = 0; - p->MTimeDefined = 0; -} - -void SzAr_Init(CSzAr *p) -{ - p->PackSizes = 0; - p->PackCRCsDefined = 0; - p->PackCRCs = 0; - p->Folders = 0; - p->Files = 0; - p->NumPackStreams = 0; - p->NumFolders = 0; - p->NumFiles = 0; -} - -void SzAr_Free(CSzAr *p, ISzAlloc *alloc) -{ - UInt32 i; - if (p->Folders) - for (i = 0; i < p->NumFolders; i++) - SzFolder_Free(&p->Folders[i], alloc); - - IAlloc_Free(alloc, p->PackSizes); - IAlloc_Free(alloc, p->PackCRCsDefined); - IAlloc_Free(alloc, p->PackCRCs); - IAlloc_Free(alloc, p->Folders); - IAlloc_Free(alloc, p->Files); - SzAr_Init(p); -} - - -void SzArEx_Init(CSzArEx *p) -{ - SzAr_Init(&p->db); - p->FolderStartPackStreamIndex = 0; - p->PackStreamStartPositions = 0; - p->FolderStartFileIndex = 0; - p->FileIndexToFolderIndexMap = 0; - p->FileNameOffsets = 0; - Buf_Init(&p->FileNames); -} - -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) -{ - IAlloc_Free(alloc, p->FolderStartPackStreamIndex); - IAlloc_Free(alloc, p->PackStreamStartPositions); - IAlloc_Free(alloc, p->FolderStartFileIndex); - IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); - - IAlloc_Free(alloc, p->FileNameOffsets); - Buf_Free(&p->FileNames, alloc); - - SzAr_Free(&p->db, alloc); - SzArEx_Init(p); -} - -/* -UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const -{ - return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; -} - -UInt64 GetFilePackSize(int fileIndex) const -{ - int folderIndex = FileIndexToFolderIndexMap[fileIndex]; - if (folderIndex >= 0) - { - const CSzFolder &folderInfo = Folders[folderIndex]; - if (FolderStartFileIndex[folderIndex] == fileIndex) - return GetFolderFullPackSize(folderIndex); - } - return 0; -} -*/ - -#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ - if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } - -static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) -{ - UInt32 startPos = 0; - UInt64 startPosSize = 0; - UInt32 i; - UInt32 folderIndex = 0; - UInt32 indexInFolder = 0; - MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); - for (i = 0; i < p->db.NumFolders; i++) - { - p->FolderStartPackStreamIndex[i] = startPos; - startPos += p->db.Folders[i].NumPackStreams; - } - - MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); - - for (i = 0; i < p->db.NumPackStreams; i++) - { - p->PackStreamStartPositions[i] = startPosSize; - startPosSize += p->db.PackSizes[i]; - } - - MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc); - MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); - - for (i = 0; i < p->db.NumFiles; i++) - { - CSzFileItem *file = p->db.Files + i; - int emptyStream = !file->HasStream; - if (emptyStream && indexInFolder == 0) - { - p->FileIndexToFolderIndexMap[i] = (UInt32)-1; - continue; - } - if (indexInFolder == 0) - { - /* - v3.13 incorrectly worked with empty folders - v4.07: Loop for skipping empty folders - */ - for (;;) - { - if (folderIndex >= p->db.NumFolders) - return SZ_ERROR_ARCHIVE; - p->FolderStartFileIndex[folderIndex] = i; - if (p->db.Folders[folderIndex].NumUnpackStreams != 0) - break; - folderIndex++; - } - } - p->FileIndexToFolderIndexMap[i] = folderIndex; - if (emptyStream) - continue; - indexInFolder++; - if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) - { - folderIndex++; - indexInFolder = 0; - } - } - return SZ_OK; -} - - -UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) -{ - return p->dataPos + - p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; -} - -int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize) -{ - UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; - CSzFolder *folder = p->db.Folders + folderIndex; - UInt64 size = 0; - UInt32 i; - for (i = 0; i < folder->NumPackStreams; i++) - { - UInt64 t = size + p->db.PackSizes[packStreamIndex + i]; - if (t < size) /* check it */ - return SZ_ERROR_FAIL; - size = t; - } - *resSize = size; - return SZ_OK; -} - - -/* -SRes SzReadTime(const CObjectVector<CBuf> &dataVector, - CObjectVector<CSzFileItem> &files, UInt64 type) -{ - CBoolVector boolVector; - RINOK(ReadBoolVector2(files.Size(), boolVector)) - - CStreamSwitch streamSwitch; - RINOK(streamSwitch.Set(this, &dataVector)); - - for (int i = 0; i < files.Size(); i++) - { - CSzFileItem &file = files[i]; - CArchiveFileTime fileTime; - bool defined = boolVector[i]; - if (defined) - { - UInt32 low, high; - RINOK(SzReadUInt32(low)); - RINOK(SzReadUInt32(high)); - fileTime.dwLowDateTime = low; - fileTime.dwHighDateTime = high; - } - switch(type) - { - case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break; - case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break; - case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break; - } - } - return SZ_OK; -} -*/ - -static int TestSignatureCandidate(Byte *testBytes) -{ - size_t i; - for (i = 0; i < k7zSignatureSize; i++) - if (testBytes[i] != k7zSignature[i]) - return 0; - return 1; -} - -typedef struct _CSzState -{ - Byte *Data; - size_t Size; -}CSzData; - -static SRes SzReadByte(CSzData *sd, Byte *b) -{ - if (sd->Size == 0) - return SZ_ERROR_ARCHIVE; - sd->Size--; - *b = *sd->Data++; - return SZ_OK; -} - -static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size) -{ - size_t i; - for (i = 0; i < size; i++) - { - RINOK(SzReadByte(sd, data + i)); - } - return SZ_OK; -} - -static SRes SzReadUInt32(CSzData *sd, UInt32 *value) -{ - int i; - *value = 0; - for (i = 0; i < 4; i++) - { - Byte b; - RINOK(SzReadByte(sd, &b)); - *value |= ((UInt32)(b) << (8 * i)); - } - return SZ_OK; -} - -static SRes SzReadNumber(CSzData *sd, UInt64 *value) -{ - Byte firstByte; - Byte mask = 0x80; - int i; - RINOK(SzReadByte(sd, &firstByte)); - *value = 0; - for (i = 0; i < 8; i++) - { - Byte b; - if ((firstByte & mask) == 0) - { - UInt64 highPart = firstByte & (mask - 1); - *value += (highPart << (8 * i)); - return SZ_OK; - } - RINOK(SzReadByte(sd, &b)); - *value |= ((UInt64)b << (8 * i)); - mask >>= 1; - } - return SZ_OK; -} - -static SRes SzReadNumber32(CSzData *sd, UInt32 *value) -{ - UInt64 value64; - RINOK(SzReadNumber(sd, &value64)); - if (value64 >= 0x80000000) - return SZ_ERROR_UNSUPPORTED; - if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) - return SZ_ERROR_UNSUPPORTED; - *value = (UInt32)value64; - return SZ_OK; -} - -static SRes SzReadID(CSzData *sd, UInt64 *value) -{ - return SzReadNumber(sd, value); -} - -static SRes SzSkeepDataSize(CSzData *sd, UInt64 size) -{ - if (size > sd->Size) - return SZ_ERROR_ARCHIVE; - sd->Size -= (size_t)size; - sd->Data += (size_t)size; - return SZ_OK; -} - -static SRes SzSkeepData(CSzData *sd) -{ - UInt64 size; - RINOK(SzReadNumber(sd, &size)); - return SzSkeepDataSize(sd, size); -} - -static SRes SzReadArchiveProperties(CSzData *sd) -{ - for (;;) - { - UInt64 type; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - break; - SzSkeepData(sd); - } - return SZ_OK; -} - -static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute) -{ - for (;;) - { - UInt64 type; - RINOK(SzReadID(sd, &type)); - if (type == attribute) - return SZ_OK; - if (type == k7zIdEnd) - return SZ_ERROR_ARCHIVE; - RINOK(SzSkeepData(sd)); - } -} - -static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) -{ - Byte b = 0; - Byte mask = 0; - size_t i; - MY_ALLOC(Byte, *v, numItems, alloc); - for (i = 0; i < numItems; i++) - { - if (mask == 0) - { - RINOK(SzReadByte(sd, &b)); - mask = 0x80; - } - (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0); - mask >>= 1; - } - return SZ_OK; -} - -static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) -{ - Byte allAreDefined; - size_t i; - RINOK(SzReadByte(sd, &allAreDefined)); - if (allAreDefined == 0) - return SzReadBoolVector(sd, numItems, v, alloc); - MY_ALLOC(Byte, *v, numItems, alloc); - for (i = 0; i < numItems; i++) - (*v)[i] = 1; - return SZ_OK; -} - -static SRes SzReadHashDigests( - CSzData *sd, - size_t numItems, - Byte **digestsDefined, - UInt32 **digests, - ISzAlloc *alloc) -{ - size_t i; - RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); - MY_ALLOC(UInt32, *digests, numItems, alloc); - for (i = 0; i < numItems; i++) - if ((*digestsDefined)[i]) - { - RINOK(SzReadUInt32(sd, (*digests) + i)); - } - return SZ_OK; -} - -static SRes SzReadPackInfo( - CSzData *sd, - UInt64 *dataOffset, - UInt32 *numPackStreams, - UInt64 **packSizes, - Byte **packCRCsDefined, - UInt32 **packCRCs, - ISzAlloc *alloc) -{ - UInt32 i; - RINOK(SzReadNumber(sd, dataOffset)); - RINOK(SzReadNumber32(sd, numPackStreams)); - - RINOK(SzWaitAttribute(sd, k7zIdSize)); - - MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc); - - for (i = 0; i < *numPackStreams; i++) - { - RINOK(SzReadNumber(sd, (*packSizes) + i)); - } - - for (;;) - { - UInt64 type; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - break; - if (type == k7zIdCRC) - { - RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); - continue; - } - RINOK(SzSkeepData(sd)); - } - if (*packCRCsDefined == 0) - { - MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc); - MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc); - for (i = 0; i < *numPackStreams; i++) - { - (*packCRCsDefined)[i] = 0; - (*packCRCs)[i] = 0; - } - } - return SZ_OK; -} - -static SRes SzReadSwitch(CSzData *sd) -{ - Byte external; - RINOK(SzReadByte(sd, &external)); - return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; -} - -static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) -{ - UInt32 numCoders, numBindPairs, numPackStreams, i; - UInt32 numInStreams = 0, numOutStreams = 0; - - RINOK(SzReadNumber32(sd, &numCoders)); - if (numCoders > NUM_FOLDER_CODERS_MAX) - return SZ_ERROR_UNSUPPORTED; - folder->NumCoders = numCoders; - - MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); - - for (i = 0; i < numCoders; i++) - SzCoderInfo_Init(folder->Coders + i); - - for (i = 0; i < numCoders; i++) - { - Byte mainByte; - CSzCoderInfo *coder = folder->Coders + i; - { - unsigned idSize, j; - Byte longID[15]; - RINOK(SzReadByte(sd, &mainByte)); - idSize = (unsigned)(mainByte & 0xF); - RINOK(SzReadBytes(sd, longID, idSize)); - if (idSize > sizeof(coder->MethodID)) - return SZ_ERROR_UNSUPPORTED; - coder->MethodID = 0; - for (j = 0; j < idSize; j++) - coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j); - - if ((mainByte & 0x10) != 0) - { - RINOK(SzReadNumber32(sd, &coder->NumInStreams)); - RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); - if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || - coder->NumOutStreams > NUM_CODER_STREAMS_MAX) - return SZ_ERROR_UNSUPPORTED; - } - else - { - coder->NumInStreams = 1; - coder->NumOutStreams = 1; - } - if ((mainByte & 0x20) != 0) - { - UInt64 propertiesSize = 0; - RINOK(SzReadNumber(sd, &propertiesSize)); - if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) - return SZ_ERROR_MEM; - RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize)); - } - } - while ((mainByte & 0x80) != 0) - { - RINOK(SzReadByte(sd, &mainByte)); - RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); - if ((mainByte & 0x10) != 0) - { - UInt32 n; - RINOK(SzReadNumber32(sd, &n)); - RINOK(SzReadNumber32(sd, &n)); - } - if ((mainByte & 0x20) != 0) - { - UInt64 propertiesSize = 0; - RINOK(SzReadNumber(sd, &propertiesSize)); - RINOK(SzSkeepDataSize(sd, propertiesSize)); - } - } - numInStreams += coder->NumInStreams; - numOutStreams += coder->NumOutStreams; - } - - if (numOutStreams == 0) - return SZ_ERROR_UNSUPPORTED; - - folder->NumBindPairs = numBindPairs = numOutStreams - 1; - MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); - - for (i = 0; i < numBindPairs; i++) - { - CSzBindPair *bp = folder->BindPairs + i; - RINOK(SzReadNumber32(sd, &bp->InIndex)); - RINOK(SzReadNumber32(sd, &bp->OutIndex)); - } - - if (numInStreams < numBindPairs) - return SZ_ERROR_UNSUPPORTED; - - folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; - MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc); - - if (numPackStreams == 1) - { - for (i = 0; i < numInStreams ; i++) - if (SzFolder_FindBindPairForInStream(folder, i) < 0) - break; - if (i == numInStreams) - return SZ_ERROR_UNSUPPORTED; - folder->PackStreams[0] = i; - } - else - for (i = 0; i < numPackStreams; i++) - { - RINOK(SzReadNumber32(sd, folder->PackStreams + i)); - } - return SZ_OK; -} - -static SRes SzReadUnpackInfo( - CSzData *sd, - UInt32 *numFolders, - CSzFolder **folders, /* for alloc */ - ISzAlloc *alloc, - ISzAlloc *allocTemp) -{ - UInt32 i; - RINOK(SzWaitAttribute(sd, k7zIdFolder)); - RINOK(SzReadNumber32(sd, numFolders)); - { - RINOK(SzReadSwitch(sd)); - - MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); - - for (i = 0; i < *numFolders; i++) - SzFolder_Init((*folders) + i); - - for (i = 0; i < *numFolders; i++) - { - RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); - } - } - - RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); - - for (i = 0; i < *numFolders; i++) - { - UInt32 j; - CSzFolder *folder = (*folders) + i; - UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); - - MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc); - - for (j = 0; j < numOutStreams; j++) - { - RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); - } - } - - for (;;) - { - UInt64 type; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - return SZ_OK; - if (type == k7zIdCRC) - { - SRes res; - Byte *crcsDefined = 0; - UInt32 *crcs = 0; - res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); - if (res == SZ_OK) - { - for (i = 0; i < *numFolders; i++) - { - CSzFolder *folder = (*folders) + i; - folder->UnpackCRCDefined = crcsDefined[i]; - folder->UnpackCRC = crcs[i]; - } - } - IAlloc_Free(allocTemp, crcs); - IAlloc_Free(allocTemp, crcsDefined); - RINOK(res); - continue; - } - RINOK(SzSkeepData(sd)); - } -} - -static SRes SzReadSubStreamsInfo( - CSzData *sd, - UInt32 numFolders, - CSzFolder *folders, - UInt32 *numUnpackStreams, - UInt64 **unpackSizes, - Byte **digestsDefined, - UInt32 **digests, - ISzAlloc *allocTemp) -{ - UInt64 type = 0; - UInt32 i; - UInt32 si = 0; - UInt32 numDigests = 0; - - for (i = 0; i < numFolders; i++) - folders[i].NumUnpackStreams = 1; - *numUnpackStreams = numFolders; - - for (;;) - { - RINOK(SzReadID(sd, &type)); - if (type == k7zIdNumUnpackStream) - { - *numUnpackStreams = 0; - for (i = 0; i < numFolders; i++) - { - UInt32 numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); - folders[i].NumUnpackStreams = numStreams; - *numUnpackStreams += numStreams; - } - continue; - } - if (type == k7zIdCRC || type == k7zIdSize) - break; - if (type == k7zIdEnd) - break; - RINOK(SzSkeepData(sd)); - } - - if (*numUnpackStreams == 0) - { - *unpackSizes = 0; - *digestsDefined = 0; - *digests = 0; - } - else - { - *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64)); - RINOM(*unpackSizes); - *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte)); - RINOM(*digestsDefined); - *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32)); - RINOM(*digests); - } - - for (i = 0; i < numFolders; i++) - { - /* - v3.13 incorrectly worked with empty folders - v4.07: we check that folder is empty - */ - UInt64 sum = 0; - UInt32 j; - UInt32 numSubstreams = folders[i].NumUnpackStreams; - if (numSubstreams == 0) - continue; - if (type == k7zIdSize) - for (j = 1; j < numSubstreams; j++) - { - UInt64 size; - RINOK(SzReadNumber(sd, &size)); - (*unpackSizes)[si++] = size; - sum += size; - } - (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; - } - if (type == k7zIdSize) - { - RINOK(SzReadID(sd, &type)); - } - - for (i = 0; i < *numUnpackStreams; i++) - { - (*digestsDefined)[i] = 0; - (*digests)[i] = 0; - } - - - for (i = 0; i < numFolders; i++) - { - UInt32 numSubstreams = folders[i].NumUnpackStreams; - if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) - numDigests += numSubstreams; - } - - - si = 0; - for (;;) - { - if (type == k7zIdCRC) - { - int digestIndex = 0; - Byte *digestsDefined2 = 0; - UInt32 *digests2 = 0; - SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); - if (res == SZ_OK) - { - for (i = 0; i < numFolders; i++) - { - CSzFolder *folder = folders + i; - UInt32 numSubstreams = folder->NumUnpackStreams; - if (numSubstreams == 1 && folder->UnpackCRCDefined) - { - (*digestsDefined)[si] = 1; - (*digests)[si] = folder->UnpackCRC; - si++; - } - else - { - UInt32 j; - for (j = 0; j < numSubstreams; j++, digestIndex++) - { - (*digestsDefined)[si] = digestsDefined2[digestIndex]; - (*digests)[si] = digests2[digestIndex]; - si++; - } - } - } - } - IAlloc_Free(allocTemp, digestsDefined2); - IAlloc_Free(allocTemp, digests2); - RINOK(res); - } - else if (type == k7zIdEnd) - return SZ_OK; - else - { - RINOK(SzSkeepData(sd)); - } - RINOK(SzReadID(sd, &type)); - } -} - - -static SRes SzReadStreamsInfo( - CSzData *sd, - UInt64 *dataOffset, - CSzAr *p, - UInt32 *numUnpackStreams, - UInt64 **unpackSizes, /* allocTemp */ - Byte **digestsDefined, /* allocTemp */ - UInt32 **digests, /* allocTemp */ - ISzAlloc *alloc, - ISzAlloc *allocTemp) -{ - for (;;) - { - UInt64 type; - RINOK(SzReadID(sd, &type)); - if ((UInt64)(int)type != type) - return SZ_ERROR_UNSUPPORTED; - switch((int)type) - { - case k7zIdEnd: - return SZ_OK; - case k7zIdPackInfo: - { - RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, - &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); - break; - } - case k7zIdUnpackInfo: - { - RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); - break; - } - case k7zIdSubStreamsInfo: - { - RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, - numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); - break; - } - default: - return SZ_ERROR_UNSUPPORTED; - } - } -} - -size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) -{ - size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; - if (dest != 0) - { - size_t i; - const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2); - for (i = 0; i < len; i++) - dest[i] = GetUi16(src + i * 2); - } - return len; -} - -static SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes) -{ - UInt32 i; - size_t pos = 0; - for (i = 0; i < numFiles; i++) - { - sizes[i] = pos; - for (;;) - { - if (pos >= size) - return SZ_ERROR_ARCHIVE; - if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0) - break; - pos++; - } - pos++; - } - sizes[i] = pos; - return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; -} - -static SRes SzReadHeader2( - CSzArEx *p, /* allocMain */ - CSzData *sd, - UInt64 **unpackSizes, /* allocTemp */ - Byte **digestsDefined, /* allocTemp */ - UInt32 **digests, /* allocTemp */ - Byte **emptyStreamVector, /* allocTemp */ - Byte **emptyFileVector, /* allocTemp */ - Byte **lwtVector, /* allocTemp */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - UInt64 type; - UInt32 numUnpackStreams = 0; - UInt32 numFiles = 0; - CSzFileItem *files = 0; - UInt32 numEmptyStreams = 0; - UInt32 i; - - RINOK(SzReadID(sd, &type)); - - if (type == k7zIdArchiveProperties) - { - RINOK(SzReadArchiveProperties(sd)); - RINOK(SzReadID(sd, &type)); - } - - - if (type == k7zIdMainStreamsInfo) - { - RINOK(SzReadStreamsInfo(sd, - &p->dataPos, - &p->db, - &numUnpackStreams, - unpackSizes, - digestsDefined, - digests, allocMain, allocTemp)); - p->dataPos += p->startPosAfterHeader; - RINOK(SzReadID(sd, &type)); - } - - if (type == k7zIdEnd) - return SZ_OK; - if (type != k7zIdFilesInfo) - return SZ_ERROR_ARCHIVE; - - RINOK(SzReadNumber32(sd, &numFiles)); - p->db.NumFiles = numFiles; - - MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); - - p->db.Files = files; - for (i = 0; i < numFiles; i++) - SzFile_Init(files + i); - - for (;;) - { - UInt64 type; - UInt64 size; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - break; - RINOK(SzReadNumber(sd, &size)); - if (size > sd->Size) - return SZ_ERROR_ARCHIVE; - if ((UInt64)(int)type != type) - { - RINOK(SzSkeepDataSize(sd, size)); - } - else - switch((int)type) - { - case k7zIdName: - { - size_t namesSize; - RINOK(SzReadSwitch(sd)); - namesSize = (size_t)size - 1; - if ((namesSize & 1) != 0) - return SZ_ERROR_ARCHIVE; - if (!Buf_Create(&p->FileNames, namesSize, allocMain)) - return SZ_ERROR_MEM; - MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); - memcpy(p->FileNames.data, sd->Data, namesSize); - RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets)) - RINOK(SzSkeepDataSize(sd, namesSize)); - break; - } - case k7zIdEmptyStream: - { - RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); - numEmptyStreams = 0; - for (i = 0; i < numFiles; i++) - if ((*emptyStreamVector)[i]) - numEmptyStreams++; - break; - } - case k7zIdEmptyFile: - { - RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); - break; - } - case k7zIdWinAttributes: - { - RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); - RINOK(SzReadSwitch(sd)); - for (i = 0; i < numFiles; i++) - { - CSzFileItem *f = &files[i]; - Byte defined = (*lwtVector)[i]; - f->AttribDefined = defined; - f->Attrib = 0; - if (defined) - { - RINOK(SzReadUInt32(sd, &f->Attrib)); - } - } - IAlloc_Free(allocTemp, *lwtVector); - *lwtVector = NULL; - break; - } - case k7zIdMTime: - { - RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); - RINOK(SzReadSwitch(sd)); - for (i = 0; i < numFiles; i++) - { - CSzFileItem *f = &files[i]; - Byte defined = (*lwtVector)[i]; - f->MTimeDefined = defined; - f->MTime.Low = f->MTime.High = 0; - if (defined) - { - RINOK(SzReadUInt32(sd, &f->MTime.Low)); - RINOK(SzReadUInt32(sd, &f->MTime.High)); - } - } - IAlloc_Free(allocTemp, *lwtVector); - *lwtVector = NULL; - break; - } - default: - { - RINOK(SzSkeepDataSize(sd, size)); - } - } - } - - { - UInt32 emptyFileIndex = 0; - UInt32 sizeIndex = 0; - for (i = 0; i < numFiles; i++) - { - CSzFileItem *file = files + i; - file->IsAnti = 0; - if (*emptyStreamVector == 0) - file->HasStream = 1; - else - file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); - if (file->HasStream) - { - file->IsDir = 0; - file->Size = (*unpackSizes)[sizeIndex]; - file->Crc = (*digests)[sizeIndex]; - file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex]; - sizeIndex++; - } - else - { - if (*emptyFileVector == 0) - file->IsDir = 1; - else - file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); - emptyFileIndex++; - file->Size = 0; - file->Crc = 0; - file->CrcDefined = 0; - } - } - } - return SzArEx_Fill(p, allocMain); -} - -static SRes SzReadHeader( - CSzArEx *p, - CSzData *sd, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - UInt64 *unpackSizes = 0; - Byte *digestsDefined = 0; - UInt32 *digests = 0; - Byte *emptyStreamVector = 0; - Byte *emptyFileVector = 0; - Byte *lwtVector = 0; - SRes res = SzReadHeader2(p, sd, - &unpackSizes, &digestsDefined, &digests, - &emptyStreamVector, &emptyFileVector, &lwtVector, - allocMain, allocTemp); - IAlloc_Free(allocTemp, unpackSizes); - IAlloc_Free(allocTemp, digestsDefined); - IAlloc_Free(allocTemp, digests); - IAlloc_Free(allocTemp, emptyStreamVector); - IAlloc_Free(allocTemp, emptyFileVector); - IAlloc_Free(allocTemp, lwtVector); - return res; -} - -static SRes SzReadAndDecodePackedStreams2( - ILookInStream *inStream, - CSzData *sd, - CBuf *outBuffer, - UInt64 baseOffset, - CSzAr *p, - UInt64 **unpackSizes, - Byte **digestsDefined, - UInt32 **digests, - ISzAlloc *allocTemp) -{ - - UInt32 numUnpackStreams = 0; - UInt64 dataStartPos; - CSzFolder *folder; - UInt64 unpackSize; - SRes res; - - RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, - &numUnpackStreams, unpackSizes, digestsDefined, digests, - allocTemp, allocTemp)); - - dataStartPos += baseOffset; - if (p->NumFolders != 1) - return SZ_ERROR_ARCHIVE; - - folder = p->Folders; - unpackSize = SzFolder_GetUnpackSize(folder); - - RINOK(LookInStream_SeekTo(inStream, dataStartPos)); - - if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) - return SZ_ERROR_MEM; - - res = SzFolder_Decode(folder, p->PackSizes, - inStream, dataStartPos, - outBuffer->data, (size_t)unpackSize, allocTemp); - RINOK(res); - if (folder->UnpackCRCDefined) - if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) - return SZ_ERROR_CRC; - return SZ_OK; -} - -static SRes SzReadAndDecodePackedStreams( - ILookInStream *inStream, - CSzData *sd, - CBuf *outBuffer, - UInt64 baseOffset, - ISzAlloc *allocTemp) -{ - CSzAr p; - UInt64 *unpackSizes = 0; - Byte *digestsDefined = 0; - UInt32 *digests = 0; - SRes res; - SzAr_Init(&p); - res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, - &p, &unpackSizes, &digestsDefined, &digests, - allocTemp); - SzAr_Free(&p, allocTemp); - IAlloc_Free(allocTemp, unpackSizes); - IAlloc_Free(allocTemp, digestsDefined); - IAlloc_Free(allocTemp, digests); - return res; -} - -static SRes SzArEx_Open2( - CSzArEx *p, - ILookInStream *inStream, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - Byte header[k7zStartHeaderSize]; - Int64 startArcPos; - UInt64 nextHeaderOffset, nextHeaderSize; - size_t nextHeaderSizeT; - UInt32 nextHeaderCRC; - CBuf buffer; - SRes res; - - startArcPos = 0; - RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); - - RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); - - if (!TestSignatureCandidate(header)) - return SZ_ERROR_NO_ARCHIVE; - if (header[6] != k7zMajorVersion) - return SZ_ERROR_UNSUPPORTED; - - nextHeaderOffset = GetUi64(header + 12); - nextHeaderSize = GetUi64(header + 20); - nextHeaderCRC = GetUi32(header + 28); - - p->startPosAfterHeader = startArcPos + k7zStartHeaderSize; - - if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) - return SZ_ERROR_CRC; - - nextHeaderSizeT = (size_t)nextHeaderSize; - if (nextHeaderSizeT != nextHeaderSize) - return SZ_ERROR_MEM; - if (nextHeaderSizeT == 0) - return SZ_OK; - if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || - nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) - return SZ_ERROR_NO_ARCHIVE; - - { - Int64 pos = 0; - RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); - if ((UInt64)pos < startArcPos + nextHeaderOffset || - (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || - (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) - return SZ_ERROR_INPUT_EOF; - } - - RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset)); - - if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) - return SZ_ERROR_MEM; - - res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); - if (res == SZ_OK) - { - res = SZ_ERROR_ARCHIVE; - if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) - { - CSzData sd; - UInt64 type; - sd.Data = buffer.data; - sd.Size = buffer.size; - res = SzReadID(&sd, &type); - if (res == SZ_OK) - { - if (type == k7zIdEncodedHeader) - { - CBuf outBuffer; - Buf_Init(&outBuffer); - res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); - if (res != SZ_OK) - Buf_Free(&outBuffer, allocTemp); - else - { - Buf_Free(&buffer, allocTemp); - buffer.data = outBuffer.data; - buffer.size = outBuffer.size; - sd.Data = buffer.data; - sd.Size = buffer.size; - res = SzReadID(&sd, &type); - } - } - } - if (res == SZ_OK) - { - if (type == k7zIdHeader) - res = SzReadHeader(p, &sd, allocMain, allocTemp); - else - res = SZ_ERROR_UNSUPPORTED; - } - } - } - Buf_Free(&buffer, allocTemp); - return res; -} - -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) -{ - SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); - if (res != SZ_OK) - SzArEx_Free(p, allocMain); - return res; -} - -SRes SzArEx_Extract( - const CSzArEx *p, - ILookInStream *inStream, - UInt32 fileIndex, - UInt32 *blockIndex, - Byte **outBuffer, - size_t *outBufferSize, - size_t *offset, - size_t *outSizeProcessed, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; - SRes res = SZ_OK; - *offset = 0; - *outSizeProcessed = 0; - if (folderIndex == (UInt32)-1) - { - IAlloc_Free(allocMain, *outBuffer); - *blockIndex = folderIndex; - *outBuffer = 0; - *outBufferSize = 0; - return SZ_OK; - } - - if (*outBuffer == 0 || *blockIndex != folderIndex) - { - CSzFolder *folder = p->db.Folders + folderIndex; - UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); - size_t unpackSize = (size_t)unpackSizeSpec; - UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); - - if (unpackSize != unpackSizeSpec) - return SZ_ERROR_MEM; - *blockIndex = folderIndex; - IAlloc_Free(allocMain, *outBuffer); - *outBuffer = 0; - - RINOK(LookInStream_SeekTo(inStream, startOffset)); - - if (res == SZ_OK) - { - *outBufferSize = unpackSize; - if (unpackSize != 0) - { - *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); - if (*outBuffer == 0) - res = SZ_ERROR_MEM; - } - if (res == SZ_OK) - { - res = SzFolder_Decode(folder, - p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex], - inStream, startOffset, - *outBuffer, unpackSize, allocTemp); - if (res == SZ_OK) - { - if (folder->UnpackCRCDefined) - { - if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) - res = SZ_ERROR_CRC; - } - } - } - } - } - if (res == SZ_OK) - { - UInt32 i; - CSzFileItem *fileItem = p->db.Files + fileIndex; - *offset = 0; - for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) - *offset += (UInt32)p->db.Files[i].Size; - *outSizeProcessed = (size_t)fileItem->Size; - if (*offset + *outSizeProcessed > *outBufferSize) - return SZ_ERROR_FAIL; - if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc) - res = SZ_ERROR_CRC; - } - return res; -} diff --git a/src/libs/7zip/win/C/7zStream.c b/src/libs/7zip/win/C/7zStream.c index 0ebb7b5f9..88f9c42b1 100644 --- a/src/libs/7zip/win/C/7zStream.c +++ b/src/libs/7zip/win/C/7zStream.c @@ -1,9 +1,11 @@ /* 7zStream.c -- 7z Stream functions -2010-03-11 : Igor Pavlov : Public domain */ +2013-11-12 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include <string.h> -#include "Types.h" +#include "7zTypes.h" SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) { diff --git a/src/libs/7zip/win/C/Types.h b/src/libs/7zip/win/C/7zTypes.h index 7732c240c..778413ef4 100644 --- a/src/libs/7zip/win/C/Types.h +++ b/src/libs/7zip/win/C/7zTypes.h @@ -1,15 +1,15 @@ -/* Types.h -- Basic types -2010-10-09 : Igor Pavlov : Public domain */ +/* 7zTypes.h -- Basic types +2013-11-12 : Igor Pavlov : Public domain */ #ifndef __7Z_TYPES_H #define __7Z_TYPES_H -#include <stddef.h> - #ifdef _WIN32 -#include <windows.h> +/* #include <windows.h> */ #endif +#include <stddef.h> + #ifndef EXTERN_C_BEGIN #ifdef __cplusplus #define EXTERN_C_BEGIN extern "C" { @@ -43,7 +43,8 @@ EXTERN_C_BEGIN typedef int SRes; #ifdef _WIN32 -typedef DWORD WRes; +/* typedef DWORD WRes; */ +typedef unsigned WRes; #else typedef int WRes; #endif @@ -116,6 +117,7 @@ typedef int Bool; #else +#define MY_NO_INLINE #define MY_CDECL #define MY_FAST_CALL diff --git a/src/libs/7zip/win/C/7zVersion.h b/src/libs/7zip/win/C/7zVersion.h index 9d99c5dff..475918352 100644 --- a/src/libs/7zip/win/C/7zVersion.h +++ b/src/libs/7zip/win/C/7zVersion.h @@ -1,7 +1,10 @@ #define MY_VER_MAJOR 9 -#define MY_VER_MINOR 20 -#define MY_VER_BUILD 0 -#define MY_VERSION "9.20" -#define MY_DATE "2010-11-18" +#define MY_VER_MINOR 38 +#define MY_VER_BUILD 00 +#define MY_VERSION "9.38 beta" +// #define MY_7ZIP_VERSION "9.38" +#define MY_DATE "2015-01-03" +#undef MY_COPYRIGHT +#undef MY_VERSION_COPYRIGHT_DATE #define MY_COPYRIGHT ": Igor Pavlov : Public domain" #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE diff --git a/src/libs/7zip/win/C/Alloc.c b/src/libs/7zip/win/C/Alloc.c index 358a7b526..1f3f6c661 100644 --- a/src/libs/7zip/win/C/Alloc.c +++ b/src/libs/7zip/win/C/Alloc.c @@ -1,7 +1,7 @@ /* Alloc.c -- Memory allocation functions -2008-09-24 -Igor Pavlov -Public domain */ +2013-11-12 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #ifdef _WIN32 #include <windows.h> @@ -99,7 +99,7 @@ void *BigAlloc(size_t size) #ifdef _SZ_ALLOC_DEBUG fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); #endif - + #ifdef _7ZIP_LARGE_PAGES if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18)) { @@ -118,7 +118,7 @@ void BigFree(void *address) if (address != 0) fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig); #endif - + if (address == 0) return; VirtualFree(address, 0, MEM_RELEASE); diff --git a/src/libs/7zip/win/C/Bcj2.c b/src/libs/7zip/win/C/Bcj2.c deleted file mode 100644 index 20199ce56..000000000 --- a/src/libs/7zip/win/C/Bcj2.c +++ /dev/null @@ -1,132 +0,0 @@ -/* Bcj2.c -- Converter for x86 code (BCJ2) -2008-10-04 : Igor Pavlov : Public domain */ - -#include "Bcj2.h" - -#ifdef _LZMA_PROB32 -#define CProb UInt32 -#else -#define CProb UInt16 -#endif - -#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) -#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_READ_BYTE (*buffer++) -#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } -#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ - { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} - -#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } - -#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; -#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; - -int Bcj2_Decode( - const Byte *buf0, SizeT size0, - const Byte *buf1, SizeT size1, - const Byte *buf2, SizeT size2, - const Byte *buf3, SizeT size3, - Byte *outBuf, SizeT outSize) -{ - CProb p[256 + 2]; - SizeT inPos = 0, outPos = 0; - - const Byte *buffer, *bufferLim; - UInt32 range, code; - Byte prevByte = 0; - - unsigned int i; - for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) - p[i] = kBitModelTotal >> 1; - - buffer = buf3; - bufferLim = buffer + size3; - RC_INIT2 - - if (outSize == 0) - return SZ_OK; - - for (;;) - { - Byte b; - CProb *prob; - UInt32 bound; - UInt32 ttt; - - SizeT limit = size0 - inPos; - if (outSize - outPos < limit) - limit = outSize - outPos; - while (limit != 0) - { - Byte b = buf0[inPos]; - outBuf[outPos++] = b; - if (IsJ(prevByte, b)) - break; - inPos++; - prevByte = b; - limit--; - } - - if (limit == 0 || outPos == outSize) - break; - - b = buf0[inPos++]; - - if (b == 0xE8) - prob = p + prevByte; - else if (b == 0xE9) - prob = p + 256; - else - prob = p + 257; - - IF_BIT_0(prob) - { - UPDATE_0(prob) - prevByte = b; - } - else - { - UInt32 dest; - const Byte *v; - UPDATE_1(prob) - if (b == 0xE8) - { - v = buf1; - if (size1 < 4) - return SZ_ERROR_DATA; - buf1 += 4; - size1 -= 4; - } - else - { - v = buf2; - if (size2 < 4) - return SZ_ERROR_DATA; - buf2 += 4; - size2 -= 4; - } - dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | - ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); - outBuf[outPos++] = (Byte)dest; - if (outPos == outSize) - break; - outBuf[outPos++] = (Byte)(dest >> 8); - if (outPos == outSize) - break; - outBuf[outPos++] = (Byte)(dest >> 16); - if (outPos == outSize) - break; - outBuf[outPos++] = prevByte = (Byte)(dest >> 24); - } - } - return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; -} diff --git a/src/libs/7zip/win/C/Bcj2.h b/src/libs/7zip/win/C/Bcj2.h deleted file mode 100644 index dbc054148..000000000 --- a/src/libs/7zip/win/C/Bcj2.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Bcj2.h -- Converter for x86 code (BCJ2) -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __BCJ2_H -#define __BCJ2_H - -#include "Types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* -Conditions: - outSize <= FullOutputSize, - where FullOutputSize is full size of output stream of x86_2 filter. - -If buf0 overlaps outBuf, there are two required conditions: - 1) (buf0 >= outBuf) - 2) (buf0 + size0 >= outBuf + FullOutputSize). - -Returns: - SZ_OK - SZ_ERROR_DATA - Data error -*/ - -int Bcj2_Decode( - const Byte *buf0, SizeT size0, - const Byte *buf1, SizeT size1, - const Byte *buf2, SizeT size2, - const Byte *buf3, SizeT size3, - Byte *outBuf, SizeT outSize); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libs/7zip/win/C/Bra.c b/src/libs/7zip/win/C/Bra.c index 2e47b1413..33f7a391c 100644 --- a/src/libs/7zip/win/C/Bra.c +++ b/src/libs/7zip/win/C/Bra.c @@ -1,6 +1,8 @@ /* Bra.c -- Converters for RISC code 2010-04-16 : Igor Pavlov : Public domain */ +#include "Precomp.h" + #include "Bra.h" SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) @@ -48,14 +50,14 @@ SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) ((UInt32)data[i + 0] << 11) | (((UInt32)data[i + 3] & 0x7) << 8) | (data[i + 2]); - + src <<= 1; if (encoding) dest = ip + (UInt32)i + src; else dest = src - (ip + (UInt32)i); dest >>= 1; - + data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); data[i + 0] = (Byte)(dest >> 11); data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); @@ -80,7 +82,7 @@ SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) ((UInt32)data[i + 1] << 16) | ((UInt32)data[i + 2] << 8) | ((UInt32)data[i + 3] & (~3)); - + UInt32 dest; if (encoding) dest = ip + (UInt32)i + src; @@ -113,14 +115,14 @@ SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) ((UInt32)data[i + 2] << 8) | ((UInt32)data[i + 3]); UInt32 dest; - + src <<= 2; if (encoding) dest = ip + i + src; else dest = src - (ip + i); dest >>= 2; - + dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; data[i + 0] = (Byte)(dest >> 24); diff --git a/src/libs/7zip/win/C/Bra.h b/src/libs/7zip/win/C/Bra.h index 5748c1c05..184c291a7 100644 --- a/src/libs/7zip/win/C/Bra.h +++ b/src/libs/7zip/win/C/Bra.h @@ -1,35 +1,33 @@ /* Bra.h -- Branch converters for executables -2009-02-07 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __BRA_H #define __BRA_H -#include "Types.h" +#include "7zTypes.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN /* These functions convert relative addresses to absolute addresses in CALL instructions to increase the compression ratio. - + In: data - data buffer size - size of data ip - current virtual Instruction Pinter (IP) value state - state variable for x86 converter encoding - 0 (for decoding), 1 (for encoding) - + Out: state - state variable for x86 converter Returns: The number of processed bytes. If you call these functions with multiple calls, you must start next call with first byte after block of processed bytes. - + Type Endian Alignment LookAhead - + x86 little 1 4 ARMT little 2 2 ARM little 4 0 @@ -61,8 +59,6 @@ SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/Bra86.c b/src/libs/7zip/win/C/Bra86.c index 1ee0e709b..6db15e7ec 100644 --- a/src/libs/7zip/win/C/Bra86.c +++ b/src/libs/7zip/win/C/Bra86.c @@ -1,85 +1,82 @@ /* Bra86.c -- Converter for x86 code (BCJ) -2008-10-04 : Igor Pavlov : Public domain */ +2013-11-12 : Igor Pavlov : Public domain */ -#include "Bra.h" +#include "Precomp.h" -#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) +#include "Bra.h" -const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; -const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; +#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0) SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) { - SizeT bufferPos = 0, prevPosT; - UInt32 prevMask = *state & 0x7; + SizeT pos = 0; + UInt32 mask = *state & 7; if (size < 5) return 0; + size -= 4; ip += 5; - prevPosT = (SizeT)0 - 1; for (;;) { - Byte *p = data + bufferPos; - Byte *limit = data + size - 4; + Byte *p = data + pos; + const Byte *limit = data + size; for (; p < limit; p++) if ((*p & 0xFE) == 0xE8) break; - bufferPos = (SizeT)(p - data); - if (p >= limit) - break; - prevPosT = bufferPos - prevPosT; - if (prevPosT > 3) - prevMask = 0; - else + { - prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; - if (prevMask != 0) + SizeT d = (SizeT)(p - data - pos); + pos = (SizeT)(p - data); + if (p >= limit) { - Byte b = p[4 - kMaskToBitNumber[prevMask]]; - if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) + *state = (d > 2 ? 0 : mask >> (unsigned)d); + return pos; + } + if (d > 2) + mask = 0; + else + { + mask >>= (unsigned)d; + if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1]))) { - prevPosT = bufferPos; - prevMask = ((prevMask << 1) & 0x7) | 1; - bufferPos++; + mask = (mask >> 1) | 4; + pos++; continue; } } } - prevPosT = bufferPos; if (Test86MSByte(p[4])) { - UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); - UInt32 dest; - for (;;) + UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); + UInt32 cur = ip + (UInt32)pos; + pos += 5; + if (encoding) + v += cur; + else + v -= cur; + if (mask != 0) { - Byte b; - int index; - if (encoding) - dest = (ip + (UInt32)bufferPos) + src; - else - dest = src - (ip + (UInt32)bufferPos); - if (prevMask == 0) - break; - index = kMaskToBitNumber[prevMask] * 8; - b = (Byte)(dest >> (24 - index)); - if (!Test86MSByte(b)) - break; - src = dest ^ ((1 << (32 - index)) - 1); + unsigned sh = (mask & 6) << 2; + if (Test86MSByte((Byte)(v >> sh))) + { + v ^= (((UInt32)0x100 << sh) - 1); + if (encoding) + v += cur; + else + v -= cur; + } + mask = 0; } - p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); - p[3] = (Byte)(dest >> 16); - p[2] = (Byte)(dest >> 8); - p[1] = (Byte)dest; - bufferPos += 5; + p[1] = (Byte)v; + p[2] = (Byte)(v >> 8); + p[3] = (Byte)(v >> 16); + p[4] = (Byte)(0 - ((v >> 24) & 1)); } else { - prevMask = ((prevMask << 1) & 0x7) | 1; - bufferPos++; + mask = (mask >> 1) | 4; + pos++; } } - prevPosT = bufferPos - prevPosT; - *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); - return bufferPos; } diff --git a/src/libs/7zip/win/C/BraIA64.c b/src/libs/7zip/win/C/BraIA64.c index 0b4ee85bc..aa1a44e1e 100644 --- a/src/libs/7zip/win/C/BraIA64.c +++ b/src/libs/7zip/win/C/BraIA64.c @@ -1,5 +1,7 @@ /* BraIA64.c -- Converter for IA-64 code -2008-10-04 : Igor Pavlov : Public domain */ +2013-11-12 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include "Bra.h" @@ -42,20 +44,20 @@ SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); UInt32 dest; src |= ((UInt32)(instNorm >> 36) & 1) << 20; - + src <<= 4; - + if (encoding) dest = ip + (UInt32)i + src; else dest = src - (ip + (UInt32)i); - + dest >>= 4; - + instNorm &= ~((UInt64)(0x8FFFFF) << 13); instNorm |= ((UInt64)(dest & 0xFFFFF) << 13); instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); - + instruction &= (1 << bitRes) - 1; instruction |= (instNorm << bitRes); for (j = 0; j < 6; j++) diff --git a/src/libs/7zip/win/C/C.pri b/src/libs/7zip/win/C/C.pri new file mode 100644 index 000000000..23d688642 --- /dev/null +++ b/src/libs/7zip/win/C/C.pri @@ -0,0 +1,48 @@ +HEADERS += $$7ZIP_BASE/C/7zCrc.h \ + $$7ZIP_BASE/C/7zTypes.h \ + $$7ZIP_BASE/C/7zVersion.h \ + $$7ZIP_BASE/C/Alloc.h \ + $$7ZIP_BASE/C/Bra.h \ + $$7ZIP_BASE/C/Compiler.h \ + $$7ZIP_BASE/C/CpuArch.h \ + $$7ZIP_BASE/C/Delta.h \ + $$7ZIP_BASE/C/LzFind.h \ + $$7ZIP_BASE/C/LzFindMt.h \ + $$7ZIP_BASE/C/LzHash.h \ + $$7ZIP_BASE/C/Lzma2Dec.h \ + $$7ZIP_BASE/C/Lzma2Enc.h \ + $$7ZIP_BASE/C/LzmaDec.h \ + $$7ZIP_BASE/C/LzmaEnc.h \ + $$7ZIP_BASE/C/MtCoder.h \ + $$7ZIP_BASE/C/Precomp.h \ + $$7ZIP_BASE/C/RotateDefs.h \ + $$7ZIP_BASE/C/Sha256.h \ + $$7ZIP_BASE/C/Threads.h \ + $$7ZIP_BASE/C/Xz.h \ + $$7ZIP_BASE/C/XzCrc64.h \ + $$7ZIP_BASE/C/XzEnc.h + +SOURCES += $$7ZIP_BASE/C/7zCrc.c \ + $$7ZIP_BASE/C/7zCrcOpt.c \ + $$7ZIP_BASE/C/7zStream.c \ + $$7ZIP_BASE/C/Alloc.c \ + $$7ZIP_BASE/C/Bra.c \ + $$7ZIP_BASE/C/Bra86.c \ + $$7ZIP_BASE/C/BraIA64.c \ + $$7ZIP_BASE/C/CpuArch.c \ + $$7ZIP_BASE/C/Delta.c \ + $$7ZIP_BASE/C/LzFind.c \ + $$7ZIP_BASE/C/LzFindMt.c \ + $$7ZIP_BASE/C/Lzma2Dec.c \ + $$7ZIP_BASE/C/Lzma2Enc.c \ + $$7ZIP_BASE/C/LzmaDec.c \ + $$7ZIP_BASE/C/LzmaEnc.c \ + $$7ZIP_BASE/C/MtCoder.c \ + $$7ZIP_BASE/C/Sha256.c \ + $$7ZIP_BASE/C/Threads.c \ + $$7ZIP_BASE/C/Xz.c \ + $$7ZIP_BASE/C/XzCrc64.c \ + $$7ZIP_BASE/C/XzCrc64Opt.c \ + $$7ZIP_BASE/C/XzDec.c \ + $$7ZIP_BASE/C/XzEnc.c \ + $$7ZIP_BASE/C/XzIn.c diff --git a/src/libs/7zip/win/C/Compiler.h b/src/libs/7zip/win/C/Compiler.h new file mode 100644 index 000000000..6e964897e --- /dev/null +++ b/src/libs/7zip/win/C/Compiler.h @@ -0,0 +1,28 @@ +/* Compiler.h -- Compiler ypes +2013-11-12 : Igor Pavlov : Public domain */ + +#ifndef __7Z_COMPILER_H +#define __7Z_COMPILER_H + +#ifdef _MSC_VER + + #ifdef UNDER_CE + #define RPC_NO_WINDOWS_H + /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */ + #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union + #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int + #endif + + #if _MSC_VER >= 1300 + #pragma warning(disable : 4996) // This function or variable may be unsafe + #else + #pragma warning(disable : 4511) // copy constructor could not be generated + #pragma warning(disable : 4512) // assignment operator could not be generated + #pragma warning(disable : 4702) // unreachable code + #pragma warning(disable : 4710) // not inlined + #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information + #endif + +#endif + +#endif diff --git a/src/libs/7zip/win/C/CpuArch.c b/src/libs/7zip/win/C/CpuArch.c index 260cc1f45..4feb028a2 100644 --- a/src/libs/7zip/win/C/CpuArch.c +++ b/src/libs/7zip/win/C/CpuArch.c @@ -1,5 +1,7 @@ /* CpuArch.c -- CPU specific code -2010-10-26: Igor Pavlov : Public domain */ +2012-05-29: Igor Pavlov : Public domain */ + +#include "Precomp.h" #include "CpuArch.h" @@ -9,6 +11,10 @@ #define USE_ASM #endif +#if !defined(USE_ASM) && _MSC_VER >= 1500 +#include <intrin.h> +#endif + #if defined(USE_ASM) && !defined(MY_CPU_AMD64) static UInt32 CheckFlag(UInt32 flag) { @@ -73,15 +79,23 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) #else __asm__ __volatile__ ( + #if defined(MY_CPU_X86) && defined(__PIC__) + "mov %%ebx, %%edi;" + "cpuid;" + "xchgl %%ebx, %%edi;" + : "=a" (*a) , + "=D" (*b) , + #else "cpuid" : "=a" (*a) , "=b" (*b) , + #endif "=c" (*c) , "=d" (*d) : "0" (function)) ; #endif - + #else int CPUInfo[4]; @@ -135,7 +149,14 @@ Bool CPU_Is_InOrder() firm = x86cpuid_GetFirm(&p); switch (firm) { - case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C)); + case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && ( + /* Atom CPU */ + model == 0x100C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */ + || model == 0x2006 /* 45 nm, Z6xx */ + || model == 0x2007 /* 32 nm, Z2460 */ + || model == 0x3005 /* 32 nm, Z2760 */ + || model == 0x3006 /* 32 nm, N2xxx, D2xxx */ + ))); case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); } @@ -143,6 +164,7 @@ Bool CPU_Is_InOrder() } #if !defined(MY_CPU_AMD64) && defined(_WIN32) +#include <windows.h> static Bool CPU_Sys_Is_SSE_Supported() { OSVERSIONINFO vi; diff --git a/src/libs/7zip/win/C/CpuArch.h b/src/libs/7zip/win/C/CpuArch.h index 01930c7e6..4fee00937 100644 --- a/src/libs/7zip/win/C/CpuArch.h +++ b/src/libs/7zip/win/C/CpuArch.h @@ -1,10 +1,10 @@ /* CpuArch.h -- CPU specific code -2010-10-26: Igor Pavlov : Public domain */ +2013-11-12: Igor Pavlov : Public domain */ #ifndef __CPU_ARCH_H #define __CPU_ARCH_H -#include "Types.h" +#include "7zTypes.h" EXTERN_C_BEGIN @@ -52,7 +52,7 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla #define MY_CPU_LE #endif -#if defined(__BIG_ENDIAN__) +#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__) #define MY_CPU_BE #endif @@ -62,9 +62,9 @@ Stop_Compiling_Bad_Endian #ifdef MY_CPU_LE_UNALIGN -#define GetUi16(p) (*(const UInt16 *)(p)) -#define GetUi32(p) (*(const UInt32 *)(p)) -#define GetUi64(p) (*(const UInt64 *)(p)) +#define GetUi16(p) (*(const UInt16 *)(const void *)(p)) +#define GetUi32(p) (*(const UInt32 *)(const void *)(p)) +#define GetUi64(p) (*(const UInt64 *)(const void *)(p)) #define SetUi16(p, d) *(UInt16 *)(p) = (d); #define SetUi32(p, d) *(UInt32 *)(p) = (d); #define SetUi64(p, d) *(UInt64 *)(p) = (d); @@ -99,6 +99,8 @@ Stop_Compiling_Bad_Endian #if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) +#include <stdlib.h> + #pragma intrinsic(_byteswap_ulong) #pragma intrinsic(_byteswap_uint64) #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) @@ -116,7 +118,7 @@ Stop_Compiling_Bad_Endian #endif -#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) +#define GetBe16(p) ((UInt16)(((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])) #ifdef MY_CPU_X86_OR_AMD64 diff --git a/src/libs/7zip/win/C/Delta.c b/src/libs/7zip/win/C/Delta.c index 2b327f15f..e3edd21ed 100644 --- a/src/libs/7zip/win/C/Delta.c +++ b/src/libs/7zip/win/C/Delta.c @@ -1,6 +1,8 @@ /* Delta.c -- Delta converter 2009-05-26 : Igor Pavlov : Public domain */ +#include "Precomp.h" + #include "Delta.h" void Delta_Init(Byte *state) diff --git a/src/libs/7zip/win/C/Delta.h b/src/libs/7zip/win/C/Delta.h index 0d4cd6274..2fa54ad67 100644 --- a/src/libs/7zip/win/C/Delta.h +++ b/src/libs/7zip/win/C/Delta.h @@ -1,14 +1,12 @@ /* Delta.h -- Delta converter -2009-04-15 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __DELTA_H #define __DELTA_H -#include "Types.h" +#include "7zTypes.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN #define DELTA_STATE_SIZE 256 @@ -16,8 +14,6 @@ void Delta_Init(Byte *state); void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size); void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/LzFind.c b/src/libs/7zip/win/C/LzFind.c index e3ecb0542..9a4d25b80 100644 --- a/src/libs/7zip/win/C/LzFind.c +++ b/src/libs/7zip/win/C/LzFind.c @@ -1,6 +1,8 @@ /* LzFind.c -- Match finder for LZ algorithms 2009-04-22 : Igor Pavlov : Public domain */ +#include "Precomp.h" + #include <string.h> #include "LzFind.h" @@ -512,7 +514,7 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) delta2 = p->pos - p->hash[hash2Value]; curMatch = p->hash[kFix3HashSize + hashValue]; - + p->hash[hash2Value] = p->hash[kFix3HashSize + hashValue] = p->pos; @@ -546,7 +548,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) delta2 = p->pos - p->hash[ hash2Value]; delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; curMatch = p->hash[kFix4HashSize + hashValue]; - + p->hash[ hash2Value] = p->hash[kFix3HashSize + hash3Value] = p->hash[kFix4HashSize + hashValue] = p->pos; diff --git a/src/libs/7zip/win/C/LzFind.h b/src/libs/7zip/win/C/LzFind.h index 010c4b92b..706143d25 100644 --- a/src/libs/7zip/win/C/LzFind.h +++ b/src/libs/7zip/win/C/LzFind.h @@ -1,14 +1,12 @@ /* LzFind.h -- Match finder for LZ algorithms -2009-04-22 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __LZ_FIND_H #define __LZ_FIND_H -#include "Types.h" +#include "7zTypes.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN typedef UInt32 CLzRef; @@ -108,8 +106,6 @@ UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/LzFindMt.c b/src/libs/7zip/win/C/LzFindMt.c index aa41ed98a..8be0adaaf 100644 --- a/src/libs/7zip/win/C/LzFindMt.c +++ b/src/libs/7zip/win/C/LzFindMt.c @@ -1,5 +1,7 @@ /* LzFindMt.c -- multithreaded Match finder for LZ algorithms -2009-09-20 : Igor Pavlov : Public domain */ +2014-12-29 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include "LzHash.h" @@ -58,7 +60,7 @@ void MtSync_StopWriting(CMtSync *p) p->csWasEntered = False; } Semaphore_Release1(&p->freeSemaphore); - + Event_Wait(&p->wasStopped); while (myNumBlocks++ != p->numProcessedBlocks) @@ -97,7 +99,7 @@ void MtSync_Destruct(CMtSync *p) #define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } -static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) +static SRes MtSync_Create2(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks) { if (p->wasCreated) return SZ_OK; @@ -108,18 +110,18 @@ static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart)); RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted)); RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped)); - + RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks)); RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks)); p->needStart = True; - + RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj)); p->wasCreated = True; return SZ_OK; } -static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) +static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks) { SRes res = MtSync_Create2(p, startAddress, obj, numBlocks); if (res != SZ_OK) @@ -385,7 +387,7 @@ void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex) CriticalSection_Enter(&sync->cs); sync->csWasEntered = True; } - + BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize); if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize) @@ -451,13 +453,12 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) #define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks) #define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks) -static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } -static unsigned MY_STD_CALL BtThreadFunc2(void *p) +static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } +static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p) { Byte allocaDummy[0x180]; - int i = 0; - for (i = 0; i < 16; i++) - allocaDummy[i] = (Byte)i; + allocaDummy[0] = 0; + allocaDummy[1] = allocaDummy[0]; BtThreadFunc((CMatchFinderMt *)p); return 0; } @@ -561,7 +562,7 @@ UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) const Byte *cur = p->pointerToCurPos; UInt32 lzPos = p->lzPos; MT_HASH2_CALC - + curMatch2 = hash[hash2Value]; hash[hash2Value] = lzPos; @@ -584,7 +585,7 @@ UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) curMatch2 = hash[ hash2Value]; curMatch3 = hash[kFix3HashSize + hash3Value]; - + hash[ hash2Value] = hash[kFix3HashSize + hash3Value] = lzPos; @@ -616,11 +617,11 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) const Byte *cur = p->pointerToCurPos; UInt32 lzPos = p->lzPos; MT_HASH4_CALC - + curMatch2 = hash[ hash2Value]; curMatch3 = hash[kFix3HashSize + hash3Value]; curMatch4 = hash[kFix4HashSize + hash4Value]; - + hash[ hash2Value] = hash[kFix3HashSize + hash3Value] = hash[kFix4HashSize + hash4Value] = diff --git a/src/libs/7zip/win/C/LzFindMt.h b/src/libs/7zip/win/C/LzFindMt.h index b985af5fe..65cc12783 100644 --- a/src/libs/7zip/win/C/LzFindMt.h +++ b/src/libs/7zip/win/C/LzFindMt.h @@ -1,5 +1,5 @@ /* LzFindMt.h -- multithreaded Match finder for LZ algorithms -2009-02-07 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __LZ_FIND_MT_H #define __LZ_FIND_MT_H @@ -7,9 +7,7 @@ #include "LzFind.h" #include "Threads.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN #define kMtHashBlockSize (1 << 13) #define kMtHashNumBlocks (1 << 3) @@ -62,7 +60,7 @@ typedef struct _CMatchFinderMt const UInt32 *crc; Mf_Mix_Matches MixMatchesFunc; - + /* LZ + BT */ CMtSync btSync; Byte btDummy[kMtCacheLineDummy]; @@ -85,7 +83,7 @@ typedef struct _CMatchFinderMt /* BT + Hash */ CMtSync hashSync; /* Byte hashDummy[kMtCacheLineDummy]; */ - + /* Hash */ Mf_GetHeads GetHeadsFunc; CMatchFinder *MatchFinder; @@ -98,8 +96,6 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/Lzma2Dec.c b/src/libs/7zip/win/C/Lzma2Dec.c index 7ea1cc953..e7dcc2725 100644 --- a/src/libs/7zip/win/C/Lzma2Dec.c +++ b/src/libs/7zip/win/C/Lzma2Dec.c @@ -1,8 +1,10 @@ /* Lzma2Dec.c -- LZMA2 Decoder -2009-05-03 : Igor Pavlov : Public domain */ +2010-12-15 : Igor Pavlov : Public domain */ /* #define SHOW_DEBUG_INFO */ +#include "Precomp.h" + #ifdef SHOW_DEBUG_INFO #include <stdio.h> #endif @@ -114,17 +116,17 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) else p->unpackSize = (UInt32)(p->control & 0x1F) << 16; return LZMA2_STATE_UNPACK0; - + case LZMA2_STATE_UNPACK0: p->unpackSize |= (UInt32)b << 8; return LZMA2_STATE_UNPACK1; - + case LZMA2_STATE_UNPACK1: p->unpackSize |= (UInt32)b; p->unpackSize++; PRF(printf(" %8d", p->unpackSize)); return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; - + case LZMA2_STATE_PACK0: p->packSize = (UInt32)b << 8; return LZMA2_STATE_PACK1; @@ -199,7 +201,7 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, SizeT destSizeCur = dicLimit - dicPos; SizeT srcSizeCur = inSize - *srcLen; ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; - + if (p->unpackSize <= destSizeCur) { destSizeCur = (SizeT)p->unpackSize; @@ -250,7 +252,7 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, Bool initState = (mode > 0); if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) return SZ_ERROR_DATA; - + LzmaDec_InitDicAndState(&p->decoder, initDic, initState); p->needInitDic = False; p->needInitState = False; @@ -258,9 +260,9 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, } if (srcSizeCur > p->packSize) srcSizeCur = (SizeT)p->packSize; - + res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); - + src += srcSizeCur; *srcLen += srcSizeCur; p->packSize -= (UInt32)srcSizeCur; @@ -330,27 +332,21 @@ SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte * SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) { - CLzma2Dec decoder; + CLzma2Dec p; SRes res; SizeT outSize = *destLen, inSize = *srcLen; - Byte props[LZMA_PROPS_SIZE]; - - Lzma2Dec_Construct(&decoder); - *destLen = *srcLen = 0; *status = LZMA_STATUS_NOT_SPECIFIED; - decoder.decoder.dic = dest; - decoder.decoder.dicBufSize = outSize; - - RINOK(Lzma2Dec_GetOldProps(prop, props)); - RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); - + Lzma2Dec_Construct(&p); + RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); + p.decoder.dic = dest; + p.decoder.dicBufSize = outSize; + Lzma2Dec_Init(&p); *srcLen = inSize; - res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); - *destLen = decoder.decoder.dicPos; + res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + *destLen = p.decoder.dicPos; if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; - - LzmaDec_FreeProbs(&decoder.decoder, alloc); + Lzma2Dec_FreeProbs(&p, alloc); return res; } diff --git a/src/libs/7zip/win/C/Lzma2Dec.h b/src/libs/7zip/win/C/Lzma2Dec.h index 6bc07bbc1..367daf6b3 100644 --- a/src/libs/7zip/win/C/Lzma2Dec.h +++ b/src/libs/7zip/win/C/Lzma2Dec.h @@ -1,14 +1,12 @@ /* Lzma2Dec.h -- LZMA2 Decoder -2009-05-03 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __LZMA2_DEC_H #define __LZMA2_DEC_H #include "LzmaDec.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN /* ---------- State Interface ---------- */ @@ -77,8 +75,6 @@ Returns: SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/Lzma2Enc.c b/src/libs/7zip/win/C/Lzma2Enc.c index e97597f63..5d67cc344 100644 --- a/src/libs/7zip/win/C/Lzma2Enc.c +++ b/src/libs/7zip/win/C/Lzma2Enc.c @@ -1,5 +1,7 @@ /* Lzma2Enc.c -- LZMA2 Encoder -2010-09-24 : Igor Pavlov : Public domain */ +2012-06-19 : Igor Pavlov : Public domain */ + +#include "Precomp.h" /* #include <stdio.h> */ #include <string.h> @@ -83,11 +85,11 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, if (packSize < lzHeaderSize) return SZ_ERROR_OUTPUT_EOF; packSize -= lzHeaderSize; - + LzmaEnc_SaveState(p->enc); res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState, outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize); - + PRF(printf("\npackSize = %7d unpackSize = %7d ", packSize, unpackSize)); if (unpackSize == 0) @@ -146,10 +148,10 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, outBuf[destPos++] = (Byte)u; outBuf[destPos++] = (Byte)(pm >> 8); outBuf[destPos++] = (Byte)pm; - + if (p->needInitProp) outBuf[destPos++] = p->props; - + p->needInitProp = False; p->needInitState = False; destPos += packSize; @@ -216,8 +218,7 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p) t3 = t1n * t2; p->lzmaProps.numThreads = t1; - p->numBlockThreads = t2; - p->numTotalThreads = t3; + LzmaEncProps_Normalize(&p->lzmaProps); if (p->blockSize == 0) @@ -231,6 +232,21 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p) if (blockSize < dictSize) blockSize = dictSize; p->blockSize = (size_t)blockSize; } + if (t2 > 1) + { + UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1; + if (temp > p->lzmaProps.reduceSize) + { + UInt64 numBlocks = temp / p->blockSize; + if (numBlocks < t2) + { + t2 = (UInt32)numBlocks; + t3 = t1 * t2; + } + } + } + p->numBlockThreads = t2; + p->numTotalThreads = t3; } static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize) @@ -244,7 +260,7 @@ typedef struct { Byte propEncoded; CLzma2EncProps props; - + Byte *outBuf; ISzAlloc *alloc; @@ -322,10 +338,10 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des if (srcSize != 0) { RINOK(Lzma2EncInt_Init(p, &mainEncoder->props)); - + RINOK(LzmaEnc_MemPrepare(p->enc, src, srcSize, LZMA2_KEEP_WINDOW_SIZE, mainEncoder->alloc, mainEncoder->allocBig)); - + while (p->srcPos < srcSize) { size_t packSize = destLim - *destSize; @@ -460,7 +476,7 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp, mtCallback.funcTable.Code = MtCallbackImp_Code; mtCallback.lzma2Enc = p; - + p->mtCoder.progress = progress; p->mtCoder.inStream = inStream; p->mtCoder.outStream = outStream; @@ -470,7 +486,7 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp, p->mtCoder.blockSize = p->props.blockSize; p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16; p->mtCoder.numThreads = p->props.numBlockThreads; - + return MtCoder_Code(&p->mtCoder); } #endif diff --git a/src/libs/7zip/win/C/Lzma2Enc.h b/src/libs/7zip/win/C/Lzma2Enc.h index 283525581..f409f184c 100644 --- a/src/libs/7zip/win/C/Lzma2Enc.h +++ b/src/libs/7zip/win/C/Lzma2Enc.h @@ -1,14 +1,12 @@ /* Lzma2Enc.h -- LZMA2 Encoder -2009-02-07 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __LZMA2_ENC_H #define __LZMA2_ENC_H #include "LzmaEnc.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN typedef struct { @@ -59,8 +57,6 @@ SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); */ -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/Lzma86.h b/src/libs/7zip/win/C/Lzma86.h deleted file mode 100644 index 6acbd888a..000000000 --- a/src/libs/7zip/win/C/Lzma86.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Lzma86.h -- LZMA + x86 (BCJ) Filter -2009-08-14 : Igor Pavlov : Public domain */ - -#ifndef __LZMA86_H -#define __LZMA86_H - -#include "Types.h" - -EXTERN_C_BEGIN - -#define LZMA86_SIZE_OFFSET (1 + 5) -#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) - -/* -It's an example for LZMA + x86 Filter use. -You can use .lzma86 extension, if you write that stream to file. -.lzma86 header adds one additional byte to standard .lzma header. -.lzma86 header (14 bytes): - Offset Size Description - 0 1 = 0 - no filter, pure LZMA - = 1 - x86 filter + LZMA - 1 1 lc, lp and pb in encoded form - 2 4 dictSize (little endian) - 6 8 uncompressed size (little endian) - - -Lzma86_Encode -------------- -level - compression level: 0 <= level <= 9, the default value for "level" is 5. - -dictSize - The dictionary size in bytes. The maximum value is - 128 MB = (1 << 27) bytes for 32-bit version - 1 GB = (1 << 30) bytes for 64-bit version - The default value is 16 MB = (1 << 24) bytes, for level = 5. - It's recommended to use the dictionary that is larger than 4 KB and - that can be calculated as (1 << N) or (3 << N) sizes. - For better compression ratio dictSize must be >= inSize. - -filterMode: - SZ_FILTER_NO - no Filter - SZ_FILTER_YES - x86 Filter - SZ_FILTER_AUTO - it tries both alternatives to select best. - Encoder will use 2 or 3 passes: - 2 passes when FILTER_NO provides better compression. - 3 passes when FILTER_YES provides better compression. - -Lzma86Encode allocates Data with MyAlloc functions. -RAM Requirements for compressing: - RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize - filterMode FilterBlockSize - SZ_FILTER_NO 0 - SZ_FILTER_YES inSize - SZ_FILTER_AUTO inSize - - -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -enum ESzFilterMode -{ - SZ_FILTER_NO, - SZ_FILTER_YES, - SZ_FILTER_AUTO -}; - -SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, - int level, UInt32 dictSize, int filterMode); - - -/* -Lzma86_GetUnpackSize: - In: - src - input data - srcLen - input data size - Out: - unpackSize - size of uncompressed stream - Return code: - SZ_OK - OK - SZ_ERROR_INPUT_EOF - Error in headers -*/ - -SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize); - -/* -Lzma86_Decode: - In: - dest - output data - destLen - output data size - src - input data - srcLen - input data size - Out: - destLen - processed output size - srcLen - processed input size - Return code: - SZ_OK - OK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - unsupported file - SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer -*/ - -SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen); - -EXTERN_C_END - -#endif diff --git a/src/libs/7zip/win/C/Lzma86Dec.c b/src/libs/7zip/win/C/Lzma86Dec.c deleted file mode 100644 index fe7726097..000000000 --- a/src/libs/7zip/win/C/Lzma86Dec.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder -2009-08-14 : Igor Pavlov : Public domain */ - -#include "Lzma86.h" - -#include "Alloc.h" -#include "Bra.h" -#include "LzmaDec.h" - -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } - -SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) -{ - unsigned i; - if (srcLen < LZMA86_HEADER_SIZE) - return SZ_ERROR_INPUT_EOF; - *unpackSize = 0; - for (i = 0; i < sizeof(UInt64); i++) - *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i); - return SZ_OK; -} - -SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) -{ - ISzAlloc g_Alloc = { SzAlloc, SzFree }; - SRes res; - int useFilter; - SizeT inSizePure; - ELzmaStatus status; - - if (*srcLen < LZMA86_HEADER_SIZE) - return SZ_ERROR_INPUT_EOF; - - useFilter = src[0]; - - if (useFilter > 1) - { - *destLen = 0; - return SZ_ERROR_UNSUPPORTED; - } - - inSizePure = *srcLen - LZMA86_HEADER_SIZE; - res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, - src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); - *srcLen = inSizePure + LZMA86_HEADER_SIZE; - if (res != SZ_OK) - return res; - if (useFilter == 1) - { - UInt32 x86State; - x86_Convert_Init(x86State); - x86_Convert(dest, *destLen, 0, &x86State, 0); - } - return SZ_OK; -} diff --git a/src/libs/7zip/win/C/Lzma86Enc.c b/src/libs/7zip/win/C/Lzma86Enc.c deleted file mode 100644 index 2ea4ac2da..000000000 --- a/src/libs/7zip/win/C/Lzma86Enc.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder -2009-08-14 : Igor Pavlov : Public domain */ - -#include <string.h> - -#include "Lzma86.h" - -#include "Alloc.h" -#include "Bra.h" -#include "LzmaEnc.h" - -#define SZE_OUT_OVERFLOW SZE_DATA_ERROR - -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } - -int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, - int level, UInt32 dictSize, int filterMode) -{ - ISzAlloc g_Alloc = { SzAlloc, SzFree }; - size_t outSize2 = *destLen; - Byte *filteredStream; - Bool useFilter; - int mainResult = SZ_ERROR_OUTPUT_EOF; - CLzmaEncProps props; - LzmaEncProps_Init(&props); - props.level = level; - props.dictSize = dictSize; - - *destLen = 0; - if (outSize2 < LZMA86_HEADER_SIZE) - return SZ_ERROR_OUTPUT_EOF; - - { - int i; - UInt64 t = srcLen; - for (i = 0; i < 8; i++, t >>= 8) - dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; - } - - filteredStream = 0; - useFilter = (filterMode != SZ_FILTER_NO); - if (useFilter) - { - if (srcLen != 0) - { - filteredStream = (Byte *)MyAlloc(srcLen); - if (filteredStream == 0) - return SZ_ERROR_MEM; - memcpy(filteredStream, src, srcLen); - } - { - UInt32 x86State; - x86_Convert_Init(x86State); - x86_Convert(filteredStream, srcLen, 0, &x86State, 1); - } - } - - { - size_t minSize = 0; - Bool bestIsFiltered = False; - - /* passes for SZ_FILTER_AUTO: - 0 - BCJ + LZMA - 1 - LZMA - 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. - */ - int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; - - int i; - for (i = 0; i < numPasses; i++) - { - size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; - size_t outPropsSize = 5; - SRes curRes; - Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); - if (curModeIsFiltered && !bestIsFiltered) - break; - if (useFilter && i == 0) - curModeIsFiltered = True; - - curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, - curModeIsFiltered ? filteredStream : src, srcLen, - &props, dest + 1, &outPropsSize, 0, - NULL, &g_Alloc, &g_Alloc); - - if (curRes != SZ_ERROR_OUTPUT_EOF) - { - if (curRes != SZ_OK) - { - mainResult = curRes; - break; - } - if (outSizeProcessed <= minSize || mainResult != SZ_OK) - { - minSize = outSizeProcessed; - bestIsFiltered = curModeIsFiltered; - mainResult = SZ_OK; - } - } - } - dest[0] = (bestIsFiltered ? 1 : 0); - *destLen = LZMA86_HEADER_SIZE + minSize; - } - if (useFilter) - MyFree(filteredStream); - return mainResult; -} diff --git a/src/libs/7zip/win/C/LzmaDec.c b/src/libs/7zip/win/C/LzmaDec.c index 2036761bf..b1a2ad150 100644 --- a/src/libs/7zip/win/C/LzmaDec.c +++ b/src/libs/7zip/win/C/LzmaDec.c @@ -1,5 +1,7 @@ /* LzmaDec.c -- LZMA Decoder -2009-09-20 : Igor Pavlov : Public domain */ +2015-01-01 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include "LzmaDec.h" @@ -44,6 +46,13 @@ i -= 0x40; } #endif +#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol) +#define MATCHED_LITER_DEC \ + matchByte <<= 1; \ + bit = (matchByte & offs); \ + probLit = prob + offs + bit + symbol; \ + GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) + #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) @@ -141,7 +150,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte Byte *dic = p->dic; SizeT dicBufSize = p->dicBufSize; SizeT dicPos = p->dicPos; - + UInt32 processedPos = p->processedPos; UInt32 checkDicSize = p->checkDicSize; unsigned len = 0; @@ -171,24 +180,47 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte { state -= (state < 4) ? state : 3; symbol = 1; - do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); + #ifdef _LZMA_SIZE_OPT + do { NORMAL_LITER_DEC } while (symbol < 0x100); + #else + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + #endif } else { - unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + unsigned matchByte = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; unsigned offs = 0x100; state -= (state < 10) ? 3 : 6; symbol = 1; + #ifdef _LZMA_SIZE_OPT do { unsigned bit; CLzmaProb *probLit; - matchByte <<= 1; - bit = (matchByte & offs); - probLit = prob + offs + bit + symbol; - GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) + MATCHED_LITER_DEC } while (symbol < 0x100); + #else + { + unsigned bit; + CLzmaProb *probLit; + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + } + #endif } dic[dicPos++] = (Byte)symbol; processedPos++; @@ -324,7 +356,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte { NORMALIZE range >>= 1; - + { UInt32 t; code -= range; @@ -442,8 +474,9 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) p->processedPos += len; p->remainLen -= len; - while (len-- != 0) + while (len != 0) { + len--; dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; dicPos++; } @@ -722,7 +755,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr SizeT inSize = *srcLen; (*srcLen) = 0; LzmaDec_WriteRem(p, dicLimit); - + *status = LZMA_STATUS_NOT_SPECIFIED; while (p->remainLen != kMatchSpecLenStart) @@ -768,7 +801,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr if (p->needInitState) LzmaDec_InitStateReal(p); - + if (p->tempBufSize == 0) { SizeT processed; @@ -899,12 +932,12 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) { UInt32 dicSize; Byte d; - + if (size < LZMA_PROPS_SIZE) return SZ_ERROR_UNSUPPORTED; else dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); - + if (dicSize < LZMA_DIC_MIN) dicSize = LZMA_DIC_MIN; p->dicSize = dicSize; @@ -972,28 +1005,21 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, { CLzmaDec p; SRes res; - SizeT inSize = *srcLen; - SizeT outSize = *destLen; - *srcLen = *destLen = 0; + SizeT outSize = *destLen, inSize = *srcLen; + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; if (inSize < RC_INIT_SIZE) return SZ_ERROR_INPUT_EOF; - LzmaDec_Construct(&p); - res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); - if (res != 0) - return res; + RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)); p.dic = dest; p.dicBufSize = outSize; - LzmaDec_Init(&p); - *srcLen = inSize; res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); - + *destLen = p.dicPos; if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; - - (*destLen) = p.dicPos; LzmaDec_FreeProbs(&p, alloc); return res; } diff --git a/src/libs/7zip/win/C/LzmaDec.h b/src/libs/7zip/win/C/LzmaDec.h index bf7f084ba..63efc351f 100644 --- a/src/libs/7zip/win/C/LzmaDec.h +++ b/src/libs/7zip/win/C/LzmaDec.h @@ -1,14 +1,12 @@ /* LzmaDec.h -- LZMA Decoder -2009-02-07 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __LZMA_DEC_H #define __LZMA_DEC_H -#include "Types.h" +#include "7zTypes.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN /* #define _LZMA_PROB32 */ /* _LZMA_PROB32 can increase the speed on some CPUs, @@ -130,7 +128,7 @@ LzmaDec_Allocate* can return: SZ_ERROR_MEM - Memory allocation error SZ_ERROR_UNSUPPORTED - Unsupported properties */ - + SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); @@ -159,7 +157,7 @@ void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); */ /* LzmaDec_DecodeToDic - + The decoding to internal dictionary buffer (CLzmaDec::dic). You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! @@ -224,8 +222,6 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/LzmaEnc.c b/src/libs/7zip/win/C/LzmaEnc.c index cf131388a..bf3cc2ddb 100644 --- a/src/libs/7zip/win/C/LzmaEnc.c +++ b/src/libs/7zip/win/C/LzmaEnc.c @@ -1,5 +1,7 @@ /* LzmaEnc.c -- LZMA Encoder -2010-04-16 : Igor Pavlov : Public domain */ +2014-12-29 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include <string.h> @@ -18,7 +20,7 @@ #endif #ifdef SHOW_STAT -static int ttt = 0; +static unsigned g_STAT_OFFSET = 0; #endif #define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) @@ -46,6 +48,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p) { p->level = 5; p->dictSize = p->mc = 0; + p->reduceSize = (UInt64)(Int64)-1; p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; p->writeEndMark = 0; } @@ -56,6 +59,15 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p) if (level < 0) level = 5; p->level = level; if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); + if (p->dictSize > p->reduceSize) + { + unsigned i; + for (i = 11; i <= 30; i++) + { + if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } + if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } + } + } if (p->lc < 0) p->lc = 3; if (p->lp < 0) p->lp = 0; if (p->pb < 0) p->pb = 2; @@ -109,7 +121,7 @@ void LzmaEnc_FastPosInit(Byte *g_FastPos) int c = 2, slotFast; g_FastPos[0] = 0; g_FastPos[1] = 1; - + for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) { UInt32 k = (1 << ((slotFast >> 1) - 1)); @@ -246,7 +258,7 @@ typedef struct CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; CLzmaProb posAlignEncoder[1 << kNumAlignBits]; - + CLenPriceEnc lenEnc; CLenPriceEnc repLenEnc; @@ -269,7 +281,7 @@ typedef struct #ifndef _7ZIP_ST Byte pad[128]; #endif - + UInt32 optimumEndIndex; UInt32 optimumCurrentIndex; @@ -277,7 +289,7 @@ typedef struct UInt32 numPairs; UInt32 numAvail; COptimal opt[kNumOpts]; - + #ifndef LZMA_LOG_BSR Byte g_FastPos[1 << kNumLogBits]; #endif @@ -311,14 +323,14 @@ typedef struct CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; CLzmaProb posAlignEncoder[1 << kNumAlignBits]; - + CLenPriceEnc lenEnc; CLenPriceEnc repLenEnc; unsigned lclp; Bool fastMode; - + CRangeEnc rc; Bool writeEndMark; @@ -329,7 +341,6 @@ typedef struct SRes result; UInt32 dictSize; - UInt32 matchFinderCycles; int needInit; @@ -398,7 +409,6 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30)) return SZ_ERROR_PARAM; p->dictSize = props.dictSize; - p->matchFinderCycles = props.mc; { unsigned fb = props.fb; if (fb < 5) @@ -508,7 +518,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p) static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) { - if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) + if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0) { Byte temp = p->cache; do @@ -534,7 +544,7 @@ static void RangeEnc_FlushData(CRangeEnc *p) RangeEnc_ShiftLow(p); } -static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) +static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits) { do { @@ -803,9 +813,10 @@ static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 static void MovePos(CLzmaEnc *p, UInt32 num) { #ifdef SHOW_STAT - ttt += num; + g_STAT_OFFSET += num; printf("\n MovePos %d", num); #endif + if (num != 0) { p->additionalOffset += num; @@ -818,15 +829,17 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) UInt32 lenRes = 0, numPairs; p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); + #ifdef SHOW_STAT - printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); - ttt++; + printf("\n i = %d numPairs = %d ", g_STAT_OFFSET, numPairs / 2); + g_STAT_OFFSET++; { UInt32 i; for (i = 0; i < numPairs; i += 2) printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); } #endif + if (numPairs > 0) { lenRes = p->matches[numPairs - 2]; @@ -909,10 +922,10 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) { UInt32 posPrev = posMem; UInt32 backCur = backMem; - + backMem = p->opt[posPrev].backPrev; posMem = p->opt[posPrev].posPrev; - + p->opt[posPrev].backPrev = backCur; p->opt[posPrev].posPrev = cur; cur = posPrev; @@ -943,7 +956,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) return lenRes; } p->optimumCurrentIndex = p->optimumEndIndex = 0; - + if (p->additionalOffset == 0) mainLen = ReadMatchDistances(p, &numPairs); else @@ -1241,7 +1254,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); - + if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) { UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); @@ -1303,7 +1316,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) } } } - + startLen = 2; /* speed optimization */ { UInt32 repIndex; @@ -1334,10 +1347,10 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) } while (--lenTest >= 2); lenTest = lenTestTemp; - + if (repIndex == 0) startLen = lenTest + 1; - + /* if (_maxMode) */ { UInt32 lenTest2 = lenTest + 1; @@ -1361,7 +1374,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) nextRepMatchPrice = curAndLenCharPrice + GET_PRICE_1(p->isMatch[state2][posStateNext]) + GET_PRICE_1(p->isRep[state2]); - + /* for (; lenTest2 >= 2; lenTest2--) */ { UInt32 curAndLenPrice; @@ -1416,7 +1429,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; else curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; - + opt = &p->opt[cur + lenTest]; if (curAndLenPrice < opt->price) { @@ -1450,7 +1463,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) nextRepMatchPrice = curAndLenCharPrice + GET_PRICE_1(p->isMatch[state2][posStateNext]) + GET_PRICE_1(p->isRep[state2]); - + /* for (; lenTest2 >= 2; lenTest2--) */ { UInt32 offset = cur + lenTest + 1 + lenTest2; @@ -1562,7 +1575,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) MovePos(p, repLen - 1); return repLen; } - + if (mainLen < 2 || numAvail <= 2) return 1; @@ -1576,7 +1589,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) return 1; } - + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; for (i = 0; i < LZMA_NUM_REPS; i++) { @@ -1837,7 +1850,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize pos -= LZMA_NUM_REPS; GetPosSlot(pos, posSlot); RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); - + if (posSlot >= kStartPosModelIndex) { UInt32 footerBits = ((posSlot >> 1) - 1); @@ -1897,12 +1910,10 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) { UInt32 beforeSize = kNumOpts; - Bool btMode; if (!RangeEnc_Alloc(&p->rc, alloc)) return SZ_ERROR_MEM; - btMode = (p->matchFinderBase.btMode != 0); #ifndef _7ZIP_ST - p->mtMode = (p->multiThread && !p->fastMode && btMode); + p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0)); #endif { @@ -2142,7 +2153,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, p->rc.outStream = &outStream.funcTable; res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); - + *unpackSize = (UInt32)(p->nowPos64 - nowPos64); *destLen -= outStream.rem; if (outStream.overflow) @@ -2157,9 +2168,8 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) #ifndef _7ZIP_ST Byte allocaDummy[0x300]; - int i = 0; - for (i = 0; i < 16; i++) - allocaDummy[i] = (Byte)i; + allocaDummy[0] = 0; + allocaDummy[1] = allocaDummy[0]; #endif for (;;) diff --git a/src/libs/7zip/win/C/LzmaEnc.h b/src/libs/7zip/win/C/LzmaEnc.h index 200d60eb8..cffe220bb 100644 --- a/src/libs/7zip/win/C/LzmaEnc.h +++ b/src/libs/7zip/win/C/LzmaEnc.h @@ -1,14 +1,12 @@ /* LzmaEnc.h -- LZMA Encoder -2009-02-07 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __LZMA_ENC_H #define __LZMA_ENC_H -#include "Types.h" +#include "7zTypes.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN #define LZMA_PROPS_SIZE 5 @@ -18,6 +16,8 @@ typedef struct _CLzmaEncProps UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version (1 << 12) <= dictSize <= (1 << 30) for 64-bit version default = (1 << 24) */ + UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF. + Encoder uses this value to reduce dictionary size */ int lc; /* 0 <= lc <= 8, default = 3 */ int lp; /* 0 <= lp <= 4, default = 0 */ int pb; /* 0 <= pb <= 4, default = 2 */ @@ -73,8 +73,6 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/LzmaLib.c b/src/libs/7zip/win/C/LzmaLib.c deleted file mode 100644 index 02a511857..000000000 --- a/src/libs/7zip/win/C/LzmaLib.c +++ /dev/null @@ -1,46 +0,0 @@ -/* LzmaLib.c -- LZMA library wrapper -2008-08-05 -Igor Pavlov -Public domain */ - -#include "LzmaEnc.h" -#include "LzmaDec.h" -#include "Alloc.h" -#include "LzmaLib.h" - -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, - unsigned char *outProps, size_t *outPropsSize, - int level, /* 0 <= level <= 9, default = 5 */ - unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ - int lc, /* 0 <= lc <= 8, default = 3 */ - int lp, /* 0 <= lp <= 4, default = 0 */ - int pb, /* 0 <= pb <= 4, default = 2 */ - int fb, /* 5 <= fb <= 273, default = 32 */ - int numThreads /* 1 or 2, default = 2 */ -) -{ - CLzmaEncProps props; - LzmaEncProps_Init(&props); - props.level = level; - props.dictSize = dictSize; - props.lc = lc; - props.lp = lp; - props.pb = pb; - props.fb = fb; - props.numThreads = numThreads; - - return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, - NULL, &g_Alloc, &g_Alloc); -} - - -MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, - const unsigned char *props, size_t propsSize) -{ - ELzmaStatus status; - return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc); -} diff --git a/src/libs/7zip/win/C/LzmaLib.h b/src/libs/7zip/win/C/LzmaLib.h deleted file mode 100644 index 76c99ce75..000000000 --- a/src/libs/7zip/win/C/LzmaLib.h +++ /dev/null @@ -1,135 +0,0 @@ -/* LzmaLib.h -- LZMA library interface -2009-04-07 : Igor Pavlov : Public domain */ - -#ifndef __LZMA_LIB_H -#define __LZMA_LIB_H - -#include "Types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MY_STDAPI int MY_STD_CALL - -#define LZMA_PROPS_SIZE 5 - -/* -RAM requirements for LZMA: - for compression: (dictSize * 11.5 + 6 MB) + state_size - for decompression: dictSize + state_size - state_size = (4 + (1.5 << (lc + lp))) KB - by default (lc=3, lp=0), state_size = 16 KB. - -LZMA properties (5 bytes) format - Offset Size Description - 0 1 lc, lp and pb in encoded form. - 1 4 dictSize (little endian). -*/ - -/* -LzmaCompress ------------- - -outPropsSize - - In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. - Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. - - LZMA Encoder will use defult values for any parameter, if it is - -1 for any from: level, loc, lp, pb, fb, numThreads - 0 for dictSize - -level - compression level: 0 <= level <= 9; - - level dictSize algo fb - 0: 16 KB 0 32 - 1: 64 KB 0 32 - 2: 256 KB 0 32 - 3: 1 MB 0 32 - 4: 4 MB 0 32 - 5: 16 MB 1 32 - 6: 32 MB 1 32 - 7+: 64 MB 1 64 - - The default value for "level" is 5. - - algo = 0 means fast method - algo = 1 means normal method - -dictSize - The dictionary size in bytes. The maximum value is - 128 MB = (1 << 27) bytes for 32-bit version - 1 GB = (1 << 30) bytes for 64-bit version - The default value is 16 MB = (1 << 24) bytes. - It's recommended to use the dictionary that is larger than 4 KB and - that can be calculated as (1 << N) or (3 << N) sizes. - -lc - The number of literal context bits (high bits of previous literal). - It can be in the range from 0 to 8. The default value is 3. - Sometimes lc=4 gives the gain for big files. - -lp - The number of literal pos bits (low bits of current position for literals). - It can be in the range from 0 to 4. The default value is 0. - The lp switch is intended for periodical data when the period is equal to 2^lp. - For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's - better to set lc=0, if you change lp switch. - -pb - The number of pos bits (low bits of current position). - It can be in the range from 0 to 4. The default value is 2. - The pb switch is intended for periodical data when the period is equal 2^pb. - -fb - Word size (the number of fast bytes). - It can be in the range from 5 to 273. The default value is 32. - Usually, a big number gives a little bit better compression ratio and - slower compression process. - -numThreads - The number of thereads. 1 or 2. The default value is 2. - Fast mode (algo = 0) can use only 1 thread. - -Out: - destLen - processed output size -Returns: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, - unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ - int level, /* 0 <= level <= 9, default = 5 */ - unsigned dictSize, /* default = (1 << 24) */ - int lc, /* 0 <= lc <= 8, default = 3 */ - int lp, /* 0 <= lp <= 4, default = 0 */ - int pb, /* 0 <= pb <= 4, default = 2 */ - int fb, /* 5 <= fb <= 273, default = 32 */ - int numThreads /* 1 or 2, default = 2 */ - ); - -/* -LzmaUncompress --------------- -In: - dest - output data - destLen - output data size - src - input data - srcLen - input data size -Out: - destLen - processed output size - srcLen - processed input size -Returns: - SZ_OK - OK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation arror - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) -*/ - -MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, - const unsigned char *props, size_t propsSize); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libs/7zip/win/C/MtCoder.c b/src/libs/7zip/win/C/MtCoder.c index 946fbbc70..3d4dd2d14 100644 --- a/src/libs/7zip/win/C/MtCoder.c +++ b/src/libs/7zip/win/C/MtCoder.c @@ -1,6 +1,8 @@ /* MtCoder.c -- Multi-thread Coder 2010-09-24 : Igor Pavlov : Public domain */ +#include "Precomp.h" + #include <stdio.h> #include "MtCoder.h" @@ -190,9 +192,9 @@ static SRes MtThread_Process(CMtThread *p, Bool *stop) *stop = True; if (Event_Wait(&p->canRead) != 0) return SZ_ERROR_THREAD; - + next = GET_NEXT_THREAD(p); - + if (p->stopReading) { next->stopReading = True; diff --git a/src/libs/7zip/win/C/MtCoder.h b/src/libs/7zip/win/C/MtCoder.h index f0f06da28..e2cbdc3ab 100644 --- a/src/libs/7zip/win/C/MtCoder.h +++ b/src/libs/7zip/win/C/MtCoder.h @@ -14,7 +14,7 @@ typedef struct CAutoResetEvent startEvent; CAutoResetEvent finishedEvent; int stop; - + THREAD_FUNC_TYPE func; LPVOID param; THREAD_FUNC_RET_TYPE res; @@ -75,7 +75,7 @@ typedef struct _CMtCoder size_t blockSize; size_t destBlockSize; unsigned numThreads; - + ISeqInStream *inStream; ISeqOutStream *outStream; ICompressProgress *progress; diff --git a/src/libs/7zip/win/C/Precomp.h b/src/libs/7zip/win/C/Precomp.h new file mode 100644 index 000000000..e8ff8b40e --- /dev/null +++ b/src/libs/7zip/win/C/Precomp.h @@ -0,0 +1,10 @@ +/* Precomp.h -- StdAfx +2013-11-12 : Igor Pavlov : Public domain */ + +#ifndef __7Z_PRECOMP_H +#define __7Z_PRECOMP_H + +#include "Compiler.h" +/* #include "7zTypes.h" */ + +#endif diff --git a/src/libs/7zip/win/C/RotateDefs.h b/src/libs/7zip/win/C/RotateDefs.h index c3a1385ce..1b83e5ea1 100644 --- a/src/libs/7zip/win/C/RotateDefs.h +++ b/src/libs/7zip/win/C/RotateDefs.h @@ -1,5 +1,5 @@ /* RotateDefs.h -- Rotate functions -2009-02-07 : Igor Pavlov : Public domain */ +2013-11-12 : Igor Pavlov : Public domain */ #ifndef __ROTATE_DEFS_H #define __ROTATE_DEFS_H @@ -7,6 +7,12 @@ #ifdef _MSC_VER #include <stdlib.h> + +// #if (_MSC_VER >= 1200) +#pragma intrinsic(_rotl) +#pragma intrinsic(_rotr) +// #endif + #define rotlFixed(x, n) _rotl((x), (n)) #define rotrFixed(x, n) _rotr((x), (n)) diff --git a/src/libs/7zip/win/C/Sha256.c b/src/libs/7zip/win/C/Sha256.c index eb4fc61fc..10df0874f 100644 --- a/src/libs/7zip/win/C/Sha256.c +++ b/src/libs/7zip/win/C/Sha256.c @@ -2,6 +2,8 @@ 2010-06-11 : Igor Pavlov : Public domain This code is based on public domain code from Wei Dai's Crypto++ library. */ +#include "Precomp.h" + #include "RotateDefs.h" #include "Sha256.h" @@ -133,7 +135,7 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data) for (j = 0; j < 8; j++) state[j] += T[j]; #endif - + /* Wipe variables */ /* memset(W, 0, sizeof(W)); */ /* memset(T, 0, sizeof(T)); */ diff --git a/src/libs/7zip/win/C/Sha256.h b/src/libs/7zip/win/C/Sha256.h index 530f513ec..3f455dbc0 100644 --- a/src/libs/7zip/win/C/Sha256.h +++ b/src/libs/7zip/win/C/Sha256.h @@ -1,10 +1,10 @@ /* Sha256.h -- SHA-256 Hash -2010-06-11 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __CRYPTO_SHA256_H #define __CRYPTO_SHA256_H -#include "Types.h" +#include "7zTypes.h" EXTERN_C_BEGIN diff --git a/src/libs/7zip/win/C/Threads.c b/src/libs/7zip/win/C/Threads.c index 7af1da2e2..5c67a1e26 100644 --- a/src/libs/7zip/win/C/Threads.c +++ b/src/libs/7zip/win/C/Threads.c @@ -1,5 +1,7 @@ /* Threads.c -- multithreading library -2009-09-20 : Igor Pavlov : Public domain */ +2013-11-12 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #ifndef _WIN32_WCE #include <process.h> @@ -29,14 +31,21 @@ WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE) WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) { - unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ - *p = - #ifdef UNDER_CE - CreateThread(0, 0, func, param, 0, &threadId); - #else - (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId); - #endif - /* maybe we must use errno here, but probably GetLastError() is also OK. */ + /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ + + #ifdef UNDER_CE + + DWORD threadId; + *p = CreateThread(0, 0, func, param, 0, &threadId); + + #else + + unsigned threadId; + *p = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId); + + #endif + + /* maybe we must use errno here, but probably GetLastError() is also OK. */ return HandleToWRes(*p); } diff --git a/src/libs/7zip/win/C/Threads.h b/src/libs/7zip/win/C/Threads.h index d0ddd80e2..9b3e1c556 100644 --- a/src/libs/7zip/win/C/Threads.h +++ b/src/libs/7zip/win/C/Threads.h @@ -1,15 +1,17 @@ /* Threads.h -- multithreading library -2009-03-27 : Igor Pavlov : Public domain */ +2013-11-12 : Igor Pavlov : Public domain */ #ifndef __7Z_THREADS_H #define __7Z_THREADS_H -#include "Types.h" - -#ifdef __cplusplus -extern "C" { +#ifdef _WIN32 +#include <windows.h> #endif +#include "7zTypes.h" + +EXTERN_C_BEGIN + WRes HandlePtr_Close(HANDLE *h); WRes Handle_WaitObject(HANDLE h); @@ -18,7 +20,15 @@ typedef HANDLE CThread; #define Thread_WasCreated(p) (*(p) != NULL) #define Thread_Close(p) HandlePtr_Close(p) #define Thread_Wait(p) Handle_WaitObject(*(p)) -typedef unsigned THREAD_FUNC_RET_TYPE; + +typedef +#ifdef UNDER_CE + DWORD +#else + unsigned +#endif + THREAD_FUNC_RET_TYPE; + #define THREAD_FUNC_CALL_TYPE MY_STD_CALL #define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *); @@ -52,8 +62,6 @@ WRes CriticalSection_Init(CCriticalSection *p); #define CriticalSection_Enter(p) EnterCriticalSection(p) #define CriticalSection_Leave(p) LeaveCriticalSection(p) -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/Xz.c b/src/libs/7zip/win/C/Xz.c index 18caba2c1..fbc732a8a 100644 --- a/src/libs/7zip/win/C/Xz.c +++ b/src/libs/7zip/win/C/Xz.c @@ -1,6 +1,8 @@ /* Xz.c - Xz 2009-04-15 : Igor Pavlov : Public domain */ +#include "Precomp.h" + #include "7zCrc.h" #include "CpuArch.h" #include "Xz.h" diff --git a/src/libs/7zip/win/C/Xz.h b/src/libs/7zip/win/C/Xz.h index 2cfa1b789..9268d5bc6 100644 --- a/src/libs/7zip/win/C/Xz.h +++ b/src/libs/7zip/win/C/Xz.h @@ -1,5 +1,5 @@ /* Xz.h - Xz interface -2010-09-17 : Igor Pavlov : Public domain */ +2014-12-30 : Igor Pavlov : Public domain */ #ifndef __XZ_H #define __XZ_H @@ -199,7 +199,7 @@ typedef struct unsigned indexPreSize; CXzStreamFlags streamFlags; - + UInt32 blockHeaderSize; UInt64 packSize; UInt64 unpackSize; @@ -209,7 +209,9 @@ typedef struct UInt64 indexPos; UInt64 padSize; - UInt64 numStreams; + UInt64 numStartedStreams; + UInt64 numFinishedStreams; + UInt64 numTotalBlocks; UInt32 crc; CMixCoder decoder; @@ -220,33 +222,54 @@ typedef struct Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; } CXzUnpacker; -SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc); +void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc); +void XzUnpacker_Init(CXzUnpacker *p); void XzUnpacker_Free(CXzUnpacker *p); /* finishMode: It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - use smallest number of input bytes - LZMA_FINISH_END - read EndOfStream marker after decoding + CODER_FINISH_ANY - use smallest number of input bytes + CODER_FINISH_END - read EndOfStream marker after decoding Returns: SZ_OK status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - SZ_ERROR_DATA - Data error + CODER_STATUS_NOT_FINISHED, + CODER_STATUS_NEEDS_MORE_INPUT - maybe there are more xz streams, + call XzUnpacker_IsStreamWasFinished to check that current stream was finished SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). + SZ_ERROR_DATA - Data error + SZ_ERROR_UNSUPPORTED - Unsupported method or method properties + SZ_ERROR_CRC - CRC error + // SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). + + SZ_ERROR_NO_ARCHIVE - the error with xz Stream Header with one of the following reasons: + - xz Stream Signature failure + - CRC32 of xz Stream Header is failed + - The size of Stream padding is not multiple of four bytes. + It's possible to get that error, if xz stream was finished and the stream + contains some another data. In that case you can call XzUnpacker_GetExtraSize() + function to get real size of xz stream. */ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, /* int srcWasFinished, */ int finishMode, + const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status); Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p); +/* +Call XzUnpacker_GetExtraSize after XzUnpacker_Code function to detect real size of +xz stream in two cases: +XzUnpacker_Code() returns: + res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT + res == SZ_ERROR_NO_ARCHIVE +*/ + +UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p); + EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/XzCrc64.c b/src/libs/7zip/win/C/XzCrc64.c index 0369554b7..2c04c0af4 100644 --- a/src/libs/7zip/win/C/XzCrc64.c +++ b/src/libs/7zip/win/C/XzCrc64.c @@ -1,33 +1,90 @@ /* XzCrc64.c -- CRC64 calculation -2010-04-16 : Igor Pavlov : Public domain */ +2011-06-28 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include "XzCrc64.h" +#include "CpuArch.h" #define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42) -UInt64 g_Crc64Table[256]; -void MY_FAST_CALL Crc64GenerateTable(void) +#ifdef MY_CPU_LE + #define CRC_NUM_TABLES 4 +#else + #define CRC_NUM_TABLES 5 + #define CRC_UINT64_SWAP(v) \ + ((v >> 56) | \ + ((v >> 40) & ((UInt64)0xFF << 8)) | \ + ((v >> 24) & ((UInt64)0xFF << 16)) | \ + ((v >> 8) & ((UInt64)0xFF << 24)) | \ + ((v << 8) & ((UInt64)0xFF << 32)) | \ + ((v << 24) & ((UInt64)0xFF << 40)) | \ + ((v << 40) & ((UInt64)0xFF << 48)) | \ + (v << 56)) + UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif + +#ifndef MY_CPU_BE + UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif + +typedef UInt64 (MY_FAST_CALL *CRC_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table); + +static CRC_FUNC g_Crc64Update; +UInt64 g_Crc64Table[256 * CRC_NUM_TABLES]; + +UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size) +{ + return g_Crc64Update(v, data, size, g_Crc64Table); +} + +UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size) +{ + return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL; +} + +void MY_FAST_CALL Crc64GenerateTable() { UInt32 i; for (i = 0; i < 256; i++) { UInt64 r = i; - int j; + unsigned j; for (j = 0; j < 8; j++) - r = (r >> 1) ^ ((UInt64)kCrc64Poly & ~((r & 1) - 1)); + r = (r >> 1) ^ (kCrc64Poly & ~((r & 1) - 1)); g_Crc64Table[i] = r; } -} + for (; i < 256 * CRC_NUM_TABLES; i++) + { + UInt64 r = g_Crc64Table[i - 256]; + g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8); + } -UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 ; size--, p++) - v = CRC64_UPDATE_BYTE(v, *p); - return v; -} + #ifdef MY_CPU_LE -UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size) -{ - return CRC64_GET_DIGEST(Crc64Update(CRC64_INIT_VAL, data, size)); + g_Crc64Update = XzCrc64UpdateT4; + + + + + + + #else + { + #ifndef MY_CPU_BE + UInt32 k = 1; + if (*(const Byte *)&k == 1) + g_Crc64Update = XzCrc64UpdateT4; + else + #endif + { + for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) + { + UInt64 x = g_Crc64Table[i - 256]; + g_Crc64Table[i] = CRC_UINT64_SWAP(x); + } + g_Crc64Update = XzCrc64UpdateT1_BeT4; + } + } + #endif } diff --git a/src/libs/7zip/win/C/XzCrc64.h b/src/libs/7zip/win/C/XzCrc64.h index 0e8efd7ea..08dbc330c 100644 --- a/src/libs/7zip/win/C/XzCrc64.h +++ b/src/libs/7zip/win/C/XzCrc64.h @@ -1,12 +1,12 @@ /* XzCrc64.h -- CRC64 calculation -2010-04-16 : Igor Pavlov : Public domain */ +2013-01-18 : Igor Pavlov : Public domain */ #ifndef __XZ_CRC64_H #define __XZ_CRC64_H #include <stddef.h> -#include "Types.h" +#include "7zTypes.h" EXTERN_C_BEGIN diff --git a/src/libs/7zip/win/C/XzCrc64Opt.c b/src/libs/7zip/win/C/XzCrc64Opt.c new file mode 100644 index 000000000..dccae1c19 --- /dev/null +++ b/src/libs/7zip/win/C/XzCrc64Opt.c @@ -0,0 +1,69 @@ +/* XzCrc64Opt.c -- CRC64 calculation +2011-06-28 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +#ifndef MY_CPU_BE + +UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + for (; size >= 4; size -= 4, p += 4) + { + UInt32 d = (UInt32)v ^ *(const UInt32 *)p; + v = (v >> 32) ^ + table[0x300 + ((d ) & 0xFF)] ^ + table[0x200 + ((d >> 8) & 0xFF)] ^ + table[0x100 + ((d >> 16) & 0xFF)] ^ + table[0x000 + ((d >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +#endif + + +#ifndef MY_CPU_LE + +#define CRC_UINT64_SWAP(v) \ + ((v >> 56) | \ + ((v >> 40) & ((UInt64)0xFF << 8)) | \ + ((v >> 24) & ((UInt64)0xFF << 16)) | \ + ((v >> 8) & ((UInt64)0xFF << 24)) | \ + ((v << 8) & ((UInt64)0xFF << 32)) | \ + ((v << 24) & ((UInt64)0xFF << 40)) | \ + ((v << 40) & ((UInt64)0xFF << 48)) | \ + (v << 56)) + +UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + v = CRC_UINT64_SWAP(v); + table += 0x100; + for (; size >= 4; size -= 4, p += 4) + { + UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p; + v = (v << 32) ^ + table[0x000 + ((d ) & 0xFF)] ^ + table[0x100 + ((d >> 8) & 0xFF)] ^ + table[0x200 + ((d >> 16) & 0xFF)] ^ + table[0x300 + ((d >> 24))]; + } + table -= 0x100; + v = CRC_UINT64_SWAP(v); + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +#endif diff --git a/src/libs/7zip/win/C/XzDec.c b/src/libs/7zip/win/C/XzDec.c index 40f1a2a45..6eef587d3 100644 --- a/src/libs/7zip/win/C/XzDec.c +++ b/src/libs/7zip/win/C/XzDec.c @@ -1,5 +1,7 @@ /* XzDec.c -- Xz Decode -2010-04-16 : Igor Pavlov : Public domain */ +2014-12-30 : Igor Pavlov : Public domain */ + +#include "Precomp.h" /* #define XZ_DUMP */ @@ -18,7 +20,8 @@ #include "Lzma2Dec.h" #ifdef USE_SUBBLOCK -#include "SbDec.h" +#include "Bcj3Dec.c" +#include "SbDec.c" #endif #include "Xz.h" @@ -72,7 +75,6 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a { CBraState *p = ((CBraState *)pp); alloc = alloc; - p->encodeMode = 0; p->ip = 0; if (p->methodId == XZ_ID_Delta) { @@ -195,7 +197,7 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, return SZ_OK; } -SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc) +SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc) { CBraState *decoder; if (id != XZ_ID_Delta && @@ -207,10 +209,11 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc) id != XZ_ID_SPARC) return SZ_ERROR_UNSUPPORTED; p->p = 0; - decoder = alloc->Alloc(alloc, sizeof(CBraState)); + decoder = (CBraState *)alloc->Alloc(alloc, sizeof(CBraState)); if (decoder == 0) return SZ_ERROR_MEM; decoder->methodId = (UInt32)id; + decoder->encodeMode = encodeMode; p->p = decoder; p->Free = BraState_Free; p->SetProps = BraState_SetProps; @@ -225,8 +228,8 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc) static void SbState_Free(void *pp, ISzAlloc *alloc) { - CSubblockDec *p = (CSubblockDec *)pp; - SubblockDec_Free(p, alloc); + CSbDec *p = (CSbDec *)pp; + SbDec_Free(p); alloc->Free(alloc, pp); } @@ -240,24 +243,32 @@ static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAl static void SbState_Init(void *pp) { - SubblockDec_Init((CSubblockDec *)pp); + SbDec_Init((CSbDec *)pp); } static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished) { - ECoderStatus status; - SRes res = SubblockDec_Decode((CSubblockDec *)pp, dest, destLen, src, srcLen, finishMode, &status); + CSbDec *p = (CSbDec *)pp; + SRes res; srcWasFinished = srcWasFinished; - *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK); + p->dest = dest; + p->destLen = *destLen; + p->src = src; + p->srcLen = *srcLen; + p->finish = finishMode; /* change it */ + res = SbDec_Decode((CSbDec *)pp); + *destLen -= p->destLen; + *srcLen -= p->srcLen; + *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */ return res; } SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc) { - CSubblockDec *decoder; + CSbDec *decoder; p->p = 0; - decoder = alloc->Alloc(alloc, sizeof(CSubblockDec)); + decoder = alloc->Alloc(alloc, sizeof(CSbDec)); if (decoder == 0) return SZ_ERROR_MEM; p->p = decoder; @@ -265,7 +276,8 @@ SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc) p->SetProps = SbState_SetProps; p->Init = SbState_Init; p->Code = SbState_Code; - SubblockDec_Construct(decoder); + SbDec_Construct(decoder); + SbDec_SetAlloc(decoder, alloc); return SZ_OK; } #endif @@ -295,7 +307,7 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr { ELzmaStatus status; /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ - SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, finishMode, &status); + SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status); srcWasFinished = srcWasFinished; *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK); return res; @@ -303,7 +315,7 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc) { - CLzma2Dec *decoder = alloc->Alloc(alloc, sizeof(CLzma2Dec)); + CLzma2Dec *decoder = (CLzma2Dec *)alloc->Alloc(alloc, sizeof(CLzma2Dec)); p->p = decoder; if (decoder == 0) return SZ_ERROR_MEM; @@ -337,7 +349,10 @@ void MixCoder_Free(CMixCoder *p) } p->numCoders = 0; if (p->buf) + { p->alloc->Free(p->alloc, p->buf); + p->buf = 0; /* 9.31: the BUG was fixed */ + } } void MixCoder_Init(CMixCoder *p) @@ -369,7 +384,7 @@ SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId) } if (coderIndex == 0) return SZ_ERROR_UNSUPPORTED; - return BraState_SetFromMethod(sc, methodId, p->alloc); + return BraState_SetFromMethod(sc, methodId, 0, p->alloc); } SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, @@ -385,7 +400,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, if (p->buf == 0) { - p->buf = p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1)); + p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1)); if (p->buf == 0) return SZ_ERROR_MEM; } @@ -411,7 +426,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, const Byte *srcCur; int srcFinishedCur; int encodingWasFinished; - + if (i == 0) { srcCur = src; @@ -424,7 +439,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, srcLenCur = p->size[i - 1] - p->pos[i - 1]; srcFinishedCur = p->finished[i - 1]; } - + if (i == p->numCoders - 1) { destCur = dest; @@ -437,7 +452,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, destCur = p->buf + (CODER_BUF_SIZE * i); destLenCur = CODER_BUF_SIZE; } - + res = coder->Code(coder->p, destCur, &destLenCur, srcCur, &srcLenCur, srcFinishedCur, finishMode, &encodingWasFinished); if (!encodingWasFinished) @@ -464,7 +479,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, p->pos[i] = 0; p->finished[i] = encodingWasFinished; } - + if (res != SZ_OK) return res; @@ -587,13 +602,20 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block) return SZ_OK; } -SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc) +void XzUnpacker_Init(CXzUnpacker *p) { - MixCoder_Construct(&p->decoder, alloc); p->state = XZ_STATE_STREAM_HEADER; p->pos = 0; - p->numStreams = 0; - return SZ_OK; + p->numStartedStreams = 0; + p->numFinishedStreams = 0; + p->numTotalBlocks = 0; + p->padSize = 0; +} + +void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc) +{ + MixCoder_Construct(&p->decoder, alloc); + XzUnpacker_Init(p); } void XzUnpacker_Free(CXzUnpacker *p) @@ -602,7 +624,7 @@ void XzUnpacker_Free(CXzUnpacker *p) } SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, int finishMode, ECoderStatus *status) + const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status) { SizeT destLenOrig = *destLen; SizeT srcLenOrig = *srcLen; @@ -623,20 +645,20 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, *status = CODER_STATUS_NOT_FINISHED; return SZ_OK; } - + res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status); XzCheck_Update(&p->check, dest, destLen2); - + (*srcLen) += srcLen2; src += srcLen2; p->packSize += srcLen2; - + (*destLen) += destLen2; dest += destLen2; p->unpackSize += destLen2; - + RINOK(res); - + if (*status == CODER_STATUS_FINISHED_WITH_MARK) { Byte temp[32]; @@ -645,14 +667,14 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, Sha256_Update(&p->sha, temp, num); p->indexSize += num; p->numBlocks++; - + p->state = XZ_STATE_BLOCK_FOOTER; p->pos = 0; p->alignPos = 0; } else if (srcLen2 == 0 && destLen2 == 0) return SZ_OK; - + continue; } @@ -662,7 +684,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, return SZ_OK; } - switch(p->state) + switch (p->state) { case XZ_STATE_STREAM_HEADER: { @@ -676,6 +698,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, else { RINOK(Xz_ParseHeader(&p->streamFlags, p->buf)); + p->numStartedStreams++; p->state = XZ_STATE_BLOCK_HEADER; Sha256_Init(&p->sha); p->indexSize = 0; @@ -716,6 +739,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, else { RINOK(XzBlock_Parse(&p->block, p->buf)); + p->numTotalBlocks++; p->state = XZ_STATE_BLOCK; p->packSize = 0; p->unpackSize = 0; @@ -833,7 +857,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, if (p->pos == XZ_STREAM_FOOTER_SIZE) { p->state = XZ_STATE_STREAM_PADDING; - p->numStreams++; + p->numFinishedStreams++; p->padSize = 0; if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf)) return SZ_ERROR_CRC; @@ -858,7 +882,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, } break; } - + case XZ_STATE_BLOCK: break; /* to disable GCC warning */ } } @@ -873,3 +897,13 @@ Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p) { return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0); } + +UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p) +{ + UInt64 num = 0; + if (p->state == XZ_STATE_STREAM_PADDING) + num += p->padSize; + else if (p->state == XZ_STATE_STREAM_HEADER) + num += p->padSize + p->pos; + return num; +} diff --git a/src/libs/7zip/win/C/XzEnc.c b/src/libs/7zip/win/C/XzEnc.c index 721b4e765..56680fcd8 100644 --- a/src/libs/7zip/win/C/XzEnc.c +++ b/src/libs/7zip/win/C/XzEnc.c @@ -1,5 +1,7 @@ /* XzEnc.c -- Xz Encode -2009-06-04 : Igor Pavlov : Public domain */ +2014-12-30 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include <stdlib.h> #include <string.h> @@ -9,7 +11,9 @@ #include "Bra.h" #include "CpuArch.h" #ifdef USE_SUBBLOCK -#include "SbEnc.h" +#include "Bcj3Enc.c" +#include "SbFind.c" +#include "SbEnc.c" #endif #include "XzEnc.h" @@ -130,7 +134,7 @@ SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAll CXzBlockSizes *blocks; if (newSize / sizeof(CXzBlockSizes) != num) return SZ_ERROR_MEM; - blocks = alloc->Alloc(alloc, newSize); + blocks = (CXzBlockSizes *)alloc->Alloc(alloc, newSize); if (blocks == 0) return SZ_ERROR_MEM; if (p->numBlocks != 0) @@ -198,158 +202,147 @@ static size_t MyWrite(void *pp, const void *data, size_t size) /* ---------- CSeqInFilter ---------- */ -/* -typedef struct _IFilter -{ - void *p; - void (*Free)(void *p, ISzAlloc *alloc); - SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc); - void (*Init)(void *p); - size_t (*Filter)(void *p, Byte *data, SizeT destLen); -} IFilter; - -#define FILT_BUF_SIZE (1 << 19) +#define FILTER_BUF_SIZE (1 << 20) typedef struct { ISeqInStream p; ISeqInStream *realStream; - UInt32 x86State; - UInt32 ip; - UInt64 processed; - CXzCheck check; - Byte buf[FILT_BUF_SIZE]; - UInt32 bufferPos; - UInt32 convertedPosBegin; - UInt32 convertedPosEnd; - IFilter *filter; + IStateCoder StateCoder; + Byte *buf; + size_t curPos; + size_t endPos; + int srcWasFinished; } CSeqInFilter; static SRes SeqInFilter_Read(void *pp, void *data, size_t *size) { CSeqInFilter *p = (CSeqInFilter *)pp; - size_t remSize = *size; + size_t sizeOriginal = *size; + if (sizeOriginal == 0) + return SZ_OK; *size = 0; - - while (remSize > 0) + for (;;) { - int i; - if (p->convertedPosBegin != p->convertedPosEnd) + if (!p->srcWasFinished && p->curPos == p->endPos) { - UInt32 sizeTemp = p->convertedPosEnd - p->convertedPosBegin; - if (remSize < sizeTemp) - sizeTemp = (UInt32)remSize; - memmove(data, p->buf + p->convertedPosBegin, sizeTemp); - p->convertedPosBegin += sizeTemp; - data = (void *)((Byte *)data + sizeTemp); - remSize -= sizeTemp; - *size += sizeTemp; - break; + p->curPos = 0; + p->endPos = FILTER_BUF_SIZE; + RINOK(p->realStream->Read(p->realStream, p->buf, &p->endPos)); + if (p->endPos == 0) + p->srcWasFinished = 1; } - for (i = 0; p->convertedPosEnd + i < p->bufferPos; i++) - p->buf[i] = p->buf[i + p->convertedPosEnd]; - p->bufferPos = i; - p->convertedPosBegin = p->convertedPosEnd = 0; { - size_t processedSizeTemp = FILT_BUF_SIZE - p->bufferPos; - RINOK(p->realStream->Read(p->realStream, p->buf + p->bufferPos, &processedSizeTemp)); - p->bufferPos = p->bufferPos + (UInt32)processedSizeTemp; - } - p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos); - if (p->convertedPosEnd == 0) - { - if (p->bufferPos == 0) - break; - else - { - p->convertedPosEnd = p->bufferPos; - continue; - } - } - if (p->convertedPosEnd > p->bufferPos) - { - for (; p->bufferPos < p->convertedPosEnd; p->bufferPos++) - p->buf[p->bufferPos] = 0; - p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos); + SizeT srcLen = p->endPos - p->curPos; + int wasFinished; + SRes res; + *size = sizeOriginal; + res = p->StateCoder.Code(p->StateCoder.p, data, size, p->buf + p->curPos, &srcLen, + p->srcWasFinished, CODER_FINISH_ANY, &wasFinished); + p->curPos += srcLen; + if (*size != 0 || srcLen == 0 || res != 0) + return res; } } +} + +static void SeqInFilter_Construct(CSeqInFilter *p) +{ + p->buf = NULL; + p->p.Read = SeqInFilter_Read; +} + +static void SeqInFilter_Free(CSeqInFilter *p) +{ + if (p->buf) + { + g_Alloc.Free(&g_Alloc, p->buf); + p->buf = NULL; + } +} + +SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc); + +static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props) +{ + if (!p->buf) + { + p->buf = g_Alloc.Alloc(&g_Alloc, FILTER_BUF_SIZE); + if (!p->buf) + return SZ_ERROR_MEM; + } + p->curPos = p->endPos = 0; + p->srcWasFinished = 0; + RINOK(BraState_SetFromMethod(&p->StateCoder, props->id, 1, &g_Alloc)); + RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, &g_Alloc)); + p->StateCoder.Init(p->StateCoder.p); return SZ_OK; } -*/ -/* +/* ---------- CSbEncInStream ---------- */ + +#ifdef USE_SUBBLOCK + typedef struct { ISeqInStream p; - ISeqInStream *realStream; - CMixCoder mixCoder; - Byte buf[FILT_BUF_SIZE]; - UInt32 bufPos; - UInt32 bufSize; -} CMixCoderSeqInStream; + ISeqInStream *inStream; + CSbEnc enc; +} CSbEncInStream; -static SRes CMixCoderSeqInStream_Read(void *pp, void *data, size_t *size) +static SRes SbEncInStream_Read(void *pp, void *data, size_t *size) { - CMixCoderSeqInStream *p = (CMixCoderSeqInStream *)pp; - SRes res = SZ_OK; - size_t remSize = *size; - *size = 0; - while (remSize > 0) + CSbEncInStream *p = (CSbEncInStream *)pp; + size_t sizeOriginal = *size; + if (sizeOriginal == 0) + return S_OK; + for (;;) { - if (p->bufPos == p->bufSize) - { - size_t curSize; - p->bufPos = p->bufSize = 0; - if (*size != 0) - break; - curSize = FILT_BUF_SIZE; - RINOK(p->realStream->Read(p->realStream, p->buf, &curSize)); - p->bufSize = (UInt32)curSize; - } + if (p->enc.needRead && !p->enc.readWasFinished) { - SizeT destLen = remSize; - SizeT srcLen = p->bufSize - p->bufPos; - res = MixCoder_Code(&p->mixCoder, data, &destLen, p->buf + p->bufPos, &srcLen, 0); - data = (void *)((Byte *)data + destLen); - remSize -= destLen; - *size += destLen; - p->bufPos += srcLen; + size_t processed = p->enc.needReadSizeMax; + RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed)); + p->enc.readPos += processed; + if (processed == 0) + { + p->enc.readWasFinished = True; + p->enc.isFinalFinished = True; + } + p->enc.needRead = False; } + *size = sizeOriginal; + RINOK(SbEnc_Read(&p->enc, data, size)); + if (*size != 0 || !p->enc.needRead) + return S_OK; } - return res; } -*/ -#ifdef USE_SUBBLOCK -typedef struct +void SbEncInStream_Construct(CSbEncInStream *p, ISzAlloc *alloc) { - ISeqInStream p; - CSubblockEnc sb; - UInt64 processed; -} CSbEncInStream; + SbEnc_Construct(&p->enc, alloc); + p->p.Read = SbEncInStream_Read; +} -void SbEncInStream_Init(CSbEncInStream *p) +SRes SbEncInStream_Init(CSbEncInStream *p) { - p->processed = 0; - SubblockEnc_Init(&p->sb); + return SbEnc_Init(&p->enc); } -static SRes SbEncInStream_Read(void *pp, void *data, size_t *size) +void SbEncInStream_Free(CSbEncInStream *p) { - CSbEncInStream *p = (CSbEncInStream *)pp; - SRes res = SubblockEnc_Read(&p->sb, data, size); - p->processed += *size; - return res; + SbEnc_Free(&p->enc); } + #endif + typedef struct { - /* CMixCoderSeqInStream inStream; */ CLzma2EncHandle lzma2; #ifdef USE_SUBBLOCK CSbEncInStream sb; #endif + CSeqInFilter filter; ISzAlloc *alloc; ISzAlloc *bigAlloc; } CLzma2WithFilters; @@ -361,9 +354,9 @@ static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, IS p->bigAlloc = bigAlloc; p->lzma2 = NULL; #ifdef USE_SUBBLOCK - p->sb.p.Read = SbEncInStream_Read; - SubblockEnc_Construct(&p->sb.sb, p->alloc); + SbEncInStream_Construct(&p->sb, alloc); #endif + SeqInFilter_Construct(&p->filter); } static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p) @@ -376,8 +369,9 @@ static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p) static void Lzma2WithFilters_Free(CLzma2WithFilters *p) { + SeqInFilter_Free(&p->filter); #ifdef USE_SUBBLOCK - SubblockEnc_Free(&p->sb.sb); + SbEncInStream_Free(&p->sb); #endif if (p->lzma2) { @@ -386,17 +380,28 @@ static void Lzma2WithFilters_Free(CLzma2WithFilters *p) } } -static SRes Xz_Compress(CXzStream *xz, - CLzma2WithFilters *lzmaf, - ISeqOutStream *outStream, - ISeqInStream *inStream, - const CLzma2EncProps *lzma2Props, - Bool useSubblock, - ICompressProgress *progress) +void XzProps_Init(CXzProps *p) +{ + p->lzma2Props = 0; + p->filterProps = 0; + p->checkId = XZ_CHECK_CRC32; +} + +void XzFilterProps_Init(CXzFilterProps *p) { - xz->flags = XZ_CHECK_CRC32; + p->id = 0; + p->delta = 0; + p->ip= 0; + p->ipDefined = False; +} + +static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf, + ISeqOutStream *outStream, ISeqInStream *inStream, + const CXzProps *props, ICompressProgress *progress) +{ + xz->flags = (Byte)props->checkId; - RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, lzma2Props)); + RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props)); RINOK(Xz_WriteHeader(xz->flags, outStream)); { @@ -404,15 +409,27 @@ static SRes Xz_Compress(CXzStream *xz, CSeqSizeOutStream seqSizeOutStream; CXzBlock block; int filterIndex = 0; - + CXzFilter *filter = NULL; + const CXzFilterProps *fp = props->filterProps; + XzBlock_ClearFlags(&block); - XzBlock_SetNumFilters(&block, 1 + (useSubblock ? 1 : 0)); - - if (useSubblock) + XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0)); + + if (fp) { - CXzFilter *f = &block.filters[filterIndex++]; - f->id = XZ_ID_Subblock; - f->propsSize = 0; + filter = &block.filters[filterIndex++]; + filter->id = fp->id; + filter->propsSize = 0; + if (fp->id == XZ_ID_Delta) + { + filter->props[0] = (Byte)(fp->delta - 1); + filter->propsSize = 1; + } + else if (fp->ipDefined) + { + SetUi32(filter->props, fp->ip); + filter->propsSize = 4; + } } { @@ -425,27 +442,37 @@ static SRes Xz_Compress(CXzStream *xz, seqSizeOutStream.p.Write = MyWrite; seqSizeOutStream.realStream = outStream; seqSizeOutStream.processed = 0; - + RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p)); - + checkInStream.p.Read = SeqCheckInStream_Read; checkInStream.realStream = inStream; SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags)); - - #ifdef USE_SUBBLOCK - if (useSubblock) + + if (fp) { - lzmaf->sb.sb.inStream = &checkInStream.p; - SubblockEnc_Init(&lzmaf->sb.sb); + #ifdef USE_SUBBLOCK + if (fp->id == XZ_ID_Subblock) + { + lzmaf->sb.inStream = &checkInStream.p; + RINOK(SbEncInStream_Init(&lzmaf->sb)); + } + else + #endif + { + lzmaf->filter.realStream = &checkInStream.p; + RINOK(SeqInFilter_Init(&lzmaf->filter, filter)); + } } - #endif - + { UInt64 packPos = seqSizeOutStream.processed; SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p, + fp ? #ifdef USE_SUBBLOCK - useSubblock ? &lzmaf->sb.p: + (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p: #endif + &lzmaf->filter.p: &checkInStream.p, progress); RINOK(res); @@ -467,8 +494,7 @@ static SRes Xz_Compress(CXzStream *xz, } SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, - const CLzma2EncProps *lzma2Props, Bool useSubblock, - ICompressProgress *progress) + const CXzProps *props, ICompressProgress *progress) { SRes res; CXzStream xz; @@ -477,8 +503,7 @@ SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, Lzma2WithFilters_Construct(&lzmaf, &g_Alloc, &g_BigAlloc); res = Lzma2WithFilters_Create(&lzmaf); if (res == SZ_OK) - res = Xz_Compress(&xz, &lzmaf, outStream, inStream, - lzma2Props, useSubblock, progress); + res = Xz_Compress(&xz, &lzmaf, outStream, inStream, props, progress); Lzma2WithFilters_Free(&lzmaf); Xz_Free(&xz, &g_Alloc); return res; diff --git a/src/libs/7zip/win/C/XzEnc.h b/src/libs/7zip/win/C/XzEnc.h index 13390df8b..c3c19eca0 100644 --- a/src/libs/7zip/win/C/XzEnc.h +++ b/src/libs/7zip/win/C/XzEnc.h @@ -1,5 +1,5 @@ /* XzEnc.h -- Xz Encode -2009-04-15 : Igor Pavlov : Public domain */ +2011-02-07 : Igor Pavlov : Public domain */ #ifndef __XZ_ENC_H #define __XZ_ENC_H @@ -8,18 +8,32 @@ #include "Xz.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN + +typedef struct +{ + UInt32 id; + UInt32 delta; + UInt32 ip; + int ipDefined; +} CXzFilterProps; + +void XzFilterProps_Init(CXzFilterProps *p); + +typedef struct +{ + const CLzma2EncProps *lzma2Props; + const CXzFilterProps *filterProps; + unsigned checkId; +} CXzProps; + +void XzProps_Init(CXzProps *p); SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, - const CLzma2EncProps *lzma2Props, Bool useSubblock, - ICompressProgress *progress); + const CXzProps *props, ICompressProgress *progress); SRes Xz_EncodeEmpty(ISeqOutStream *outStream); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/src/libs/7zip/win/C/XzIn.c b/src/libs/7zip/win/C/XzIn.c index 7f0f6af8d..ed9eac31a 100644 --- a/src/libs/7zip/win/C/XzIn.c +++ b/src/libs/7zip/win/C/XzIn.c @@ -1,5 +1,7 @@ /* XzIn.c - Xz input -2009-06-19 : Igor Pavlov : Public domain */ +2014-12-30 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include <string.h> @@ -70,7 +72,7 @@ SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream) static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc) { - size_t i, numBlocks, crcStartPos, pos = 1; + size_t i, numBlocks, pos = 1; UInt32 crc; if (size < 5 || buf[0] != 0) @@ -88,8 +90,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc * if (numBlocks != numBlocks64 || numBlocks * 2 > size) return SZ_ERROR_ARCHIVE; } - - crcStartPos = pos; + Xz_Free(p, alloc); if (numBlocks != 0) { @@ -149,44 +150,43 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff RINOK(SeekFromCur(stream, startOffset)); RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE)); - + if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) { - Int64 i = 0; + UInt32 total = 0; *startOffset += XZ_STREAM_FOOTER_SIZE; for (;;) { - int j; - size_t processedSize; + size_t i; #define TEMP_BUF_SIZE (1 << 10) Byte tempBuf[TEMP_BUF_SIZE]; - if (*startOffset < XZ_STREAM_FOOTER_SIZE || i > (1 << 16)) + if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16)) return SZ_ERROR_NO_ARCHIVE; - processedSize = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset; - i += processedSize; - *startOffset = -(Int64)processedSize; + i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset; + total += (UInt32)i; + *startOffset = -(Int64)i; RINOK(SeekFromCur(stream, startOffset)); - RINOK(LookInStream_Read2(stream, tempBuf, processedSize, SZ_ERROR_NO_ARCHIVE)); - for (j = (int)processedSize; j >= 0; j--) - if (tempBuf[j -1] != 0) + RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE)); + for (; i != 0; i--) + if (tempBuf[i - 1] != 0) break; - if (j != 0) + if (i != 0) { - if ((j & 3) != 0) - return SZ_ERROR_NO_ARCHIVE; - *startOffset += j; - if (*startOffset < XZ_STREAM_FOOTER_SIZE) - return SZ_ERROR_NO_ARCHIVE; - *startOffset -= XZ_STREAM_FOOTER_SIZE; - RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET)); - RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE)); - if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) + if ((i & 3) != 0) return SZ_ERROR_NO_ARCHIVE; + *startOffset += i; break; } } + if (*startOffset < XZ_STREAM_FOOTER_SIZE) + return SZ_ERROR_NO_ARCHIVE; + *startOffset -= XZ_STREAM_FOOTER_SIZE; + RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET)); + RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE)); + if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) + return SZ_ERROR_NO_ARCHIVE; } - + p->flags = (CXzStreamFlags)GetBe16(buf + 8); if (!XzFlags_IsSupported(p->flags)) @@ -291,7 +291,8 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr if (data == 0) return SZ_ERROR_MEM; p->numAllocated = newNum; - memcpy(data, p->streams, p->num * sizeof(CXzStream)); + if (p->num != 0) + memcpy(data, p->streams, p->num * sizeof(CXzStream)); alloc->Free(alloc, p->streams); p->streams = (CXzStream *)data; } diff --git a/src/libs/7zip/win/CPP/7zip/7zip.pri b/src/libs/7zip/win/CPP/7zip/7zip.pri new file mode 100644 index 000000000..a2b70a1f2 --- /dev/null +++ b/src/libs/7zip/win/CPP/7zip/7zip.pri @@ -0,0 +1,6 @@ +HEADERS += $$7ZIP_BASE/CPP/7zip/ICoder.h \ + $$7ZIP_BASE/CPP/7zip/IDecl.h \ + $$7ZIP_BASE/CPP/7zip/IPassword.h \ + $$7ZIP_BASE/CPP/7zip/IProgress.h \ + $$7ZIP_BASE/CPP/7zip/IStream.h \ + $$7ZIP_BASE/CPP/7zip/PropID.h diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7z.pri b/src/libs/7zip/win/CPP/7zip/Archive/7z/7z.pri new file mode 100644 index 000000000..7763cf705 --- /dev/null +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7z.pri @@ -0,0 +1,30 @@ +HEADERS += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zCompressionMode.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zDecode.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zEncode.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zFolderInStream.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zFolderOutStream.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHandler.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHeader.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zIn.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zItem.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zOut.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zProperties.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zSpecStream.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zUpdate.h \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/StdAfx.h + +SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zDecode.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zEncode.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zExtract.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zFolderInStream.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zFolderOutStream.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHandler.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHandlerOut.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHeader.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zIn.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zOut.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zProperties.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zRegister.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zSpecStream.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/7z/7zUpdate.cpp + diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.cpp deleted file mode 100644 index 6774fc482..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// CompressionMethod.cpp - -#include "StdAfx.h" diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.h index 55bbc68ee..5cde97c38 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.h @@ -3,19 +3,18 @@ #ifndef __7Z_COMPRESSION_MODE_H #define __7Z_COMPRESSION_MODE_H -#include "../../../Common/MyString.h" - -#include "../../../Windows/PropVariant.h" - +#include "../../Common/MethodId.h" #include "../../Common/MethodProps.h" namespace NArchive { namespace N7z { -struct CMethodFull: public CMethod +struct CMethodFull: public CProps { + CMethodId Id; UInt32 NumInStreams; UInt32 NumOutStreams; + bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); } }; diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.cpp index 425a34157..973966bd3 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.cpp @@ -16,29 +16,33 @@ static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, CBindInfoEx &bindInfo) { bindInfo.Clear(); - int i; + bindInfo.BindPairs.ClearAndSetSize(folder.BindPairs.Size()); + unsigned i; for (i = 0; i < folder.BindPairs.Size(); i++) { - NCoderMixer::CBindPair bindPair; + NCoderMixer::CBindPair &bindPair = bindInfo.BindPairs[i]; bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex; bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex; - bindInfo.BindPairs.Add(bindPair); } + + bindInfo.Coders.ClearAndSetSize(folder.Coders.Size()); + bindInfo.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size()); + UInt32 outStreamIndex = 0; for (i = 0; i < folder.Coders.Size(); i++) { - NCoderMixer::CCoderStreamsInfo coderStreamsInfo; + NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i]; const CCoderInfo &coderInfo = folder.Coders[i]; coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams; coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams; - bindInfo.Coders.Add(coderStreamsInfo); - bindInfo.CoderMethodIDs.Add(coderInfo.MethodID); + bindInfo.CoderMethodIDs[i] = coderInfo.MethodID; for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++) if (folder.FindBindPairForOutStream(outStreamIndex) < 0) bindInfo.OutStreams.Add(outStreamIndex); } + bindInfo.InStreams.ClearAndSetSize(folder.PackStreams.Size()); for (i = 0; i < folder.PackStreams.Size(); i++) - bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]); + bindInfo.InStreams[i] = (UInt32)folder.PackStreams[i]; } static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1, @@ -58,7 +62,7 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) { if (a1.Coders.Size() != a2.Coders.Size()) return false; - int i; + unsigned i; for (i = 0; i < a1.Coders.Size(); i++) if (!AreCodersEqual(a1.Coders[i], a2.Coders[i])) return false; @@ -90,46 +94,50 @@ HRESULT CDecoder::Decode( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, UInt64 startPos, - const UInt64 *packSizes, - const CFolder &folderInfo, + const CFolders &folders, int folderIndex, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS_DECL #if !defined(_7ZIP_ST) && !defined(_SFX) , bool mtMode, UInt32 numThreads #endif ) { - if (!folderInfo.CheckStructure()) + const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]]; + CFolder folderInfo; + folders.ParseFolderInfo(folderIndex, folderInfo); + + if (!folderInfo.CheckStructure(folders.GetNumFolderUnpackSizes(folderIndex))) return E_NOTIMPL; + + /* + We don't need to init isEncrypted and passwordIsDefined + We must upgrade them only #ifndef _NO_CRYPTO + isEncrypted = false; passwordIsDefined = false; #endif + */ + CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; - + CLockedInStream lockedInStream; lockedInStream.Init(inStream); - - for (int j = 0; j < folderInfo.PackStreams.Size(); j++) + + for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++) { - CLockedSequentialInStreamImp *lockedStreamImpSpec = new - CLockedSequentialInStreamImp; + CLockedSequentialInStreamImp *lockedStreamImpSpec = new CLockedSequentialInStreamImp; CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec; - lockedStreamImpSpec->Init(&lockedInStream, startPos); - startPos += packSizes[j]; - - CLimitedSequentialInStream *streamSpec = new - CLimitedSequentialInStream; + lockedStreamImpSpec->Init(&lockedInStream, startPos + packPositions[j]); + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> inStream = streamSpec; streamSpec->SetStream(lockedStreamImp); - streamSpec->Init(packSizes[j]); + streamSpec->Init(packPositions[j + 1] - packPositions[j]); inStreams.Add(inStream); } - - int numCoders = folderInfo.Coders.Size(); - + + unsigned numCoders = folderInfo.Coders.Size(); + CBindInfoEx bindInfo; ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo); bool createNewCoders; @@ -139,10 +147,10 @@ HRESULT CDecoder::Decode( createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev); if (createNewCoders) { - int i; + unsigned i; _decoders.Clear(); // _decoders2.Clear(); - + _mixerCoder.Release(); if (_multiThread) @@ -160,12 +168,12 @@ HRESULT CDecoder::Decode( #endif } RINOK(_mixerCoderCommon->SetBindInfo(bindInfo)); - + for (i = 0; i < numCoders; i++) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; - + CMyComPtr<ICompressCoder> decoder; CMyComPtr<ICompressCoder2> decoder2; RINOK(CreateCoder( @@ -178,7 +186,7 @@ HRESULT CDecoder::Decode( return E_NOTIMPL; decoderUnknown = (IUnknown *)decoder; - + if (_multiThread) _mixerCoderMTSpec->AddCoder(decoder); #ifdef _ST_MODE @@ -204,32 +212,34 @@ HRESULT CDecoder::Decode( decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); } #endif } _bindInfoExPrev = bindInfo; _bindInfoExPrevIsDefined = true; } - int i; + unsigned i; _mixerCoderCommon->ReInit(); - - UInt32 packStreamIndex = 0, unpackStreamIndex = 0; + + UInt32 packStreamIndex = 0; + UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex]; + UInt32 unpackStreamIndex = unpackStreamIndexStart; UInt32 coderIndex = 0; // UInt32 coder2Index = 0; - + for (i = 0; i < numCoders; i++) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; CMyComPtr<IUnknown> &decoder = _decoders[coderIndex]; - + { CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); if (setDecoderProperties) { const CByteBuffer &props = coderInfo.Props; - size_t size = props.GetCapacity(); + size_t size = props.Size(); if (size > 0xFFFFFFFF) return E_NOTIMPL; // if (size > 0) @@ -257,56 +267,55 @@ HRESULT CDecoder::Decode( decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); if (cryptoSetPassword) { - if (getTextPassword == 0) - return E_FAIL; + isEncrypted = true; + if (!getTextPassword) + return E_NOTIMPL; CMyComBSTR passwordBSTR; RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)); - CByteBuffer buffer; passwordIsDefined = true; - const UString password(passwordBSTR); - const UInt32 sizeInBytes = password.Length() * 2; - buffer.SetCapacity(sizeInBytes); - for (int i = 0; i < password.Length(); i++) + size_t len = 0; + if (passwordBSTR) + len = MyStringLen((BSTR)passwordBSTR); + CByteBuffer buffer(len * 2); + for (size_t i = 0; i < len; i++) { - wchar_t c = password[i]; + wchar_t c = passwordBSTR[i]; ((Byte *)buffer)[i * 2] = (Byte)c; ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); } - RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes)); + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())); } } #endif coderIndex++; - + UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; - CRecordVector<const UInt64 *> packSizesPointers; - CRecordVector<const UInt64 *> unpackSizesPointers; - packSizesPointers.Reserve(numInStreams); - unpackSizesPointers.Reserve(numOutStreams); + CObjArray<UInt64> packSizes(numInStreams); + CObjArray<const UInt64 *> packSizesPointers(numInStreams); + CObjArray<const UInt64 *> unpackSizesPointers(numOutStreams); UInt32 j; + for (j = 0; j < numOutStreams; j++, unpackStreamIndex++) - unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]); - + unpackSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndex]; + for (j = 0; j < numInStreams; j++, packStreamIndex++) { int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); if (bindPairIndex >= 0) - packSizesPointers.Add( - &folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]); + packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + (UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]; else { int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); if (index < 0) - return E_FAIL; - packSizesPointers.Add(&packSizes[index]); + return S_FALSE; // check it + packSizes[j] = packPositions[index + 1] - packPositions[index]; + packSizesPointers[j] = &packSizes[j]; } } - - _mixerCoderCommon->SetCoderInfo(i, - &packSizesPointers.Front(), - &unpackSizesPointers.Front()); + + _mixerCoderCommon->SetCoderInfo(i, packSizesPointers, unpackSizesPointers); } UInt32 mainCoder, temp; bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); @@ -317,16 +326,18 @@ HRESULT CDecoder::Decode( else _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);; */ - + if (numCoders == 0) return 0; - CRecordVector<ISequentialInStream *> inStreamPointers; - inStreamPointers.Reserve(inStreams.Size()); - for (i = 0; i < inStreams.Size(); i++) - inStreamPointers.Add(inStreams[i]); + unsigned num = inStreams.Size(); + CObjArray<ISequentialInStream *> inStreamPointers(num); + for (i = 0; i < num; i++) + inStreamPointers[i] = inStreams[i]; ISequentialOutStream *outStreamPointer = outStream; - return _mixerCoder->Code(&inStreamPointers.Front(), NULL, - inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress); + return _mixerCoder->Code( + inStreamPointers, NULL, num, + &outStreamPointer, NULL, 1, + compressProgress); } }} diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.h index d8a424a36..54e9d2b52 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.h @@ -14,7 +14,7 @@ #include "../../Common/CreateCoder.h" -#include "7zItem.h" +#include "7zIn.h" namespace NArchive { namespace N7z { @@ -33,14 +33,14 @@ class CDecoder { bool _bindInfoExPrevIsDefined; CBindInfoEx _bindInfoExPrev; - + bool _multiThread; #ifdef _ST_MODE NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec; #endif NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec; NCoderMixer::CCoderMixer2 *_mixerCoderCommon; - + CMyComPtr<ICompressCoder2> _mixerCoder; CObjectVector<CMyComPtr<IUnknown> > _decoders; // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2; @@ -50,13 +50,10 @@ public: DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, UInt64 startPos, - const UInt64 *packSizes, - const CFolder &folder, + const CFolders &folders, int folderIndex, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPasswordSpec, bool &passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS_DECL #if !defined(_7ZIP_ST) && !defined(_SFX) , bool mtMode, UInt32 numThreads #endif diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.cpp index 87996bc0e..5f1436fc7 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.cpp @@ -23,30 +23,39 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindIn const CRecordVector<CMethodId> decompressionMethods, CFolder &folder) { - folder.Coders.Clear(); // bindInfo.CoderMethodIDs.Clear(); // folder.OutStreams.Clear(); - folder.PackStreams.Clear(); - folder.BindPairs.Clear(); - int i; + folder.BindPairs.SetSize(bindInfo.BindPairs.Size()); + unsigned i; for (i = 0; i < bindInfo.BindPairs.Size(); i++) { - CBindPair bindPair; - bindPair.InIndex = bindInfo.BindPairs[i].InIndex; - bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex; - folder.BindPairs.Add(bindPair); + CBindPair &bp = folder.BindPairs[i]; + const NCoderMixer::CBindPair &mixerBp = bindInfo.BindPairs[i]; + bp.InIndex = mixerBp.InIndex; + bp.OutIndex = mixerBp.OutIndex; } + folder.Coders.SetSize(bindInfo.Coders.Size()); for (i = 0; i < bindInfo.Coders.Size(); i++) { - CCoderInfo coderInfo; + CCoderInfo &coderInfo = folder.Coders[i]; const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i]; coderInfo.NumInStreams = coderStreamsInfo.NumInStreams; coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams; coderInfo.MethodID = decompressionMethods[i]; - folder.Coders.Add(coderInfo); + // coderInfo.Props can be nonFree; } + folder.PackStreams.SetSize(bindInfo.InStreams.Size()); for (i = 0; i < bindInfo.InStreams.Size(); i++) - folder.PackStreams.Add(bindInfo.InStreams[i]); + folder.PackStreams[i] = bindInfo.InStreams[i]; +} + +static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder) +{ + CMyComPtr<ICompressSetCoderProperties> setCoderProperties; + coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties); + if (setCoderProperties) + return props.SetCoderProps(setCoderProperties, dataSizeReduce); + return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK; } HRESULT CEncoder::CreateMixerCoder( @@ -56,15 +65,14 @@ HRESULT CEncoder::CreateMixerCoder( _mixerCoderSpec = new NCoderMixer::CCoderMixer2MT; _mixerCoder = _mixerCoderSpec; RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo)); - for (int i = 0; i < _options.Methods.Size(); i++) + FOR_VECTOR (i, _options.Methods) { const CMethodFull &methodFull = _options.Methods[i]; - _codersInfo.Add(CCoderInfo()); - CCoderInfo &encodingInfo = _codersInfo.Back(); + CCoderInfo &encodingInfo = _codersInfo.AddNew(); encodingInfo.MethodID = methodFull.Id; CMyComPtr<ICompressCoder> encoder; CMyComPtr<ICompressCoder2> encoder2; - + RINOK(CreateCoder( EXTERNAL_CODECS_LOC_VARS @@ -74,7 +82,7 @@ HRESULT CEncoder::CreateMixerCoder( return E_FAIL; CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2; - + #ifndef _7ZIP_ST { CMyComPtr<ICompressSetCoderMt> setCoderMt; @@ -85,14 +93,13 @@ HRESULT CEncoder::CreateMixerCoder( } } #endif - - RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon)); + RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon)); /* CMyComPtr<ICryptoResetSalt> resetSalt; encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt); - if (resetSalt != NULL) + if (resetSalt) { resetSalt->ResetSalt(); } @@ -103,19 +110,18 @@ HRESULT CEncoder::CreateMixerCoder( encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); } #endif - + CMyComPtr<ICryptoSetPassword> cryptoSetPassword; encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); if (cryptoSetPassword) { - CByteBuffer buffer; - const UInt32 sizeInBytes = _options.Password.Length() * 2; - buffer.SetCapacity(sizeInBytes); - for (int i = 0; i < _options.Password.Length(); i++) + const UInt32 sizeInBytes = _options.Password.Len() * 2; + CByteBuffer buffer(sizeInBytes); + for (unsigned i = 0; i < _options.Password.Len(); i++) { wchar_t c = _options.Password[i]; ((Byte *)buffer)[i * 2] = (Byte)c; @@ -137,13 +143,15 @@ HRESULT CEncoder::Encode( ISequentialInStream *inStream, const UInt64 *inStreamSize, const UInt64 *inSizeForReduce, CFolder &folderItem, + CRecordVector<UInt64> &coderUnpackSizes, + UInt64 &unpackSize, ISequentialOutStream *outStream, CRecordVector<UInt64> &packSizes, ICompressProgressInfo *compressProgress) { RINOK(EncoderConstr()); - if (_mixerCoderSpec == NULL) + if (!_mixerCoderSpec) { RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce)); } @@ -153,13 +161,13 @@ HRESULT CEncoder::Encode( CObjectVector<CInOutTempBuffer> inOutTempBuffers; CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs; CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers; - int numMethods = _bindInfo.Coders.Size(); - int i; + unsigned numMethods = _bindInfo.Coders.Size(); + unsigned i; for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { - inOutTempBuffers.Add(CInOutTempBuffer()); - inOutTempBuffers.Back().Create(); - inOutTempBuffers.Back().InitWriting(); + CInOutTempBuffer &iotb = inOutTempBuffers.AddNew(); + iotb.Create(); + iotb.InitWriting(); } for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { @@ -177,8 +185,8 @@ HRESULT CEncoder::Encode( return E_FAIL; UInt32 mainCoderIndex, mainStreamIndex; _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex); - - if (inStreamSize != NULL) + + if (inStreamSize) { CRecordVector<const UInt64 *> sizePointers; for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++) @@ -189,40 +197,47 @@ HRESULT CEncoder::Encode( _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL); } - + // UInt64 outStreamStartPos; // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos)); - + CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2; CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec; - CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount; - CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec; + CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL; + CMyComPtr<ISequentialOutStream> outStreamSizeCount; inStreamSizeCountSpec->Init(inStream); - outStreamSizeCountSpec->SetStream(outStream); - outStreamSizeCountSpec->Init(); CRecordVector<ISequentialInStream *> inStreamPointers; CRecordVector<ISequentialOutStream *> outStreamPointers; inStreamPointers.Add(inStreamSizeCount); - outStreamPointers.Add(outStreamSizeCount); + + if (_bindInfo.OutStreams.Size() != 0) + { + outStreamSizeCountSpec = new CSequentialOutStreamSizeCount; + outStreamSizeCount = outStreamSizeCountSpec; + outStreamSizeCountSpec->SetStream(outStream); + outStreamSizeCountSpec->Init(); + outStreamPointers.Add(outStreamSizeCount); + } + for (i = 1; i < _bindInfo.OutStreams.Size(); i++) outStreamPointers.Add(tempBuffers[i - 1]); for (i = 0; i < _codersInfo.Size(); i++) { CCoderInfo &encodingInfo = _codersInfo[i]; - + CMyComPtr<ICryptoResetInitVector> resetInitVector; _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector); - if (resetInitVector != NULL) + if (resetInitVector) { resetInitVector->ResetInitVector(); } CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties; _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties); - if (writeCoderProperties != NULL) + if (writeCoderProperties) { CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream; CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); @@ -242,33 +257,38 @@ HRESULT CEncoder::Encode( } _mixerCoderSpec->SetProgressCoderIndex(progressIndex); - + RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1, &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress)); - + ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem); - - packSizes.Add(outStreamSizeCountSpec->GetSize()); - + + if (_bindInfo.OutStreams.Size() != 0) + packSizes.Add(outStreamSizeCountSpec->GetSize()); + for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1]; RINOK(inOutTempBuffer.WriteToStream(outStream)); packSizes.Add(inOutTempBuffer.GetDataSize()); } - + + unpackSize = 0; for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++) { int binder = _bindInfo.FindBinderForInStream( _bindReverseConverter->DestOutToSrcInMap[i]); UInt64 streamSize; if (binder < 0) + { streamSize = inStreamSizeCountSpec->GetSize(); + unpackSize = streamSize; + } else streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder); - folderItem.UnpackSizes.Add(streamSize); + coderUnpackSizes.Add(streamSize); } - for (i = numMethods - 1; i >= 0; i--) + for (i = 0; i < numMethods; i++) folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props; return S_OK; } @@ -298,16 +318,16 @@ HRESULT CEncoder::EncoderConstr() throw 1; NCoderMixer::CCoderStreamsInfo coderStreamsInfo; CMethodFull method; - + method.NumInStreams = 1; method.NumOutStreams = 1; coderStreamsInfo.NumInStreams = 1; coderStreamsInfo.NumOutStreams = 1; method.Id = k_AES; - + _options.Methods.Add(method); _bindInfo.Coders.Add(coderStreamsInfo); - + _bindInfo.InStreams.Add(0); _bindInfo.OutStreams.Add(0); } @@ -315,7 +335,7 @@ HRESULT CEncoder::EncoderConstr() { UInt32 numInStreams = 0, numOutStreams = 0; - int i; + unsigned i; for (i = 0; i < _options.Methods.Size(); i++) { const CMethodFull &methodFull = _options.Methods[i]; @@ -331,12 +351,12 @@ HRESULT CEncoder::EncoderConstr() bindPair.OutIndex = numOutStreams; _bindInfo.BindPairs.Add(bindPair); } - else + else if (coderStreamsInfo.NumOutStreams != 0) _bindInfo.OutStreams.Insert(0, numOutStreams); for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++) _bindInfo.OutStreams.Add(numOutStreams + j); } - + numInStreams += coderStreamsInfo.NumInStreams; numOutStreams += coderStreamsInfo.NumOutStreams; @@ -390,7 +410,7 @@ HRESULT CEncoder::EncoderConstr() if (_options.PasswordIsDefined) { - int numCryptoStreams = _bindInfo.OutStreams.Size(); + unsigned numCryptoStreams = _bindInfo.OutStreams.Size(); for (i = 0; i < numCryptoStreams; i++) { diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.h index 4909a6e89..8e20bdb5f 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.h @@ -45,6 +45,8 @@ public: ISequentialInStream *inStream, const UInt64 *inStreamSize, const UInt64 *inSizeForReduce, CFolder &folderItem, + CRecordVector<UInt64> &coderUnpackSizes, + UInt64 &unpackSize, ISequentialOutStream *outStream, CRecordVector<UInt64> &packSizes, ICompressProgressInfo *compressProgress); diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zExtract.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zExtract.cpp index d55f38e13..bb350455c 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zExtract.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zExtract.cpp @@ -37,8 +37,8 @@ struct CExtractFolderInfo { if (fileIndex != kNumNoIndex) { - ExtractStatuses.Reserve(1); - ExtractStatuses.Add(true); + ExtractStatuses.ClearAndSetSize(1); + ExtractStatuses[0] = true; } }; }; @@ -51,7 +51,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; UInt64 importantTotalUnpacked = 0; - bool allFilesMode = (numItems == (UInt32)-1); + bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = #ifdef _7Z_VOL @@ -60,17 +60,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, _db.Files.Size(); #endif - if(numItems == 0) + if (numItems == 0) return S_OK; /* - if(_volumes.Size() != 1) + if (_volumes.Size() != 1) return E_FAIL; const CVolume &volume = _volumes.Front(); - const CArchiveDatabaseEx &_db = volume.Database; + const CDbEx &_db = volume.Database; IInStream *_inStream = volume.Stream; */ - + CObjectVector<CExtractFolderInfo> extractFolderInfoVector; for (UInt32 ii = 0; ii < numItems; ii++) { @@ -86,10 +86,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, int volumeIndex = ref.VolumeIndex; const CVolume &volume = _volumes[volumeIndex]; - const CArchiveDatabaseEx &db = volume.Database; + const CDbEx &db = volume.Database; UInt32 fileIndex = ref.ItemIndex; #else - const CArchiveDatabaseEx &db = _db; + const CDbEx &db = _db; UInt32 fileIndex = ref2Index; #endif @@ -115,14 +115,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, volumeIndex, #endif kNumNoIndex, folderIndex)); - const CFolder &folderInfo = db.Folders[folderIndex]; - UInt64 unpackSize = folderInfo.GetUnpackSize(); + UInt64 unpackSize = db.GetFolderUnpackSize(folderIndex); importantTotalUnpacked += unpackSize; extractFolderInfoVector.Back().UnpackSize = unpackSize; } - + CExtractFolderInfo &efi = extractFolderInfoVector.Back(); - + // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex]; CNum startIndex = db.FolderStartFileIndex[folderIndex]; for (CNum index = efi.ExtractStatuses.Size(); @@ -156,7 +155,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, CMyComPtr<ICompressProgressInfo> progress = lps; lps->Init(extractCallback, false); - for (int i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked) + for (unsigned i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked) { lps->OutSize = totalUnpacked; lps->InSize = totalPacked; @@ -164,7 +163,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, if (i >= extractFolderInfoVector.Size()) break; - + const CExtractFolderInfo &efi = extractFolderInfoVector[i]; curUnpacked = efi.UnpackSize; curPacked = 0; @@ -174,9 +173,9 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, #ifdef _7Z_VOL const CVolume &volume = _volumes[efi.VolumeIndex]; - const CArchiveDatabaseEx &db = volume.Database; + const CDbEx &db = volume.Database; #else - const CArchiveDatabaseEx &db = _db; + const CDbEx &db = _db; #endif CNum startIndex; @@ -200,13 +199,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, continue; CNum folderIndex = efi.FolderIndex; - const CFolder &folderInfo = db.Folders[folderIndex]; - curPacked = _db.GetFolderFullPackSize(folderIndex); - CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex]; - UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0); - #ifndef _NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> getTextPassword; if (extractCallback) @@ -216,26 +210,24 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, try { #ifndef _NO_CRYPTO - bool passwordIsDefined; + bool isEncrypted = false; + bool passwordIsDefined = false; #endif HRESULT result = decoder.Decode( EXTERNAL_CODECS_VARS #ifdef _7Z_VOL - volume.Stream, + volume.Stream, #else - _inStream, + _inStream, #endif - folderStartPackPos, - &db.PackSizes[packStreamIndex], - folderInfo, + db.ArcInfo.DataStartPosition, + db, folderIndex, outStream, progress - #ifndef _NO_CRYPTO - , getTextPassword, passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS #if !defined(_7ZIP_ST) && !defined(_SFX) - , true, _numThreads + , true, _numThreads #endif ); @@ -246,7 +238,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, } if (result == E_NOTIMPL) { - RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnsupportedMethod)); continue; } if (result != S_OK) diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.cpp index edd276bc1..3f420a513 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.cpp @@ -106,8 +106,8 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) { *value = 0; - int index2 = (int)subStream; - if (index2 < 0 || subStream > Sizes.Size()) + unsigned index2 = (unsigned)subStream; + if (subStream > Sizes.Size()) return E_FAIL; if (index2 < Sizes.Size()) { diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.h index 6df3672a1..4ed4b2dd2 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.h @@ -47,7 +47,7 @@ public: UInt64 GetFullSize() const { UInt64 size = 0; - for (int i = 0; i < Sizes.Size(); i++) + FOR_VECTOR (i, Sizes) size += Sizes[i]; return size; } diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.cpp index 22c4600ec..847f65bf2 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.cpp @@ -14,7 +14,7 @@ CFolderOutStream::CFolderOutStream() } HRESULT CFolderOutStream::Init( - const CArchiveDatabaseEx *db, + const CDbEx *db, UInt32 ref2Offset, UInt32 startIndex, const CBoolVector *extractStatuses, IArchiveExtractCallback *extractCallback, diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.h index f9bb1af42..cc2d77343 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.h @@ -19,12 +19,12 @@ class CFolderOutStream: { COutStreamWithCRC *_crcStreamSpec; CMyComPtr<ISequentialOutStream> _crcStream; - const CArchiveDatabaseEx *_db; + const CDbEx *_db; const CBoolVector *_extractStatuses; CMyComPtr<IArchiveExtractCallback> _extractCallback; UInt32 _ref2Offset; UInt32 _startIndex; - int _currentIndex; + unsigned _currentIndex; bool _testMode; bool _checkCrc; bool _fileIsOpen; @@ -43,7 +43,7 @@ public: STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); HRESULT Init( - const CArchiveDatabaseEx *db, + const CDbEx *db, UInt32 ref2Offset, UInt32 startIndex, const CBoolVector *extractStatuses, IArchiveExtractCallback *extractCallback, diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.cpp index 4ab7afa87..ed65dc20c 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.cpp @@ -23,26 +23,23 @@ #endif using namespace NWindows; - -extern UString ConvertMethodIdToString(UInt64 id); +using namespace NCOM; namespace NArchive { namespace N7z { CHandler::CHandler() { - _crcSize = 4; - #ifndef _NO_CRYPTO + _isEncrypted = false; _passwordIsDefined = false; #endif #ifdef EXTRACT_ONLY + _crcSize = 4; #ifdef __7Z_SET_PROPERTIES _numThreads = NSystem::GetNumberOfProcessors(); #endif - #else - Init(); #endif } @@ -54,11 +51,12 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) #ifdef _SFX -IMP_IInArchive_ArcProps_NO +IMP_IInArchive_ArcProps_NO_Table -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) { - return E_NOTIMPL; + *numProps = 0; + return S_OK; } STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */, @@ -67,162 +65,502 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */, return E_NOTIMPL; } - #else -STATPROPSTG kArcProps[] = +static const Byte kArcProps[] = { - { NULL, kpidMethod, VT_BSTR}, - { NULL, kpidSolid, VT_BOOL}, - { NULL, kpidNumBlocks, VT_UI4}, - { NULL, kpidPhySize, VT_UI8}, - { NULL, kpidHeadersSize, VT_UI8}, - { NULL, kpidOffset, VT_UI8} + kpidHeadersSize, + kpidMethod, + kpidSolid, + kpidNumBlocks + // , kpidIsTree }; +IMP_IInArchive_ArcProps + +static inline char GetHex(unsigned value) +{ + return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); +} + +static unsigned ConvertMethodIdToString_Back(char *s, UInt64 id) +{ + int len = 0; + do + { + s[--len] = GetHex((unsigned)id & 0xF); id >>= 4; + s[--len] = GetHex((unsigned)id & 0xF); id >>= 4; + } + while (id != 0); + return (unsigned)-len; +} + +static void ConvertMethodIdToString(AString &res, UInt64 id) +{ + const unsigned kLen = 32; + char s[kLen]; + unsigned len = kLen - 1; + s[len] = 0; + res += s + len - ConvertMethodIdToString_Back(s + len, id); +} + +static unsigned GetStringForSizeValue(char *s, UInt32 val) +{ + unsigned i; + for (i = 0; i <= 31; i++) + if (((UInt32)1 << i) == val) + { + if (i < 10) + { + s[0] = (char)('0' + i); + s[1] = 0; + return 1; + } + if (i < 20) { s[0] = '1'; s[1] = (char)('0' + i - 10); } + else if (i < 30) { s[0] = '2'; s[1] = (char)('0' + i - 20); } + else { s[0] = '3'; s[1] = (char)('0' + i - 30); } + s[2] = 0; + return 2; + } + char c = 'b'; + if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } + else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } + ::ConvertUInt32ToString(val, s); + unsigned pos = MyStringLen(s); + s[pos++] = c; + s[pos] = 0; + return pos; +} + +/* +static inline void AddHexToString(UString &res, Byte value) +{ + res += GetHex((Byte)(value >> 4)); + res += GetHex((Byte)(value & 0xF)); +} +*/ + +static char *AddProp32(char *s, const char *name, UInt32 v) +{ + *s++ = ':'; + s = MyStpCpy(s, name); + ::ConvertUInt32ToString(v, s); + return s + MyStringLen(s); +} + +void CHandler::AddMethodName(AString &s, UInt64 id) +{ + UString methodName; + FindMethod(EXTERNAL_CODECS_VARS id, methodName); + if (methodName.IsEmpty()) + { + for (unsigned i = 0; i < methodName.Len(); i++) + if (methodName[i] >= 0x80) + { + methodName.Empty(); + break; + } + } + if (methodName.IsEmpty()) + ConvertMethodIdToString(s, id); + else + for (unsigned i = 0; i < methodName.Len(); i++) + s += (char)methodName[i]; +} + +#endif + STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { + #ifndef _SFX COM_TRY_BEGIN + #endif NCOM::CPropVariant prop; - switch(propID) + switch (propID) { + #ifndef _SFX case kpidMethod: { - UString resString; - CRecordVector<UInt64> ids; - int i; - for (i = 0; i < _db.Folders.Size(); i++) - { - const CFolder &f = _db.Folders[i]; - for (int j = f.Coders.Size() - 1; j >= 0; j--) - ids.AddToUniqueSorted(f.Coders[j].MethodID); - } - - for (i = 0; i < ids.Size(); i++) + AString s; + const CParsedMethods &pm = _db.ParsedMethods; + FOR_VECTOR (i, pm.IDs) { - UInt64 id = ids[i]; - UString methodName; - /* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName); - if (methodName.IsEmpty()) - methodName = ConvertMethodIdToString(id); - if (!resString.IsEmpty()) - resString += L' '; - resString += methodName; + UInt64 id = pm.IDs[i]; + if (!s.IsEmpty()) + s += ' '; + char temp[16]; + if (id == k_LZMA2) + { + s += "LZMA2:"; + if ((pm.Lzma2Prop & 1) == 0) + ConvertUInt32ToString((pm.Lzma2Prop >> 1) + 12, temp); + else + GetStringForSizeValue(temp, 3 << ((pm.Lzma2Prop >> 1) + 11)); + s += temp; + } + else if (id == k_LZMA) + { + s += "LZMA:"; + GetStringForSizeValue(temp, pm.LzmaDic); + s += temp; + } + else + AddMethodName(s, id); } - prop = resString; + prop = s; break; } case kpidSolid: prop = _db.IsSolid(); break; - case kpidNumBlocks: prop = (UInt32)_db.Folders.Size(); break; + case kpidNumBlocks: prop = (UInt32)_db.NumFolders; break; case kpidHeadersSize: prop = _db.HeadersSize; break; case kpidPhySize: prop = _db.PhySize; break; - case kpidOffset: if (_db.ArchiveInfo.StartPosition != 0) prop = _db.ArchiveInfo.StartPosition; break; + case kpidOffset: if (_db.ArcInfo.StartPosition != 0) prop = _db.ArcInfo.StartPosition; break; + /* + case kpidIsTree: if (_db.IsTree) prop = true; break; + case kpidIsAltStream: if (_db.ThereAreAltStreams) prop = true; break; + case kpidIsAux: if (_db.IsTree) prop = true; break; + */ + // case kpidError: if (_db.ThereIsHeaderError) prop = "Header error"; break; + #endif + + case kpidWarningFlags: + { + UInt32 v = 0; + if (_db.StartHeaderWasRecovered) v |= kpv_ErrorFlags_HeadersError; + if (_db.UnsupportedFeatureWarning) v |= kpv_ErrorFlags_UnsupportedFeature; + if (v != 0) + prop = v; + break; + } + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_db.IsArc) v |= kpv_ErrorFlags_IsNotArc; + if (_db.ThereIsHeaderError) v |= kpv_ErrorFlags_HeadersError; + if (_db.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; + // if (_db.UnsupportedVersion) v |= kpv_ErrorFlags_Unsupported; + if (_db.UnsupportedFeatureError) v |= kpv_ErrorFlags_UnsupportedFeature; + prop = v; + break; + } } prop.Detach(value); return S_OK; + #ifndef _SFX COM_TRY_END + #endif } -IMP_IInArchive_ArcProps - -#endif - -static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop) +static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, int index) { UInt64 value; if (v.GetItem(index, value)) + PropVarEm_Set_FileTime64(prop, value); +} + +bool CHandler::IsFolderEncrypted(CNum folderIndex) const +{ + if (folderIndex == kNumNoIndex) + return false; + size_t startPos = _db.FoCodersDataOffset[folderIndex]; + const Byte *p = _db.CodersData + startPos; + size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; + CInByte2 inByte; + inByte.Init(p, size); + + CNum numCoders = inByte.ReadNum(); + for (; numCoders != 0; numCoders--) { - FILETIME ft; - ft.dwLowDateTime = (DWORD)value; - ft.dwHighDateTime = (DWORD)(value >> 32); - prop = ft; + Byte mainByte = inByte.ReadByte(); + unsigned idSize = (mainByte & 0xF); + const Byte *longID = inByte.GetPtr(); + UInt64 id64 = 0; + for (unsigned j = 0; j < idSize; j++) + id64 = ((id64 << 8) | longID[j]); + inByte.SkipDataNoCheck(idSize); + if (id64 == k_AES) + return true; + if ((mainByte & 0x20) != 0) + inByte.SkipDataNoCheck(inByte.ReadNum()); } + return false; } -#ifndef _SFX +STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +{ + *numProps = 0; + return S_OK; +} -static UString ConvertUInt32ToString(UInt32 value) +STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) { - wchar_t buffer[32]; - ConvertUInt64ToString(value, buffer); - return buffer; + *name = NULL; + *propID = kpidNtSecure; + return S_OK; } -static UString GetStringForSizeValue(UInt32 value) +STDMETHODIMP CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType) { - for (int i = 31; i >= 0; i--) - if ((UInt32(1) << i) == value) - return ConvertUInt32ToString(i); - UString result; - if (value % (1 << 20) == 0) - { - result += ConvertUInt32ToString(value >> 20); - result += L"m"; - } - else if (value % (1 << 10) == 0) + /* + const CFileItem &file = _db.Files[index]; + *parentType = (file.IsAltStream ? NParentType::kAltStream : NParentType::kDir); + *parent = (UInt32)(Int32)file.Parent; + */ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; + return S_OK; +} + +STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (/* _db.IsTree && propID == kpidName || + !_db.IsTree && */ propID == kpidPath) { - result += ConvertUInt32ToString(value >> 10); - result += L"k"; + if (_db.NameOffsets && _db.NamesBuf) + { + size_t offset = _db.NameOffsets[index]; + size_t size = (_db.NameOffsets[index + 1] - offset) * 2; + if (size < ((UInt32)1 << 31)) + { + *data = (const void *)(_db.NamesBuf + offset * 2); + *dataSize = (UInt32)size; + *propType = NPropDataType::kUtf16z; + } + } + return S_OK; } - else + /* + if (propID == kpidNtSecure) { - result += ConvertUInt32ToString(value); - result += L"b"; + if (index < (UInt32)_db.SecureIDs.Size()) + { + int id = _db.SecureIDs[index]; + size_t offs = _db.SecureOffsets[id]; + size_t size = _db.SecureOffsets[id + 1] - offs; + if (size >= 0) + { + *data = _db.SecureBuf + offs; + *dataSize = (UInt32)size; + *propType = NPropDataType::kRaw; + } + } } - return result; + */ + return S_OK; } -static const UInt64 k_Copy = 0x0; -static const UInt64 k_Delta = 3; -static const UInt64 k_LZMA2 = 0x21; -static const UInt64 k_LZMA = 0x030101; -static const UInt64 k_PPMD = 0x030401; +#ifndef _SFX -static wchar_t GetHex(Byte value) -{ - return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10))); -} -static inline void AddHexToString(UString &res, Byte value) +HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const { - res += GetHex((Byte)(value >> 4)); - res += GetHex((Byte)(value & 0xF)); + PropVariant_Clear(prop); + if (folderIndex == kNumNoIndex) + return S_OK; + // for (int ttt = 0; ttt < 1; ttt++) { + const unsigned kTempSize = 256; + char temp[kTempSize]; + unsigned pos = kTempSize; + temp[--pos] = 0; + + size_t startPos = _db.FoCodersDataOffset[folderIndex]; + const Byte *p = _db.CodersData + startPos; + size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; + CInByte2 inByte; + inByte.Init(p, size); + + // numCoders == 0 ??? + CNum numCoders = inByte.ReadNum(); + bool needSpace = false; + for (; numCoders != 0; numCoders--, needSpace = true) + { + if (pos < 32) // max size of property + break; + Byte mainByte = inByte.ReadByte(); + unsigned idSize = (mainByte & 0xF); + const Byte *longID = inByte.GetPtr(); + UInt64 id64 = 0; + for (unsigned j = 0; j < idSize; j++) + id64 = ((id64 << 8) | longID[j]); + inByte.SkipDataNoCheck(idSize); + + if ((mainByte & 0x10) != 0) + { + inByte.ReadNum(); // NumInStreams + inByte.ReadNum(); // NumOutStreams + } + + CNum propsSize = 0; + const Byte *props = NULL; + if ((mainByte & 0x20) != 0) + { + propsSize = inByte.ReadNum(); + props = inByte.GetPtr(); + inByte.SkipDataNoCheck(propsSize); + } + + const char *name = NULL; + char s[32]; + s[0] = 0; + + if (id64 <= (UInt32)0xFFFFFFFF) + { + UInt32 id = (UInt32)id64; + if (id == k_LZMA) + { + name = "LZMA"; + if (propsSize == 5) + { + UInt32 dicSize = GetUi32((const Byte *)props + 1); + char *dest = s + GetStringForSizeValue(s, dicSize); + UInt32 d = props[0]; + if (d != 0x5D) + { + UInt32 lc = d % 9; + d /= 9; + UInt32 pb = d / 5; + UInt32 lp = d % 5; + if (lc != 3) dest = AddProp32(dest, "lc", lc); + if (lp != 0) dest = AddProp32(dest, "lp", lp); + if (pb != 2) dest = AddProp32(dest, "pb", pb); + } + } + } + else if (id == k_LZMA2) + { + name = "LZMA2"; + if (propsSize == 1) + { + Byte p = props[0]; + if ((p & 1) == 0) + ConvertUInt32ToString((UInt32)((p >> 1) + 12), s); + else + GetStringForSizeValue(s, 3 << ((p >> 1) + 11)); + } + } + else if (id == k_PPMD) + { + name = "PPMD"; + if (propsSize == 5) + { + Byte order = *props; + char *dest = s; + *dest++ = 'o'; + ConvertUInt32ToString(order, dest); + dest += MyStringLen(dest); + dest = MyStpCpy(dest, ":mem"); + GetStringForSizeValue(dest, GetUi32(props + 1)); + } + } + else if (id == k_Delta) + { + name = "Delta"; + if (propsSize == 1) + ConvertUInt32ToString((UInt32)props[0] + 1, s); + } + else if (id == k_BCJ2) name = "BCJ2"; + else if (id == k_BCJ) name = "BCJ"; + else if (id == k_AES) + { + name = "7zAES"; + if (propsSize >= 1) + { + Byte firstByte = props[0]; + UInt32 numCyclesPower = firstByte & 0x3F; + ConvertUInt32ToString(numCyclesPower, s); + } + } + } + + if (name) + { + unsigned nameLen = MyStringLen(name); + unsigned propsLen = MyStringLen(s); + unsigned totalLen = nameLen + propsLen; + if (propsLen != 0) + totalLen++; + if (needSpace) + totalLen++; + if (totalLen + 5 >= pos) + break; + pos -= totalLen; + MyStringCopy(temp + pos, name); + if (propsLen != 0) + { + char *dest = temp + pos + nameLen; + *dest++ = ':'; + MyStringCopy(dest, s); + } + if (needSpace) + temp[pos + totalLen - 1] = ' '; + } + else + { + UString methodName; + FindMethod(EXTERNAL_CODECS_VARS id64, methodName); + if (methodName.IsEmpty()) + { + for (unsigned j = 0; j < methodName.Len(); j++) + if (methodName[j] >= 0x80) + { + methodName.Empty(); + break; + } + } + if (needSpace) + temp[--pos] = ' '; + if (methodName.IsEmpty()) + pos -= ConvertMethodIdToString_Back(temp + pos, id64); + else + { + unsigned len = methodName.Len(); + if (len + 5 > pos) + break; + pos -= len; + for (unsigned i = 0; i < len; i++) + temp[pos + i] = (char)methodName[i]; + } + } + } + if (numCoders != 0 && pos >= 4) + { + temp[--pos] = ' '; + temp[--pos] = '.'; + temp[--pos] = '.'; + temp[--pos] = '.'; + } + return PropVarEm_Set_Str(prop, temp + pos); + // } } #endif -bool CHandler::IsEncrypted(UInt32 index2) const +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; - if (folderIndex != kNumNoIndex) - return _db.Folders[folderIndex].IsEncrypted(); - return false; -} + PropVariant_Clear(value); + // COM_TRY_BEGIN + // NCOM::CPropVariant prop; -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - /* const CRef2 &ref2 = _refs[index]; if (ref2.Refs.IsEmpty()) return E_FAIL; const CRef &ref = ref2.Refs.Front(); */ - + const CFileItem &item = _db.Files[index]; UInt32 index2 = index; switch(propID) { - case kpidPath: - if (!item.Name.IsEmpty()) - prop = NItemName::GetOSName(item.Name); - break; - case kpidIsDir: prop = item.IsDir; break; + case kpidIsDir: PropVarEm_Set_Bool(value, item.IsDir); break; case kpidSize: { - prop = item.Size; + PropVarEm_Set_UInt64(value, item.Size); // prop = ref2.Size; break; } @@ -234,122 +572,49 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va if (folderIndex != kNumNoIndex) { if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2) - prop = _db.GetFolderFullPackSize(folderIndex); + PropVarEm_Set_UInt64(value, _db.GetFolderFullPackSize(folderIndex)); /* else - prop = (UInt64)0; + PropVarEm_Set_UInt64(value, 0); */ } else - prop = (UInt64)0; + PropVarEm_Set_UInt64(value, 0); } break; } - case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; } - case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break; - case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break; - case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break; - case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break; - case kpidCRC: if (item.CrcDefined) prop = item.Crc; break; - case kpidEncrypted: prop = IsEncrypted(index2); break; - case kpidIsAnti: prop = _db.IsItemAnti(index2); break; - #ifndef _SFX - case kpidMethod: + // case kpidIsAux: prop = _db.IsItemAux(index2); break; + case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) PropVarEm_Set_UInt64(value, v); break; } + case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break; + case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break; + case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break; + case kpidAttrib: if (item.AttribDefined) PropVarEm_Set_UInt32(value, item.Attrib); break; + case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break; + case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break; + case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break; + /* + case kpidIsAltStream: prop = item.IsAltStream; break; + case kpidNtSecure: { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; - if (folderIndex != kNumNoIndex) + int id = _db.SecureIDs[index]; + size_t offs = _db.SecureOffsets[id]; + size_t size = _db.SecureOffsets[id + 1] - offs; + if (size >= 0) { - const CFolder &folderInfo = _db.Folders[folderIndex]; - UString methodsString; - for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--) - { - const CCoderInfo &coder = folderInfo.Coders[i]; - if (!methodsString.IsEmpty()) - methodsString += L' '; - - UString methodName, propsString; - bool methodIsKnown = FindMethod( - EXTERNAL_CODECS_VARS - coder.MethodID, methodName); - - if (!methodIsKnown) - methodsString += ConvertMethodIdToString(coder.MethodID); - else - { - methodsString += methodName; - if (coder.MethodID == k_Delta && coder.Props.GetCapacity() == 1) - propsString = ConvertUInt32ToString((UInt32)coder.Props[0] + 1); - else if (coder.MethodID == k_LZMA && coder.Props.GetCapacity() == 5) - { - UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1); - propsString = GetStringForSizeValue(dicSize); - } - else if (coder.MethodID == k_LZMA2 && coder.Props.GetCapacity() == 1) - { - Byte p = coder.Props[0]; - UInt32 dicSize = (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)); - propsString = GetStringForSizeValue(dicSize); - } - else if (coder.MethodID == k_PPMD && coder.Props.GetCapacity() == 5) - { - Byte order = *(const Byte *)coder.Props; - propsString = L'o'; - propsString += ConvertUInt32ToString(order); - propsString += L":mem"; - UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1); - propsString += GetStringForSizeValue(dicSize); - } - else if (coder.MethodID == k_AES && coder.Props.GetCapacity() >= 1) - { - const Byte *data = (const Byte *)coder.Props; - Byte firstByte = *data++; - UInt32 numCyclesPower = firstByte & 0x3F; - propsString = ConvertUInt32ToString(numCyclesPower); - /* - if ((firstByte & 0xC0) != 0) - { - UInt32 saltSize = (firstByte >> 7) & 1; - UInt32 ivSize = (firstByte >> 6) & 1; - if (coder.Props.GetCapacity() >= 2) - { - Byte secondByte = *data++; - saltSize += (secondByte >> 4); - ivSize += (secondByte & 0x0F); - } - } - */ - } - } - if (!propsString.IsEmpty()) - { - methodsString += L':'; - methodsString += propsString; - } - else if (coder.Props.GetCapacity() > 0) - { - methodsString += L":["; - for (size_t bi = 0; bi < coder.Props.GetCapacity(); bi++) - { - if (bi > 5 && bi + 1 < coder.Props.GetCapacity()) - { - methodsString += L".."; - break; - } - else - AddHexToString(methodsString, coder.Props[bi]); - } - methodsString += L']'; - } - } - prop = methodsString; + prop.SetBlob(_db.SecureBuf + offs, (ULONG)size); } + break; } - break; + */ + + case kpidPath: return _db.GetPath_Prop(index, value); + #ifndef _SFX + case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value); case kpidBlock: { CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) - prop = (UInt32)folderIndex; + PropVarEm_Set_UInt32(value, (UInt32)folderIndex); } break; case kpidPackedSize0: @@ -358,6 +623,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va case kpidPackedSize3: case kpidPackedSize4: { + /* CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) { @@ -372,13 +638,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va } else prop = (UInt64)0; + */ } break; #endif } - prop.Detach(value); + // prop.Detach(value); return S_OK; - COM_TRY_END + // COM_TRY_END } STDMETHODIMP CHandler::Open(IInStream *stream, @@ -390,6 +657,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, #ifndef _SFX _fileInfoPopIDs.Clear(); #endif + try { CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback; @@ -397,31 +665,30 @@ STDMETHODIMP CHandler::Open(IInStream *stream, #ifndef _NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> getTextPassword; if (openArchiveCallback) - { - openArchiveCallbackTemp.QueryInterface( - IID_ICryptoGetTextPassword, &getTextPassword); - } + openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); #endif + CInArchive archive; + _db.IsArc = false; RINOK(archive.Open(stream, maxCheckStartPosition)); - #ifndef _NO_CRYPTO - _passwordIsDefined = false; - UString password; - #endif + _db.IsArc = true; + HRESULT result = archive.ReadDatabase( - EXTERNAL_CODECS_VARS - _db - #ifndef _NO_CRYPTO - , getTextPassword, _passwordIsDefined - #endif - ); + EXTERNAL_CODECS_VARS + _db + #ifndef _NO_CRYPTO + , getTextPassword, _isEncrypted, _passwordIsDefined + #endif + ); RINOK(result); - _db.Fill(); + _inStream = stream; } catch(...) { Close(); + // return E_INVALIDARG; + // we must return out_of_memory here return S_FALSE; } // _inStream = stream; @@ -437,6 +704,10 @@ STDMETHODIMP CHandler::Close() COM_TRY_BEGIN _inStream.Release(); _db.Clear(); + #ifndef _NO_CRYPTO + _isEncrypted = false; + _passwordIsDefined = false; + #endif return S_OK; COM_TRY_END } @@ -444,16 +715,16 @@ STDMETHODIMP CHandler::Close() #ifdef __7Z_SET_PROPERTIES #ifdef EXTRACT_ONLY -STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps) { COM_TRY_BEGIN const UInt32 numProcessors = NSystem::GetNumberOfProcessors(); _numThreads = numProcessors; - for (int i = 0; i < numProperties; i++) + for (UInt32 i = 0; i < numProps; i++) { UString name = names[i]; - name.MakeUpper(); + name.MakeLower_Ascii(); if (name.IsEmpty()) return E_INVALIDARG; const PROPVARIANT &value = values[i]; @@ -461,9 +732,9 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v int index = ParseStringToUInt32(name, number); if (index == 0) { - if(name.Left(2).CompareNoCase(L"MT") == 0) + if (name.IsPrefixedBy(L"mt")) { - RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads)); + RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads)); continue; } else diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.h index 56062d464..677a3e10a 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.h @@ -18,6 +18,16 @@ namespace NArchive { namespace N7z { +const UInt32 k_Copy = 0x0; +const UInt32 k_Delta = 3; +const UInt32 k_LZMA2 = 0x21; +const UInt32 k_LZMA = 0x030101; +const UInt32 k_PPMD = 0x030401; +const UInt32 k_BCJ = 0x03030103; +const UInt32 k_BCJ2 = 0x0303011B; +const UInt32 k_Deflate = 0x040108; +const UInt32 k_BZip2 = 0x040202; + #ifndef __7Z_SET_PROPERTIES #ifdef EXTRACT_ONLY @@ -31,11 +41,53 @@ namespace N7z { #endif +#ifndef EXTRACT_ONLY + +class COutHandler: public CMultiMethodProps +{ + HRESULT SetSolidFromString(const UString &s); + HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value); +public: + bool _removeSfxBlock; + + UInt64 _numSolidFiles; + UInt64 _numSolidBytes; + bool _numSolidBytesDefined; + bool _solidExtension; + + bool _compressHeaders; + bool _encryptHeadersSpecified; + bool _encryptHeaders; + // bool _useParents; 9.26 + + CBoolPair Write_CTime; + CBoolPair Write_ATime; + CBoolPair Write_MTime; + + bool _volumeMode; + + void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); } + void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); } + void InitSolid() + { + InitSolidFiles(); + InitSolidSize(); + _solidExtension = false; + _numSolidBytesDefined = false; + } + + void InitProps(); + + COutHandler() { InitProps(); } + + HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); +}; + +#endif + class CHandler: - #ifndef EXTRACT_ONLY - public NArchive::COutHandler, - #endif public IInArchive, + public IArchiveGetRawProps, #ifdef __7Z_SET_PROPERTIES public ISetProperties, #endif @@ -44,9 +96,13 @@ class CHandler: #endif PUBLIC_ISetCompressCodecsInfo public CMyUnknownImp + #ifndef EXTRACT_ONLY + , public COutHandler + #endif { public: MY_QUERYINTERFACE_BEGIN2(IInArchive) + MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) #ifdef __7Z_SET_PROPERTIES MY_QUERYINTERFACE_ENTRY(ISetProperties) #endif @@ -58,9 +114,10 @@ public: MY_ADDREF_RELEASE INTERFACE_IInArchive(;) + INTERFACE_IArchiveGetRawProps(;) #ifdef __7Z_SET_PROPERTIES - STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps); #endif #ifndef EXTRACT_ONLY @@ -73,13 +130,14 @@ public: private: CMyComPtr<IInStream> _inStream; - NArchive::N7z::CArchiveDatabaseEx _db; + NArchive::N7z::CDbEx _db; #ifndef _NO_CRYPTO + bool _isEncrypted; bool _passwordIsDefined; #endif #ifdef EXTRACT_ONLY - + #ifdef __7Z_SET_PROPERTIES UInt32 _numThreads; #endif @@ -87,27 +145,29 @@ private: UInt32 _crcSize; #else - + CRecordVector<CBind> _binds; - HRESULT SetCompressionMethod(CCompressionMethodMode &method, + HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m); + HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod); + void AddDefaultMethod(); + HRESULT SetMainMethod(CCompressionMethodMode &method, CObjectVector<COneMethodInfo> &methodsInfo #ifndef _7ZIP_ST , UInt32 numThreads #endif ); - HRESULT SetCompressionMethod( - CCompressionMethodMode &method, - CCompressionMethodMode &headerMethod); #endif - bool IsEncrypted(UInt32 index2) const; + bool IsFolderEncrypted(CNum folderIndex) const; #ifndef _SFX CRecordVector<UInt64> _fileInfoPopIDs; void FillPopIDs(); + void AddMethodName(AString &s, UInt64 id); + HRESULT SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const; #endif diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandlerOut.cpp index a8ccab6df..7de5b8140 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandlerOut.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandlerOut.cpp @@ -2,12 +2,9 @@ #include "StdAfx.h" -#include "../../../Windows/PropVariant.h" - #include "../../../Common/ComTry.h" #include "../../../Common/StringToInt.h" - -#include "../../ICoder.h" +#include "../../../Common/Wildcard.h" #include "../Common/ItemNameUtils.h" #include "../Common/ParseProperties.h" @@ -21,24 +18,19 @@ using namespace NWindows; namespace NArchive { namespace N7z { -static const wchar_t *kLZMAMethodName = L"LZMA"; -static const wchar_t *kCopyMethod = L"Copy"; -static const wchar_t *kDefaultMethodName = kLZMAMethodName; +static const wchar_t *k_LZMA_Name = L"LZMA"; +static const wchar_t *kDefaultMethodName = L"LZMA2"; +static const wchar_t *k_Copy_Name = L"Copy"; -static const UInt32 kLzmaAlgorithmX5 = 1; -static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2"; -static const UInt32 kDictionaryForHeaders = +static const wchar_t *k_MatchFinder_ForHeaders = L"BT2"; +static const UInt32 k_NumFastBytes_ForHeaders = 273; +static const UInt32 k_Level_ForHeaders = 5; +static const UInt32 k_Dictionary_ForHeaders = #ifdef UNDER_CE - 1 << 18 + 1 << 18; #else - 1 << 20 + 1 << 20; #endif -; -static const UInt32 kNumFastBytesForHeaders = 273; -static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5; - -static inline bool IsCopyMethod(const UString &methodName) - { return (methodName.CompareNoCase(kCopyMethod) == 0); } STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) { @@ -46,132 +38,112 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) return S_OK; } -HRESULT CHandler::SetCompressionMethod( - CCompressionMethodMode &methodMode, - CCompressionMethodMode &headerMethod) +HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m) { - HRESULT res = SetCompressionMethod(methodMode, _methods - #ifndef _7ZIP_ST - , _numThreads - #endif - ); - RINOK(res); - methodMode.Binds = _binds; + if (!FindMethod( + EXTERNAL_CODECS_VARS + m.MethodName, dest.Id, dest.NumInStreams, dest.NumOutStreams)) + return E_INVALIDARG; + (CProps &)dest = (CProps &)m; + return S_OK; +} - if (_compressHeaders) - { - // headerMethod.Methods.Add(methodMode.Methods.Back()); +HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod) +{ + if (!_compressHeaders) + return S_OK; + COneMethodInfo m; + m.MethodName = k_LZMA_Name; + m.AddPropString(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders); + m.AddProp32(NCoderPropID::kLevel, k_Level_ForHeaders); + m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders); + m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders); + m.AddNumThreadsProp(1); + + CMethodFull methodFull; + RINOK(PropsMethod_To_FullMethod(methodFull, m)); + headerMethod.Methods.Add(methodFull); + return S_OK; +} - CObjectVector<COneMethodInfo> headerMethodInfoVector; - COneMethodInfo oneMethodInfo; - oneMethodInfo.MethodName = kLZMAMethodName; - { - CProp prop; - prop.Id = NCoderPropID::kMatchFinder; - prop.Value = kLzmaMatchFinderForHeaders; - oneMethodInfo.Props.Add(prop); - } - { - CProp prop; - prop.Id = NCoderPropID::kAlgorithm; - prop.Value = kAlgorithmForHeaders; - oneMethodInfo.Props.Add(prop); - } - { - CProp prop; - prop.Id = NCoderPropID::kNumFastBytes; - prop.Value = (UInt32)kNumFastBytesForHeaders; - oneMethodInfo.Props.Add(prop); - } - { - CProp prop; - prop.Id = NCoderPropID::kDictionarySize; - prop.Value = (UInt32)kDictionaryForHeaders; - oneMethodInfo.Props.Add(prop); - } - headerMethodInfoVector.Add(oneMethodInfo); - HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector - #ifndef _7ZIP_ST - , 1 - #endif - ); - RINOK(res); +void CHandler::AddDefaultMethod() +{ + FOR_VECTOR (i, _methods) + { + UString &methodName = _methods[i].MethodName; + if (methodName.IsEmpty()) + methodName = kDefaultMethodName; + } + if (_methods.IsEmpty()) + { + COneMethodInfo m; + m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName); + _methods.Add(m); } - return S_OK; } -HRESULT CHandler::SetCompressionMethod( +HRESULT CHandler::SetMainMethod( CCompressionMethodMode &methodMode, - CObjectVector<COneMethodInfo> &methodsInfo + CObjectVector<COneMethodInfo> &methods #ifndef _7ZIP_ST , UInt32 numThreads #endif ) { - UInt32 level = _level; - - if (methodsInfo.IsEmpty()) - { - COneMethodInfo oneMethodInfo; - oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName); - methodsInfo.Add(oneMethodInfo); - } + AddDefaultMethod(); + + const UInt64 kSolidBytes_Min = (1 << 24); + const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1; bool needSolid = false; - for(int i = 0; i < methodsInfo.Size(); i++) + FOR_VECTOR (i, methods) { - COneMethodInfo &oneMethodInfo = methodsInfo[i]; - SetCompressionMethod2(oneMethodInfo + COneMethodInfo &oneMethodInfo = methods[i]; + SetGlobalLevelAndThreads(oneMethodInfo #ifndef _7ZIP_ST , numThreads #endif ); - if (!IsCopyMethod(oneMethodInfo.MethodName)) - needSolid = true; - CMethodFull methodFull; - - if (!FindMethod( - EXTERNAL_CODECS_VARS - oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams)) - return E_INVALIDARG; - methodFull.Props = oneMethodInfo.Props; + RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo)); methodMode.Methods.Add(methodFull); - if (!_numSolidBytesDefined) + if (methodFull.Id != k_Copy) + needSolid = true; + + if (_numSolidBytesDefined) + continue; + + UInt32 dicSize; + switch (methodFull.Id) { - for (int j = 0; j < methodFull.Props.Size(); j++) - { - const CProp &prop = methodFull.Props[j]; - if ((prop.Id == NCoderPropID::kDictionarySize || - prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4) - { - _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7; - const UInt64 kMinSize = (1 << 24); - if (_numSolidBytes < kMinSize) - _numSolidBytes = kMinSize; - _numSolidBytesDefined = true; - break; - } - } + case k_LZMA: + case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break; + case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break; + case k_Deflate: dicSize = (UInt32)1 << 15; break; + case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break; + default: continue; } - } - - if (!needSolid && !_numSolidBytesDefined) - { + _numSolidBytes = (UInt64)dicSize << 7; + if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min; + if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max; _numSolidBytesDefined = true; - _numSolidBytes = 0; } + + if (!_numSolidBytesDefined) + if (needSolid) + _numSolidBytes = kSolidBytes_Max; + else + _numSolidBytes = 0; + _numSolidBytesDefined = true; return S_OK; } -static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool writeTime, PROPID propID, UInt64 &ft, bool &ftDefined) +static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined) { - ft = 0; - ftDefined = false; - if (!writeTime) - return S_OK; + // ft = 0; + // ftDefined = false; NCOM::CPropVariant prop; RINOK(updateCallback->GetProperty(index, propID, &prop)); if (prop.vt == VT_FILETIME) @@ -181,15 +153,87 @@ static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool w } else if (prop.vt != VT_EMPTY) return E_INVALIDARG; + else + { + ft = 0; + ftDefined = false; + } return S_OK; } +/* + +#ifdef _WIN32 +static const wchar_t kDirDelimiter1 = L'\\'; +#endif +static const wchar_t kDirDelimiter2 = L'/'; + +static inline bool IsCharDirLimiter(wchar_t c) +{ + return ( + #ifdef _WIN32 + c == kDirDelimiter1 || + #endif + c == kDirDelimiter2); +} + +static int FillSortIndex(CObjectVector<CTreeFolder> &treeFolders, int cur, int curSortIndex) +{ + CTreeFolder &tf = treeFolders[cur]; + tf.SortIndex = curSortIndex++; + for (int i = 0; i < tf.SubFolders.Size(); i++) + curSortIndex = FillSortIndex(treeFolders, tf.SubFolders[i], curSortIndex); + tf.SortIndexEnd = curSortIndex; + return curSortIndex; +} + +static int FindSubFolder(const CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name, int &insertPos) +{ + const CIntVector &subFolders = treeFolders[cur].SubFolders; + int left = 0, right = subFolders.Size(); + insertPos = -1; + for (;;) + { + if (left == right) + { + insertPos = left; + return -1; + } + int mid = (left + right) / 2; + int midFolder = subFolders[mid]; + int compare = CompareFileNames(name, treeFolders[midFolder].Name); + if (compare == 0) + return midFolder; + if (compare < 0) + right = mid; + else + left = mid + 1; + } +} + +static int AddFolder(CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name) +{ + int insertPos; + int folderIndex = FindSubFolder(treeFolders, cur, name, insertPos); + if (folderIndex < 0) + { + folderIndex = treeFolders.Size(); + CTreeFolder &newFolder = treeFolders.AddNew(); + newFolder.Parent = cur; + newFolder.Name = name; + treeFolders[cur].SubFolders.Insert(insertPos, folderIndex); + } + // else if (treeFolders[folderIndex].IsAltStreamFolder != isAltStreamFolder) throw 1123234234; + return folderIndex; +} +*/ + STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) { COM_TRY_BEGIN - const CArchiveDatabaseEx *db = 0; + const CDbEx *db = 0; #ifdef _7Z_VOL if (_volumes.Size() > 1) return E_FAIL; @@ -204,8 +248,35 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt db = &_db; #endif + /* + CMyComPtr<IArchiveGetRawProps> getRawProps; + updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps); + + CUniqBlocks secureBlocks; + secureBlocks.AddUniq(NULL, 0); + + CObjectVector<CTreeFolder> treeFolders; + { + CTreeFolder folder; + folder.Parent = -1; + treeFolders.Add(folder); + } + */ + CObjectVector<CUpdateItem> updateItems; - + + bool need_CTime = (Write_CTime.Def && Write_CTime.Val); + bool need_ATime = (Write_ATime.Def && Write_ATime.Val); + bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def); + if (db) + { + if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty(); + if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty(); + if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty(); + } + + UString s; + for (UInt32 i = 0; i < numItems; i++) { Int32 newData, newProps; @@ -221,24 +292,32 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt ui.IsAnti = false; ui.Size = 0; + UString name; + // bool isAltStream = false; if (ui.IndexInArchive != -1) { - if (db == 0 || ui.IndexInArchive >= db->Files.Size()) + if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size()) return E_INVALIDARG; const CFileItem &fi = db->Files[ui.IndexInArchive]; - ui.Name = fi.Name; + if (!ui.NewProps) + { + _db.GetPath(ui.IndexInArchive, name); + } ui.IsDir = fi.IsDir; ui.Size = fi.Size; + // isAltStream = fi.IsAltStream; ui.IsAnti = db->IsItemAnti(ui.IndexInArchive); - - ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime); - ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime); - ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime); + + if (!ui.NewProps) + { + ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime); + ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime); + ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime); + } } if (ui.NewProps) { - bool nameIsDefined; bool folderStatusIsDefined; { NCOM::CPropVariant prop; @@ -253,23 +332,37 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt ui.AttribDefined = true; } } - + // we need MTime to sort files. - RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTimeDefined)); - RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATimeDefined)); - RINOK(GetTime(updateCallback, i, true, kpidMTime, ui.MTime, ui.MTimeDefined)); + if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined)); + if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined)); + if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined)); + + /* + if (getRawProps) + { + const void *data; + UInt32 dataSize; + UInt32 propType; + + getRawProps->GetRawProp(i, kpidNtSecure, &data, &dataSize, &propType); + if (dataSize != 0 && propType != NPropDataType::kRaw) + return E_FAIL; + ui.SecureIndex = secureBlocks.AddUniq((const Byte *)data, dataSize); + } + */ { NCOM::CPropVariant prop; RINOK(updateCallback->GetProperty(i, kpidPath, &prop)); if (prop.vt == VT_EMPTY) - nameIsDefined = false; + { + } else if (prop.vt != VT_BSTR) return E_INVALIDARG; else { - ui.Name = NItemName::MakeLegalName(prop.bstrVal); - nameIsDefined = true; + name = NItemName::MakeLegalName(prop.bstrVal); } } { @@ -297,6 +390,19 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt ui.IsAnti = (prop.boolVal != VARIANT_FALSE); } + /* + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidIsAltStream, &prop)); + if (prop.vt == VT_EMPTY) + isAltStream = false; + else if (prop.vt != VT_BOOL) + return E_INVALIDARG; + else + isAltStream = (prop.boolVal != VARIANT_FALSE); + } + */ + if (ui.IsAnti) { ui.AttribDefined = false; @@ -304,13 +410,87 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt ui.CTimeDefined = false; ui.ATimeDefined = false; ui.MTimeDefined = false; - + ui.Size = 0; } if (!folderStatusIsDefined && ui.AttribDefined) ui.SetDirStatusFromAttrib(); } + else + { + /* + if (_db.SecureIDs.IsEmpty()) + ui.SecureIndex = secureBlocks.AddUniq(NULL, 0); + else + { + int id = _db.SecureIDs[ui.IndexInArchive]; + size_t offs = _db.SecureOffsets[id]; + size_t size = _db.SecureOffsets[id + 1] - offs; + ui.SecureIndex = secureBlocks.AddUniq(_db.SecureBuf + offs, size); + } + */ + } + + /* + { + int folderIndex = 0; + if (_useParents) + { + int j; + s.Empty(); + for (j = 0; j < name.Len(); j++) + { + wchar_t c = name[j]; + if (IsCharDirLimiter(c)) + { + folderIndex = AddFolder(treeFolders, folderIndex, s); + s.Empty(); + continue; + } + s += c; + } + if (isAltStream) + { + int colonPos = s.Find(':'); + if (colonPos < 0) + { + // isAltStream = false; + return E_INVALIDARG; + } + UString mainName = s.Left(colonPos); + int newFolderIndex = AddFolder(treeFolders, folderIndex, mainName); + if (treeFolders[newFolderIndex].UpdateItemIndex < 0) + { + for (int j = updateItems.Size() - 1; j >= 0; j--) + { + CUpdateItem &ui2 = updateItems[j]; + if (ui2.ParentFolderIndex == folderIndex + && ui2.Name == mainName) + { + ui2.TreeFolderIndex = newFolderIndex; + treeFolders[newFolderIndex].UpdateItemIndex = j; + } + } + } + folderIndex = newFolderIndex; + s.Delete(0, colonPos + 1); + } + ui.Name = s; + } + else + ui.Name = name; + ui.IsAltStream = isAltStream; + ui.ParentFolderIndex = folderIndex; + ui.TreeFolderIndex = -1; + if (ui.IsDir && !s.IsEmpty()) + { + ui.TreeFolderIndex = AddFolder(treeFolders, folderIndex, s); + treeFolders[ui.TreeFolderIndex].UpdateItemIndex = updateItems.Size(); + } + } + */ + ui.Name = name; if (ui.NewData) { @@ -325,8 +505,27 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt updateItems.Add(ui); } + /* + FillSortIndex(treeFolders, 0, 0); + for (i = 0; i < (UInt32)updateItems.Size(); i++) + { + CUpdateItem &ui = updateItems[i]; + ui.ParentSortIndex = treeFolders[ui.ParentFolderIndex].SortIndex; + ui.ParentSortIndexEnd = treeFolders[ui.ParentFolderIndex].SortIndexEnd; + } + */ + CCompressionMethodMode methodMode, headerMethod; - RINOK(SetCompressionMethod(methodMode, headerMethod)); + + HRESULT res = SetMainMethod(methodMode, _methods + #ifndef _7ZIP_ST + , _numThreads + #endif + ); + RINOK(res); + methodMode.Binds = _binds; + + RINOK(SetHeaderMethod(headerMethod)); #ifndef _7ZIP_ST methodMode.NumThreads = _numThreads; headerMethod.NumThreads = 1; @@ -335,17 +534,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt CMyComPtr<ICryptoGetTextPassword2> getPassword2; updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2); + methodMode.PasswordIsDefined = false; + methodMode.Password.Empty(); if (getPassword2) { CMyComBSTR password; Int32 passwordIsDefined; RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password)); methodMode.PasswordIsDefined = IntToBool(passwordIsDefined); - if (methodMode.PasswordIsDefined) + if (methodMode.PasswordIsDefined && (BSTR)password) methodMode.Password = password; } - else - methodMode.PasswordIsDefined = false; bool compressMainHeader = _compressHeaders; // check it @@ -373,14 +572,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt CUpdateOptions options; options.Method = &methodMode; options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0; - options.UseFilters = _level != 0 && _autoFilter; - options.MaxFilter = _level >= 8; + int level = GetLevel(); + options.UseFilters = level != 0 && _autoFilter; + options.MaxFilter = level >= 8; options.HeaderOptions.CompressMainHeader = compressMainHeader; - options.HeaderOptions.WriteCTime = WriteCTime; - options.HeaderOptions.WriteATime = WriteATime; - options.HeaderOptions.WriteMTime = WriteMTime; - + /* + options.HeaderOptions.WriteCTime = Write_CTime; + options.HeaderOptions.WriteATime = Write_ATime; + options.HeaderOptions.WriteMTime = Write_MTime; + */ + options.NumSolidFiles = _numSolidFiles; options.NumSolidBytes = _numSolidBytes; options.SolidExtension = _solidExtension; @@ -388,12 +590,24 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt options.VolumeMode = _volumeMode; COutArchive archive; - CArchiveDatabase newDatabase; + CArchiveDatabaseOut newDatabase; CMyComPtr<ICryptoGetTextPassword> getPassword; updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword); - - HRESULT res = Update( + + /* + if (secureBlocks.Sorted.Size() > 1) + { + secureBlocks.GetReverseMap(); + for (int i = 0; i < updateItems.Size(); i++) + { + int &secureIndex = updateItems[i].SecureIndex; + secureIndex = secureBlocks.BufIndexToSortedIndex[secureIndex]; + } + } + */ + + res = Update( EXTERNAL_CODECS_VARS #ifdef _7Z_VOL volume ? volume->Stream: 0, @@ -403,6 +617,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt db, #endif updateItems, + // treeFolders, + // secureBlocks, archive, newDatabase, outStream, updateCallback, options #ifndef _NO_CRYPTO , getPassword @@ -426,7 +642,7 @@ static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream if (index == 0) return E_INVALIDARG; srcString.Delete(0, index); - if (srcString[0] == 'S') + if (srcString[0] == 's') { srcString.Delete(0); int index = ParseStringToUInt32(srcString, stream); @@ -437,38 +653,173 @@ static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream return S_OK; } -static HRESULT GetBindInfo(UString &srcString, CBind &bind) +void COutHandler::InitProps() { - RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream)); - if (srcString[0] != ':') - return E_INVALIDARG; - srcString.Delete(0); - RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream)); - if (!srcString.IsEmpty()) - return E_INVALIDARG; + CMultiMethodProps::Init(); + + _removeSfxBlock = false; + _compressHeaders = true; + _encryptHeadersSpecified = false; + _encryptHeaders = false; + // _useParents = false; + + Write_CTime.Init(); + Write_ATime.Init(); + Write_MTime.Init(); + + _volumeMode = false; + InitSolid(); +} + +HRESULT COutHandler::SetSolidFromString(const UString &s) +{ + UString s2 = s; + s2.MakeLower_Ascii(); + for (unsigned i = 0; i < s2.Len();) + { + const wchar_t *start = ((const wchar_t *)s2) + i; + const wchar_t *end; + UInt64 v = ConvertStringToUInt64(start, &end); + if (start == end) + { + if (s2[i++] != 'e') + return E_INVALIDARG; + _solidExtension = true; + continue; + } + i += (int)(end - start); + if (i == s2.Len()) + return E_INVALIDARG; + wchar_t c = s2[i++]; + if (c == 'f') + { + if (v < 1) + v = 1; + _numSolidFiles = v; + } + else + { + unsigned numBits; + switch (c) + { + case 'b': numBits = 0; break; + case 'k': numBits = 10; break; + case 'm': numBits = 20; break; + case 'g': numBits = 30; break; + case 't': numBits = 40; break; + default: return E_INVALIDARG; + } + _numSolidBytes = (v << numBits); + _numSolidBytesDefined = true; + } + } return S_OK; } -STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) +HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value) +{ + bool isSolid; + switch (value.vt) + { + case VT_EMPTY: isSolid = true; break; + case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break; + case VT_BSTR: + if (StringToBool(value.bstrVal, isSolid)) + break; + return SetSolidFromString(value.bstrVal); + default: return E_INVALIDARG; + } + if (isSolid) + InitSolid(); + else + _numSolidFiles = 1; + return S_OK; +} + +static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest) +{ + RINOK(PROPVARIANT_to_bool(prop, dest.Val)); + dest.Def = true; + return S_OK; +} + +HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) +{ + UString name = nameSpec; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + if (name[0] == L's') + { + name.Delete(0); + if (name.IsEmpty()) + return SetSolidFromPROPVARIANT(value); + if (value.vt != VT_EMPTY) + return E_INVALIDARG; + return SetSolidFromString(name); + } + + UInt32 number; + int index = ParseStringToUInt32(name, number); + UString realName = name.Ptr(index); + if (index == 0) + { + if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock); + if (name.IsEqualTo("hc")) return PROPVARIANT_to_bool(value, _compressHeaders); + // if (name.IsEqualToNoCase(L"HS")) return PROPVARIANT_to_bool(value, _useParents); + + if (name.IsEqualTo("hcf")) + { + bool compressHeadersFull = true; + RINOK(PROPVARIANT_to_bool(value, compressHeadersFull)); + return compressHeadersFull ? S_OK: E_INVALIDARG; + } + + if (name.IsEqualTo("he")) + { + RINOK(PROPVARIANT_to_bool(value, _encryptHeaders)); + _encryptHeadersSpecified = true; + return S_OK; + } + + if (name.IsEqualTo("tc")) return PROPVARIANT_to_BoolPair(value, Write_CTime); + if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime); + if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime); + + if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode); + } + return CMultiMethodProps::SetProperty(name, value); +} + +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps) { COM_TRY_BEGIN _binds.Clear(); - BeforeSetProperty(); + InitProps(); - for (int i = 0; i < numProperties; i++) + for (UInt32 i = 0; i < numProps; i++) { UString name = names[i]; - name.MakeUpper(); + name.MakeLower_Ascii(); if (name.IsEmpty()) return E_INVALIDARG; const PROPVARIANT &value = values[i]; - if (name[0] == 'B') + if (name[0] == 'b') { + if (value.vt != VT_EMPTY) + return E_INVALIDARG; name.Delete(0); CBind bind; - RINOK(GetBindInfo(name, bind)); + RINOK(GetBindInfoPart(name, bind.OutCoder, bind.OutStream)); + if (name[0] != ':') + return E_INVALIDARG; + name.Delete(0); + RINOK(GetBindInfoPart(name, bind.InCoder, bind.InStream)); + if (!name.IsEmpty()) + return E_INVALIDARG; _binds.Add(bind); continue; } @@ -476,6 +827,47 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v RINOK(SetProperty(name, value)); } + unsigned numEmptyMethods = GetNumEmptyMethods(); + if (numEmptyMethods > 0) + { + unsigned k; + for (k = 0; k < _binds.Size(); k++) + { + const CBind &bind = _binds[k]; + if (bind.InCoder < (UInt32)numEmptyMethods || + bind.OutCoder < (UInt32)numEmptyMethods) + return E_INVALIDARG; + } + for (k = 0; k < _binds.Size(); k++) + { + CBind &bind = _binds[k]; + bind.InCoder -= (UInt32)numEmptyMethods; + bind.OutCoder -= (UInt32)numEmptyMethods; + } + _methods.DeleteFrontal(numEmptyMethods); + } + + AddDefaultMethod(); + + if (!_filterMethod.MethodName.IsEmpty()) + { + FOR_VECTOR (k, _binds) + { + CBind &bind = _binds[k]; + bind.InCoder++; + bind.OutCoder++; + } + _methods.Insert(0, _filterMethod); + } + + FOR_VECTOR (k, _binds) + { + const CBind &bind = _binds[k]; + if (bind.InCoder >= (UInt32)_methods.Size() || + bind.OutCoder >= (UInt32)_methods.Size()) + return E_INVALIDARG; + } + return S_OK; COM_TRY_END } diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.cpp index 5b5f2fb37..acff2fdd8 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.cpp @@ -1,6 +1,7 @@ // 7zHeader.cpp #include "StdAfx.h" + #include "7zHeader.h" namespace NArchive { @@ -11,4 +12,8 @@ Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; #endif +// We can change signature. So file doesn't contain correct signature. +// struct SignatureInitializer { SignatureInitializer() { kSignature[0]--; } }; +// static SignatureInitializer g_SignatureInitializer; + }} diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.h index 30622b90e..61dad655d 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.h @@ -3,12 +3,12 @@ #ifndef __7Z_HEADER_H #define __7Z_HEADER_H -#include "../../../Common/Types.h" +#include "../../../Common/MyTypes.h" namespace NArchive { namespace N7z { -const int kSignatureSize = 6; +const unsigned kSignatureSize = 6; extern Byte kSignature[kSignatureSize]; // #define _7Z_VOL @@ -57,11 +57,11 @@ namespace NID kHeader, kArchiveProperties, - + kAdditionalStreamsInfo, kMainStreamsInfo, kFilesInfo, - + kPackInfo, kUnpackInfo, kSubStreamsInfo, @@ -82,13 +82,17 @@ namespace NID kCTime, kATime, kMTime, - kWinAttributes, + kWinAttrib, kComment, kEncodedHeader, kStartPos, kDummy + + // kNtSecure, + // kParent, + // kIsAux }; } diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.cpp index 0feb81d2c..28ec5e083 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.cpp @@ -2,6 +2,12 @@ #include "StdAfx.h" +#ifdef _WIN32 +#include <wchar.h> +#else +#include <ctype.h> +#endif + #include "../../../../C/7zCrc.h" #include "../../../../C/CpuArch.h" @@ -20,15 +26,21 @@ #define FORMAT_7Z_RECOVERY #endif +using namespace NWindows; +using namespace NCOM; + namespace NArchive { namespace N7z { -static void BoolVector_Fill_False(CBoolVector &v, int size) +static const UInt32 k_LZMA2 = 0x21; +static const UInt32 k_LZMA = 0x030101; + +static void BoolVector_Fill_False(CBoolVector &v, unsigned size) { - v.Clear(); - v.Reserve(size); - for (int i = 0; i < size; i++) - v.Add(false); + v.ClearAndSetSize(size); + bool *p = &v[0]; + for (unsigned i = 0; i < size; i++) + p[i] = false; } static bool BoolVector_GetAndSet(CBoolVector &v, UInt32 index) @@ -40,11 +52,11 @@ static bool BoolVector_GetAndSet(CBoolVector &v, UInt32 index) return res; } -bool CFolder::CheckStructure() const +bool CFolder::CheckStructure(unsigned numUnpackSizes) const { - const int kNumCodersMax = sizeof(UInt32) * 8; // don't change it - const int kMaskSize = sizeof(UInt32) * 8; // it must be >= kNumCodersMax - const int kNumBindsMax = 32; + const unsigned kNumCodersMax = sizeof(UInt32) * 8; // don't change it + const unsigned kMaskSize = sizeof(UInt32) * 8; // it must be >= kNumCodersMax + const unsigned kNumBindsMax = 32; if (Coders.Size() > kNumCodersMax || BindPairs.Size() > kNumBindsMax) return false; @@ -52,28 +64,28 @@ bool CFolder::CheckStructure() const { CBoolVector v; BoolVector_Fill_False(v, BindPairs.Size() + PackStreams.Size()); - - int i; + + unsigned i; for (i = 0; i < BindPairs.Size(); i++) if (BoolVector_GetAndSet(v, BindPairs[i].InIndex)) return false; for (i = 0; i < PackStreams.Size(); i++) if (BoolVector_GetAndSet(v, PackStreams[i])) return false; - - BoolVector_Fill_False(v, UnpackSizes.Size()); + + BoolVector_Fill_False(v, numUnpackSizes); for (i = 0; i < BindPairs.Size(); i++) if (BoolVector_GetAndSet(v, BindPairs[i].OutIndex)) return false; } - + UInt32 mask[kMaskSize]; - int i; + unsigned i; for (i = 0; i < kMaskSize; i++) mask[i] = 0; { - CIntVector inStreamToCoder, outStreamToCoder; + CUIntVector inStreamToCoder, outStreamToCoder; for (i = 0; i < Coders.Size(); i++) { CNum j; @@ -83,16 +95,16 @@ bool CFolder::CheckStructure() const for (j = 0; j < coder.NumOutStreams; j++) outStreamToCoder.Add(i); } - + for (i = 0; i < BindPairs.Size(); i++) { const CBindPair &bp = BindPairs[i]; mask[inStreamToCoder[bp.InIndex]] |= (1 << outStreamToCoder[bp.OutIndex]); } } - + for (i = 0; i < kMaskSize; i++) - for (int j = 0; j < kMaskSize; j++) + for (unsigned j = 0; j < kMaskSize; j++) if (((1 << j) & mask[i]) != 0) mask[i] |= mask[j]; @@ -104,43 +116,23 @@ bool CFolder::CheckStructure() const } class CInArchiveException {}; +class CUnsupportedFeatureException: public CInArchiveException {}; static void ThrowException() { throw CInArchiveException(); } static inline void ThrowEndOfData() { ThrowException(); } -static inline void ThrowUnsupported() { ThrowException(); } +static inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); } static inline void ThrowIncorrect() { ThrowException(); } -static inline void ThrowUnsupportedVersion() { ThrowException(); } - -/* -class CInArchiveException -{ -public: - enum CCauseType - { - kUnsupportedVersion = 0, - kUnsupported, - kIncorrect, - kEndOfData - } Cause; - CInArchiveException(CCauseType cause): Cause(cause) {}; -}; - -static void ThrowException(CInArchiveException::CCauseType c) { throw CInArchiveException(c); } -static void ThrowEndOfData() { ThrowException(CInArchiveException::kEndOfData); } -static void ThrowUnsupported() { ThrowException(CInArchiveException::kUnsupported); } -static void ThrowIncorrect() { ThrowException(CInArchiveException::kIncorrect); } -static void ThrowUnsupportedVersion() { ThrowException(CInArchiveException::kUnsupportedVersion); } -*/ class CStreamSwitch { CInArchive *_archive; bool _needRemove; + bool _needUpdatePos; public: - CStreamSwitch(): _needRemove(false) {} + CStreamSwitch(): _needRemove(false), _needUpdatePos(false) {} ~CStreamSwitch() { Remove(); } void Remove(); - void Set(CInArchive *archive, const Byte *data, size_t size); + void Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos); void Set(CInArchive *archive, const CByteBuffer &byteBuffer); void Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector); }; @@ -149,22 +141,25 @@ void CStreamSwitch::Remove() { if (_needRemove) { - _archive->DeleteByteStream(); + if (_archive->_inByteBack->GetRem() != 0) + _archive->ThereIsHeaderError = true; + _archive->DeleteByteStream(_needUpdatePos); _needRemove = false; } } -void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size) +void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos) { Remove(); _archive = archive; _archive->AddByteStream(data, size); _needRemove = true; + _needUpdatePos = needUpdatePos; } void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) { - Set(archive, byteBuffer, byteBuffer.GetCapacity()); + Set(archive, byteBuffer, byteBuffer.Size(), false); } void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector) @@ -173,13 +168,22 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d Byte external = archive->ReadByte(); if (external != 0) { - int dataIndex = (int)archive->ReadNum(); - if (dataIndex < 0 || dataIndex >= dataVector->Size()) + CNum dataIndex = archive->ReadNum(); + if (dataIndex >= dataVector->Size()) ThrowIncorrect(); Set(archive, (*dataVector)[dataIndex]); } } +void CInArchive::AddByteStream(const Byte *buf, size_t size) +{ + if (_numInByteBufs == kNumBufLevelsMax) + ThrowIncorrect(); + _inByteBack = &_inByteVector[_numInByteBufs++]; + _inByteBack->Init(buf, size); +} + + Byte CInByte2::ReadByte() { if (_pos >= _size) @@ -191,8 +195,8 @@ void CInByte2::ReadBytes(Byte *data, size_t size) { if (size > _size - _pos) ThrowEndOfData(); - for (size_t i = 0; i < size; i++) - data[i] = _buffer[_pos++]; + memcpy(data, _buffer + _pos, size); + _pos += size; } void CInByte2::SkipData(UInt64 size) @@ -207,31 +211,75 @@ void CInByte2::SkipData() SkipData(ReadNumber()); } -UInt64 CInByte2::ReadNumber() +static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed) { - if (_pos >= _size) - ThrowEndOfData(); - Byte firstByte = _buffer[_pos++]; - Byte mask = 0x80; - UInt64 value = 0; - for (int i = 0; i < 8; i++) + if (size == 0) + { + processed = 0; + return 0; + } + Byte firstByte = *p++; + size--; + if ((firstByte & 0x80) == 0) + { + processed = 1; + return firstByte; + } + Byte mask = 0x40; + if (size == 0) + { + processed = 0; + return 0; + } + UInt64 value = (UInt64)*p; + p++; + size--; + for (unsigned i = 1; i < 8; i++) { if ((firstByte & mask) == 0) { UInt64 highPart = firstByte & (mask - 1); value += (highPart << (i * 8)); + processed = i + 1; return value; } - if (_pos >= _size) - ThrowEndOfData(); - value |= ((UInt64)_buffer[_pos++] << (8 * i)); + if (size == 0) + { + processed = 0; + return 0; + } + value |= ((UInt64)*p << (i * 8)); + p++; + size--; mask >>= 1; } + processed = 9; return value; } +UInt64 CInByte2::ReadNumber() +{ + size_t processed; + UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed); + if (processed == 0) + ThrowEndOfData(); + _pos += processed; + return res; +} + CNum CInByte2::ReadNum() { + /* + if (_pos < _size) + { + Byte val = _buffer[_pos]; + if ((unsigned)val < 0x80) + { + _pos++; + return (unsigned)val; + } + } + */ UInt64 value = ReadNumber(); if (value > kNumMax) ThrowUnsupported(); @@ -256,48 +304,21 @@ UInt64 CInByte2::ReadUInt64() return res; } -void CInByte2::ReadString(UString &s) -{ - const Byte *buf = _buffer + _pos; - size_t rem = (_size - _pos) / 2 * 2; - { - size_t i; - for (i = 0; i < rem; i += 2) - if (buf[i] == 0 && buf[i + 1] == 0) - break; - if (i == rem) - ThrowEndOfData(); - rem = i; - } - int len = (int)(rem / 2); - if (len < 0 || (size_t)len * 2 != rem) - ThrowUnsupported(); - wchar_t *p = s.GetBuffer(len); - int i; - for (i = 0; i < len; i++, buf += 2) - p[i] = (wchar_t)Get16(buf); - s.ReleaseBuffer(len); - _pos += rem + 2; -} +#define CHECK_SIGNATURE if (p[0] != '7' || p[1] != 'z' || p[2] != 0xBC || p[3] != 0xAF || p[4] != 0x27 || p[5] != 0x1C) return false; static inline bool TestSignature(const Byte *p) { - for (int i = 0; i < kSignatureSize; i++) - if (p[i] != kSignature[i]) - return false; - return CrcCalc(p + 12, 20) == GetUi32(p + 8); + CHECK_SIGNATURE + return CrcCalc(p + 12, 20) == Get32(p + 8); } #ifdef FORMAT_7Z_RECOVERY static inline bool TestSignature2(const Byte *p) { - int i; - for (i = 0; i < kSignatureSize; i++) - if (p[i] != kSignature[i]) - return false; - if (CrcCalc(p + 12, 20) == GetUi32(p + 8)) + CHECK_SIGNATURE; + if (CrcCalc(p + 12, 20) == Get32(p + 8)) return true; - for (i = 8; i < kHeaderSize; i++) + for (unsigned i = 8; i < kHeaderSize; i++) if (p[i] != 0) return false; return (p[6] != 0 || p[7] != 0); @@ -312,48 +333,52 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search if (TestSignature2(_header)) return S_OK; + if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) + return S_FALSE; + + const UInt32 kBufSize = 1 << 15; + CByteArr buf(kBufSize); + memcpy(buf, _header, kHeaderSize); + UInt64 offset = 0; - CByteBuffer byteBuffer; - const UInt32 kBufferSize = (1 << 16); - byteBuffer.SetCapacity(kBufferSize); - Byte *buffer = byteBuffer; - UInt32 numPrevBytes = kHeaderSize; - memcpy(buffer, _header, kHeaderSize); - UInt64 curTestPos = _arhiveBeginStreamPosition; for (;;) { - if (searchHeaderSizeLimit != NULL) - if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit) - break; - do + UInt32 readSize = kBufSize - kHeaderSize; { - UInt32 numReadBytes = kBufferSize - numPrevBytes; - UInt32 processedSize; - RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); - numPrevBytes += processedSize; - if (processedSize == 0) + UInt64 rem = *searchHeaderSizeLimit - offset; + if (readSize > rem) + readSize = (UInt32)rem; + if (readSize == 0) return S_FALSE; } - while (numPrevBytes <= kHeaderSize); - UInt32 numTests = numPrevBytes - kHeaderSize; - for (UInt32 pos = 0; pos < numTests; pos++) + UInt32 processed = 0; + RINOK(stream->Read(buf + kHeaderSize, readSize, &processed)); + if (processed == 0) + return S_FALSE; + for (UInt32 pos = 0;;) { - for (; buffer[pos] != '7' && pos < numTests; pos++); - if (pos == numTests) + const Byte *p = buf + pos + 1; + const Byte *lim = buf + processed; + for (; p <= lim; p += 4) + { + if (p[0] == '7') break; + if (p[1] == '7') { p += 1; break; } + if (p[2] == '7') { p += 2; break; } + if (p[3] == '7') { p += 3; break; } + }; + if (p > lim) break; - if (TestSignature(buffer + pos)) + pos = (UInt32)(p - buf); + if (TestSignature(p)) { - memcpy(_header, buffer + pos, kHeaderSize); - curTestPos += pos; - _arhiveBeginStreamPosition = curTestPos; - return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL); + memcpy(_header, p, kHeaderSize); + _arhiveBeginStreamPosition += offset + pos; + return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL); } } - curTestPos += numTests; - numPrevBytes -= numTests; - memmove(buffer, buffer + numTests, numPrevBytes); + offset += processed; + memmove(buf, buf + processed, kHeaderSize); } - return S_FALSE; } // S_FALSE means that file is not archive @@ -362,14 +387,18 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) HeadersSize = 0; Close(); RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) + RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition)) + RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL)) RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); _stream = stream; return S_OK; } - + void CInArchive::Close() { + _numInByteBufs = 0; _stream.Release(); + ThereIsHeaderError = false; } void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */) @@ -382,30 +411,32 @@ void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */) } } -void CInArchive::GetNextFolderItem(CFolder &folder) +// CFolder &folder can be non empty. So we must set all fields + +void CInByte2::ParseFolder(CFolder &folder) { CNum numCoders = ReadNum(); - folder.Coders.Clear(); - folder.Coders.Reserve((int)numCoders); + folder.Coders.SetSize(numCoders); + CNum numInStreams = 0; CNum numOutStreams = 0; CNum i; for (i = 0; i < numCoders; i++) { - folder.Coders.Add(CCoderInfo()); - CCoderInfo &coder = folder.Coders.Back(); - + CCoderInfo &coder = folder.Coders[i]; { Byte mainByte = ReadByte(); - int idSize = (mainByte & 0xF); - Byte longID[15]; - ReadBytes(longID, idSize); - if (idSize > 8) + if ((mainByte & 0xC0) != 0) ThrowUnsupported(); + unsigned idSize = (mainByte & 0xF); + if (idSize > 8 || idSize > GetRem()) + ThrowUnsupported(); + const Byte *longID = GetPtr(); UInt64 id = 0; - for (int j = 0; j < idSize; j++) - id |= (UInt64)longID[idSize - 1 - j] << (8 * j); + for (unsigned j = 0; j < idSize; j++) + id = ((id << 8) | longID[j]); + SkipDataNoCheck(idSize); coder.MethodID = id; if ((mainByte & 0x10) != 0) @@ -421,53 +452,171 @@ void CInArchive::GetNextFolderItem(CFolder &folder) if ((mainByte & 0x20) != 0) { CNum propsSize = ReadNum(); - coder.Props.SetCapacity((size_t)propsSize); + coder.Props.Alloc((size_t)propsSize); ReadBytes((Byte *)coder.Props, (size_t)propsSize); } - if ((mainByte & 0x80) != 0) - ThrowUnsupported(); + else + coder.Props.Free(); } numInStreams += coder.NumInStreams; numOutStreams += coder.NumOutStreams; } CNum numBindPairs = numOutStreams - 1; - folder.BindPairs.Clear(); - folder.BindPairs.Reserve(numBindPairs); + folder.BindPairs.SetSize(numBindPairs); for (i = 0; i < numBindPairs; i++) { - CBindPair bp; + CBindPair &bp = folder.BindPairs[i]; bp.InIndex = ReadNum(); bp.OutIndex = ReadNum(); - folder.BindPairs.Add(bp); } if (numInStreams < numBindPairs) ThrowUnsupported(); CNum numPackStreams = numInStreams - numBindPairs; - folder.PackStreams.Reserve(numPackStreams); + folder.PackStreams.SetSize(numPackStreams); if (numPackStreams == 1) { for (i = 0; i < numInStreams; i++) if (folder.FindBindPairForInStream(i) < 0) { - folder.PackStreams.Add(i); + folder.PackStreams[0] = i; break; } - if (folder.PackStreams.Size() != 1) + if (i == numInStreams) ThrowUnsupported(); } else for (i = 0; i < numPackStreams; i++) - folder.PackStreams.Add(ReadNum()); + folder.PackStreams[i] = ReadNum(); +} + +void CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const +{ + size_t startPos = FoCodersDataOffset[folderIndex]; + CInByte2 inByte; + inByte.Init(CodersData + startPos, FoCodersDataOffset[folderIndex + 1] - startPos); + inByte.ParseFolder(folder); + if (inByte.GetRem() != 0) + throw 20120424; +} + + +void CDatabase::GetPath(unsigned index, UString &path) const +{ + path.Empty(); + if (!NameOffsets || !NamesBuf) + return; + + size_t offset = NameOffsets[index]; + size_t size = NameOffsets[index + 1] - offset - 1; + + if (size >= (1 << 20)) + return; + + wchar_t *s = path.GetBuffer((unsigned)size); + + const Byte *p = ((const Byte *)NamesBuf + offset * 2); + + #if defined(_WIN32) && defined(MY_CPU_LE) + + wmemcpy(s, (const wchar_t *)p, size); + + #else + + for (size_t i = 0; i < size; i++) + { + *s = Get16(p); + p += 2; + s++; + } + + #endif + + path.ReleaseBuffer((unsigned)size); +} + +HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw() +{ + PropVariant_Clear(path); + if (!NameOffsets || !NamesBuf) + return S_OK; + + size_t offset = NameOffsets[index]; + size_t size = NameOffsets[index + 1] - offset; + + if (size >= (1 << 14)) + return S_OK; + + RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1)); + wchar_t *s = path->bstrVal; + + const Byte *p = ((const Byte *)NamesBuf + offset * 2); + + for (size_t i = 0; i < size; i++) + { + wchar_t c = Get16(p); + p += 2; + #if WCHAR_PATH_SEPARATOR != L'/' + if (c == L'/') + c = WCHAR_PATH_SEPARATOR; + #endif + *s++ = c; + } + + return S_OK; + + /* + unsigned cur = index; + unsigned size = 0; + + for (int i = 0;; i++) + { + size_t len = NameOffsets[cur + 1] - NameOffsets[cur]; + size += (unsigned)len; + if (i > 256 || len > (1 << 14) || size > (1 << 14)) + return PropVarEm_Set_Str(path, "[TOO-LONG]"); + cur = Files[cur].Parent; + if (cur < 0) + break; + } + size--; + + RINOK(PropVarEm_Alloc_Bstr(path, size)); + wchar_t *s = path->bstrVal; + s += size; + *s = 0; + cur = index; + + for (;;) + { + unsigned len = (unsigned)(NameOffsets[cur + 1] - NameOffsets[cur] - 1); + const Byte *p = (const Byte *)NamesBuf + (NameOffsets[cur + 1] * 2) - 2; + do + { + p -= 2; + --s; + wchar_t c = Get16(p); + if (c == '/') + c = WCHAR_PATH_SEPARATOR; + *s = c; + } + while (--len); + const CFileItem &file = Files[cur]; + cur = file.Parent; + if (cur < 0) + return S_OK; + *(--s) = (file.IsAltStream ? ':' : WCHAR_PATH_SEPARATOR); + } + */ } -void CInArchive::WaitAttribute(UInt64 attribute) +void CInArchive::WaitId(UInt64 id) { for (;;) { UInt64 type = ReadID(); - if (type == attribute) + if (type == id) return; if (type == NID::kEnd) ThrowIncorrect(); @@ -475,91 +624,210 @@ void CInArchive::WaitAttribute(UInt64 attribute) } } -void CInArchive::ReadHashDigests(int numItems, - CBoolVector &digestsDefined, - CRecordVector<UInt32> &digests) +void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs) { - ReadBoolVector2(numItems, digestsDefined); - digests.Clear(); - digests.Reserve(numItems); - for (int i = 0; i < numItems; i++) + ReadBoolVector2(numItems, crcs.Defs); + crcs.Vals.ClearAndSetSize(numItems); + UInt32 *p = &crcs.Vals[0]; + const bool *defs = &crcs.Defs[0]; + for (unsigned i = 0; i < numItems; i++) { UInt32 crc = 0; - if (digestsDefined[i]) + if (defs[i]) crc = ReadUInt32(); - digests.Add(crc); + p[i] = crc; } } -void CInArchive::ReadPackInfo( - UInt64 &dataOffset, - CRecordVector<UInt64> &packSizes, - CBoolVector &packCRCsDefined, - CRecordVector<UInt32> &packCRCs) +void CInArchive::ReadPackInfo(CFolders &f) { - dataOffset = ReadNumber(); CNum numPackStreams = ReadNum(); - WaitAttribute(NID::kSize); - packSizes.Clear(); - packSizes.Reserve(numPackStreams); + WaitId(NID::kSize); + f.PackPositions.Alloc(numPackStreams + 1); + f.NumPackStreams = numPackStreams; + UInt64 sum = 0; for (CNum i = 0; i < numPackStreams; i++) - packSizes.Add(ReadNumber()); + { + f.PackPositions[i] = sum; + UInt64 packSize = ReadNumber(); + sum += packSize; + if (sum < packSize) + ThrowIncorrect(); + } + f.PackPositions[numPackStreams] = sum; UInt64 type; for (;;) { type = ReadID(); if (type == NID::kEnd) - break; + return; if (type == NID::kCRC) { - ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs); + CUInt32DefVector PackCRCs; + ReadHashDigests(numPackStreams, PackCRCs); continue; } SkipData(); } - if (packCRCsDefined.IsEmpty()) - { - BoolVector_Fill_False(packCRCsDefined, numPackStreams); - packCRCs.Reserve(numPackStreams); - packCRCs.Clear(); - for (CNum i = 0; i < numPackStreams; i++) - packCRCs.Add(0); - } } void CInArchive::ReadUnpackInfo( const CObjectVector<CByteBuffer> *dataVector, - CObjectVector<CFolder> &folders) + CFolders &folders) { - WaitAttribute(NID::kFolder); + WaitId(NID::kFolder); CNum numFolders = ReadNum(); + CNum numCodersOutStreams = 0; { CStreamSwitch streamSwitch; streamSwitch.Set(this, dataVector); - folders.Clear(); - folders.Reserve(numFolders); - for (CNum i = 0; i < numFolders; i++) + const Byte *startBufPtr = _inByteBack->GetPtr(); + folders.NumFolders = numFolders; + + folders.FoStartPackStreamIndex.Alloc(numFolders + 1); + folders.FoToMainUnpackSizeIndex.Alloc(numFolders); + folders.FoCodersDataOffset.Alloc(numFolders + 1); + folders.FoToCoderUnpackSizes.Alloc(numFolders + 1); + + CRecordVector<bool> InStreamUsed; + CRecordVector<bool> OutStreamUsed; + + CNum packStreamIndex = 0; + CNum fo; + CInByte2 *inByte = _inByteBack; + for (fo = 0; fo < numFolders; fo++) { - folders.Add(CFolder()); - GetNextFolderItem(folders.Back()); - } - } + UInt32 numOutStreams = 0; + UInt32 indexOfMainStream = 0; + UInt32 numPackStreams = 0; + folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr; + + numOutStreams = 0; + CNum numInStreams = 0; + CNum numCoders = inByte->ReadNum(); + for (CNum ci = 0; ci < numCoders; ci++) + { + Byte mainByte = inByte->ReadByte(); + if ((mainByte & 0xC0) != 0) + ThrowUnsupported(); + unsigned idSize = (mainByte & 0xF); + if (idSize > 8) + ThrowUnsupported(); + if (idSize > inByte->GetRem()) + ThrowEndOfData(); + const Byte *longID = inByte->GetPtr(); + UInt64 id = 0; + for (unsigned j = 0; j < idSize; j++) + id = ((id << 8) | longID[j]); + inByte->SkipDataNoCheck(idSize); + if (folders.ParsedMethods.IDs.Size() < 128) + folders.ParsedMethods.IDs.AddToUniqueSorted(id); + CNum coderInStreams = 1; + CNum coderOutStreams = 1; + if ((mainByte & 0x10) != 0) + { + coderInStreams = inByte->ReadNum(); + coderOutStreams = inByte->ReadNum(); + } + numInStreams += coderInStreams; + if (numInStreams < coderInStreams) + ThrowUnsupported(); + numOutStreams += coderOutStreams; + if (numOutStreams < coderOutStreams) + ThrowUnsupported(); + if ((mainByte & 0x20) != 0) + { + CNum propsSize = inByte->ReadNum(); + if (propsSize > inByte->GetRem()) + ThrowEndOfData(); + if (id == k_LZMA2 && propsSize == 1) + { + Byte v = *_inByteBack->GetPtr(); + if (folders.ParsedMethods.Lzma2Prop < v) + folders.ParsedMethods.Lzma2Prop = v; + } + else if (id == k_LZMA && propsSize == 5) + { + UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1); + if (folders.ParsedMethods.LzmaDic < dicSize) + folders.ParsedMethods.LzmaDic = dicSize; + } + inByte->SkipDataNoCheck((size_t)propsSize); + } + } + + if (numOutStreams == 1 && numInStreams == 1) + { + indexOfMainStream = 0; + numPackStreams = 1; + } + else + { + UInt32 i; + if (numOutStreams == 0) + ThrowUnsupported(); + CNum numBindPairs = numOutStreams - 1; + if (numInStreams < numBindPairs) + ThrowUnsupported(); + if (numInStreams >= 256 || numOutStreams >= 256) + ThrowUnsupported(); + + InStreamUsed.ClearAndSetSize(numInStreams); + for (i = 0; i < numInStreams; i++) + InStreamUsed[i] = false; + + OutStreamUsed.ClearAndSetSize(numOutStreams); + for (i = 0; i < numOutStreams; i++) + OutStreamUsed[i] = false; + + for (i = 0; i < numBindPairs; i++) + { + CNum index = ReadNum(); + if (index >= numInStreams || InStreamUsed[index]) + ThrowUnsupported(); + InStreamUsed[index] = true; + index = ReadNum(); + if (index >= numOutStreams || OutStreamUsed[index]) + ThrowUnsupported(); + OutStreamUsed[index] = true; + } - WaitAttribute(NID::kCodersUnpackSize); + numPackStreams = numInStreams - numBindPairs; - CNum i; - for (i = 0; i < numFolders; i++) - { - CFolder &folder = folders[i]; - CNum numOutStreams = folder.GetNumOutStreams(); - folder.UnpackSizes.Reserve(numOutStreams); - for (CNum j = 0; j < numOutStreams; j++) - folder.UnpackSizes.Add(ReadNumber()); + if (numPackStreams != 1) + for (i = 0; i < numPackStreams; i++) + inByte->ReadNum(); // PackStreams + + for (i = 0; i < numOutStreams; i++) + if (!OutStreamUsed[i]) + { + indexOfMainStream = i; + break; + } + if (i == numOutStreams) + ThrowUnsupported(); + } + folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; + numCodersOutStreams += numOutStreams; + folders.FoStartPackStreamIndex[fo] = packStreamIndex; + packStreamIndex += numPackStreams; + folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream; + } + size_t dataSize = _inByteBack->GetPtr() - startBufPtr; + folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; + folders.FoStartPackStreamIndex[fo] = packStreamIndex; + folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr; + folders.CodersData.CopyFrom(startBufPtr, dataSize); } + WaitId(NID::kCodersUnpackSize); + folders.CoderUnpackSizes.Alloc(numCodersOutStreams); + for (CNum i = 0; i < numCodersOutStreams; i++) + folders.CoderUnpackSizes[i] = ReadNumber(); + for (;;) { UInt64 type = ReadID(); @@ -567,15 +835,7 @@ void CInArchive::ReadUnpackInfo( return; if (type == NID::kCRC) { - CBoolVector crcsDefined; - CRecordVector<UInt32> crcs; - ReadHashDigests(numFolders, crcsDefined, crcs); - for (i = 0; i < numFolders; i++) - { - CFolder &folder = folders[i]; - folder.UnpackCRCDefined = crcsDefined[i]; - folder.UnpackCRC = crcs[i]; - } + ReadHashDigests(numFolders, folders.FolderCRCs); continue; } SkipData(); @@ -583,170 +843,217 @@ void CInArchive::ReadUnpackInfo( } void CInArchive::ReadSubStreamsInfo( - const CObjectVector<CFolder> &folders, - CRecordVector<CNum> &numUnpackStreamsInFolders, + CFolders &folders, CRecordVector<UInt64> &unpackSizes, - CBoolVector &digestsDefined, - CRecordVector<UInt32> &digests) + CUInt32DefVector &digests) { - numUnpackStreamsInFolders.Clear(); - numUnpackStreamsInFolders.Reserve(folders.Size()); + folders.NumUnpackStreamsVector.Alloc(folders.NumFolders); + CNum i; + for (i = 0; i < folders.NumFolders; i++) + folders.NumUnpackStreamsVector[i] = 1; + UInt64 type; + for (;;) { type = ReadID(); if (type == NID::kNumUnpackStream) { - for (int i = 0; i < folders.Size(); i++) - numUnpackStreamsInFolders.Add(ReadNum()); + for (i = 0; i < folders.NumFolders; i++) + folders.NumUnpackStreamsVector[i] = ReadNum(); continue; } - if (type == NID::kCRC || type == NID::kSize) - break; - if (type == NID::kEnd) + if (type == NID::kCRC || type == NID::kSize || type == NID::kEnd) break; SkipData(); } - if (numUnpackStreamsInFolders.IsEmpty()) - for (int i = 0; i < folders.Size(); i++) - numUnpackStreamsInFolders.Add(1); - - int i; - for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) + if (type == NID::kSize) { - // v3.13 incorrectly worked with empty folders - // v4.07: we check that folder is empty - CNum numSubstreams = numUnpackStreamsInFolders[i]; - if (numSubstreams == 0) - continue; - UInt64 sum = 0; - for (CNum j = 1; j < numSubstreams; j++) - if (type == NID::kSize) + for (i = 0; i < folders.NumFolders; i++) + { + // v3.13 incorrectly worked with empty folders + // v4.07: we check that folder is empty + CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + if (numSubstreams == 0) + continue; + UInt64 sum = 0; + for (CNum j = 1; j < numSubstreams; j++) { UInt64 size = ReadNumber(); unpackSizes.Add(size); sum += size; + if (sum < size) + ThrowIncorrect(); } - unpackSizes.Add(folders[i].GetUnpackSize() - sum); - } - if (type == NID::kSize) + UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i); + if (folderUnpackSize < sum) + ThrowIncorrect(); + unpackSizes.Add(folderUnpackSize - sum); + } type = ReadID(); + } + else + { + for (i = 0; i < folders.NumFolders; i++) + { + /* v9.26 - v9.29 incorrectly worked: + if (folders.NumUnpackStreamsVector[i] == 0), it threw error */ + CNum val = folders.NumUnpackStreamsVector[i]; + if (val > 1) + ThrowIncorrect(); + if (val == 1) + unpackSizes.Add(folders.GetFolderUnpackSize(i)); + } + } - int numDigests = 0; - int numDigestsTotal = 0; - for (i = 0; i < folders.Size(); i++) + unsigned numDigests = 0; + for (i = 0; i < folders.NumFolders; i++) { - CNum numSubstreams = numUnpackStreamsInFolders[i]; - if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) + CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + if (numSubstreams != 1 || !folders.FolderCRCs.ValidAndDefined(i)) numDigests += numSubstreams; - numDigestsTotal += numSubstreams; } for (;;) { + if (type == NID::kEnd) + break; if (type == NID::kCRC) { - CBoolVector digestsDefined2; - CRecordVector<UInt32> digests2; - ReadHashDigests(numDigests, digestsDefined2, digests2); - int digestIndex = 0; - for (i = 0; i < folders.Size(); i++) + // CUInt32DefVector digests2; + // ReadHashDigests(numDigests, digests2); + CBoolVector digests2; + ReadBoolVector2(numDigests, digests2); + + digests.ClearAndSetSize(unpackSizes.Size()); + + unsigned k = 0; + unsigned k2 = 0; + + for (i = 0; i < folders.NumFolders; i++) { - CNum numSubstreams = numUnpackStreamsInFolders[i]; - const CFolder &folder = folders[i]; - if (numSubstreams == 1 && folder.UnpackCRCDefined) + CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) { - digestsDefined.Add(true); - digests.Add(folder.UnpackCRC); + digests.Defs[k] = true; + digests.Vals[k] = folders.FolderCRCs.Vals[i]; + k++; + } + else for (CNum j = 0; j < numSubstreams; j++) + { + bool defined = digests2[k2++]; + digests.Defs[k] = defined; + UInt32 crc = 0; + if (defined) + crc = ReadUInt32(); + digests.Vals[k] = crc; + k++; } - else - for (CNum j = 0; j < numSubstreams; j++, digestIndex++) - { - digestsDefined.Add(digestsDefined2[digestIndex]); - digests.Add(digests2[digestIndex]); - } } + // if (k != unpackSizes.Size()) throw 1234567; } - else if (type == NID::kEnd) + else + SkipData(); + + type = ReadID(); + } + + if (digests.Defs.Size() != unpackSizes.Size()) + { + digests.ClearAndSetSize(unpackSizes.Size()); + unsigned k = 0; + for (i = 0; i < folders.NumFolders; i++) { - if (digestsDefined.IsEmpty()) + CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) { - BoolVector_Fill_False(digestsDefined, numDigestsTotal); - digests.Clear(); - for (int i = 0; i < numDigestsTotal; i++) - digests.Add(0); + digests.Defs[k] = true; + digests.Vals[k] = folders.FolderCRCs.Vals[i]; + k++; + } + else for (CNum j = 0; j < numSubstreams; j++) + { + digests.Defs[k] = false; + digests.Vals[k] = 0; + k++; } - return; } - else - SkipData(); - type = ReadID(); } } void CInArchive::ReadStreamsInfo( const CObjectVector<CByteBuffer> *dataVector, UInt64 &dataOffset, - CRecordVector<UInt64> &packSizes, - CBoolVector &packCRCsDefined, - CRecordVector<UInt32> &packCRCs, - CObjectVector<CFolder> &folders, - CRecordVector<CNum> &numUnpackStreamsInFolders, + CFolders &folders, CRecordVector<UInt64> &unpackSizes, - CBoolVector &digestsDefined, - CRecordVector<UInt32> &digests) + CUInt32DefVector &digests) { - for (;;) + UInt64 type = ReadID(); + + if (type == NID::kPackInfo) { - UInt64 type = ReadID(); - if (type > ((UInt32)1 << 30)) - ThrowIncorrect(); - switch((UInt32)type) + dataOffset = ReadNumber(); + ReadPackInfo(folders); + type = ReadID(); + } + + if (type == NID::kUnpackInfo) + { + ReadUnpackInfo(dataVector, folders); + type = ReadID(); + } + + if (folders.NumFolders != 0 && !folders.PackPositions) + { + // if there are folders, we need PackPositions also + folders.PackPositions.Alloc(1); + folders.PackPositions[0] = 0; + } + + if (type == NID::kSubStreamsInfo) + { + ReadSubStreamsInfo(folders, unpackSizes, digests); + type = ReadID(); + } + else + { + folders.NumUnpackStreamsVector.Alloc(folders.NumFolders); + /* If digests.Defs.Size() == 0, it means that there are no crcs. + So we don't need to fill digests with values. */ + // digests.Vals.ClearAndSetSize(folders.NumFolders); + // BoolVector_Fill_False(digests.Defs, folders.NumFolders); + for (CNum i = 0; i < folders.NumFolders; i++) { - case NID::kEnd: - return; - case NID::kPackInfo: - { - ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs); - break; - } - case NID::kUnpackInfo: - { - ReadUnpackInfo(dataVector, folders); - break; - } - case NID::kSubStreamsInfo: - { - ReadSubStreamsInfo(folders, numUnpackStreamsInFolders, - unpackSizes, digestsDefined, digests); - break; - } - default: - ThrowIncorrect(); + folders.NumUnpackStreamsVector[i] = 1; + unpackSizes.Add(folders.GetFolderUnpackSize(i)); + // digests.Vals[i] = 0; } } + + if (type != NID::kEnd) + ThrowIncorrect(); } -void CInArchive::ReadBoolVector(int numItems, CBoolVector &v) +void CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v) { - v.Clear(); - v.Reserve(numItems); + v.ClearAndSetSize(numItems); Byte b = 0; Byte mask = 0; - for (int i = 0; i < numItems; i++) + bool *p = &v[0]; + for (unsigned i = 0; i < numItems; i++) { if (mask == 0) { b = ReadByte(); mask = 0x80; } - v.Add((b & mask) != 0); + p[i] = ((b & mask) != 0); mask >>= 1; } } -void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v) +void CInArchive::ReadBoolVector2(unsigned numItems, CBoolVector &v) { Byte allAreDefined = ReadByte(); if (allAreDefined == 0) @@ -754,27 +1061,30 @@ void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v) ReadBoolVector(numItems, v); return; } - v.Clear(); - v.Reserve(numItems); - for (int i = 0; i < numItems; i++) - v.Add(true); + v.ClearAndSetSize(numItems); + bool *p = &v[0]; + for (unsigned i = 0; i < numItems; i++) + p[i] = true; } void CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector, - CUInt64DefVector &v, int numFiles) + CUInt64DefVector &v, unsigned numItems) { - ReadBoolVector2(numFiles, v.Defined); + ReadBoolVector2(numItems, v.Defs); CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); - v.Values.Reserve(numFiles); - for (int i = 0; i < numFiles; i++) + v.Vals.ClearAndSetSize(numItems); + UInt64 *p = &v.Vals[0]; + const bool *defs = &v.Defs[0]; + + for (unsigned i = 0; i < numItems; i++) { UInt64 t = 0; - if (v.Defined[i]) + if (defs[i]) t = ReadUInt64(); - v.Values.Add(t); + p[i] = t; } } @@ -782,35 +1092,19 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( DECL_EXTERNAL_CODECS_LOC_VARS UInt64 baseOffset, UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS_DECL ) { - CRecordVector<UInt64> packSizes; - CBoolVector packCRCsDefined; - CRecordVector<UInt32> packCRCs; - CObjectVector<CFolder> folders; - - CRecordVector<CNum> numUnpackStreamsInFolders; + CFolders folders; CRecordVector<UInt64> unpackSizes; - CBoolVector digestsDefined; - CRecordVector<UInt32> digests; - + CUInt32DefVector digests; + ReadStreamsInfo(NULL, dataOffset, - packSizes, - packCRCsDefined, - packCRCs, folders, - numUnpackStreamsInFolders, unpackSizes, - digestsDefined, digests); - - // db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader; - - CNum packIndex = 0; + CDecoder decoder( #ifdef _ST_MODE false @@ -818,134 +1112,107 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( true #endif ); - UInt64 dataStartPos = baseOffset + dataOffset; - for (int i = 0; i < folders.Size(); i++) + + for (CNum i = 0; i < folders.NumFolders; i++) { - const CFolder &folder = folders[i]; - dataVector.Add(CByteBuffer()); - CByteBuffer &data = dataVector.Back(); - UInt64 unpackSize64 = folder.GetUnpackSize(); + CByteBuffer &data = dataVector.AddNew(); + UInt64 unpackSize64 = folders.GetFolderUnpackSize(i); size_t unpackSize = (size_t)unpackSize64; if (unpackSize != unpackSize64) ThrowUnsupported(); - data.SetCapacity(unpackSize); - + data.Alloc(unpackSize); + CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream; CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; outStreamSpec->Init(data, unpackSize); - + HRESULT result = decoder.Decode( EXTERNAL_CODECS_LOC_VARS - _stream, dataStartPos, - &packSizes[packIndex], folder, outStream, NULL - #ifndef _NO_CRYPTO - , getTextPassword, passwordIsDefined - #endif + _stream, baseOffset + dataOffset, + folders, i, + outStream, NULL + _7Z_DECODER_CRYPRO_VARS #if !defined(_7ZIP_ST) && !defined(_SFX) , false, 1 #endif ); RINOK(result); - - if (folder.UnpackCRCDefined) - if (CrcCalc(data, unpackSize) != folder.UnpackCRC) + + if (folders.FolderCRCs.ValidAndDefined(i)) + if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i]) ThrowIncorrect(); - for (int j = 0; j < folder.PackStreams.Size(); j++) - { - UInt64 packSize = packSizes[packIndex++]; - dataStartPos += packSize; - HeadersSize += packSize; - } } + HeadersSize += folders.PackPositions[folders.NumPackStreams]; return S_OK; } HRESULT CInArchive::ReadHeader( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &db - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined - #endif + CDbEx &db + _7Z_DECODER_CRYPRO_VARS_DECL ) { UInt64 type = ReadID(); if (type == NID::kArchiveProperties) { - ReadArchiveProperties(db.ArchiveInfo); + ReadArchiveProperties(db.ArcInfo); type = ReadID(); } - + CObjectVector<CByteBuffer> dataVector; - + if (type == NID::kAdditionalStreamsInfo) { HRESULT result = ReadAndDecodePackedStreams( EXTERNAL_CODECS_LOC_VARS - db.ArchiveInfo.StartPositionAfterHeader, - db.ArchiveInfo.DataStartPosition2, + db.ArcInfo.StartPositionAfterHeader, + db.ArcInfo.DataStartPosition2, dataVector - #ifndef _NO_CRYPTO - , getTextPassword, passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS ); RINOK(result); - db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader; + db.ArcInfo.DataStartPosition2 += db.ArcInfo.StartPositionAfterHeader; type = ReadID(); } CRecordVector<UInt64> unpackSizes; - CBoolVector digestsDefined; - CRecordVector<UInt32> digests; - + CUInt32DefVector digests; + if (type == NID::kMainStreamsInfo) { ReadStreamsInfo(&dataVector, - db.ArchiveInfo.DataStartPosition, - db.PackSizes, - db.PackCRCsDefined, - db.PackCRCs, - db.Folders, - db.NumUnpackStreamsVector, + db.ArcInfo.DataStartPosition, + (CFolders &)db, unpackSizes, - digestsDefined, digests); - db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader; + db.ArcInfo.DataStartPosition += db.ArcInfo.StartPositionAfterHeader; type = ReadID(); } - else - { - for (int i = 0; i < db.Folders.Size(); i++) - { - db.NumUnpackStreamsVector.Add(1); - CFolder &folder = db.Folders[i]; - unpackSizes.Add(folder.GetUnpackSize()); - digestsDefined.Add(folder.UnpackCRCDefined); - digests.Add(folder.UnpackCRC); - } - } db.Files.Clear(); - if (type == NID::kEnd) - return S_OK; - if (type != NID::kFilesInfo) - ThrowIncorrect(); - + if (type == NID::kFilesInfo) + { + CNum numFiles = ReadNum(); + db.Files.ClearAndSetSize(numFiles); + CNum i; + /* db.Files.Reserve(numFiles); CNum i; for (i = 0; i < numFiles; i++) db.Files.Add(CFileItem()); + */ - db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize); - if (!db.PackSizes.IsEmpty()) - db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo); - if (numFiles > 0 && !digests.IsEmpty()) - db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC); + db.ArcInfo.FileInfoPopIDs.Add(NID::kSize); + // if (!db.PackSizes.IsEmpty()) + db.ArcInfo.FileInfoPopIDs.Add(NID::kPackInfo); + if (numFiles > 0 && !digests.Defs.IsEmpty()) + db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC); CBoolVector emptyStreamVector; - BoolVector_Fill_False(emptyStreamVector, (int)numFiles); + BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles); CBoolVector emptyFileVector; CBoolVector antiFileVector; CNum numEmptyStreams = 0; @@ -956,7 +1223,10 @@ HRESULT CInArchive::ReadHeader( if (type == NID::kEnd) break; UInt64 size = ReadNumber(); - size_t ppp = _inByteBack->_pos; + if (size > _inByteBack->GetRem()) + ThrowIncorrect(); + CStreamSwitch switchProp; + switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true); bool addPropIdToList = true; bool isKnownType = true; if (type > ((UInt32)1 << 30)) @@ -967,11 +1237,29 @@ HRESULT CInArchive::ReadHeader( { CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); - for (int i = 0; i < db.Files.Size(); i++) - _inByteBack->ReadString(db.Files[i].Name); + size_t rem = _inByteBack->GetRem(); + db.NamesBuf.Alloc(rem); + ReadBytes(db.NamesBuf, rem); + db.NameOffsets.Alloc(db.Files.Size() + 1); + size_t pos = 0; + unsigned i; + for (i = 0; i < db.Files.Size(); i++) + { + size_t curRem = (rem - pos) / 2; + const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos); + size_t j; + for (j = 0; j < curRem && buf[j] != 0; j++); + if (j == curRem) + ThrowEndOfData(); + db.NameOffsets[i] = pos / 2; + pos += j * 2 + 2; + } + db.NameOffsets[i] = pos / 2; + if (pos != rem) + ThereIsHeaderError = true; break; } - case NID::kWinAttributes: + case NID::kWinAttrib: { CBoolVector boolVector; ReadBoolVector2(db.Files.Size(), boolVector); @@ -986,9 +1274,40 @@ HRESULT CInArchive::ReadHeader( } break; } + /* + case NID::kIsAux: + { + ReadBoolVector(db.Files.Size(), db.IsAux); + break; + } + case NID::kParent: + { + db.IsTree = true; + // CBoolVector boolVector; + // ReadBoolVector2(db.Files.Size(), boolVector); + // CStreamSwitch streamSwitch; + // streamSwitch.Set(this, &dataVector); + CBoolVector boolVector; + ReadBoolVector2(db.Files.Size(), boolVector); + + db.ThereAreAltStreams = false; + for (i = 0; i < numFiles; i++) + { + CFileItem &file = db.Files[i]; + // file.Parent = -1; + // if (boolVector[i]) + file.Parent = (int)ReadUInt32(); + file.IsAltStream = !boolVector[i]; + if (file.IsAltStream) + db.ThereAreAltStreams = true; + } + break; + } + */ case NID::kEmptyStream: { ReadBoolVector(numFiles, emptyStreamVector); + numEmptyStreams = 0; for (i = 0; i < (CNum)emptyStreamVector.Size(); i++) if (emptyStreamVector[i]) numEmptyStreams++; @@ -1000,34 +1319,83 @@ HRESULT CInArchive::ReadHeader( } case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break; case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break; - case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break; - case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break; - case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break; - case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break; + case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (unsigned)numFiles); break; + case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (unsigned)numFiles); break; + case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (unsigned)numFiles); break; + case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (unsigned)numFiles); break; case NID::kDummy: { for (UInt64 j = 0; j < size; j++) if (ReadByte() != 0) - ThrowIncorrect(); + ThereIsHeaderError = true; addPropIdToList = false; break; } + /* + case NID::kNtSecure: + { + try + { + { + CStreamSwitch streamSwitch; + streamSwitch.Set(this, &dataVector); + UInt32 numDescriptors = ReadUInt32(); + size_t offset = 0; + db.SecureOffsets.Clear(); + for (i = 0; i < numDescriptors; i++) + { + UInt32 size = ReadUInt32(); + db.SecureOffsets.Add(offset); + offset += size; + } + // ThrowIncorrect();; + db.SecureOffsets.Add(offset); + db.SecureBuf.SetCapacity(offset); + for (i = 0; i < numDescriptors; i++) + { + offset = db.SecureOffsets[i]; + ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset); + } + db.SecureIDs.Clear(); + for (unsigned i = 0; i < db.Files.Size(); i++) + { + db.SecureIDs.Add(ReadNum()); + // db.SecureIDs.Add(ReadUInt32()); + } + // ReadUInt32(); + if (_inByteBack->GetRem() != 0) + ThrowIncorrect();; + } + } + catch(CInArchiveException &) + { + ThereIsHeaderError = true; + addPropIdToList = isKnownType = false; + db.ClearSecure(); + } + break; + } + */ default: addPropIdToList = isKnownType = false; } if (isKnownType) { - if(addPropIdToList) - db.ArchiveInfo.FileInfoPopIDs.Add(type); + if (addPropIdToList) + db.ArcInfo.FileInfoPopIDs.Add(type); } else - SkipData(size); - bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 || - db.ArchiveInfo.Version.Minor > 2); - if (checkRecordsSize && _inByteBack->_pos - ppp != size) + { + db.UnsupportedFeatureWarning = true; + _inByteBack->SkipRem(); + } + // SkipData worked incorrectly in some versions before v4.59 (7zVer <= 00.02) + if (_inByteBack->GetRem() != 0) ThrowIncorrect(); } + type = ReadID(); // Read (NID::kEnd) end of headers + CNum emptyFileIndex = 0; CNum sizeIndex = 0; @@ -1035,19 +1403,21 @@ HRESULT CInArchive::ReadHeader( for (i = 0; i < numEmptyStreams; i++) if (antiFileVector[i]) numAntiItems++; - + for (i = 0; i < numFiles; i++) { CFileItem &file = db.Files[i]; bool isAnti; file.HasStream = !emptyStreamVector[i]; + file.Crc = 0; if (file.HasStream) { file.IsDir = false; isAnti = false; file.Size = unpackSizes[sizeIndex]; - file.Crc = digests[sizeIndex]; - file.CrcDefined = digestsDefined[sizeIndex]; + file.CrcDefined = digests.ValidAndDefined(sizeIndex); + if (file.CrcDefined) + file.Crc = digests.Vals[sizeIndex]; sizeIndex++; } else @@ -1061,162 +1431,187 @@ HRESULT CInArchive::ReadHeader( if (numAntiItems != 0) db.IsAnti.Add(isAnti); } + } + db.FillLinks(); + /* + if (type != NID::kEnd) + ThrowIncorrect(); + if (_inByteBack->GetRem() != 0) + ThrowIncorrect(); + */ return S_OK; } - -void CArchiveDatabaseEx::FillFolderStartPackStream() +void CDbEx::FillLinks() { - FolderStartPackStreamIndex.Clear(); - FolderStartPackStreamIndex.Reserve(Folders.Size()); - CNum startPos = 0; - for (int i = 0; i < Folders.Size(); i++) - { - FolderStartPackStreamIndex.Add(startPos); - startPos += (CNum)Folders[i].PackStreams.Size(); - } -} + FolderStartFileIndex.ClearAndSetSize(NumFolders); -void CArchiveDatabaseEx::FillStartPos() -{ - PackStreamStartPositions.Clear(); - PackStreamStartPositions.Reserve(PackSizes.Size()); - UInt64 startPos = 0; - for (int i = 0; i < PackSizes.Size(); i++) - { - PackStreamStartPositions.Add(startPos); - startPos += PackSizes[i]; - } -} + FileIndexToFolderIndexMap.ClearAndSetSize(Files.Size()); -void CArchiveDatabaseEx::FillFolderStartFileIndex() -{ - FolderStartFileIndex.Clear(); - FolderStartFileIndex.Reserve(Folders.Size()); - FileIndexToFolderIndexMap.Clear(); - FileIndexToFolderIndexMap.Reserve(Files.Size()); - - int folderIndex = 0; + CNum folderIndex = 0; CNum indexInFolder = 0; - for (int i = 0; i < Files.Size(); i++) + unsigned i; + for (i = 0; i < Files.Size(); i++) { - const CFileItem &file = Files[i]; - bool emptyStream = !file.HasStream; - if (emptyStream && indexInFolder == 0) - { - FileIndexToFolderIndexMap.Add(kNumNoIndex); - continue; - } + bool emptyStream = !Files[i].HasStream; if (indexInFolder == 0) { + if (emptyStream) + { + FileIndexToFolderIndexMap[i] = kNumNoIndex; + continue; + } // v3.13 incorrectly worked with empty folders - // v4.07: Loop for skipping empty folders + // v4.07: we skip empty folders for (;;) { - if (folderIndex >= Folders.Size()) + if (folderIndex >= NumFolders) ThrowIncorrect(); - FolderStartFileIndex.Add(i); // check it + FolderStartFileIndex[folderIndex] = i; if (NumUnpackStreamsVector[folderIndex] != 0) break; folderIndex++; } } - FileIndexToFolderIndexMap.Add(folderIndex); + FileIndexToFolderIndexMap[i] = folderIndex; if (emptyStream) continue; - indexInFolder++; - if (indexInFolder >= NumUnpackStreamsVector[folderIndex]) + if (++indexInFolder >= NumUnpackStreamsVector[folderIndex]) { folderIndex++; indexInFolder = 0; } } + + if (indexInFolder != 0) + folderIndex++; + /* + if (indexInFolder != 0) + ThrowIncorrect(); + */ + for (;;) + { + if (folderIndex >= NumFolders) + return; + FolderStartFileIndex[folderIndex] = i; + /* + if (NumUnpackStreamsVector[folderIndex] != 0) + ThrowIncorrect();; + */ + folderIndex++; + } } HRESULT CInArchive::ReadDatabase2( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &db - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined - #endif + CDbEx &db + _7Z_DECODER_CRYPRO_VARS_DECL ) { db.Clear(); - db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; + db.ArcInfo.StartPosition = _arhiveBeginStreamPosition; - db.ArchiveInfo.Version.Major = _header[6]; - db.ArchiveInfo.Version.Minor = _header[7]; + db.ArcInfo.Version.Major = _header[6]; + db.ArcInfo.Version.Minor = _header[7]; - if (db.ArchiveInfo.Version.Major != kMajorVersion) - ThrowUnsupportedVersion(); + if (db.ArcInfo.Version.Major != kMajorVersion) + { + // db.UnsupportedVersion = true; + return S_FALSE; + } - UInt32 crcFromArchive = Get32(_header + 8); - UInt64 nextHeaderOffset = Get64(_header + 0xC); - UInt64 nextHeaderSize = Get64(_header + 0x14); - UInt32 nextHeaderCRC = Get32(_header + 0x1C); - UInt32 crc = CrcCalc(_header + 0xC, 20); + UInt64 nextHeaderOffset = Get64(_header + 12); + UInt64 nextHeaderSize = Get64(_header + 20); + UInt32 nextHeaderCRC = Get32(_header + 28); #ifdef FORMAT_7Z_RECOVERY - if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0) + UInt32 crcFromArc = Get32(_header + 8); + if (crcFromArc == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0) { - UInt64 cur, cur2; + UInt64 cur, fileSize; RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur)); - const int kCheckSize = 500; + const unsigned kCheckSize = 512; Byte buf[kCheckSize]; - RINOK(_stream->Seek(0, STREAM_SEEK_END, &cur2)); - int checkSize = kCheckSize; - if (cur2 - cur < kCheckSize) - checkSize = (int)(cur2 - cur); - RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2)); - + RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize)); + UInt64 rem = fileSize - cur; + unsigned checkSize = kCheckSize; + if (rem < kCheckSize) + checkSize = (unsigned)(rem); + if (checkSize < 3) + return S_FALSE; + RINOK(_stream->Seek(fileSize - checkSize, STREAM_SEEK_SET, NULL)); RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize)); - int i; - for (i = (int)checkSize - 2; i >= 0; i--) - if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04) - break; - if (i < 0) + if (buf[checkSize - 1] != 0) return S_FALSE; + + unsigned i; + for (i = checkSize - 2;; i--) + { + if (buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo || + buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo) + break; + if (i == 0) + return S_FALSE; + } nextHeaderSize = checkSize - i; - nextHeaderOffset = cur2 - cur + i; + nextHeaderOffset = rem - nextHeaderSize; nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL)); + db.StartHeaderWasRecovered = true; } else #endif { - if (crc != crcFromArchive) - ThrowIncorrect(); + // Crc was tested already at signature check + // if (CrcCalc(_header + 12, 20) != crcFromArchive) ThrowIncorrect(); } - db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; + db.ArcInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; + db.PhySize = kHeaderSize; + db.IsArc = false; + if ((Int64)nextHeaderOffset < 0 || + nextHeaderSize > ((UInt64)1 << 62)) + return S_FALSE; if (nextHeaderSize == 0) + { + if (nextHeaderOffset != 0) + return S_FALSE; + db.IsArc = true; return S_OK; + } - if (nextHeaderSize > (UInt64)0xFFFFFFFF) - return S_FALSE; + if (!db.StartHeaderWasRecovered) + db.IsArc = true; - if ((Int64)nextHeaderOffset < 0) + HeadersSize += kHeaderSize + nextHeaderSize; + db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize; + if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize) + { + db.UnexpectedEnd = true; return S_FALSE; - + } RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL)); - CByteBuffer buffer2; - buffer2.SetCapacity((size_t)nextHeaderSize); + size_t nextHeaderSize_t = (size_t)nextHeaderSize; + if (nextHeaderSize_t != nextHeaderSize) + return E_OUTOFMEMORY; + CByteBuffer buffer2(nextHeaderSize_t); - RINOK(ReadStream_FALSE(_stream, buffer2, (size_t)nextHeaderSize)); - HeadersSize += kHeaderSize + nextHeaderSize; - db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize; + RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t)); - if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC) + if (CrcCalc(buffer2, nextHeaderSize_t) != nextHeaderCRC) ThrowIncorrect(); - + + if (!db.StartHeaderWasRecovered) + db.PhySizeWasConfirmed = true; + CStreamSwitch streamSwitch; streamSwitch.Set(this, buffer2); - + CObjectVector<CByteBuffer> dataVector; - + UInt64 type = ReadID(); if (type != NID::kHeader) { @@ -1224,12 +1619,10 @@ HRESULT CInArchive::ReadDatabase2( ThrowIncorrect(); HRESULT result = ReadAndDecodePackedStreams( EXTERNAL_CODECS_LOC_VARS - db.ArchiveInfo.StartPositionAfterHeader, - db.ArchiveInfo.DataStartPosition2, + db.ArcInfo.StartPositionAfterHeader, + db.ArcInfo.DataStartPosition2, dataVector - #ifndef _NO_CRYPTO - , getTextPassword, passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS ); RINOK(result); if (dataVector.Size() == 0) @@ -1242,35 +1635,45 @@ HRESULT CInArchive::ReadDatabase2( ThrowIncorrect(); } + db.IsArc = true; + db.HeadersSize = HeadersSize; return ReadHeader( EXTERNAL_CODECS_LOC_VARS db - #ifndef _NO_CRYPTO - , getTextPassword, passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS ); } HRESULT CInArchive::ReadDatabase( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &db - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined - #endif + CDbEx &db + _7Z_DECODER_CRYPRO_VARS_DECL ) { try { - return ReadDatabase2( + HRESULT res = ReadDatabase2( EXTERNAL_CODECS_LOC_VARS db - #ifndef _NO_CRYPTO - , getTextPassword, passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS ); + if (ThereIsHeaderError) + db.ThereIsHeaderError = true; + if (res == E_NOTIMPL) + ThrowUnsupported(); + return res; + } + catch(CUnsupportedFeatureException &) + { + db.UnsupportedFeatureError = true; + return S_FALSE; + } + catch(CInArchiveException &) + { + db.ThereIsHeaderError = true; + return S_FALSE; } - catch(CInArchiveException &) { return S_FALSE; } } }} diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.h index 971f27b2a..98f61c81e 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.h @@ -5,6 +5,8 @@ #include "../../../Common/MyCom.h" +#include "../../../Windows/PropVariant.h" + #include "../../IPassword.h" #include "../../IStream.h" @@ -12,10 +14,151 @@ #include "../../Common/InBuffer.h" #include "7zItem.h" - + namespace NArchive { namespace N7z { - + +/* + We don't need to init isEncrypted and passwordIsDefined + We must upgrade them only */ + +#ifdef _NO_CRYPTO +#define _7Z_DECODER_CRYPRO_VARS_DECL +#define _7Z_DECODER_CRYPRO_VARS +#else +#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined +#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined +#endif + +struct CParsedMethods +{ + Byte Lzma2Prop; + UInt32 LzmaDic; + CRecordVector<UInt64> IDs; + + CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {} +}; + +struct CFolders +{ + CNum NumPackStreams; + CNum NumFolders; + + CObjArray<UInt64> PackPositions; // NumPackStreams + 1 + // CUInt32DefVector PackCRCs; // we don't use PackCRCs now + + CUInt32DefVector FolderCRCs; // NumFolders + CObjArray<CNum> NumUnpackStreamsVector; // NumFolders + + CObjArray<UInt64> CoderUnpackSizes; // including unpack sizes of bind coders + CObjArray<CNum> FoToCoderUnpackSizes; // NumFolders + 1 + CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1 + CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders + + CObjArray<size_t> FoCodersDataOffset; // NumFolders + 1 + CByteBuffer CodersData; + + CParsedMethods ParsedMethods; + + void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const; + + unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const + { + return FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]; + } + + UInt64 GetFolderUnpackSize(unsigned folderIndex) const + { + return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]]; + } + + UInt64 GetStreamPackSize(unsigned index) const + { + return PackPositions[index + 1] - PackPositions[index]; + } + + void Clear() + { + NumPackStreams = 0; + PackPositions.Free(); + // PackCRCs.Clear(); + + NumFolders = 0; + FolderCRCs.Clear(); + NumUnpackStreamsVector.Free(); + CoderUnpackSizes.Free(); + FoToCoderUnpackSizes.Free(); + FoStartPackStreamIndex.Free(); + FoToMainUnpackSizeIndex.Free(); + FoCodersDataOffset.Free(); + CodersData.Free(); + } +}; + +struct CDatabase: public CFolders +{ + CRecordVector<CFileItem> Files; + + CUInt64DefVector CTime; + CUInt64DefVector ATime; + CUInt64DefVector MTime; + CUInt64DefVector StartPos; + CRecordVector<bool> IsAnti; + /* + CRecordVector<bool> IsAux; + CByteBuffer SecureBuf; + CRecordVector<UInt32> SecureIDs; + */ + + CByteBuffer NamesBuf; + CObjArray<size_t> NameOffsets; // numFiles + 1, offsets of utf-16 symbols + + /* + void ClearSecure() + { + SecureBuf.Free(); + SecureIDs.Clear(); + } + */ + + void Clear() + { + CFolders::Clear(); + // ClearSecure(); + + NamesBuf.Free(); + NameOffsets.Free(); + + Files.Clear(); + CTime.Clear(); + ATime.Clear(); + MTime.Clear(); + StartPos.Clear(); + IsAnti.Clear(); + // IsAux.Clear(); + } + + bool IsSolid() const + { + for (CNum i = 0; i < NumFolders; i++) + if (NumUnpackStreamsVector[i] > 1) + return true; + return false; + } + bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } + // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } + + const void * GetName(unsigned index) const + { + if (!NameOffsets || !NamesBuf) + return NULL; + return (const void *)((const Byte *)NamesBuf + NameOffsets[index] * 2); + }; + + void GetPath(unsigned index, UString &path) const; + HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw(); +}; + struct CInArchiveInfo { CArchiveVersion Version; @@ -24,29 +167,73 @@ struct CInArchiveInfo UInt64 DataStartPosition; UInt64 DataStartPosition2; CRecordVector<UInt64> FileInfoPopIDs; + void Clear() { + StartPosition = 0; + StartPositionAfterHeader = 0; + DataStartPosition = 0; + DataStartPosition2 = 0; FileInfoPopIDs.Clear(); } }; -struct CArchiveDatabaseEx: public CArchiveDatabase +struct CDbEx: public CDatabase { - CInArchiveInfo ArchiveInfo; - CRecordVector<UInt64> PackStreamStartPositions; - CRecordVector<CNum> FolderStartPackStreamIndex; + CInArchiveInfo ArcInfo; CRecordVector<CNum> FolderStartFileIndex; CRecordVector<CNum> FileIndexToFolderIndexMap; UInt64 HeadersSize; UInt64 PhySize; + /* + CRecordVector<size_t> SecureOffsets; + bool IsTree; + bool ThereAreAltStreams; + */ + + bool IsArc; + bool PhySizeWasConfirmed; + + bool ThereIsHeaderError; + bool UnexpectedEnd; + // bool UnsupportedVersion; + + bool StartHeaderWasRecovered; + bool UnsupportedFeatureWarning; + bool UnsupportedFeatureError; + + /* + void ClearSecureEx() + { + ClearSecure(); + SecureOffsets.Clear(); + } + */ + void Clear() { - CArchiveDatabase::Clear(); - ArchiveInfo.Clear(); - PackStreamStartPositions.Clear(); - FolderStartPackStreamIndex.Clear(); + IsArc = false; + PhySizeWasConfirmed = false; + + ThereIsHeaderError = false; + UnexpectedEnd = false; + // UnsupportedVersion = false; + + StartHeaderWasRecovered = false; + UnsupportedFeatureError = false; + UnsupportedFeatureWarning = false; + + /* + IsTree = false; + ThereAreAltStreams = false; + */ + + CDatabase::Clear(); + + // SecureOffsets.Clear(); + ArcInfo.Clear(); FolderStartFileIndex.Clear(); FileIndexToFolderIndexMap.Clear(); @@ -54,36 +241,25 @@ struct CArchiveDatabaseEx: public CArchiveDatabase PhySize = 0; } - void FillFolderStartPackStream(); - void FillStartPos(); - void FillFolderStartFileIndex(); + void FillLinks(); - void Fill() - { - FillFolderStartPackStream(); - FillStartPos(); - FillFolderStartFileIndex(); - } - - UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const + UInt64 GetFolderStreamPos(unsigned folderIndex, unsigned indexInFolder) const { - return ArchiveInfo.DataStartPosition + - PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder]; + return ArcInfo.DataStartPosition + + PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder]; } - - UInt64 GetFolderFullPackSize(int folderIndex) const + + UInt64 GetFolderFullPackSize(unsigned folderIndex) const { - CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex]; - const CFolder &folder = Folders[folderIndex]; - UInt64 size = 0; - for (int i = 0; i < folder.PackStreams.Size(); i++) - size += PackSizes[packStreamIndex + i]; - return size; + return + PackPositions[FoStartPackStreamIndex[folderIndex + 1]] - + PackPositions[FoStartPackStreamIndex[folderIndex]]; } - - UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const + + UInt64 GetFolderPackStreamSize(unsigned folderIndex, unsigned streamIndex) const { - return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; + unsigned i = FoStartPackStreamIndex[folderIndex] + streamIndex; + return PackPositions[i + 1] - PackPositions[i]; } UInt64 GetFilePackSize(CNum fileIndex) const @@ -96,12 +272,17 @@ struct CArchiveDatabaseEx: public CArchiveDatabase } }; -class CInByte2 +const unsigned kNumBufLevelsMax = 4; + +struct CInByte2 { const Byte *_buffer; - size_t _size; public: + size_t _size; size_t _pos; + + size_t GetRem() const { return _size - _pos; } + const Byte *GetPtr() const { return _buffer + _pos; } void Init(const Byte *buffer, size_t size) { _buffer = buffer; @@ -110,13 +291,17 @@ public: } Byte ReadByte(); void ReadBytes(Byte *data, size_t size); + void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; } void SkipData(UInt64 size); + void SkipData(); + void SkipRem() { _pos = _size; } UInt64 ReadNumber(); CNum ReadNum(); UInt32 ReadUInt32(); UInt64 ReadUInt64(); - void ReadString(UString &s); + + void ParseFolder(CFolder &folder); }; class CStreamSwitch; @@ -129,32 +314,35 @@ class CInArchive CMyComPtr<IInStream> _stream; - CObjectVector<CInByte2> _inByteVector; + unsigned _numInByteBufs; + CInByte2 _inByteVector[kNumBufLevelsMax]; + CInByte2 *_inByteBack; - + bool ThereIsHeaderError; + UInt64 _arhiveBeginStreamPosition; + UInt64 _fileEndPosition; Byte _header[kHeaderSize]; UInt64 HeadersSize; - void AddByteStream(const Byte *buffer, size_t size) - { - _inByteVector.Add(CInByte2()); - _inByteBack = &_inByteVector.Back(); - _inByteBack->Init(buffer, size); - } - - void DeleteByteStream() + void AddByteStream(const Byte *buffer, size_t size); + + void DeleteByteStream(bool needUpdatePos) { - _inByteVector.DeleteBack(); - if (!_inByteVector.IsEmpty()) - _inByteBack = &_inByteVector.Back(); + _numInByteBufs--; + if (_numInByteBufs > 0) + { + _inByteBack = &_inByteVector[_numInByteBufs - 1]; + if (needUpdatePos) + _inByteBack->_pos += _inByteVector[_numInByteBufs]._pos; + } } private: HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); - + void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); } Byte ReadByte() { return _inByteBack->ReadByte(); } UInt64 ReadNumber() { return _inByteBack->ReadNumber(); } @@ -164,82 +352,61 @@ private: UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); } void SkipData(UInt64 size) { _inByteBack->SkipData(size); } void SkipData() { _inByteBack->SkipData(); } - void WaitAttribute(UInt64 attribute); + void WaitId(UInt64 id); void ReadArchiveProperties(CInArchiveInfo &archiveInfo); - void GetNextFolderItem(CFolder &itemInfo); - void ReadHashDigests(int numItems, - CBoolVector &digestsDefined, CRecordVector<UInt32> &digests); - - void ReadPackInfo( - UInt64 &dataOffset, - CRecordVector<UInt64> &packSizes, - CBoolVector &packCRCsDefined, - CRecordVector<UInt32> &packCRCs); - + void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs); + + void ReadPackInfo(CFolders &f); + void ReadUnpackInfo( const CObjectVector<CByteBuffer> *dataVector, - CObjectVector<CFolder> &folders); - + CFolders &folders); + void ReadSubStreamsInfo( - const CObjectVector<CFolder> &folders, - CRecordVector<CNum> &numUnpackStreamsInFolders, + CFolders &folders, CRecordVector<UInt64> &unpackSizes, - CBoolVector &digestsDefined, - CRecordVector<UInt32> &digests); + CUInt32DefVector &digests); void ReadStreamsInfo( const CObjectVector<CByteBuffer> *dataVector, UInt64 &dataOffset, - CRecordVector<UInt64> &packSizes, - CBoolVector &packCRCsDefined, - CRecordVector<UInt32> &packCRCs, - CObjectVector<CFolder> &folders, - CRecordVector<CNum> &numUnpackStreamsInFolders, + CFolders &folders, CRecordVector<UInt64> &unpackSizes, - CBoolVector &digestsDefined, - CRecordVector<UInt32> &digests); - + CUInt32DefVector &digests); - void ReadBoolVector(int numItems, CBoolVector &v); - void ReadBoolVector2(int numItems, CBoolVector &v); + void ReadBoolVector(unsigned numItems, CBoolVector &v); + void ReadBoolVector2(unsigned numItems, CBoolVector &v); void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector, - CUInt64DefVector &v, int numFiles); + CUInt64DefVector &v, unsigned numItems); HRESULT ReadAndDecodePackedStreams( DECL_EXTERNAL_CODECS_LOC_VARS UInt64 baseOffset, UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS_DECL ); HRESULT ReadHeader( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &db - #ifndef _NO_CRYPTO - ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined - #endif + CDbEx &db + _7Z_DECODER_CRYPRO_VARS_DECL ); HRESULT ReadDatabase2( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &db - #ifndef _NO_CRYPTO - ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined - #endif + CDbEx &db + _7Z_DECODER_CRYPRO_VARS_DECL ); public: + CInArchive(): _numInByteBufs(0) { } HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive void Close(); HRESULT ReadDatabase( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &db - #ifndef _NO_CRYPTO - ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined - #endif + CDbEx &db + _7Z_DECODER_CRYPRO_VARS_DECL ); }; - + }} - + #endif diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zItem.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zItem.h index 34f10775c..c112f83fd 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zItem.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zItem.h @@ -3,7 +3,7 @@ #ifndef __7Z_ITEM_H #define __7Z_ITEM_H -#include "../../../Common/Buffer.h" +#include "../../../Common/MyBuffer.h" #include "../../../Common/MyString.h" #include "../../Common/MethodId.h" @@ -25,6 +25,7 @@ struct CCoderInfo CByteBuffer Props; CNum NumInStreams; CNum NumOutStreams; + bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); } }; @@ -36,55 +37,48 @@ struct CBindPair struct CFolder { - CObjectVector<CCoderInfo> Coders; - CRecordVector<CBindPair> BindPairs; - CRecordVector<CNum> PackStreams; - CRecordVector<UInt64> UnpackSizes; - UInt32 UnpackCRC; - bool UnpackCRCDefined; - - CFolder(): UnpackCRCDefined(false) {} - - UInt64 GetUnpackSize() const // test it - { - if (UnpackSizes.IsEmpty()) - return 0; - for (int i = UnpackSizes.Size() - 1; i >= 0; i--) - if (FindBindPairForOutStream(i) < 0) - return UnpackSizes[i]; - throw 1; - } + CObjArray2<CCoderInfo> Coders; + CObjArray2<CBindPair> BindPairs; + CObjArray2<CNum> PackStreams; CNum GetNumOutStreams() const { CNum result = 0; - for (int i = 0; i < Coders.Size(); i++) + FOR_VECTOR(i, Coders) result += Coders[i].NumOutStreams; return result; } int FindBindPairForInStream(CNum inStreamIndex) const { - for(int i = 0; i < BindPairs.Size(); i++) + FOR_VECTOR(i, BindPairs) if (BindPairs[i].InIndex == inStreamIndex) return i; return -1; } int FindBindPairForOutStream(CNum outStreamIndex) const { - for(int i = 0; i < BindPairs.Size(); i++) + FOR_VECTOR(i, BindPairs) if (BindPairs[i].OutIndex == outStreamIndex) return i; return -1; } int FindPackStreamArrayIndex(CNum inStreamIndex) const { - for(int i = 0; i < PackStreams.Size(); i++) + FOR_VECTOR(i, PackStreams) if (PackStreams[i] == inStreamIndex) return i; return -1; } + int GetIndexOfMainOutStream() const + { + for (int i = (int)GetNumOutStreams() - 1; i >= 0; i--) + if (FindBindPairForOutStream(i) < 0) + return i; + throw 1; + } + bool IsEncrypted() const { for (int i = Coders.Size() - 1; i >= 0; i--) @@ -93,50 +87,66 @@ struct CFolder return false; } - bool CheckStructure() const; + bool CheckStructure(unsigned numUnpackSizes) const; +}; + +struct CUInt32DefVector +{ + CBoolVector Defs; + CRecordVector<UInt32> Vals; + + void ClearAndSetSize(unsigned newSize) + { + Defs.ClearAndSetSize(newSize); + Vals.ClearAndSetSize(newSize); + } + + void Clear() + { + Defs.Clear(); + Vals.Clear(); + } + + void ReserveDown() + { + Defs.ReserveDown(); + Vals.ReserveDown(); + } + + bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; } }; struct CUInt64DefVector { - CRecordVector<UInt64> Values; - CRecordVector<bool> Defined; - + CBoolVector Defs; + CRecordVector<UInt64> Vals; + void Clear() { - Values.Clear(); - Defined.Clear(); + Defs.Clear(); + Vals.Clear(); } - + void ReserveDown() { - Values.ReserveDown(); - Values.ReserveDown(); + Defs.ReserveDown(); + Vals.ReserveDown(); } - bool GetItem(int index, UInt64 &value) const + bool GetItem(unsigned index, UInt64 &value) const { - if (index < Defined.Size() && Defined[index]) + if (index < Defs.Size() && Defs[index]) { - value = Values[index]; + value = Vals[index]; return true; } value = 0; return false; } - - void SetItem(int index, bool defined, UInt64 value) - { - while (index >= Defined.Size()) - Defined.Add(false); - Defined[index] = defined; - if (!defined) - return; - while (index >= Values.Size()) - Values.Add(0); - Values[index] = value; - } - bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; } + void SetItem(unsigned index, bool defined, UInt64 value); + + bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; } }; struct CFileItem @@ -144,8 +154,10 @@ struct CFileItem UInt64 Size; UInt32 Attrib; UInt32 Crc; - UString Name; - + /* + int Parent; + bool IsAltStream; + */ bool HasStream; // Test it !!! it means that there is // stream in some folder. It can be empty stream bool IsDir; @@ -153,6 +165,10 @@ struct CFileItem bool AttribDefined; CFileItem(): + /* + Parent(-1), + IsAltStream(false), + */ HasStream(true), IsDir(false), CrcDefined(false), @@ -165,104 +181,6 @@ struct CFileItem } }; -struct CFileItem2 -{ - UInt64 CTime; - UInt64 ATime; - UInt64 MTime; - UInt64 StartPos; - bool CTimeDefined; - bool ATimeDefined; - bool MTimeDefined; - bool StartPosDefined; - bool IsAnti; -}; - -struct CArchiveDatabase -{ - CRecordVector<UInt64> PackSizes; - CRecordVector<bool> PackCRCsDefined; - CRecordVector<UInt32> PackCRCs; - CObjectVector<CFolder> Folders; - CRecordVector<CNum> NumUnpackStreamsVector; - CObjectVector<CFileItem> Files; - - CUInt64DefVector CTime; - CUInt64DefVector ATime; - CUInt64DefVector MTime; - CUInt64DefVector StartPos; - CRecordVector<bool> IsAnti; - - void Clear() - { - PackSizes.Clear(); - PackCRCsDefined.Clear(); - PackCRCs.Clear(); - Folders.Clear(); - NumUnpackStreamsVector.Clear(); - Files.Clear(); - CTime.Clear(); - ATime.Clear(); - MTime.Clear(); - StartPos.Clear(); - IsAnti.Clear(); - } - - void ReserveDown() - { - PackSizes.ReserveDown(); - PackCRCsDefined.ReserveDown(); - PackCRCs.ReserveDown(); - Folders.ReserveDown(); - NumUnpackStreamsVector.ReserveDown(); - Files.ReserveDown(); - CTime.ReserveDown(); - ATime.ReserveDown(); - MTime.ReserveDown(); - StartPos.ReserveDown(); - IsAnti.ReserveDown(); - } - - bool IsEmpty() const - { - return (PackSizes.IsEmpty() && - PackCRCsDefined.IsEmpty() && - PackCRCs.IsEmpty() && - Folders.IsEmpty() && - NumUnpackStreamsVector.IsEmpty() && - Files.IsEmpty()); - } - - bool CheckNumFiles() const - { - int size = Files.Size(); - return ( - CTime.CheckSize(size) && - ATime.CheckSize(size) && - MTime.CheckSize(size) && - StartPos.CheckSize(size) && - (size == IsAnti.Size() || IsAnti.Size() == 0)); - } - - bool IsSolid() const - { - for (int i = 0; i < NumUnpackStreamsVector.Size(); i++) - if (NumUnpackStreamsVector[i] > 1) - return true; - return false; - } - bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); } - void SetItemAnti(int index, bool isAnti) - { - while (index >= IsAnti.Size()) - IsAnti.Add(false); - IsAnti[index] = isAnti; - } - - void GetFile(int index, CFileItem &file, CFileItem2 &file2) const; - void AddFile(const CFileItem &file, const CFileItem2 &file2); -}; - }} #endif diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp index 0c8aa7e8c..e20858ea7 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp @@ -4,41 +4,19 @@ #include "../../../../C/7zCrc.h" -#include "../../../Common/AutoPtr.h" - #include "../../Common/StreamObjects.h" #include "7zOut.h" -static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size) -{ - while (size > 0) - { - UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF); - UInt32 processedSize; - RINOK(stream->Write(data, curSize, &processedSize)); - if (processedSize == 0) - return E_FAIL; - data = (const void *)((const Byte *)data + processedSize); - size -= processedSize; - } - return S_OK; -} - namespace NArchive { namespace N7z { -HRESULT COutArchive::WriteDirect(const void *data, UInt32 size) -{ - return ::WriteBytes(SeqStream, data, size); -} - HRESULT COutArchive::WriteSignature() { Byte buf[8]; memcpy(buf, kSignature, kSignatureSize); buf[kSignatureSize] = kMajorVersion; - buf[kSignatureSize + 1] = 3; + buf[kSignatureSize + 1] = 4; return WriteDirect(buf, 8); } @@ -145,7 +123,9 @@ HRESULT COutArchive::SkipPrefixArchiveHeader() if (_endMarker) return S_OK; #endif - return Stream->Seek(24, STREAM_SEEK_CUR, NULL); + Byte buf[24]; + memset(buf, 0, 24); + return WriteDirect(buf, 24); } UInt64 COutArchive::GetPos() const @@ -271,19 +251,19 @@ UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props) void COutArchive::WriteFolder(const CFolder &folder) { WriteNumber(folder.Coders.Size()); - int i; + unsigned i; for (i = 0; i < folder.Coders.Size(); i++) { const CCoderInfo &coder = folder.Coders[i]; { - size_t propsSize = coder.Props.GetCapacity(); - + size_t propsSize = coder.Props.Size(); + UInt64 id = coder.MethodID; int idSize; for (idSize = 1; idSize < sizeof(id); idSize++) if ((id >> (8 * idSize)) == 0) break; - BYTE longID[15]; + Byte longID[15]; for (int t = idSize - 1; t >= 0 ; t--, id >>= 8) longID[t] = (Byte)(id & 0xFF); Byte b; @@ -321,7 +301,7 @@ void COutArchive::WriteBoolVector(const CBoolVector &boolVector) { Byte b = 0; Byte mask = 0x80; - for (int i = 0; i < boolVector.Size(); i++) + FOR_VECTOR (i, boolVector) { if (boolVector[i]) b |= mask; @@ -337,37 +317,42 @@ void COutArchive::WriteBoolVector(const CBoolVector &boolVector) WriteByte(b); } +static inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; } -void COutArchive::WriteHashDigests( - const CRecordVector<bool> &digestsDefined, - const CRecordVector<UInt32> &digests) +void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector) { - int numDefined = 0; - int i; - for (i = 0; i < digestsDefined.Size(); i++) - if (digestsDefined[i]) + WriteByte(id); + WriteNumber(Bv_GetSizeInBytes(boolVector)); + WriteBoolVector(boolVector); +} + +void COutArchive::WriteHashDigests(const CUInt32DefVector &digests) +{ + unsigned numDefined = 0; + unsigned i; + for (i = 0; i < digests.Defs.Size(); i++) + if (digests.Defs[i]) numDefined++; if (numDefined == 0) return; WriteByte(NID::kCRC); - if (numDefined == digestsDefined.Size()) + if (numDefined == digests.Defs.Size()) WriteByte(1); else { WriteByte(0); - WriteBoolVector(digestsDefined); + WriteBoolVector(digests.Defs); } - for (i = 0; i < digests.Size(); i++) - if (digestsDefined[i]) - WriteUInt32(digests[i]); + for (i = 0; i < digests.Defs.Size(); i++) + if (digests.Defs[i]) + WriteUInt32(digests.Vals[i]); } void COutArchive::WritePackInfo( UInt64 dataOffset, const CRecordVector<UInt64> &packSizes, - const CRecordVector<bool> &packCRCsDefined, - const CRecordVector<UInt32> &packCRCs) + const CUInt32DefVector &packCRCs) { if (packSizes.IsEmpty()) return; @@ -375,15 +360,15 @@ void COutArchive::WritePackInfo( WriteNumber(dataOffset); WriteNumber(packSizes.Size()); WriteByte(NID::kSize); - for (int i = 0; i < packSizes.Size(); i++) + FOR_VECTOR (i, packSizes) WriteNumber(packSizes[i]); - WriteHashDigests(packCRCsDefined, packCRCs); - + WriteHashDigests(packCRCs); + WriteByte(NID::kEnd); } -void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders) +void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders, const COutFolders &outFolders) { if (folders.IsEmpty()) return; @@ -394,44 +379,29 @@ void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders) WriteNumber(folders.Size()); { WriteByte(0); - for (int i = 0; i < folders.Size(); i++) + FOR_VECTOR (i, folders) WriteFolder(folders[i]); } - + WriteByte(NID::kCodersUnpackSize); - int i; - for (i = 0; i < folders.Size(); i++) - { - const CFolder &folder = folders[i]; - for (int j = 0; j < folder.UnpackSizes.Size(); j++) - WriteNumber(folder.UnpackSizes[j]); - } + FOR_VECTOR (i, outFolders.CoderUnpackSizes) + WriteNumber(outFolders.CoderUnpackSizes[i]); - CRecordVector<bool> unpackCRCsDefined; - CRecordVector<UInt32> unpackCRCs; - for (i = 0; i < folders.Size(); i++) - { - const CFolder &folder = folders[i]; - unpackCRCsDefined.Add(folder.UnpackCRCDefined); - unpackCRCs.Add(folder.UnpackCRC); - } - WriteHashDigests(unpackCRCsDefined, unpackCRCs); + WriteHashDigests(outFolders.FolderUnpackCRCs); WriteByte(NID::kEnd); } -void COutArchive::WriteSubStreamsInfo( - const CObjectVector<CFolder> &folders, - const CRecordVector<CNum> &numUnpackStreamsInFolders, +void COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders, + const COutFolders &outFolders, const CRecordVector<UInt64> &unpackSizes, - const CRecordVector<bool> &digestsDefined, - const CRecordVector<UInt32> &digests) + const CUInt32DefVector &digests) { + const CRecordVector<CNum> &numUnpackStreamsInFolders = outFolders.NumUnpackStreamsVector; WriteByte(NID::kSubStreamsInfo); - int i; + unsigned i; for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) - { if (numUnpackStreamsInFolders[i] != 1) { WriteByte(NID::kNumUnpackStream); @@ -439,54 +409,50 @@ void COutArchive::WriteSubStreamsInfo( WriteNumber(numUnpackStreamsInFolders[i]); break; } - } - - bool needFlag = true; - CNum index = 0; for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) - for (CNum j = 0; j < numUnpackStreamsInFolders[i]; j++) + if (numUnpackStreamsInFolders[i] > 1) { - if (j + 1 != numUnpackStreamsInFolders[i]) + WriteByte(NID::kSize); + CNum index = 0; + for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) { - if (needFlag) - WriteByte(NID::kSize); - needFlag = false; - WriteNumber(unpackSizes[index]); + CNum num = numUnpackStreamsInFolders[i]; + for (CNum j = 0; j < num; j++) + { + if (j + 1 != num) + WriteNumber(unpackSizes[index]); + index++; + } } - index++; + break; } - CRecordVector<bool> digestsDefined2; - CRecordVector<UInt32> digests2; + CUInt32DefVector digests2; - int digestIndex = 0; + unsigned digestIndex = 0; for (i = 0; i < folders.Size(); i++) { - int numSubStreams = (int)numUnpackStreamsInFolders[i]; - if (numSubStreams == 1 && folders[i].UnpackCRCDefined) + unsigned numSubStreams = (unsigned)numUnpackStreamsInFolders[i]; + if (numSubStreams == 1 && outFolders.FolderUnpackCRCs.ValidAndDefined(i)) digestIndex++; else - for (int j = 0; j < numSubStreams; j++, digestIndex++) + for (unsigned j = 0; j < numSubStreams; j++, digestIndex++) { - digestsDefined2.Add(digestsDefined[digestIndex]); - digests2.Add(digests[digestIndex]); + digests2.Defs.Add(digests.Defs[digestIndex]); + digests2.Vals.Add(digests.Vals[digestIndex]); } } - WriteHashDigests(digestsDefined2, digests2); + WriteHashDigests(digests2); WriteByte(NID::kEnd); } -void COutArchive::SkipAlign(unsigned /* pos */, unsigned /* alignSize */) -{ - return; -} - -/* -7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field. +// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field. void COutArchive::SkipAlign(unsigned pos, unsigned alignSize) { + if (!_useAlign) + return; pos += (unsigned)GetPos(); pos &= (alignSize - 1); if (pos == 0) @@ -500,11 +466,8 @@ void COutArchive::SkipAlign(unsigned pos, unsigned alignSize) for (unsigned i = 0; i < skip; i++) WriteByte(0); } -*/ -static inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; } - -void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize) +void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize) { const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v); const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2; @@ -524,49 +487,54 @@ void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, B void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type) { - int numDefined = 0; + unsigned numDefined = 0; - int i; - for (i = 0; i < v.Defined.Size(); i++) - if (v.Defined[i]) + unsigned i; + for (i = 0; i < v.Defs.Size(); i++) + if (v.Defs[i]) numDefined++; if (numDefined == 0) return; - WriteAlignedBoolHeader(v.Defined, numDefined, type, 8); - - for (i = 0; i < v.Defined.Size(); i++) - if (v.Defined[i]) - WriteUInt64(v.Values[i]); + WriteAlignedBoolHeader(v.Defs, numDefined, type, 8); + + for (i = 0; i < v.Defs.Size(); i++) + if (v.Defs[i]) + WriteUInt64(v.Vals[i]); } HRESULT COutArchive::EncodeStream( DECL_EXTERNAL_CODECS_LOC_VARS CEncoder &encoder, const CByteBuffer &data, - CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders) + CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders) { CBufInStream *streamSpec = new CBufInStream; CMyComPtr<ISequentialInStream> stream = streamSpec; - streamSpec->Init(data, data.GetCapacity()); - CFolder folderItem; - folderItem.UnpackCRCDefined = true; - folderItem.UnpackCRC = CrcCalc(data, data.GetCapacity()); - UInt64 dataSize64 = data.GetCapacity(); + streamSpec->Init(data, data.Size()); + outFolders.FolderUnpackCRCs.Defs.Add(true); + outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size())); + // outFolders.NumUnpackStreamsVector.Add(1); + UInt64 dataSize64 = data.Size(); + UInt64 unpackSize; RINOK(encoder.Encode( EXTERNAL_CODECS_LOC_VARS - stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL)) - folders.Add(folderItem); + stream, NULL, &dataSize64, folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL)) return S_OK; } void COutArchive::WriteHeader( - const CArchiveDatabase &db, - const CHeaderOptions &headerOptions, + const CArchiveDatabaseOut &db, + // const CHeaderOptions &headerOptions, UInt64 &headerOffset) { - int i; - + /* + bool thereIsSecure = (db.SecureBuf.Size() != 0); + */ + _useAlign = true; + + unsigned i; + UInt64 packedSize = 0; for (i = 0; i < db.PackSizes.Size(); i++) packedSize += db.PackSizes[i]; @@ -580,31 +548,22 @@ void COutArchive::WriteHeader( if (db.Folders.Size() > 0) { WriteByte(NID::kMainStreamsInfo); - WritePackInfo(0, db.PackSizes, - db.PackCRCsDefined, - db.PackCRCs); - - WriteUnpackInfo(db.Folders); + WritePackInfo(0, db.PackSizes, db.PackCRCs); + WriteUnpackInfo(db.Folders, (const COutFolders &)db); CRecordVector<UInt64> unpackSizes; - CRecordVector<bool> digestsDefined; - CRecordVector<UInt32> digests; + CUInt32DefVector digests; for (i = 0; i < db.Files.Size(); i++) { const CFileItem &file = db.Files[i]; if (!file.HasStream) continue; unpackSizes.Add(file.Size); - digestsDefined.Add(file.CrcDefined); - digests.Add(file.Crc); + digests.Defs.Add(file.CrcDefined); + digests.Vals.Add(file.Crc); } - WriteSubStreamsInfo( - db.Folders, - db.NumUnpackStreamsVector, - unpackSizes, - digestsDefined, - digests); + WriteSubStreamsInfo(db.Folders, (const COutFolders &)db, unpackSizes, digests); WriteByte(NID::kEnd); } @@ -618,85 +577,75 @@ void COutArchive::WriteHeader( WriteNumber(db.Files.Size()); { - /* ---------- Empty Streams ---------- */ - CBoolVector emptyStreamVector; - emptyStreamVector.Reserve(db.Files.Size()); - int numEmptyStreams = 0; - for (i = 0; i < db.Files.Size(); i++) - if (db.Files[i].HasStream) - emptyStreamVector.Add(false); - else - { - emptyStreamVector.Add(true); - numEmptyStreams++; - } - if (numEmptyStreams > 0) - { - WriteByte(NID::kEmptyStream); - WriteNumber(Bv_GetSizeInBytes(emptyStreamVector)); - WriteBoolVector(emptyStreamVector); - - CBoolVector emptyFileVector, antiVector; - emptyFileVector.Reserve(numEmptyStreams); - antiVector.Reserve(numEmptyStreams); - CNum numEmptyFiles = 0, numAntiItems = 0; + /* ---------- Empty Streams ---------- */ + CBoolVector emptyStreamVector; + emptyStreamVector.ClearAndSetSize(db.Files.Size()); + unsigned numEmptyStreams = 0; for (i = 0; i < db.Files.Size(); i++) + if (db.Files[i].HasStream) + emptyStreamVector[i] = false; + else + { + emptyStreamVector[i] = true; + numEmptyStreams++; + } + if (numEmptyStreams != 0) { - const CFileItem &file = db.Files[i]; - if (!file.HasStream) + WritePropBoolVector(NID::kEmptyStream, emptyStreamVector); + + CBoolVector emptyFileVector, antiVector; + emptyFileVector.ClearAndSetSize(numEmptyStreams); + antiVector.ClearAndSetSize(numEmptyStreams); + bool thereAreEmptyFiles = false, thereAreAntiItems = false; + unsigned cur = 0; + for (i = 0; i < db.Files.Size(); i++) { - emptyFileVector.Add(!file.IsDir); + const CFileItem &file = db.Files[i]; + if (file.HasStream) + continue; + emptyFileVector[cur] = !file.IsDir; if (!file.IsDir) - numEmptyFiles++; + thereAreEmptyFiles = true; bool isAnti = db.IsItemAnti(i); - antiVector.Add(isAnti); + antiVector[cur] = isAnti; if (isAnti) - numAntiItems++; + thereAreAntiItems = true; + cur++; } - } - if (numEmptyFiles > 0) - { - WriteByte(NID::kEmptyFile); - WriteNumber(Bv_GetSizeInBytes(emptyFileVector)); - WriteBoolVector(emptyFileVector); - } - - if (numAntiItems > 0) - { - WriteByte(NID::kAnti); - WriteNumber(Bv_GetSizeInBytes(antiVector)); - WriteBoolVector(antiVector); + if (thereAreEmptyFiles) + WritePropBoolVector(NID::kEmptyFile, emptyFileVector); + if (thereAreAntiItems) + WritePropBoolVector(NID::kAnti, antiVector); } } - } { /* ---------- Names ---------- */ - - int numDefined = 0; + + unsigned numDefined = 0; size_t namesDataSize = 0; - for (int i = 0; i < db.Files.Size(); i++) + FOR_VECTOR (i, db.Files) { - const UString &name = db.Files[i].Name; + const UString &name = db.Names[i]; if (!name.IsEmpty()) numDefined++; - namesDataSize += (name.Length() + 1) * 2; + namesDataSize += (name.Len() + 1) * 2; } - + if (numDefined > 0) { namesDataSize++; - SkipAlign(2 + GetBigNumberSize(namesDataSize), 2); + SkipAlign(2 + GetBigNumberSize(namesDataSize), 16); WriteByte(NID::kName); WriteNumber(namesDataSize); WriteByte(0); - for (int i = 0; i < db.Files.Size(); i++) + FOR_VECTOR (i, db.Files) { - const UString &name = db.Files[i].Name; - for (int t = 0; t <= name.Length(); t++) + const UString &name = db.Names[i]; + for (unsigned t = 0; t <= name.Len(); t++) { wchar_t c = name[t]; WriteByte((Byte)c); @@ -706,26 +655,26 @@ void COutArchive::WriteHeader( } } - if (headerOptions.WriteCTime) WriteUInt64DefVector(db.CTime, NID::kCTime); - if (headerOptions.WriteATime) WriteUInt64DefVector(db.ATime, NID::kATime); - if (headerOptions.WriteMTime) WriteUInt64DefVector(db.MTime, NID::kMTime); + /* if (headerOptions.WriteCTime) */ WriteUInt64DefVector(db.CTime, NID::kCTime); + /* if (headerOptions.WriteATime) */ WriteUInt64DefVector(db.ATime, NID::kATime); + /* if (headerOptions.WriteMTime) */ WriteUInt64DefVector(db.MTime, NID::kMTime); WriteUInt64DefVector(db.StartPos, NID::kStartPos); - + { /* ---------- Write Attrib ---------- */ CBoolVector boolVector; - boolVector.Reserve(db.Files.Size()); - int numDefined = 0; + boolVector.ClearAndSetSize(db.Files.Size()); + unsigned numDefined = 0; for (i = 0; i < db.Files.Size(); i++) { bool defined = db.Files[i].AttribDefined; - boolVector.Add(defined); + boolVector[i] = defined; if (defined) numDefined++; } - if (numDefined > 0) + if (numDefined != 0) { - WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttributes, 4); + WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4); for (i = 0; i < db.Files.Size(); i++) { const CFileItem &file = db.Files[i]; @@ -735,13 +684,95 @@ void COutArchive::WriteHeader( } } + /* + { + // ---------- Write IsAux ---------- + unsigned numAux = 0; + const CBoolVector &isAux = db.IsAux; + for (i = 0; i < isAux.Size(); i++) + if (isAux[i]) + numAux++; + if (numAux > 0) + { + const unsigned bvSize = Bv_GetSizeInBytes(isAux); + WriteByte(NID::kIsAux); + WriteNumber(bvSize); + WriteBoolVector(isAux); + } + } + + { + // ---------- Write Parent ---------- + CBoolVector boolVector; + boolVector.Reserve(db.Files.Size()); + unsigned numIsDir = 0; + unsigned numParentLinks = 0; + for (i = 0; i < db.Files.Size(); i++) + { + const CFileItem &file = db.Files[i]; + bool defined = !file.IsAltStream; + boolVector.Add(defined); + if (defined) + numIsDir++; + if (file.Parent >= 0) + numParentLinks++; + } + if (numParentLinks > 0) + { + // WriteAlignedBoolHeader(boolVector, numDefined, NID::kParent, 4); + const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector); + const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1; + SkipAlign(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 4); + + WriteByte(NID::kParent); + WriteNumber(dataSize); + if (numIsDir == boolVector.Size()) + WriteByte(1); + else + { + WriteByte(0); + WriteBoolVector(boolVector); + } + for (i = 0; i < db.Files.Size(); i++) + { + const CFileItem &file = db.Files[i]; + // if (file.Parent >= 0) + WriteUInt32(file.Parent); + } + } + } + + if (thereIsSecure) + { + UInt64 secureDataSize = 1 + 4 + + db.SecureBuf.Size() + + db.SecureSizes.Size() * 4; + // secureDataSize += db.SecureIDs.Size() * 4; + for (i = 0; i < db.SecureIDs.Size(); i++) + secureDataSize += GetBigNumberSize(db.SecureIDs[i]); + SkipAlign(2 + GetBigNumberSize(secureDataSize), 4); + WriteByte(NID::kNtSecure); + WriteNumber(secureDataSize); + WriteByte(0); + WriteUInt32(db.SecureSizes.Size()); + for (i = 0; i < db.SecureSizes.Size(); i++) + WriteUInt32(db.SecureSizes[i]); + WriteBytes(db.SecureBuf, db.SecureBuf.Size()); + for (i = 0; i < db.SecureIDs.Size(); i++) + { + WriteNumber(db.SecureIDs[i]); + // WriteUInt32(db.SecureIDs[i]); + } + } + */ + WriteByte(NID::kEnd); // for files WriteByte(NID::kEnd); // for headers } HRESULT COutArchive::WriteDatabase( DECL_EXTERNAL_CODECS_LOC_VARS - const CArchiveDatabase &db, + const CArchiveDatabaseOut &db, const CCompressionMethodMode *options, const CHeaderOptions &headerOptions) { @@ -773,18 +804,17 @@ HRESULT COutArchive::WriteDatabase( _countMode = encodeHeaders; _writeToStream = true; _countSize = 0; - WriteHeader(db, headerOptions, headerOffset); + WriteHeader(db, /* headerOptions, */ headerOffset); if (encodeHeaders) { - CByteBuffer buf; - buf.SetCapacity(_countSize); + CByteBuffer buf(_countSize); _outByte2.Init((Byte *)buf, _countSize); - + _countMode = false; _writeToStream = false; - WriteHeader(db, headerOptions, headerOffset); - + WriteHeader(db, /* headerOptions, */ headerOffset); + if (_countSize != _outByte2.GetPos()) return E_FAIL; @@ -794,22 +824,23 @@ HRESULT COutArchive::WriteDatabase( CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions); CRecordVector<UInt64> packSizes; CObjectVector<CFolder> folders; + COutFolders outFolders; + RINOK(EncodeStream( EXTERNAL_CODECS_LOC_VARS encoder, buf, - packSizes, folders)); + packSizes, folders, outFolders)); _writeToStream = true; - + if (folders.Size() == 0) throw 1; WriteID(NID::kEncodedHeader); - WritePackInfo(headerOffset, packSizes, - CRecordVector<bool>(), CRecordVector<UInt32>()); - WriteUnpackInfo(folders); + WritePackInfo(headerOffset, packSizes, CUInt32DefVector()); + WriteUnpackInfo(folders, outFolders); WriteByte(NID::kEnd); - for (int i = 0; i < packSizes.Size(); i++) + FOR_VECTOR (i, packSizes) headerOffset += packSizes[i]; } RINOK(_outByte.Flush()); @@ -842,24 +873,28 @@ HRESULT COutArchive::WriteDatabase( } } -void CArchiveDatabase::GetFile(int index, CFileItem &file, CFileItem2 &file2) const +void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value) { - file = Files[index]; - file2.CTimeDefined = CTime.GetItem(index, file2.CTime); - file2.ATimeDefined = ATime.GetItem(index, file2.ATime); - file2.MTimeDefined = MTime.GetItem(index, file2.MTime); - file2.StartPosDefined = StartPos.GetItem(index, file2.StartPos); - file2.IsAnti = IsItemAnti(index); + while (index >= Defs.Size()) + Defs.Add(false); + Defs[index] = defined; + if (!defined) + return; + while (index >= Vals.Size()) + Vals.Add(0); + Vals[index] = value; } -void CArchiveDatabase::AddFile(const CFileItem &file, const CFileItem2 &file2) +void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name) { - int index = Files.Size(); + unsigned index = Files.Size(); CTime.SetItem(index, file2.CTimeDefined, file2.CTime); ATime.SetItem(index, file2.ATimeDefined, file2.ATime); MTime.SetItem(index, file2.MTimeDefined, file2.MTime); StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos); - SetItemAnti(index, file2.IsAnti); + SetItem_Anti(index, file2.IsAnti); + // SetItem_Aux(index, file2.IsAux); + Names.Add(name); Files.Add(file); } diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.h index 7b1b528e6..391ca9d02 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.h @@ -9,6 +9,7 @@ #include "7zItem.h" #include "../../Common/OutBuffer.h" +#include "../../Common/StreamUtils.h" namespace NArchive { namespace N7z { @@ -45,27 +46,191 @@ public: struct CHeaderOptions { bool CompressMainHeader; + /* bool WriteCTime; bool WriteATime; bool WriteMTime; + */ CHeaderOptions(): - CompressMainHeader(true), - WriteCTime(false), - WriteATime(false), - WriteMTime(true) + CompressMainHeader(true) + /* + , WriteCTime(false) + , WriteATime(false) + , WriteMTime(true) + */ {} }; + +struct CFileItem2 +{ + UInt64 CTime; + UInt64 ATime; + UInt64 MTime; + UInt64 StartPos; + bool CTimeDefined; + bool ATimeDefined; + bool MTimeDefined; + bool StartPosDefined; + bool IsAnti; + // bool IsAux; + + void Init() + { + CTimeDefined = false; + ATimeDefined = false; + MTimeDefined = false; + StartPosDefined = false; + IsAnti = false; + // IsAux = false; + } +}; + +struct COutFolders +{ + CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only. + + CRecordVector<CNum> NumUnpackStreamsVector; + CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bind coders + + void OutFoldersClear() + { + FolderUnpackCRCs.Clear(); + NumUnpackStreamsVector.Clear(); + CoderUnpackSizes.Clear(); + } + + void OutFoldersReserveDown() + { + FolderUnpackCRCs.ReserveDown(); + NumUnpackStreamsVector.ReserveDown(); + CoderUnpackSizes.ReserveDown(); + } +}; + +struct CArchiveDatabaseOut: public COutFolders +{ + CRecordVector<UInt64> PackSizes; + CUInt32DefVector PackCRCs; + CObjectVector<CFolder> Folders; + + CRecordVector<CFileItem> Files; + UStringVector Names; + CUInt64DefVector CTime; + CUInt64DefVector ATime; + CUInt64DefVector MTime; + CUInt64DefVector StartPos; + CRecordVector<bool> IsAnti; + + /* + CRecordVector<bool> IsAux; + + CByteBuffer SecureBuf; + CRecordVector<UInt32> SecureSizes; + CRecordVector<UInt32> SecureIDs; + + void ClearSecure() + { + SecureBuf.Free(); + SecureSizes.Clear(); + SecureIDs.Clear(); + } + */ + + void Clear() + { + OutFoldersClear(); + + PackSizes.Clear(); + PackCRCs.Clear(); + Folders.Clear(); + + Files.Clear(); + Names.Clear(); + CTime.Clear(); + ATime.Clear(); + MTime.Clear(); + StartPos.Clear(); + IsAnti.Clear(); + + /* + IsAux.Clear(); + ClearSecure(); + */ + } + + void ReserveDown() + { + OutFoldersReserveDown(); + + PackSizes.ReserveDown(); + PackCRCs.ReserveDown(); + Folders.ReserveDown(); + + Files.ReserveDown(); + Names.ReserveDown(); + CTime.ReserveDown(); + ATime.ReserveDown(); + MTime.ReserveDown(); + StartPos.ReserveDown(); + IsAnti.ReserveDown(); + + /* + IsAux.ReserveDown(); + */ + } + + bool IsEmpty() const + { + return ( + PackSizes.IsEmpty() && + NumUnpackStreamsVector.IsEmpty() && + Folders.IsEmpty() && + Files.IsEmpty()); + } + + bool CheckNumFiles() const + { + unsigned size = Files.Size(); + return ( + CTime.CheckSize(size) && + ATime.CheckSize(size) && + MTime.CheckSize(size) && + StartPos.CheckSize(size) && + (size == IsAnti.Size() || IsAnti.Size() == 0)); + } + + bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } + // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } + + void SetItem_Anti(unsigned index, bool isAnti) + { + while (index >= IsAnti.Size()) + IsAnti.Add(false); + IsAnti[index] = isAnti; + } + /* + void SetItem_Aux(unsigned index, bool isAux) + { + while (index >= IsAux.Size()) + IsAux.Add(false); + IsAux[index] = isAux; + } + */ + + void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name); +}; + class COutArchive { UInt64 _prefixHeaderPos; - HRESULT WriteDirect(const void *data, UInt32 size); - + HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); } + UInt64 GetPos() const; void WriteBytes(const void *data, size_t size); - void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.GetCapacity()); } + void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); } void WriteByte(Byte b); void WriteUInt32(UInt32 value); void WriteUInt64(UInt64 value); @@ -75,38 +240,38 @@ class COutArchive void WriteFolder(const CFolder &folder); HRESULT WriteFileHeader(const CFileItem &itemInfo); void WriteBoolVector(const CBoolVector &boolVector); - void WriteHashDigests( - const CRecordVector<bool> &digestsDefined, - const CRecordVector<UInt32> &hashDigests); + void WritePropBoolVector(Byte id, const CBoolVector &boolVector); + + void WriteHashDigests(const CUInt32DefVector &digests); void WritePackInfo( UInt64 dataOffset, const CRecordVector<UInt64> &packSizes, - const CRecordVector<bool> &packCRCsDefined, - const CRecordVector<UInt32> &packCRCs); + const CUInt32DefVector &packCRCs); - void WriteUnpackInfo(const CObjectVector<CFolder> &folders); + void WriteUnpackInfo( + const CObjectVector<CFolder> &folders, + const COutFolders &outFolders); void WriteSubStreamsInfo( const CObjectVector<CFolder> &folders, - const CRecordVector<CNum> &numUnpackStreamsInFolders, + const COutFolders &outFolders, const CRecordVector<UInt64> &unpackSizes, - const CRecordVector<bool> &digestsDefined, - const CRecordVector<UInt32> &hashDigests); + const CUInt32DefVector &digests); void SkipAlign(unsigned pos, unsigned alignSize); - void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize); + void WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize); void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type); HRESULT EncodeStream( DECL_EXTERNAL_CODECS_LOC_VARS CEncoder &encoder, const CByteBuffer &data, - CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders); + CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders); void WriteHeader( - const CArchiveDatabase &db, - const CHeaderOptions &headerOptions, + const CArchiveDatabaseOut &db, + // const CHeaderOptions &headerOptions, UInt64 &headerOffset); - + bool _countMode; bool _writeToStream; size_t _countSize; @@ -118,6 +283,8 @@ class COutArchive bool _endMarker; #endif + bool _useAlign; + HRESULT WriteSignature(); #ifdef _7Z_VOL HRESULT WriteFinishSignature(); @@ -136,7 +303,7 @@ public: HRESULT SkipPrefixArchiveHeader(); HRESULT WriteDatabase( DECL_EXTERNAL_CODECS_LOC_VARS - const CArchiveDatabase &db, + const CArchiveDatabaseOut &db, const CCompressionMethodMode *options, const CHeaderOptions &headerOptions); diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zProperties.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zProperties.cpp index fd4af49c7..a29f8abe9 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zProperties.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zProperties.cpp @@ -17,12 +17,12 @@ struct CPropMap STATPROPSTG StatPROPSTG; }; -CPropMap kPropMap[] = +static const CPropMap kPropMap[] = { { NID::kName, { NULL, kpidPath, VT_BSTR } }, { NID::kSize, { NULL, kpidSize, VT_UI8 } }, { NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } }, - + #ifdef _MULTI_PACK { 100, { L"Pack0", kpidPackedSize0, VT_UI8 } }, { 101, { L"Pack1", kpidPackedSize1, VT_UI8 } }, @@ -34,11 +34,12 @@ CPropMap kPropMap[] = { NID::kCTime, { NULL, kpidCTime, VT_FILETIME } }, { NID::kMTime, { NULL, kpidMTime, VT_FILETIME } }, { NID::kATime, { NULL, kpidATime, VT_FILETIME } }, - { NID::kWinAttributes, { NULL, kpidAttrib, VT_UI4 } }, + { NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } }, { NID::kStartPos, { NULL, kpidPosition, VT_UI4 } }, { NID::kCRC, { NULL, kpidCRC, VT_UI4 } }, - + +// { NID::kIsAux, { NULL, kpidIsAux, VT_BOOL } }, { NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } } #ifndef _SFX @@ -49,11 +50,9 @@ CPropMap kPropMap[] = #endif }; -static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]); - static int FindPropInMap(UInt64 filePropID) { - for (int i = 0; i < kPropMapSize; i++) + for (int i = 0; i < ARRAY_SIZE(kPropMap); i++) if (kPropMap[i].FilePropID == filePropID) return i; return -1; @@ -62,7 +61,7 @@ static int FindPropInMap(UInt64 filePropID) static void CopyOneItem(CRecordVector<UInt64> &src, CRecordVector<UInt64> &dest, UInt32 item) { - for (int i = 0; i < src.Size(); i++) + FOR_VECTOR (i, src) if (src[i] == item) { dest.Add(item); @@ -73,7 +72,7 @@ static void CopyOneItem(CRecordVector<UInt64> &src, static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item) { - for (int i = 0; i < src.Size(); i++) + FOR_VECTOR (i, src) if (src[i] == item) { src.Delete(i); @@ -83,7 +82,7 @@ static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item) static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item) { - for (int i = 0; i < dest.Size(); i++) + FOR_VECTOR (i, dest) if (dest[i] == item) { dest.Delete(i); @@ -92,34 +91,41 @@ static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item) dest.Insert(0, item); } +#define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id); + void CHandler::FillPopIDs() { _fileInfoPopIDs.Clear(); #ifdef _7Z_VOL - if(_volumes.Size() < 1) + if (_volumes.Size() < 1) return; const CVolume &volume = _volumes.Front(); const CArchiveDatabaseEx &_db = volume.Database; #endif - CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs; + CRecordVector<UInt64> fileInfoPopIDs = _db.ArcInfo.FileInfoPopIDs; RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream); RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); + /* + RemoveOneItem(fileInfoPopIDs, NID::kParent); + RemoveOneItem(fileInfoPopIDs, NID::kNtSecure); + */ + + COPY_ONE_ITEM(kName); + COPY_ONE_ITEM(kAnti); + COPY_ONE_ITEM(kSize); + COPY_ONE_ITEM(kPackInfo); + COPY_ONE_ITEM(kCTime); + COPY_ONE_ITEM(kMTime); + COPY_ONE_ITEM(kATime); + COPY_ONE_ITEM(kWinAttrib); + COPY_ONE_ITEM(kCRC); + COPY_ONE_ITEM(kComment); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment); _fileInfoPopIDs += fileInfoPopIDs; - + #ifndef _SFX _fileInfoPopIDs.Add(97); _fileInfoPopIDs.Add(98); @@ -141,9 +147,9 @@ void CHandler::FillPopIDs() #endif } -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) { - *numProperties = _fileInfoPopIDs.Size(); + *numProps = _fileInfoPopIDs.Size(); return S_OK; } diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zRegister.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zRegister.cpp index 6e9bf6b99..37ea29d30 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zRegister.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zRegister.cpp @@ -5,14 +5,21 @@ #include "../../Common/RegisterArc.h" #include "7zHandler.h" -static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; } -#ifndef EXTRACT_ONLY -static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; } -#else -#define CreateArcOut 0 -#endif + +namespace NArchive { +namespace N7z { + +IMP_CreateArcIn +IMP_CreateArcOut static CArcInfo g_ArcInfo = - { L"7z", L"7z", 0, 7, {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut }; + { "7z", "7z", 0, 7, + 6, {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C}, + 0, + NArcInfoFlags::kFindSignature, + REF_CreateArc_Pair }; + +REGISTER_ARC_DEC_SIG(7z) +// REGISTER_ARC(7z) -REGISTER_ARC(7z) +}} diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zSpecStream.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zSpecStream.cpp index 06969636d..8e45d9875 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zSpecStream.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zSpecStream.cpp @@ -9,16 +9,14 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 UInt32 realProcessedSize; HRESULT result = _stream->Read(data, size, &realProcessedSize); _size += realProcessedSize; - if (processedSize != 0) + if (processedSize) *processedSize = realProcessedSize; return result; } -STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize( - UInt64 subStream, UInt64 *value) +STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value) { - if (_getSubStreamSize == NULL) + if (!_getSubStreamSize) return E_NOTIMPL; - return _getSubStreamSize->GetSubStreamSize(subStream, value); + return _getSubStreamSize->GetSubStreamSize(subStream, value); } - diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.cpp index ee7f55c04..26faf2a18 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.cpp @@ -4,10 +4,11 @@ #include "../../../../C/CpuArch.h" -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" +#include "../../../Common/Wildcard.h" #include "../../Common/CreateCoder.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" #include "../../Compress/CopyCoder.h" @@ -24,15 +25,6 @@ namespace NArchive { namespace N7z { -static const UInt64 k_LZMA = 0x030101; -static const UInt64 k_BCJ = 0x03030103; -static const UInt64 k_BCJ2 = 0x0303011B; - -static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2"; -static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20; -static const UInt32 kAlgorithmForBCJ2_LZMA = 1; -static const UInt32 kNumFastBytesForBCJ2_LZMA = 64; - #ifdef MY_CPU_X86_OR_AMD64 #define USE_86_FILTER #endif @@ -67,19 +59,20 @@ int CUpdateItem::GetExtensionPos() const int slashPos = GetReverseSlashPos(Name); int dotPos = Name.ReverseFind(L'.'); if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0)) - return Name.Length(); + return Name.Len(); return dotPos + 1; } UString CUpdateItem::GetExtension() const { - return Name.Mid(GetExtensionPos()); + return Name.Ptr(GetExtensionPos()); } #define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } #define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b)) +/* static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2) { size_t c1 = a1.GetCapacity(); @@ -119,11 +112,12 @@ static int CompareFolders(const CFolder &f1, const CFolder &f2) RINOZ(CompareBindPairs(f1.BindPairs[i], f2.BindPairs[i])); return 0; } +*/ /* static int CompareFiles(const CFileItem &f1, const CFileItem &f2) { - return MyStringCompareNoCase(f1.Name, f2.Name); + return CompareFileNames(f1.Name, f2.Name); } */ @@ -134,15 +128,19 @@ struct CFolderRepack CNum NumCopyFiles; }; -static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void *param) +static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void * /* param */) { RINOZ_COMP(p1->Group, p2->Group); int i1 = p1->FolderIndex; int i2 = p2->FolderIndex; - const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param; + /* + // In that version we don't want to parse folders here, so we don't compare folders + // probably it must be improved in future + const CDbEx &db = *(const CDbEx *)param; RINOZ(CompareFolders( db.Folders[i1], db.Folders[i2])); + */ return MyCompare(i1, i2); /* RINOZ_COMP( @@ -156,25 +154,31 @@ static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2 */ } -//////////////////////////////////////////////////////////// +/* + we sort empty files and dirs in such order: + - Dir.NonAnti (name sorted) + - File.NonAnti (name sorted) + - File.Anti (name sorted) + - Dir.Anti (reverse name sorted) +*/ static int CompareEmptyItems(const int *p1, const int *p2, void *param) { const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param; const CUpdateItem &u1 = updateItems[*p1]; const CUpdateItem &u2 = updateItems[*p2]; + // NonAnti < Anti + if (u1.IsAnti != u2.IsAnti) + return (u1.IsAnti ? 1 : -1); if (u1.IsDir != u2.IsDir) - return (u1.IsDir) ? 1 : -1; - if (u1.IsDir) { - if (u1.IsAnti != u2.IsAnti) + // Dir.NonAnti < File < Dir.Anti + if (u1.IsDir) return (u1.IsAnti ? 1 : -1); - int n = MyStringCompareNoCase(u1.Name, u2.Name); - return -n; + return (u2.IsAnti ? -1 : 1); } - if (u1.IsAnti != u2.IsAnti) - return (u1.IsAnti ? 1 : -1); - return MyStringCompareNoCase(u1.Name, u2.Name); + int n = CompareFileNames(u1.Name, u2.Name); + return (u1.IsDir && u1.IsAnti) ? -n : n; } static const char *g_Exts = @@ -207,7 +211,7 @@ static const char *g_Exts = " exe dll ocx vbx sfx sys tlb awx com obj lib out o so " " pdb pch idb ncb opt"; -int GetExtIndex(const char *ext) +static int GetExtIndex(const char *ext) { int extIndex = 1; const char *p = g_Exts; @@ -246,7 +250,9 @@ struct CRefItem UInt32 Index; UInt32 ExtensionPos; UInt32 NamePos; - int ExtensionIndex; + unsigned ExtensionIndex; + + CRefItem() {}; CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType): UpdateItem(&ui), Index(index), @@ -257,64 +263,134 @@ struct CRefItem if (sortByType) { int slashPos = GetReverseSlashPos(ui.Name); - NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0); + NamePos = slashPos + 1; int dotPos = ui.Name.ReverseFind(L'.'); - if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0)) - ExtensionPos = ui.Name.Length(); + if (dotPos < 0 || dotPos < slashPos) + ExtensionPos = ui.Name.Len(); else { ExtensionPos = dotPos + 1; - UString us = ui.Name.Mid(ExtensionPos); - if (!us.IsEmpty()) + if (ExtensionPos != ui.Name.Len()) { - us.MakeLower(); - int i; AString s; - for (i = 0; i < us.Length(); i++) + for (unsigned pos = ExtensionPos;; pos++) { - wchar_t c = us[i]; + wchar_t c = ui.Name[pos]; if (c >= 0x80) break; - s += (char)c; + if (c == 0) + { + ExtensionIndex = GetExtIndex(s); + break; + } + s += (char)MyCharLower_Ascii((char)c); } - if (i == us.Length()) - ExtensionIndex = GetExtIndex(s); - else - ExtensionIndex = 0; } } } } }; +struct CSortParam +{ + // const CObjectVector<CTreeFolder> *TreeFolders; + bool SortByType; +}; + +/* + we sort files in such order: + - Dir.NonAnti (name sorted) + - alt streams + - Dirs + - Dir.Anti (reverse name sorted) +*/ + + static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param) { const CRefItem &a1 = *p1; const CRefItem &a2 = *p2; const CUpdateItem &u1 = *a1.UpdateItem; const CUpdateItem &u2 = *a2.UpdateItem; - int n; + + /* + if (u1.IsAltStream != u2.IsAltStream) + return u1.IsAltStream ? 1 : -1; + */ + + // Actually there are no dirs that time. They were stored in other steps + // So that code is unused? if (u1.IsDir != u2.IsDir) - return (u1.IsDir) ? 1 : -1; + return u1.IsDir ? 1 : -1; if (u1.IsDir) { if (u1.IsAnti != u2.IsAnti) return (u1.IsAnti ? 1 : -1); - n = MyStringCompareNoCase(u1.Name, u2.Name); + int n = CompareFileNames(u1.Name, u2.Name); return -n; } - bool sortByType = *(bool *)param; + + // bool sortByType = *(bool *)param; + const CSortParam *sortParam = (const CSortParam *)param; + bool sortByType = sortParam->SortByType; if (sortByType) { RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex); - RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos)); - RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos)); + RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos))); + RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos))); if (!u1.MTimeDefined && u2.MTimeDefined) return 1; if (u1.MTimeDefined && !u2.MTimeDefined) return -1; if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime); RINOZ_COMP(u1.Size, u2.Size); } - return MyStringCompareNoCase(u1.Name, u2.Name); + /* + int par1 = a1.UpdateItem->ParentFolderIndex; + int par2 = a2.UpdateItem->ParentFolderIndex; + const CTreeFolder &tf1 = (*sortParam->TreeFolders)[par1]; + const CTreeFolder &tf2 = (*sortParam->TreeFolders)[par2]; + + int b1 = tf1.SortIndex, e1 = tf1.SortIndexEnd; + int b2 = tf2.SortIndex, e2 = tf2.SortIndexEnd; + if (b1 < b2) + { + if (e1 <= b2) + return -1; + // p2 in p1 + int par = par2; + for (;;) + { + const CTreeFolder &tf = (*sortParam->TreeFolders)[par]; + par = tf.Parent; + if (par == par1) + { + RINOZ(CompareFileNames(u1.Name, tf.Name)); + break; + } + } + } + else if (b2 < b1) + { + if (e2 <= b1) + return 1; + // p1 in p2 + int par = par1; + for (;;) + { + const CTreeFolder &tf = (*sortParam->TreeFolders)[par]; + par = tf.Parent; + if (par == par2) + { + RINOZ(CompareFileNames(tf.Name, u2.Name)); + break; + } + } + } + */ + // RINOZ_COMP(a1.UpdateItem->ParentSortIndex, a2.UpdateItem->ParentSortIndex); + RINOK(CompareFileNames(u1.Name, u2.Name)); + RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient); + RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive); + return 0; } struct CSolidGroup @@ -322,124 +398,109 @@ struct CSolidGroup CRecordVector<UInt32> Indices; }; -static wchar_t *g_ExeExts[] = +static const wchar_t *g_ExeExts[] = { - L"dll", - L"exe", - L"ocx", - L"sfx", - L"sys" + L"dll" + , L"exe" + , L"ocx" + , L"sfx" + , L"sys" }; -static bool IsExeExt(const UString &ext) +static bool IsExeExt(const wchar_t *ext) { - for (int i = 0; i < sizeof(g_ExeExts) / sizeof(g_ExeExts[0]); i++) - if (ext.CompareNoCase(g_ExeExts[i]) == 0) + for (int i = 0; i < ARRAY_SIZE(g_ExeExts); i++) + if (MyStringCompareNoCase(ext, g_ExeExts[i]) == 0) return true; return false; } -#ifdef USE_86_FILTER -static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult) +static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &m) { - methodResult.Id = methodID; - methodResult.NumInStreams = numInStreams; - methodResult.NumOutStreams = 1; + m.Id = methodID; + m.NumInStreams = numInStreams; + m.NumOutStreams = 1; } -static void MakeExeMethod(const CCompressionMethodMode &method, - bool bcj2Filter, CCompressionMethodMode &exeMethod) +static void AddBcj2Methods(CCompressionMethodMode &mode) { - exeMethod = method; + CMethodFull m; + GetMethodFull(k_LZMA, 1, m); + + m.AddProp32(NCoderPropID::kDictionarySize, 1 << 20); + m.AddProp32(NCoderPropID::kNumFastBytes, 128); + m.AddProp32(NCoderPropID::kNumThreads, 1); + m.AddProp32(NCoderPropID::kLitPosBits, 2); + m.AddProp32(NCoderPropID::kLitContextBits, 0); + // m.AddPropString(NCoderPropID::kMatchFinder, L"BT2"); + + mode.Methods.Add(m); + mode.Methods.Add(m); + + CBind bind; + bind.OutCoder = 0; + bind.InStream = 0; + bind.InCoder = 1; bind.OutStream = 0; mode.Binds.Add(bind); + bind.InCoder = 2; bind.OutStream = 1; mode.Binds.Add(bind); + bind.InCoder = 3; bind.OutStream = 2; mode.Binds.Add(bind); +} + +static void MakeExeMethod(CCompressionMethodMode &mode, + bool useFilters, bool addFilter, bool bcj2Filter) +{ + if (!mode.Binds.IsEmpty() || !useFilters || mode.Methods.Size() > 2) + return; + if (mode.Methods.Size() == 2) + { + if (mode.Methods[0].Id == k_BCJ2) + AddBcj2Methods(mode); + return; + } + if (!addFilter) + return; + bcj2Filter = bcj2Filter; + #ifdef USE_86_FILTER if (bcj2Filter) { - CMethodFull methodFull; - GetMethodFull(k_BCJ2, 4, methodFull); - exeMethod.Methods.Insert(0, methodFull); - GetMethodFull(k_LZMA, 1, methodFull); - { - CProp prop; - prop.Id = NCoderPropID::kAlgorithm; - prop.Value = kAlgorithmForBCJ2_LZMA; - methodFull.Props.Add(prop); - } - { - CProp prop; - prop.Id = NCoderPropID::kMatchFinder; - prop.Value = kMatchFinderForBCJ2_LZMA; - methodFull.Props.Add(prop); - } - { - CProp prop; - prop.Id = NCoderPropID::kDictionarySize; - prop.Value = kDictionaryForBCJ2_LZMA; - methodFull.Props.Add(prop); - } - { - CProp prop; - prop.Id = NCoderPropID::kNumFastBytes; - prop.Value = kNumFastBytesForBCJ2_LZMA; - methodFull.Props.Add(prop); - } - { - CProp prop; - prop.Id = NCoderPropID::kNumThreads; - prop.Value = (UInt32)1; - methodFull.Props.Add(prop); - } - - exeMethod.Methods.Add(methodFull); - exeMethod.Methods.Add(methodFull); - CBind bind; - - bind.OutCoder = 0; - bind.InStream = 0; - - bind.InCoder = 1; - bind.OutStream = 0; - exeMethod.Binds.Add(bind); - - bind.InCoder = 2; - bind.OutStream = 1; - exeMethod.Binds.Add(bind); - - bind.InCoder = 3; - bind.OutStream = 2; - exeMethod.Binds.Add(bind); + CMethodFull m; + GetMethodFull(k_BCJ2, 4, m); + mode.Methods.Insert(0, m); + AddBcj2Methods(mode); } else { - CMethodFull methodFull; - GetMethodFull(k_BCJ, 1, methodFull); - exeMethod.Methods.Insert(0, methodFull); + CMethodFull m; + GetMethodFull(k_BCJ, 1, m); + mode.Methods.Insert(0, m); CBind bind; bind.OutCoder = 0; bind.InStream = 0; bind.InCoder = 1; bind.OutStream = 0; - exeMethod.Binds.Add(bind); + mode.Binds.Add(bind); } + #endif } -#endif static void FromUpdateItemToFileItem(const CUpdateItem &ui, CFileItem &file, CFileItem2 &file2) { - file.Name = NItemName::MakeLegalName(ui.Name); if (ui.AttribDefined) file.SetAttrib(ui.Attrib); - + file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined; file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined; file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined; file2.IsAnti = ui.IsAnti; + // file2.IsAux = false; file2.StartPosDefined = false; file.Size = ui.Size; file.IsDir = ui.IsDir; file.HasStream = ui.HasStream(); + // file.IsAltStream = ui.IsAltStream; } class CFolderOutStream2: @@ -448,11 +509,11 @@ class CFolderOutStream2: { COutStreamWithCRC *_crcStreamSpec; CMyComPtr<ISequentialOutStream> _crcStream; - const CArchiveDatabaseEx *_db; + const CDbEx *_db; const CBoolVector *_extractStatuses; CMyComPtr<ISequentialOutStream> _outStream; UInt32 _startIndex; - int _currentIndex; + unsigned _currentIndex; bool _fileIsOpen; UInt64 _rem; @@ -462,14 +523,14 @@ class CFolderOutStream2: HRESULT ProcessEmptyFiles(); public: MY_UNKNOWN_IMP - + CFolderOutStream2() { _crcStreamSpec = new COutStreamWithCRC; _crcStream = _crcStreamSpec; } - HRESULT Init(const CArchiveDatabaseEx *db, UInt32 startIndex, + HRESULT Init(const CDbEx *db, UInt32 startIndex, const CBoolVector *extractStatuses, ISequentialOutStream *outStream); void ReleaseOutStream(); HRESULT CheckFinishedState() const { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; } @@ -477,7 +538,7 @@ public: STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -HRESULT CFolderOutStream2::Init(const CArchiveDatabaseEx *db, UInt32 startIndex, +HRESULT CFolderOutStream2::Init(const CDbEx *db, UInt32 startIndex, const CBoolVector *extractStatuses, ISequentialOutStream *outStream) { _db = db; @@ -576,13 +637,13 @@ public: CMyComPtr<ISequentialOutStream> Fos; UInt64 StartPos; - const UInt64 *PackSizes; - const CFolder *Folder; + const CFolders *Folders; + int FolderIndex; #ifndef _NO_CRYPTO - CMyComPtr<ICryptoGetTextPassword> GetTextPassword; + CMyComPtr<ICryptoGetTextPassword> getTextPassword; #endif - DECL_EXTERNAL_CODECS_VARS + DECL_EXTERNAL_CODECS_LOC_VARS2; CDecoder Decoder; #ifndef _7ZIP_ST @@ -601,6 +662,7 @@ public: Fos = FosSpec; Result = E_FAIL; } + ~CThreadDecoder() { CVirtThread::WaitThreadFinish(); } virtual void Execute(); }; @@ -609,21 +671,20 @@ void CThreadDecoder::Execute() try { #ifndef _NO_CRYPTO - bool passwordIsDefined; + bool isEncrypted = false; + bool passwordIsDefined = false; #endif + Result = Decoder.Decode( - EXTERNAL_CODECS_VARS + EXTERNAL_CODECS_LOC_VARS InStream, StartPos, - PackSizes, - *Folder, + *Folders, FolderIndex, Fos, NULL - #ifndef _NO_CRYPTO - , GetTextPassword, passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS #ifndef _7ZIP_ST - , MtMode, NumThreads + , MtMode, NumThreads #endif ); } @@ -638,7 +699,7 @@ void CThreadDecoder::Execute() bool static Is86FilteredFolder(const CFolder &f) { - for (int i = 0; i < f.Coders.Size(); i++) + FOR_VECTOR(i, f.Coders) { CMethodId m = f.Coders[i].MethodID; if (m == k_BCJ || m == k_BCJ2) @@ -669,20 +730,31 @@ STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password) static const int kNumGroupsMax = 4; -#ifdef USE_86_FILTER static bool Is86Group(int group) { return (group & 1) != 0; } -#endif static bool IsEncryptedGroup(int group) { return (group & 2) != 0; } static int GetGroupIndex(bool encrypted, int bcjFiltered) { return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); } +static void GetFile(const CDatabase &inDb, int index, CFileItem &file, CFileItem2 &file2) +{ + file = inDb.Files[index]; + file2.CTimeDefined = inDb.CTime.GetItem(index, file2.CTime); + file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime); + file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime); + file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos); + file2.IsAnti = inDb.IsItemAnti(index); + // file2.IsAux = inDb.IsItemAux(index); +} + HRESULT Update( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, - const CArchiveDatabaseEx *db, + const CDbEx *db, const CObjectVector<CUpdateItem> &updateItems, + // const CObjectVector<CTreeFolder> &treeFolders, + // const CUniqBlocks &secureBlocks, COutArchive &archive, - CArchiveDatabase &newDatabase, + CArchiveDatabaseOut &newDatabase, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, const CUpdateOptions &options @@ -694,6 +766,9 @@ HRESULT Update( UInt64 numSolidFiles = options.NumSolidFiles; if (numSolidFiles == 0) numSolidFiles = 1; + + // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes(); + /* CMyComPtr<IOutStream> outStream; RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream)); @@ -701,23 +776,23 @@ HRESULT Update( return E_NOTIMPL; */ - UInt64 startBlockSize = db != 0 ? db->ArchiveInfo.StartPosition: 0; + UInt64 startBlockSize = db != 0 ? db->ArcInfo.StartPosition: 0; if (startBlockSize > 0 && !options.RemoveSfxBlock) { RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL)); } - CRecordVector<int> fileIndexToUpdateIndexMap; + CIntArr fileIndexToUpdateIndexMap; CRecordVector<CFolderRepack> folderRefs; UInt64 complexity = 0; UInt64 inSizeForReduce2 = 0; bool needEncryptedRepack = false; if (db != 0) { - fileIndexToUpdateIndexMap.Reserve(db->Files.Size()); - int i; + fileIndexToUpdateIndexMap.Alloc(db->Files.Size()); + unsigned i; for (i = 0; i < db->Files.Size(); i++) - fileIndexToUpdateIndexMap.Add(-1); + fileIndexToUpdateIndexMap[i] = -1; for (i = 0; i < updateItems.Size(); i++) { @@ -726,7 +801,7 @@ HRESULT Update( fileIndexToUpdateIndexMap[index] = i; } - for (i = 0; i < db->Folders.Size(); i++) + for (i = 0; i < (int)db->NumFolders; i++) { CNum indexInFolder = 0; CNum numCopyItems = 0; @@ -753,7 +828,8 @@ HRESULT Update( CFolderRepack rep; rep.FolderIndex = i; rep.NumCopyFiles = numCopyItems; - const CFolder &f = db->Folders[i]; + CFolder f; + db->ParseFolderInfo(i, f); bool isEncrypted = f.IsEncrypted(); rep.Group = GetGroupIndex(isEncrypted, Is86FilteredFolder(f)); folderRefs.Add(rep); @@ -772,7 +848,7 @@ HRESULT Update( } UInt64 inSizeForReduce = 0; - int i; + unsigned i; for (i = 0; i < updateItems.Size(); i++) { const CUpdateItem &ui = updateItems[i]; @@ -789,32 +865,30 @@ HRESULT Update( if (inSizeForReduce2 > inSizeForReduce) inSizeForReduce = inSizeForReduce2; - const UInt32 kMinReduceSize = (1 << 16); - if (inSizeForReduce < kMinReduceSize) - inSizeForReduce = kMinReduceSize; - RINOK(updateCallback->SetTotal(complexity)); CLocalProgress *lps = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = lps; lps->Init(updateCallback, true); + CStreamBinder sb; + RINOK(sb.CreateEvents()); + CThreadDecoder threadDecoder; if (!folderRefs.IsEmpty()) { #ifdef EXTERNAL_CODECS - threadDecoder._codecsInfo = codecsInfo; - threadDecoder._externalCodecs = *externalCodecs; + threadDecoder.__externalCodecs = __externalCodecs; #endif RINOK(threadDecoder.Create()); } CObjectVector<CSolidGroup> groups; for (i = 0; i < kNumGroupsMax; i++) - groups.Add(CSolidGroup()); + groups.AddNew(); { - // ---------- Split files to 2 groups ---------- + // ---------- Split files to groups ---------- bool useFilters = options.UseFilters; const CCompressionMethodMode &method = *options.Method; @@ -830,7 +904,7 @@ HRESULT Update( { int dotPos = ui.Name.ReverseFind(L'.'); if (dotPos >= 0) - filteredGroup = IsExeExt(ui.Name.Mid(dotPos + 1)); + filteredGroup = IsExeExt(ui.Name.Ptr(dotPos + 1)); } groups[GetGroupIndex(method.PasswordIsDefined, filteredGroup)].Indices.Add(i); } @@ -842,7 +916,7 @@ HRESULT Update( if (needEncryptedRepack) { getPasswordSpec = new CCryptoGetTextPassword; - threadDecoder.GetTextPassword = getPasswordSpec; + threadDecoder.getTextPassword = getPasswordSpec; if (options.Method->PasswordIsDefined) getPasswordSpec->Password = options.Method->Password; @@ -852,31 +926,119 @@ HRESULT Update( return E_NOTIMPL; CMyComBSTR password; RINOK(getDecoderPassword->CryptoGetTextPassword(&password)); - getPasswordSpec->Password = password; + if ((BSTR)password) + getPasswordSpec->Password = password; } } #endif + // ---------- Compress ---------- RINOK(archive.Create(seqOutStream, false)); RINOK(archive.SkipPrefixArchiveHeader()); - int folderRefIndex = 0; + /* + CIntVector treeFolderToArcIndex; + treeFolderToArcIndex.Reserve(treeFolders.Size()); + for (i = 0; i < treeFolders.Size(); i++) + treeFolderToArcIndex.Add(-1); + // ---------- Write Tree (only AUX dirs) ---------- + for (i = 1; i < treeFolders.Size(); i++) + { + const CTreeFolder &treeFolder = treeFolders[i]; + CFileItem file; + CFileItem2 file2; + file2.Init(); + int secureID = 0; + if (treeFolder.UpdateItemIndex < 0) + { + // we can store virtual dir item wuthout attrib, but we want all items have attrib. + file.SetAttrib(FILE_ATTRIBUTE_DIRECTORY); + file2.IsAux = true; + } + else + { + const CUpdateItem &ui = updateItems[treeFolder.UpdateItemIndex]; + // if item is not dir, then it's parent for alt streams. + // we will write such items later + if (!ui.IsDir) + continue; + secureID = ui.SecureIndex; + if (ui.NewProps) + FromUpdateItemToFileItem(ui, file, file2); + else + GetFile(*db, ui.IndexInArchive, file, file2); + } + file.Size = 0; + file.HasStream = false; + file.IsDir = true; + file.Parent = treeFolder.Parent; + + treeFolderToArcIndex[i] = newDatabase.Files.Size(); + newDatabase.AddFile(file, file2, treeFolder.Name); + + if (totalSecureDataSize != 0) + newDatabase.SecureIDs.Add(secureID); + } + */ + + { + /* ---------- Write non-AUX dirs and Empty files ---------- */ + CRecordVector<int> emptyRefs; + for (i = 0; i < updateItems.Size(); i++) + { + const CUpdateItem &ui = updateItems[i]; + if (ui.NewData) + { + if (ui.HasStream()) + continue; + } + else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream) + continue; + /* + if (ui.TreeFolderIndex >= 0) + continue; + */ + emptyRefs.Add(i); + } + emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems); + for (i = 0; i < emptyRefs.Size(); i++) + { + const CUpdateItem &ui = updateItems[emptyRefs[i]]; + CFileItem file; + CFileItem2 file2; + UString name; + if (ui.NewProps) + { + FromUpdateItemToFileItem(ui, file, file2); + name = ui.Name; + } + else + { + GetFile(*db, ui.IndexInArchive, file, file2); + db->GetPath(ui.IndexInArchive, name); + } + + /* + if (totalSecureDataSize != 0) + newDatabase.SecureIDs.Add(ui.SecureIndex); + file.Parent = ui.ParentFolderIndex; + */ + newDatabase.AddFile(file, file2, name); + } + } + + unsigned folderRefIndex = 0; lps->ProgressOffset = 0; for (int groupIndex = 0; groupIndex < kNumGroupsMax; groupIndex++) { const CSolidGroup &group = groups[groupIndex]; - CCompressionMethodMode method; - #ifdef USE_86_FILTER - if (Is86Group(groupIndex)) - MakeExeMethod(*options.Method, options.MaxFilter, method); - else - #endif - method = *options.Method; + CCompressionMethodMode method = *options.Method; + MakeExeMethod(method, options.UseFilters, Is86Group(groupIndex), options.MaxFilter); if (IsEncryptedGroup(groupIndex)) { @@ -903,36 +1065,36 @@ HRESULT Update( if (rep.Group != groupIndex) break; int folderIndex = rep.FolderIndex; - + if (rep.NumCopyFiles == db->NumUnpackStreamsVector[folderIndex]) { UInt64 packSize = db->GetFolderFullPackSize(folderIndex); RINOK(WriteRange(inStream, archive.SeqStream, db->GetFolderStreamPos(folderIndex, 0), packSize, progress)); lps->ProgressOffset += packSize; - - const CFolder &folder = db->Folders[folderIndex]; - CNum startIndex = db->FolderStartPackStreamIndex[folderIndex]; - for (int j = 0; j < folder.PackStreams.Size(); j++) + + CFolder &folder = newDatabase.Folders.AddNew(); + db->ParseFolderInfo(folderIndex, folder); + CNum startIndex = db->FoStartPackStreamIndex[folderIndex]; + for (unsigned j = 0; j < folder.PackStreams.Size(); j++) { - newDatabase.PackSizes.Add(db->PackSizes[startIndex + j]); + newDatabase.PackSizes.Add(db->GetStreamPackSize(startIndex + j)); // newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]); // newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]); } - newDatabase.Folders.Add(folder); + + UInt32 indexStart = db->FoToCoderUnpackSizes[folderIndex]; + UInt32 indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1]; + for (; indexStart < indexEnd; indexStart++) + newDatabase.CoderUnpackSizes.Add(db->CoderUnpackSizes[indexStart]); } else { - CStreamBinder sb; - RINOK(sb.CreateEvents()); - CMyComPtr<ISequentialOutStream> sbOutStream; - CMyComPtr<ISequentialInStream> sbInStream; - sb.CreateStreams(&sbInStream, &sbOutStream); CBoolVector extractStatuses; - + CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex]; CNum indexInFolder = 0; - + for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++) { bool needExtract = false; @@ -946,44 +1108,52 @@ HRESULT Update( extractStatuses.Add(needExtract); } - RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream)); - sbOutStream.Release(); - - threadDecoder.InStream = inStream; - threadDecoder.Folder = &db->Folders[folderIndex]; - threadDecoder.StartPos = db->GetFolderStreamPos(folderIndex, 0); - threadDecoder.PackSizes = &db->PackSizes[db->FolderStartPackStreamIndex[folderIndex]]; - - threadDecoder.Start(); - - int startPackIndex = newDatabase.PackSizes.Size(); - CFolder newFolder; - RINOK(encoder.Encode( - EXTERNAL_CODECS_LOC_VARS - sbInStream, NULL, &inSizeForReduce, newFolder, - archive.SeqStream, newDatabase.PackSizes, progress)); - - threadDecoder.WaitFinish(); + unsigned startPackIndex = newDatabase.PackSizes.Size(); + UInt64 curUnpackSize; + { + CMyComPtr<ISequentialInStream> sbInStream; + { + CMyComPtr<ISequentialOutStream> sbOutStream; + sb.CreateStreams(&sbInStream, &sbOutStream); + sb.ReInit(); + RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream)); + } + + threadDecoder.InStream = inStream; + threadDecoder.Folders = (const CFolders *)db; + threadDecoder.FolderIndex = folderIndex; + threadDecoder.StartPos = db->ArcInfo.DataStartPosition; // db->GetFolderStreamPos(folderIndex, 0); + + threadDecoder.Start(); + + RINOK(encoder.Encode( + EXTERNAL_CODECS_LOC_VARS + sbInStream, NULL, &inSizeForReduce, + newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curUnpackSize, + archive.SeqStream, newDatabase.PackSizes, progress)); + + threadDecoder.WaitExecuteFinish(); + } RINOK(threadDecoder.Result); for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) lps->OutSize += newDatabase.PackSizes[startPackIndex]; - lps->InSize += newFolder.GetUnpackSize(); - - newDatabase.Folders.Add(newFolder); + lps->InSize += curUnpackSize; } - + newDatabase.NumUnpackStreamsVector.Add(rep.NumCopyFiles); - + CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex]; - + CNum indexInFolder = 0; for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++) { CFileItem file; CFileItem2 file2; - db->GetFile(fi, file, file2); + GetFile(*db, fi, file, file2); + UString name; + db->GetPath(fi, name); if (file.HasStream) { indexInFolder++; @@ -1002,30 +1172,40 @@ HRESULT Update( uf.CrcDefined = file.CrcDefined; uf.HasStream = file.HasStream; file = uf; + name = ui.Name; } - newDatabase.AddFile(file, file2); + /* + file.Parent = ui.ParentFolderIndex; + if (ui.TreeFolderIndex >= 0) + treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size(); + if (totalSecureDataSize != 0) + newDatabase.SecureIDs.Add(ui.SecureIndex); + */ + newDatabase.AddFile(file, file2, name); } } } } - int numFiles = group.Indices.Size(); + unsigned numFiles = group.Indices.Size(); if (numFiles == 0) continue; CRecordVector<CRefItem> refItems; - refItems.Reserve(numFiles); + refItems.ClearAndSetSize(numFiles); bool sortByType = (numSolidFiles > 1); for (i = 0; i < numFiles; i++) - refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType)); - refItems.Sort(CompareUpdateItems, (void *)&sortByType); - - CRecordVector<UInt32> indices; - indices.Reserve(numFiles); + refItems[i] = CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType); + CSortParam sortParam; + // sortParam.TreeFolders = &treeFolders; + sortParam.SortByType = sortByType; + refItems.Sort(CompareUpdateItems, (void *)&sortParam); + + CObjArray<UInt32> indices(numFiles); for (i = 0; i < numFiles; i++) { UInt32 index = refItems[i].Index; - indices.Add(index); + indices[i] = index; /* const CUpdateItem &ui = updateItems[index]; CFileItem file; @@ -1038,7 +1218,7 @@ HRESULT Update( newDatabase.Files.Add(file); */ } - + for (i = 0; i < numFiles;) { UInt64 totalSize = 0; @@ -1057,7 +1237,7 @@ HRESULT Update( if (numSubFiles == 0) prevExtension = ext; else - if (ext.CompareNoCase(prevExtension) != 0) + if (!ext.IsEqualToNoCase(prevExtension)) break; } } @@ -1067,38 +1247,43 @@ HRESULT Update( CFolderInStream *inStreamSpec = new CFolderInStream; CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec); inStreamSpec->Init(updateCallback, &indices[i], numSubFiles); - - CFolder folderItem; - int startPackIndex = newDatabase.PackSizes.Size(); + unsigned startPackIndex = newDatabase.PackSizes.Size(); + UInt64 curFolderUnpackSize; RINOK(encoder.Encode( EXTERNAL_CODECS_LOC_VARS - solidInStream, NULL, &inSizeForReduce, folderItem, + solidInStream, NULL, &inSizeForReduce, + newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curFolderUnpackSize, archive.SeqStream, newDatabase.PackSizes, progress)); for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) lps->OutSize += newDatabase.PackSizes[startPackIndex]; - lps->InSize += folderItem.GetUnpackSize(); + lps->InSize += curFolderUnpackSize; // for () // newDatabase.PackCRCsDefined.Add(false); // newDatabase.PackCRCs.Add(0); - - newDatabase.Folders.Add(folderItem); - + CNum numUnpackStreams = 0; for (int subIndex = 0; subIndex < numSubFiles; subIndex++) { const CUpdateItem &ui = updateItems[indices[i + subIndex]]; CFileItem file; CFileItem2 file2; + UString name; if (ui.NewProps) + { FromUpdateItemToFileItem(ui, file, file2); + name = ui.Name; + } else - db->GetFile(ui.IndexInArchive, file, file2); + { + GetFile(*db, ui.IndexInArchive, file, file2); + db->GetPath(ui.IndexInArchive, name); + } if (file2.IsAnti || file.IsDir) return E_FAIL; - + /* CFileItem &file = newDatabase.Files[ startFileIndexInDatabase + i + subIndex]; @@ -1122,7 +1307,14 @@ HRESULT Update( file.CrcDefined = false; file.HasStream = false; } - newDatabase.AddFile(file, file2); + /* + file.Parent = ui.ParentFolderIndex; + if (ui.TreeFolderIndex >= 0) + treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size(); + if (totalSecureDataSize != 0) + newDatabase.SecureIDs.Add(ui.SecureIndex); + */ + newDatabase.AddFile(file, file2, name); } // numUnpackStreams = 0 is very bad case for locked files // v3.13 doesn't understand it. @@ -1134,42 +1326,36 @@ HRESULT Update( if (folderRefIndex != folderRefs.Size()) return E_FAIL; + RINOK(lps->SetCur()); + /* folderRefs.ClearAndFree(); fileIndexToUpdateIndexMap.ClearAndFree(); groups.ClearAndFree(); */ + /* + for (i = 0; i < newDatabase.Files.Size(); i++) { - // ---------- Write Folders & Empty Files ---------- - - CRecordVector<int> emptyRefs; - for (i = 0; i < updateItems.Size(); i++) - { - const CUpdateItem &ui = updateItems[i]; - if (ui.NewData) - { - if (ui.HasStream()) - continue; - } - else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream) - continue; - emptyRefs.Add(i); - } - emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems); - for (i = 0; i < emptyRefs.Size(); i++) + CFileItem &file = newDatabase.Files[i]; + file.Parent = treeFolderToArcIndex[file.Parent]; + } + + if (totalSecureDataSize != 0) + { + newDatabase.SecureBuf.SetCapacity(totalSecureDataSize); + size_t pos = 0; + newDatabase.SecureSizes.Reserve(secureBlocks.Sorted.Size()); + for (i = 0; i < secureBlocks.Sorted.Size(); i++) { - const CUpdateItem &ui = updateItems[emptyRefs[i]]; - CFileItem file; - CFileItem2 file2; - if (ui.NewProps) - FromUpdateItemToFileItem(ui, file, file2); - else - db->GetFile(ui.IndexInArchive, file, file2); - newDatabase.AddFile(file, file2); + const CByteBuffer &buf = secureBlocks.Bufs[secureBlocks.Sorted[i]]; + size_t size = buf.GetCapacity(); + memcpy(newDatabase.SecureBuf + pos, buf, size); + newDatabase.SecureSizes.Add((UInt32)size); + pos += size; } } - + */ newDatabase.ReserveDown(); return S_OK; } diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.h index 31e362246..aee2d5ed3 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.h @@ -3,29 +3,54 @@ #ifndef __7Z_UPDATE_H #define __7Z_UPDATE_H +#include "../IArchive.h" + +// #include "../../Common/UniqBlocks.h" + #include "7zCompressionMode.h" #include "7zIn.h" #include "7zOut.h" -#include "../IArchive.h" - namespace NArchive { namespace N7z { +/* +struct CTreeFolder +{ + UString Name; + int Parent; + CIntVector SubFolders; + int UpdateItemIndex; + int SortIndex; + int SortIndexEnd; + + CTreeFolder(): UpdateItemIndex(-1) {} +}; +*/ + struct CUpdateItem { int IndexInArchive; int IndexInClient; - + UInt64 CTime; UInt64 ATime; UInt64 MTime; UInt64 Size; UString Name; + /* + bool IsAltStream; + int ParentFolderIndex; + int TreeFolderIndex; + */ + + // that code is not used in 9.26 + // int ParentSortIndex; + // int ParentSortIndexEnd; UInt32 Attrib; - + bool NewData; bool NewProps; @@ -37,15 +62,20 @@ struct CUpdateItem bool ATimeDefined; bool MTimeDefined; + // int SecureIndex; // 0 means (no_security) + bool HasStream() const { return !IsDir && !IsAnti && Size != 0; } CUpdateItem(): + // ParentSortIndex(-1), + // IsAltStream(false), IsAnti(false), IsDir(false), AttribDefined(false), CTimeDefined(false), ATimeDefined(false), MTimeDefined(false) + // SecureIndex(0) {} void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); }; @@ -72,10 +102,12 @@ struct CUpdateOptions HRESULT Update( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, - const CArchiveDatabaseEx *db, + const CDbEx *db, const CObjectVector<CUpdateItem> &updateItems, + // const CObjectVector<CTreeFolder> &treeFolders, // treeFolders[0] is root + // const CUniqBlocks &secureBlocks, COutArchive &archive, - CArchiveDatabase &newDatabase, + CArchiveDatabaseOut &newDatabase, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, const CUpdateOptions &options diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.cpp deleted file mode 100644 index d0feea85c..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.h index 2e4be10b2..2854ff3e9 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.h @@ -3,7 +3,6 @@ #ifndef __STDAFX_H #define __STDAFX_H -#include "../../../Common/MyWindows.h" -#include "../../../Common/NewHandler.h" +#include "../../../Common/Common.h" #endif diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Archive.def b/src/libs/7zip/win/CPP/7zip/Archive/Archive.def deleted file mode 100644 index 55b530b2d..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Archive.def +++ /dev/null @@ -1,6 +0,0 @@ -EXPORTS - CreateObject PRIVATE - GetHandlerProperty PRIVATE - GetNumberOfFormats PRIVATE - GetHandlerProperty2 PRIVATE - CreateObject PRIVATE diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Archive.pri b/src/libs/7zip/win/CPP/7zip/Archive/Archive.pri new file mode 100644 index 000000000..e8a1c7832 --- /dev/null +++ b/src/libs/7zip/win/CPP/7zip/Archive/Archive.pri @@ -0,0 +1,6 @@ +HEADERS += $$7ZIP_BASE/CPP/7zip/Archive/IArchive.h \ + $$7ZIP_BASE/CPP/7zip/Archive/StdAfx.h + +SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/LzmaHandler.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/SplitHandler.cpp \ + $$7ZIP_BASE/CPP/7zip/Archive/XzHandler.cpp diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Archive2.def b/src/libs/7zip/win/CPP/7zip/Archive/Archive2.def deleted file mode 100644 index 885d39d14..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Archive2.def +++ /dev/null @@ -1,9 +0,0 @@ -EXPORTS - CreateObject PRIVATE - GetHandlerProperty PRIVATE - GetNumberOfFormats PRIVATE - GetHandlerProperty2 PRIVATE - CreateObject PRIVATE - GetNumberOfMethods PRIVATE - GetMethodProperty PRIVATE - SetLargePageMode PRIVATE diff --git a/src/libs/7zip/win/CPP/7zip/Archive/ArchiveExports.cpp b/src/libs/7zip/win/CPP/7zip/Archive/ArchiveExports.cpp deleted file mode 100644 index c7908b591..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/ArchiveExports.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// ArchiveExports.cpp - -#include "StdAfx.h" - -#include "../../Common/ComTry.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/RegisterArc.h" - -static const unsigned int kNumArcsMax = 48; -static unsigned int g_NumArcs = 0; -static unsigned int g_DefaultArcIndex = 0; -static const CArcInfo *g_Arcs[kNumArcsMax]; -void RegisterArc(const CArcInfo *arcInfo) -{ - if (g_NumArcs < kNumArcsMax) - { - const wchar_t *p = arcInfo->Name; - if (p[0] == '7' && p[1] == 'z' && p[2] == 0) - g_DefaultArcIndex = g_NumArcs; - g_Arcs[g_NumArcs++] = arcInfo; - } -} - -DEFINE_GUID(CLSID_CArchiveHandler, -0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); - -#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5]) - -static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value) -{ - if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0) - value->vt = VT_BSTR; - return S_OK; -} - -static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) -{ - return SetPropString((const char *)&guid, sizeof(GUID), value); -} - -int FindFormatCalssId(const GUID *clsID) -{ - GUID cls = *clsID; - CLS_ARC_ID_ITEM(cls) = 0; - if (cls != CLSID_CArchiveHandler) - return -1; - Byte id = CLS_ARC_ID_ITEM(*clsID); - for (unsigned i = 0; i < g_NumArcs; i++) - if (g_Arcs[i]->ClassId == id) - return (int)i; - return -1; -} - -STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject) -{ - COM_TRY_BEGIN - { - int needIn = (*iid == IID_IInArchive); - int needOut = (*iid == IID_IOutArchive); - if (!needIn && !needOut) - return E_NOINTERFACE; - int formatIndex = FindFormatCalssId(clsid); - if (formatIndex < 0) - return CLASS_E_CLASSNOTAVAILABLE; - - const CArcInfo &arc = *g_Arcs[formatIndex]; - if (needIn) - { - *outObject = arc.CreateInArchive(); - ((IInArchive *)*outObject)->AddRef(); - } - else - { - if (!arc.CreateOutArchive) - return CLASS_E_CLASSNOTAVAILABLE; - *outObject = arc.CreateOutArchive(); - ((IOutArchive *)*outObject)->AddRef(); - } - } - COM_TRY_END - return S_OK; -} - -STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - if (formatIndex >= g_NumArcs) - return E_INVALIDARG; - const CArcInfo &arc = *g_Arcs[formatIndex]; - NWindows::NCOM::CPropVariant prop; - switch(propID) - { - case NArchive::kName: - prop = arc.Name; - break; - case NArchive::kClassID: - { - GUID clsId = CLSID_CArchiveHandler; - CLS_ARC_ID_ITEM(clsId) = arc.ClassId; - return SetPropGUID(clsId, value); - } - case NArchive::kExtension: - if (arc.Ext != 0) - prop = arc.Ext; - break; - case NArchive::kAddExtension: - if (arc.AddExt != 0) - prop = arc.AddExt; - break; - case NArchive::kUpdate: - prop = (bool)(arc.CreateOutArchive != 0); - break; - case NArchive::kKeepName: - prop = arc.KeepName; - break; - case NArchive::kStartSignature: - return SetPropString((const char *)arc.Signature, arc.SignatureSize, value); - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) -{ - return GetHandlerProperty2(g_DefaultArcIndex, propID, value); -} - -STDAPI GetNumberOfFormats(UINT32 *numFormats) -{ - *numFormats = g_NumArcs; - return S_OK; -} diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.cpp index 0b06a489f..e562fec58 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.cpp @@ -11,16 +11,23 @@ CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo): { srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams); - UInt32 j; + UInt32 j; + _srcInToDestOutMap.ClearAndSetSize(NumSrcInStreams); + DestOutToSrcInMap.ClearAndSetSize(NumSrcInStreams); + for (j = 0; j < NumSrcInStreams; j++) { - _srcInToDestOutMap.Add(0); - DestOutToSrcInMap.Add(0); + _srcInToDestOutMap[j] = 0; + DestOutToSrcInMap[j] = 0; } + + _srcOutToDestInMap.ClearAndSetSize(_numSrcOutStreams); + _destInToSrcOutMap.ClearAndSetSize(_numSrcOutStreams); + for (j = 0; j < _numSrcOutStreams; j++) { - _srcOutToDestInMap.Add(0); - _destInToSrcOutMap.Add(0); + _srcOutToDestInMap[j] = 0; + _destInToSrcOutMap[j] = 0; } UInt32 destInOffset = 0; @@ -34,7 +41,7 @@ CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo): srcInOffset -= srcCoderInfo.NumInStreams; srcOutOffset -= srcCoderInfo.NumOutStreams; - + UInt32 j; for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++) { @@ -53,66 +60,57 @@ CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo): void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo) { - destBindInfo.Coders.Clear(); - destBindInfo.BindPairs.Clear(); - destBindInfo.InStreams.Clear(); - destBindInfo.OutStreams.Clear(); + destBindInfo.Coders.ClearAndReserve(_srcBindInfo.Coders.Size()); + destBindInfo.BindPairs.ClearAndReserve(_srcBindInfo.BindPairs.Size()); + destBindInfo.InStreams.ClearAndReserve(_srcBindInfo.OutStreams.Size()); + destBindInfo.OutStreams.ClearAndReserve(_srcBindInfo.InStreams.Size()); - int i; - for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--) + unsigned i; + for (i = _srcBindInfo.Coders.Size(); i != 0;) { + i--; const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i]; CCoderStreamsInfo destCoderInfo; destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams; destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams; - destBindInfo.Coders.Add(destCoderInfo); + destBindInfo.Coders.AddInReserved(destCoderInfo); } - for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--) + for (i = _srcBindInfo.BindPairs.Size(); i != 0;) { + i--; const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i]; CBindPair destBindPair; destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex]; destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex]; - destBindInfo.BindPairs.Add(destBindPair); + destBindInfo.BindPairs.AddInReserved(destBindPair); } for (i = 0; i < _srcBindInfo.InStreams.Size(); i++) - destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]); + destBindInfo.OutStreams.AddInReserved(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]); for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++) - destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]); -} - -CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams): - NumInStreams(numInStreams), - NumOutStreams(numOutStreams) -{ - InSizes.Reserve(NumInStreams); - InSizePointers.Reserve(NumInStreams); - OutSizes.Reserve(NumOutStreams); - OutSizePointers.Reserve(NumOutStreams); + destBindInfo.InStreams.AddInReserved(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]); } -static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, +void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems) { - sizes.Clear(); - sizePointers.Clear(); - for(UInt32 i = 0; i < numItems; i++) + sizes.ClearAndSetSize(numItems); + sizePointers.ClearAndSetSize(numItems); + for (UInt32 i = 0; i < numItems; i++) { - if (srcSizes == 0 || srcSizes[i] == NULL) + if (!srcSizes || !srcSizes[i]) { - sizes.Add(0); - sizePointers.Add(NULL); + sizes[i] = 0; + sizePointers[i] = NULL; } else { - sizes.Add(*srcSizes[i]); - sizePointers.Add(&sizes.Back()); + sizes[i] = *(srcSizes[i]); + sizePointers[i] = &sizes[i]; } } } -void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes, - const UInt64 **outSizes) +void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes) { SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.h index a03722d61..50e7077ae 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.h +++ b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.h @@ -3,9 +3,9 @@ #ifndef __CODER_MIXER2_H #define __CODER_MIXER2_H -#include "../../../Common/MyVector.h" -#include "../../../Common/Types.h" #include "../../../Common/MyCom.h" +#include "../../../Common/MyVector.h" + #include "../../ICoder.h" namespace NCoderMixer { @@ -52,7 +52,7 @@ struct CBindInfo { numInStreams = 0; numOutStreams = 0; - for (int i = 0; i < Coders.Size(); i++) + FOR_VECTOR (i, Coders) { const CCoderStreamsInfo &coderStreamsInfo = Coders[i]; numInStreams += coderStreamsInfo.NumInStreams; @@ -62,14 +62,14 @@ struct CBindInfo int FindBinderForInStream(UInt32 inStream) const { - for (int i = 0; i < BindPairs.Size(); i++) + FOR_VECTOR (i, BindPairs) if (BindPairs[i].InIndex == inStream) return i; return -1; } int FindBinderForOutStream(UInt32 outStream) const { - for (int i = 0; i < BindPairs.Size(); i++) + FOR_VECTOR (i, BindPairs) if (BindPairs[i].OutIndex == outStream) return i; return -1; @@ -139,6 +139,9 @@ public: void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo); }; +void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, + CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems); + struct CCoderInfo2 { CMyComPtr<ICompressCoder> Coder; @@ -151,7 +154,9 @@ struct CCoderInfo2 CRecordVector<const UInt64 *> InSizePointers; CRecordVector<const UInt64 *> OutSizePointers; - CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams); + CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams): + NumInStreams(numInStreams), + NumOutStreams(numOutStreams) {} void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes); HRESULT QueryInterface(REFGUID iid, void** pp) const @@ -170,5 +175,5 @@ public: }; } -#endif +#endif diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2MT.cpp index d76450bd1..36b252600 100644 --- a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2MT.cpp +++ b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @@ -9,30 +9,28 @@ namespace NCoderMixer { CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams): CCoderInfo2(numInStreams, numOutStreams) { - InStreams.Reserve(NumInStreams); - InStreamPointers.Reserve(NumInStreams); - OutStreams.Reserve(NumOutStreams); - OutStreamPointers.Reserve(NumOutStreams); + InStreams.ClearAndReserve(NumInStreams); + OutStreams.ClearAndReserve(NumOutStreams); } void CCoder2::Execute() { Code(NULL); } void CCoder2::Code(ICompressProgressInfo *progress) { - InStreamPointers.Clear(); - OutStreamPointers.Clear(); + InStreamPointers.ClearAndReserve(NumInStreams); + OutStreamPointers.ClearAndReserve(NumOutStreams); UInt32 i; for (i = 0; i < NumInStreams; i++) { - if (InSizePointers[i] != NULL) + if (InSizePointers[i]) InSizePointers[i] = &InSizes[i]; - InStreamPointers.Add((ISequentialInStream *)InStreams[i]); + InStreamPointers.AddInReserved((ISequentialInStream *)InStreams[i]); } for (i = 0; i < NumOutStreams; i++) { - if (OutSizePointers[i] != NULL) + if (OutSizePointers[i]) OutSizePointers[i] = &OutSizes[i]; - OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]); + OutStreamPointers.AddInReserved((ISequentialOutStream *)OutStreams[i]); } if (Coder) Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], @@ -41,7 +39,7 @@ void CCoder2::Code(ICompressProgressInfo *progress) Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams, &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress); { - int i; + unsigned i; for (i = 0; i < InStreams.Size(); i++) InStreams[i].Release(); for (i = 0; i < OutStreams.Size(); i++) @@ -49,32 +47,13 @@ void CCoder2::Code(ICompressProgressInfo *progress) } } -static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, - CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems) -{ - sizes.Clear(); - sizePointers.Clear(); - for (UInt32 i = 0; i < numItems; i++) - { - if (srcSizes == 0 || srcSizes[i] == NULL) - { - sizes.Add(0); - sizePointers.Add(NULL); - } - else - { - sizes.Add(*srcSizes[i]); - sizePointers.Add(&sizes.Back()); - } - } -} - - +/* void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes) { SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); } +*/ ////////////////////////////////////// // CCoderMixer2MT @@ -83,10 +62,9 @@ HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo) { _bindInfo = bindInfo; _streamBinders.Clear(); - for (int i = 0; i < _bindInfo.BindPairs.Size(); i++) + FOR_VECTOR (i, _bindInfo.BindPairs) { - _streamBinders.Add(CStreamBinder()); - RINOK(_streamBinders.Back().CreateEvents()); + RINOK(_streamBinders.AddNew().CreateEvents()); } return S_OK; } @@ -113,7 +91,7 @@ void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder) void CCoderMixer2MT::ReInit() { - for (int i = 0; i < _streamBinders.Size(); i++) + FOR_VECTOR (i, _streamBinders) |