Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2018-05-03 00:28:04 +0300
committerKornel <kornel@geekhood.net>2018-05-03 00:28:04 +0300
commit18dc2b41613055f0daf7f6a1d4311368798ea12a (patch)
tree866f6e6a50406fe822cb78f80728b7aebfd79786
parentf19b649c73cd8b74c4e0b8a3a728a82c6bda47b4 (diff)
18.0518.05
-rw-r--r--C/7zVersion.h6
-rw-r--r--C/Alloc.c4
-rw-r--r--C/Bcj2.c10
-rw-r--r--C/Bcj2Enc.c3
-rw-r--r--C/Lzma2Enc.c14
-rw-r--r--C/LzmaDec.h14
-rw-r--r--C/LzmaEnc.c2231
-rw-r--r--C/Util/7z/7zMain.c27
-rw-r--r--C/Util/7zipInstall/makefile1
-rw-r--r--C/Util/7zipUninstall/makefile1
-rw-r--r--C/Util/SfxSetup/makefile1
-rw-r--r--C/Util/SfxSetup/makefile_con1
-rw-r--r--C/XzDec.c4
-rw-r--r--C/XzEnc.c4
-rw-r--r--CPP/7zip/Archive/Cab/CabHandler.cpp53
-rw-r--r--CPP/7zip/Archive/DmgHandler.cpp70
-rw-r--r--CPP/7zip/Archive/ElfHandler.cpp1
-rw-r--r--CPP/7zip/Archive/HfsHandler.cpp110
-rw-r--r--CPP/7zip/Archive/PeHandler.cpp5
-rw-r--r--CPP/7zip/Archive/Rar/Rar5Handler.cpp21
-rw-r--r--CPP/7zip/Archive/Rar/Rar5Handler.h2
-rw-r--r--CPP/7zip/Archive/Rar/RarHandler.cpp10
-rw-r--r--CPP/7zip/Archive/Rar/RarHandler.h2
-rw-r--r--CPP/7zip/Archive/Tar/TarIn.cpp4
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.cpp29
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.h2
-rw-r--r--CPP/7zip/Bundles/Alone/Alone.dsp16
-rw-r--r--CPP/7zip/Bundles/Alone/makefile2
-rw-r--r--CPP/7zip/Bundles/Alone/resource.rc4
-rw-r--r--CPP/7zip/Bundles/Alone7z/Alone.dsp16
-rw-r--r--CPP/7zip/Bundles/Alone7z/makefile3
-rw-r--r--CPP/7zip/Bundles/Alone7z/resource.rc4
-rw-r--r--CPP/7zip/Bundles/Fm/FM.dsp16
-rw-r--r--CPP/7zip/Bundles/Fm/makefile1
-rw-r--r--CPP/7zip/Bundles/SFXCon/SFXCon.dsp4
-rw-r--r--CPP/7zip/Bundles/SFXCon/makefile2
-rw-r--r--CPP/7zip/Bundles/SFXSetup/makefile2
-rw-r--r--CPP/7zip/Bundles/SFXWin/makefile2
-rw-r--r--CPP/7zip/Compress/Lzma2Encoder.cpp2
-rw-r--r--CPP/7zip/Compress/LzmaEncoder.cpp6
-rw-r--r--CPP/7zip/Compress/Rar1Decoder.cpp408
-rw-r--r--CPP/7zip/Compress/Rar1Decoder.h50
-rw-r--r--CPP/7zip/Compress/Rar2Decoder.cpp31
-rw-r--r--CPP/7zip/Compress/Rar2Decoder.h11
-rw-r--r--CPP/7zip/Compress/Rar3Decoder.cpp28
-rw-r--r--CPP/7zip/Compress/Rar3Decoder.h5
-rw-r--r--CPP/7zip/Compress/Rar5Decoder.cpp89
-rw-r--r--CPP/7zip/Compress/Rar5Decoder.h14
-rw-r--r--CPP/7zip/Crypto/Rar5Aes.cpp7
-rw-r--r--CPP/7zip/GuiCommon.rc3
-rw-r--r--CPP/7zip/UI/Common/ArchiveCommandLine.cpp200
-rw-r--r--CPP/7zip/UI/Common/ArchiveCommandLine.h20
-rw-r--r--CPP/7zip/UI/Common/Bench.cpp55
-rw-r--r--CPP/7zip/UI/Common/CompressCall.cpp4
-rw-r--r--CPP/7zip/UI/Common/CompressCall2.cpp5
-rw-r--r--CPP/7zip/UI/Common/EnumDirItems.cpp159
-rw-r--r--CPP/7zip/UI/Common/EnumDirItems.h20
-rw-r--r--CPP/7zip/UI/Common/HashCalc.h1
-rw-r--r--CPP/7zip/UI/Common/OpenArchive.cpp6
-rw-r--r--CPP/7zip/UI/Common/PropIDUtils.cpp6
-rw-r--r--CPP/7zip/UI/Common/Update.cpp4
-rw-r--r--CPP/7zip/UI/Console/Console.manifest13
-rw-r--r--CPP/7zip/UI/Console/ExtractCallbackConsole.cpp42
-rw-r--r--CPP/7zip/UI/Console/HashCon.cpp2
-rw-r--r--CPP/7zip/UI/Console/List.cpp99
-rw-r--r--CPP/7zip/UI/Console/Main.cpp35
-rw-r--r--CPP/7zip/UI/Console/MainAr.cpp2
-rw-r--r--CPP/7zip/UI/Console/PercentPrinter.cpp8
-rw-r--r--CPP/7zip/UI/Console/UpdateCallbackConsole.cpp20
-rw-r--r--CPP/7zip/UI/Console/resource.rc4
-rw-r--r--CPP/7zip/UI/Explorer/Explorer.dsp8
-rw-r--r--CPP/7zip/UI/Explorer/makefile1
-rw-r--r--CPP/7zip/UI/Far/ExtractEngine.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/7zFM.exe.manifest7
-rw-r--r--CPP/7zip/UI/FileManager/EditDialog.cpp57
-rw-r--r--CPP/7zip/UI/FileManager/EditDialog.h25
-rw-r--r--CPP/7zip/UI/FileManager/EditDialog.rc15
-rw-r--r--CPP/7zip/UI/FileManager/EditDialogRes.h2
-rw-r--r--CPP/7zip/UI/FileManager/FM.cpp1
-rw-r--r--CPP/7zip/UI/FileManager/FM.dsp8
-rw-r--r--CPP/7zip/UI/FileManager/FM.mak1
-rw-r--r--CPP/7zip/UI/FileManager/LangUtils.cpp1
-rw-r--r--CPP/7zip/UI/FileManager/ListViewDialog.cpp210
-rw-r--r--CPP/7zip/UI/FileManager/ListViewDialog.h18
-rw-r--r--CPP/7zip/UI/FileManager/ListViewDialog.rc4
-rw-r--r--CPP/7zip/UI/FileManager/PanelCopy.cpp67
-rw-r--r--CPP/7zip/UI/FileManager/PanelCrc.cpp52
-rw-r--r--CPP/7zip/UI/FileManager/PanelDrag.cpp118
-rw-r--r--CPP/7zip/UI/FileManager/PanelFolderChange.cpp1
-rw-r--r--CPP/7zip/UI/FileManager/PanelItemOpen.cpp4
-rw-r--r--CPP/7zip/UI/FileManager/PanelMenu.cpp72
-rw-r--r--CPP/7zip/UI/FileManager/PanelOperations.cpp14
-rw-r--r--CPP/7zip/UI/FileManager/PanelSplitFile.cpp8
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog2.cpp30
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog2.h70
-rw-r--r--CPP/7zip/UI/FileManager/resource.rc1
-rw-r--r--CPP/7zip/UI/GUI/7zG.exe.manifest7
-rw-r--r--CPP/7zip/UI/GUI/ExtractGUI.cpp79
-rw-r--r--CPP/7zip/UI/GUI/GUI.cpp27
-rw-r--r--CPP/7zip/UI/GUI/GUI.dsp32
-rw-r--r--CPP/7zip/UI/GUI/HashGUI.cpp187
-rw-r--r--CPP/7zip/UI/GUI/HashGUI.h11
-rw-r--r--CPP/7zip/UI/GUI/UpdateGUI.cpp6
-rw-r--r--CPP/7zip/UI/GUI/makefile4
-rw-r--r--CPP/7zip/UI/GUI/resource.rc2
-rw-r--r--CPP/Build.mak4
-rw-r--r--CPP/Common/MyString.h4
-rw-r--r--CPP/Common/MyWindows.h5
-rw-r--r--CPP/Common/StdOutStream.cpp59
-rw-r--r--CPP/Common/StdOutStream.h11
-rw-r--r--CPP/Windows/Control/Dialog.cpp1
-rw-r--r--CPP/Windows/Control/Dialog.h3
-rw-r--r--CPP/Windows/MemoryLock.cpp25
-rw-r--r--CPP/Windows/MemoryLock.h2
-rw-r--r--CPP/Windows/Registry.cpp2
-rw-r--r--DOC/7zip.inf4
-rw-r--r--DOC/7zip.nsi2
-rw-r--r--DOC/7zip.wxs2
-rw-r--r--DOC/lzma.txt8
-rw-r--r--DOC/readme.txt2
-rw-r--r--DOC/src-history.txt10
121 files changed, 3507 insertions, 1850 deletions
diff --git a/C/7zVersion.h b/C/7zVersion.h
index 42b2fb64..f3fb623a 100644
--- a/C/7zVersion.h
+++ b/C/7zVersion.h
@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 18
-#define MY_VER_MINOR 03
+#define MY_VER_MINOR 05
#define MY_VER_BUILD 0
-#define MY_VERSION_NUMBERS "18.03 beta"
+#define MY_VERSION_NUMBERS "18.05"
#define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME
@@ -10,7 +10,7 @@
#define MY_VERSION_CPU MY_VERSION
#endif
-#define MY_DATE "2018-03-04"
+#define MY_DATE "2018-04-30"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"
diff --git a/C/Alloc.c b/C/Alloc.c
index 64edd504..bcede4b8 100644
--- a/C/Alloc.c
+++ b/C/Alloc.c
@@ -1,5 +1,5 @@
/* Alloc.c -- Memory allocation functions
-2018-03-01 : Igor Pavlov : Public domain */
+2018-04-27 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -283,7 +283,7 @@ const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align)
-#if (_POSIX_C_SOURCE >= 200112L)
+#if (_POSIX_C_SOURCE >= 200112L) && !defined(_WIN32)
#define USE_posix_memalign
#endif
diff --git a/C/Bcj2.c b/C/Bcj2.c
index 0efff4e5..9a0046a6 100644
--- a/C/Bcj2.c
+++ b/C/Bcj2.c
@@ -1,5 +1,5 @@
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
-2017-04-03 : Igor Pavlov : Public domain */
+2018-04-28 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -232,10 +232,10 @@ SRes Bcj2Dec_Decode(CBcj2Dec *p)
if (rem < 4)
{
- SizeT i;
- SetUi32(p->temp, val);
- for (i = 0; i < rem; i++)
- dest[i] = p->temp[i];
+ p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8;
+ p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8;
+ p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8;
+ p->temp[3] = (Byte)val;
p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
break;
diff --git a/C/Bcj2Enc.c b/C/Bcj2Enc.c
index 98b775b7..5c682982 100644
--- a/C/Bcj2Enc.c
+++ b/C/Bcj2Enc.c
@@ -1,5 +1,5 @@
/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code)
-2017-04-03 : Igor Pavlov : Public domain */
+2017-04-28 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -12,7 +12,6 @@
#define PRF(x)
#endif
-#include <windows.h>
#include <string.h>
#include "Bcj2.h"
diff --git a/C/Lzma2Enc.c b/C/Lzma2Enc.c
index 3aa89d78..f83c8008 100644
--- a/C/Lzma2Enc.c
+++ b/C/Lzma2Enc.c
@@ -1,5 +1,5 @@
/* Lzma2Enc.c -- LZMA2 Encoder
-2018-02-08 : Igor Pavlov : Public domain */
+2018-04-27 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -369,7 +369,9 @@ typedef struct
ISeqOutStream *outStream;
Byte *outBuf;
- size_t outBufSize;
+ size_t outBuf_Rem; /* remainder in outBuf */
+
+ size_t outBufSize; /* size of allocated outBufs[i] */
size_t outBufsDataSizes[MTCODER__BLOCKS_MAX];
Bool mtCoder_WasConstructed;
CMtCoder mtCoder;
@@ -699,10 +701,10 @@ static SRes Lzma2Enc_MtCallback_Write(void *pp, unsigned outBufIndex)
if (me->outStream)
return ISeqOutStream_Write(me->outStream, data, size) == size ? SZ_OK : SZ_ERROR_WRITE;
- if (size > me->outBufSize)
+ if (size > me->outBuf_Rem)
return SZ_ERROR_OUTPUT_EOF;
memcpy(me->outBuf, data, size);
- me->outBufSize -= size;
+ me->outBuf_Rem -= size;
me->outBuf += size;
return SZ_OK;
}
@@ -749,11 +751,11 @@ SRes Lzma2Enc_Encode2(CLzma2EncHandle pp,
p->outStream = outStream;
p->outBuf = NULL;
- p->outBufSize = 0;
+ p->outBuf_Rem = 0;
if (!outStream)
{
p->outBuf = outBuf;
- p->outBufSize = *outBufSize;
+ p->outBuf_Rem = *outBufSize;
*outBufSize = 0;
}
diff --git a/C/LzmaDec.h b/C/LzmaDec.h
index 2567aaaa..1f0927ab 100644
--- a/C/LzmaDec.h
+++ b/C/LzmaDec.h
@@ -1,5 +1,5 @@
/* LzmaDec.h -- LZMA Decoder
-2018-02-06 : Igor Pavlov : Public domain */
+2018-04-21 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
@@ -12,11 +12,13 @@ EXTERN_C_BEGIN
/* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */
+typedef
#ifdef _LZMA_PROB32
-#define CLzmaProb UInt32
+ UInt32
#else
-#define CLzmaProb UInt16
+ UInt16
#endif
+ CLzmaProb;
/* ---------- LZMA Properties ---------- */
@@ -76,8 +78,8 @@ typedef struct
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams:
- 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
- 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
+ - Stream with end mark. That end mark adds about 6 bytes to compressed size.
+ - Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum
{
@@ -147,7 +149,7 @@ void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
You must work with CLzmaDec variables directly in this interface.
STEPS:
- LzmaDec_Constr()
+ LzmaDec_Construct()
LzmaDec_Allocate()
for (each new stream)
{
diff --git a/C/LzmaEnc.c b/C/LzmaEnc.c
index 9b7e6910..24e58264 100644
--- a/C/LzmaEnc.c
+++ b/C/LzmaEnc.c
@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder
-2017-06-22 : Igor Pavlov : Public domain */
+2018-04-29 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -26,15 +26,6 @@ static unsigned g_STAT_OFFSET = 0;
#define kLzmaMaxHistorySize ((UInt32)3 << 29)
/* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */
-#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
-
-#define kBlockSize (9 << 10)
-#define kUnpackBlockSize (1 << 18)
-#define kMatchArraySize (1 << 21)
-#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
-
-#define kNumMaxDirectBits (31)
-
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
@@ -111,9 +102,9 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); }
-static UInt32 GetPosSlot1(UInt32 pos)
+static unsigned GetPosSlot1(UInt32 pos)
{
- UInt32 res;
+ unsigned res;
BSR2_RET(pos, res);
return res;
}
@@ -146,18 +137,18 @@ static void LzmaEnc_FastPosInit(Byte *g_FastPos)
/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
/*
-#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
+#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
res = p->g_FastPos[pos >> zz] + (zz * 2); }
*/
/*
-#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
+#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \
(0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
res = p->g_FastPos[pos >> zz] + (zz * 2); }
*/
-#define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
+#define BSR2_RET(pos, res) { unsigned zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
res = p->g_FastPos[pos >> zz] + (zz * 2); }
/*
@@ -168,32 +159,32 @@ static void LzmaEnc_FastPosInit(Byte *g_FastPos)
#define GetPosSlot1(pos) p->g_FastPos[pos]
#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); }
#endif
#define LZMA_NUM_REPS 4
-typedef unsigned CState;
+typedef UInt16 CState;
+typedef UInt16 CExtra;
typedef struct
{
UInt32 price;
-
CState state;
- int prev1IsChar;
- int prev2;
-
- UInt32 posPrev2;
- UInt32 backPrev2;
-
- UInt32 posPrev;
- UInt32 backPrev;
- UInt32 backs[LZMA_NUM_REPS];
+ CExtra extra;
+ // 0 : normal
+ // 1 : LIT : MATCH
+ // > 1 : MATCH (extra-1) : LIT : REP0 (len)
+ UInt32 len;
+ UInt32 dist;
+ UInt32 reps[LZMA_NUM_REPS];
} COptimal;
+
#define kNumOpts (1 << 12)
+#define kPackReserve (1 + kNumOpts * 2)
#define kNumLenToPosStates 4
#define kNumPosSlotBits 6
@@ -201,22 +192,21 @@ typedef struct
#define kDicLogSizeMax 32
#define kDistTableSizeMax (kDicLogSizeMax * 2)
-
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kAlignMask (kAlignTableSize - 1)
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
-#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
-
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+typedef
#ifdef _LZMA_PROB32
-#define CLzmaProb UInt32
+ UInt32
#else
-#define CLzmaProb UInt16
+ UInt16
#endif
+ CLzmaProb;
#define LZMA_PB_MAX 4
#define LZMA_LC_MAX 8
@@ -224,15 +214,11 @@ typedef struct
#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
-
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
-#define kLenNumMidBits 3
-#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
-
-#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+#define kLenNumSymbolsTotal (kLenNumLowSymbols * 2 + kLenNumHighSymbols)
#define LZMA_MATCH_LEN_MIN 2
#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
@@ -242,27 +228,23 @@ typedef struct
typedef struct
{
- CLzmaProb choice;
- CLzmaProb choice2;
- CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
- CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)];
CLzmaProb high[kLenNumHighSymbols];
} CLenEnc;
typedef struct
{
- CLenEnc p;
- UInt32 tableSize;
+ unsigned tableSize;
+ unsigned counters[LZMA_NUM_PB_STATES_MAX];
UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
- UInt32 counters[LZMA_NUM_PB_STATES_MAX];
} CLenPriceEnc;
typedef struct
{
UInt32 range;
- Byte cache;
+ unsigned cache;
UInt64 low;
UInt64 cacheSize;
Byte *buf;
@@ -278,48 +260,54 @@ typedef struct
{
CLzmaProb *litProbs;
- UInt32 state;
+ unsigned state;
UInt32 reps[LZMA_NUM_REPS];
- CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
CLzmaProb isRep[kNumStates];
CLzmaProb isRepG0[kNumStates];
CLzmaProb isRepG1[kNumStates];
CLzmaProb isRepG2[kNumStates];
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
- CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
- CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+ CLzmaProb posEncoders[kNumFullDistances];
- CLenPriceEnc lenEnc;
- CLenPriceEnc repLenEnc;
+ CLenEnc lenProbs;
+ CLenEnc repLenProbs;
+
} CSaveState;
+typedef UInt32 CProbPrice;
+
+
typedef struct
{
void *matchFinderObj;
IMatchFinder matchFinder;
- UInt32 optimumEndIndex;
- UInt32 optimumCurrentIndex;
+ unsigned optCur;
+ unsigned optEnd;
- UInt32 longestMatchLength;
- UInt32 numPairs;
+ unsigned longestMatchLen;
+ unsigned numPairs;
UInt32 numAvail;
- UInt32 numFastBytes;
- UInt32 additionalOffset;
+ unsigned state;
+ unsigned numFastBytes;
+ unsigned additionalOffset;
UInt32 reps[LZMA_NUM_REPS];
- UInt32 state;
+ unsigned lpMask, pbMask;
+ CLzmaProb *litProbs;
+ CRangeEnc rc;
+
+ UInt32 backRes;
unsigned lc, lp, pb;
- unsigned lpMask, pbMask;
unsigned lclp;
- CLzmaProb *litProbs;
-
Bool fastMode;
Bool writeEndMark;
Bool finished;
@@ -328,19 +316,19 @@ typedef struct
UInt64 nowPos64;
- UInt32 matchPriceCount;
- UInt32 alignPriceCount;
+ unsigned matchPriceCount;
+ unsigned alignPriceCount;
- UInt32 distTableSize;
+ unsigned distTableSize;
UInt32 dictSize;
SRes result;
- CRangeEnc rc;
-
#ifndef _7ZIP_ST
Bool mtMode;
+ // begin of CMatchFinderMt is used in LZ thread
CMatchFinderMt matchFinderMt;
+ // end of CMatchFinderMt is used in BT and HASH threads
#endif
CMatchFinder matchFinderBase;
@@ -349,33 +337,37 @@ typedef struct
Byte pad[128];
#endif
- COptimal opt[kNumOpts];
-
- #ifndef LZMA_LOG_BSR
- Byte g_FastPos[1 << kNumLogBits];
- #endif
+ // LZ thread
+ CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
- UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
+ UInt32 alignPrices[kAlignTableSize];
UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
- UInt32 alignPrices[kAlignTableSize];
- CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
CLzmaProb isRep[kNumStates];
CLzmaProb isRepG0[kNumStates];
CLzmaProb isRepG1[kNumStates];
CLzmaProb isRepG2[kNumStates];
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-
CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
- CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
- CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+ CLzmaProb posEncoders[kNumFullDistances];
+ CLenEnc lenProbs;
+ CLenEnc repLenProbs;
+
+ #ifndef LZMA_LOG_BSR
+ Byte g_FastPos[1 << kNumLogBits];
+ #endif
+
CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc;
+ COptimal opt[kNumOpts];
+
CSaveState saveState;
#ifndef _7ZIP_ST
@@ -384,58 +376,62 @@ typedef struct
} CLzmaEnc;
+
+#define COPY_ARR(dest, src, arr) memcpy(dest->arr, src->arr, sizeof(src->arr));
+
void LzmaEnc_SaveState(CLzmaEncHandle pp)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
CSaveState *dest = &p->saveState;
- int i;
- dest->lenEnc = p->lenEnc;
- dest->repLenEnc = p->repLenEnc;
+
dest->state = p->state;
+
+ dest->lenProbs = p->lenProbs;
+ dest->repLenProbs = p->repLenProbs;
+
+ COPY_ARR(dest, p, reps);
+
+ COPY_ARR(dest, p, posAlignEncoder);
+ COPY_ARR(dest, p, isRep);
+ COPY_ARR(dest, p, isRepG0);
+ COPY_ARR(dest, p, isRepG1);
+ COPY_ARR(dest, p, isRepG2);
+ COPY_ARR(dest, p, isMatch);
+ COPY_ARR(dest, p, isRep0Long);
+ COPY_ARR(dest, p, posSlotEncoder);
+ COPY_ARR(dest, p, posEncoders);
- for (i = 0; i < kNumStates; i++)
- {
- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
- }
- for (i = 0; i < kNumLenToPosStates; i++)
- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
- memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
- memcpy(dest->reps, p->reps, sizeof(p->reps));
memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb));
}
+
void LzmaEnc_RestoreState(CLzmaEncHandle pp)
{
CLzmaEnc *dest = (CLzmaEnc *)pp;
const CSaveState *p = &dest->saveState;
- int i;
- dest->lenEnc = p->lenEnc;
- dest->repLenEnc = p->repLenEnc;
+
dest->state = p->state;
- for (i = 0; i < kNumStates; i++)
- {
- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
- }
- for (i = 0; i < kNumLenToPosStates; i++)
- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
- memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
- memcpy(dest->reps, p->reps, sizeof(p->reps));
+ dest->lenProbs = p->lenProbs;
+ dest->repLenProbs = p->repLenProbs;
+
+ COPY_ARR(dest, p, reps);
+
+ COPY_ARR(dest, p, posAlignEncoder);
+ COPY_ARR(dest, p, isRep);
+ COPY_ARR(dest, p, isRepG0);
+ COPY_ARR(dest, p, isRepG1);
+ COPY_ARR(dest, p, isRepG2);
+ COPY_ARR(dest, p, isMatch);
+ COPY_ARR(dest, p, isRep0Long);
+ COPY_ARR(dest, p, posSlotEncoder);
+ COPY_ARR(dest, p, posEncoders);
+
memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb));
}
+
+
SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -464,7 +460,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
p->fastMode = (props.algo == 0);
p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0);
{
- UInt32 numHashBytes = 4;
+ unsigned numHashBytes = 4;
if (props.btMode)
{
if (props.numHashBytes < 2)
@@ -501,14 +497,19 @@ void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
}
+#define kState_Start 0
+#define kState_LitAfterMatch 4
+#define kState_LitAfterRep 5
+#define kState_MatchAfterLit 7
+#define kState_RepAfterLit 8
-static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
-static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
-static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
-static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
-
-#define IsCharState(s) ((s) < 7)
+static const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+static const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+static const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+static const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+#define IsLitState(s) ((s) < 7)
+#define GetLenToPosState2(len) (((len) < kNumLenToPosStates - 1) ? (len) : kNumLenToPosStates - 1)
#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
#define kInfinityPrice (1 << 30)
@@ -519,9 +520,11 @@ static void RangeEnc_Construct(CRangeEnc *p)
p->bufBase = NULL;
}
-#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
+#define RangeEnc_GetProcessed_sizet(p) ((size_t)(p)->processed + ((p)->buf - (p)->bufBase) + (size_t)(p)->cacheSize)
#define RC_BUF_SIZE (1 << 16)
+
static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)
{
if (!p->bufBase)
@@ -543,10 +546,10 @@ static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)
static void RangeEnc_Init(CRangeEnc *p)
{
/* Stream.Init(); */
- p->low = 0;
p->range = 0xFFFFFFFF;
- p->cacheSize = 1;
p->cache = 0;
+ p->low = 0;
+ p->cacheSize = 0;
p->buf = p->bufBase;
@@ -554,7 +557,7 @@ static void RangeEnc_Init(CRangeEnc *p)
p->res = SZ_OK;
}
-static void RangeEnc_FlushStream(CRangeEnc *p)
+MY_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p)
{
size_t num;
if (p->res != SZ_OK)
@@ -566,25 +569,36 @@ static void RangeEnc_FlushStream(CRangeEnc *p)
p->buf = p->bufBase;
}
-static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
+MY_NO_INLINE static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
{
- if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0)
+ UInt32 low = (UInt32)p->low;
+ unsigned high = (unsigned)(p->low >> 32);
+ p->low = (UInt32)(low << 8);
+ if (low < (UInt32)0xFF000000 || high != 0)
{
- Byte temp = p->cache;
- do
{
Byte *buf = p->buf;
- *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
+ *buf++ = (Byte)(p->cache + high);
+ p->cache = (unsigned)(low >> 24);
p->buf = buf;
if (buf == p->bufLim)
RangeEnc_FlushStream(p);
- temp = 0xFF;
+ if (p->cacheSize == 0)
+ return;
+ }
+ high += 0xFF;
+ for (;;)
+ {
+ Byte *buf = p->buf;
+ *buf++ = (Byte)(high);
+ p->buf = buf;
+ if (buf == p->bufLim)
+ RangeEnc_FlushStream(p);
+ if (--p->cacheSize == 0)
+ return;
}
- while (--p->cacheSize != 0);
- p->cache = (Byte)((UInt32)p->low >> 24);
}
p->cacheSize++;
- p->low = (UInt32)p->low << 8;
}
static void RangeEnc_FlushData(CRangeEnc *p)
@@ -594,78 +608,121 @@ static void RangeEnc_FlushData(CRangeEnc *p)
RangeEnc_ShiftLow(p);
}
-static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits)
-{
- do
- {
- p->range >>= 1;
- p->low += p->range & (0 - ((value >> --numBits) & 1));
- if (p->range < kTopValue)
- {
- p->range <<= 8;
- RangeEnc_ShiftLow(p);
- }
- }
- while (numBits != 0);
-}
+#define RC_NORM(p) if (range < kTopValue) { range <<= 8; RangeEnc_ShiftLow(p); }
-static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
-{
- UInt32 ttt = *prob;
- UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
- if (symbol == 0)
- {
- p->range = newBound;
- ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
- }
- else
- {
- p->low += newBound;
- p->range -= newBound;
- ttt -= ttt >> kNumMoveBits;
+#define RC_BIT_PRE(p, prob) \
+ ttt = *(prob); \
+ newBound = (range >> kNumBitModelTotalBits) * ttt;
+
+// #define _LZMA_ENC_USE_BRANCH
+
+#ifdef _LZMA_ENC_USE_BRANCH
+
+#define RC_BIT(p, prob, symbol) { \
+ RC_BIT_PRE(p, prob) \
+ if (symbol == 0) { range = newBound; ttt += (kBitModelTotal - ttt) >> kNumMoveBits; } \
+ else { (p)->low += newBound; range -= newBound; ttt -= ttt >> kNumMoveBits; } \
+ *(prob) = (CLzmaProb)ttt; \
+ RC_NORM(p) \
}
- *prob = (CLzmaProb)ttt;
- if (p->range < kTopValue)
- {
- p->range <<= 8;
- RangeEnc_ShiftLow(p);
+
+#else
+
+#define RC_BIT(p, prob, symbol) { \
+ UInt32 mask; \
+ RC_BIT_PRE(p, prob) \
+ mask = 0 - (UInt32)symbol; \
+ range &= mask; \
+ mask &= newBound; \
+ range -= mask; \
+ (p)->low += mask; \
+ mask = (UInt32)symbol - 1; \
+ range += newBound & mask; \
+ mask &= (kBitModelTotal - ((1 << kNumMoveBits) - 1)); \
+ mask += ((1 << kNumMoveBits) - 1); \
+ ttt += (Int32)(mask - ttt) >> kNumMoveBits; \
+ *(prob) = (CLzmaProb)ttt; \
+ RC_NORM(p) \
}
+
+#endif
+
+
+
+
+#define RC_BIT_0_BASE(p, prob) \
+ range = newBound; *(prob) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+
+#define RC_BIT_1_BASE(p, prob) \
+ range -= newBound; (p)->low += newBound; *(prob) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); \
+
+#define RC_BIT_0(p, prob) \
+ RC_BIT_0_BASE(p, prob) \
+ RC_NORM(p)
+
+#define RC_BIT_1(p, prob) \
+ RC_BIT_1_BASE(p, prob) \
+ RC_NORM(p)
+
+static void RangeEnc_EncodeBit_0(CRangeEnc *p, CLzmaProb *prob)
+{
+ UInt32 range, ttt, newBound;
+ range = p->range;
+ RC_BIT_PRE(p, prob)
+ RC_BIT_0(p, prob)
+ p->range = range;
}
static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
{
+ UInt32 range = p->range;
symbol |= 0x100;
do
{
- RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
+ UInt32 ttt, newBound;
+ // RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
+ CLzmaProb *prob = probs + (symbol >> 8);
+ UInt32 bit = (symbol >> 7) & 1;
symbol <<= 1;
+ RC_BIT(p, prob, bit);
}
while (symbol < 0x10000);
+ p->range = range;
}
static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
{
+ UInt32 range = p->range;
UInt32 offs = 0x100;
symbol |= 0x100;
do
{
+ UInt32 ttt, newBound;
+ CLzmaProb *prob;
+ UInt32 bit;
matchByte <<= 1;
- RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
+ // RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
+ prob = probs + (offs + (matchByte & offs) + (symbol >> 8));
+ bit = (symbol >> 7) & 1;
symbol <<= 1;
offs &= ~(matchByte ^ symbol);
+ RC_BIT(p, prob, bit);
}
while (symbol < 0x10000);
+ p->range = range;
}
-static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
+
+
+static void LzmaEnc_InitPriceTables(CProbPrice *ProbPrices)
{
UInt32 i;
- for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
+ for (i = 0; i < (kBitModelTotal >> kNumMoveReducingBits); i++)
{
- const int kCyclesBits = kNumBitPriceShiftBits;
- UInt32 w = i;
- UInt32 bitCount = 0;
- int j;
+ const unsigned kCyclesBits = kNumBitPriceShiftBits;
+ UInt32 w = (i << kNumMoveReducingBits) + (1 << (kNumMoveReducingBits - 1));
+ unsigned bitCount = 0;
+ unsigned j;
for (j = 0; j < kCyclesBits; j++)
{
w = w * w;
@@ -676,37 +733,41 @@ static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
bitCount++;
}
}
- ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
+ ProbPrices[i] = (CProbPrice)((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
+ // printf("\n%3d: %5d", i, ProbPrices[i]);
}
}
#define GET_PRICE(prob, symbol) \
- p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+ p->ProbPrices[((prob) ^ (unsigned)(((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
#define GET_PRICEa(prob, symbol) \
- ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+ ProbPrices[((prob) ^ (unsigned)((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
-#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+#define GET_PRICEa_0(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICEa_1(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
-static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const UInt32 *ProbPrices)
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const CProbPrice *ProbPrices)
{
UInt32 price = 0;
symbol |= 0x100;
do
{
- price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
- symbol <<= 1;
+ unsigned bit = symbol & 1;
+ symbol >>= 1;
+ price += GET_PRICEa(probs[symbol], bit);
}
- while (symbol < 0x10000);
+ while (symbol >= 2);
return price;
}
-static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const UInt32 *ProbPrices)
+
+static UInt32 LitEnc_Matched_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const CProbPrice *ProbPrices)
{
UInt32 price = 0;
UInt32 offs = 0x100;
@@ -723,520 +784,525 @@ static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt
}
-static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-{
- UInt32 m = 1;
- int i;
- for (i = numBitLevels; i != 0;)
- {
- UInt32 bit;
- i--;
- bit = (symbol >> i) & 1;
- RangeEnc_EncodeBit(rc, probs + m, bit);
- m = (m << 1) | bit;
- }
-}
-
-static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-{
- UInt32 m = 1;
- int i;
- for (i = 0; i < numBitLevels; i++)
- {
- UInt32 bit = symbol & 1;
- RangeEnc_EncodeBit(rc, probs + m, bit);
- m = (m << 1) | bit;
- symbol >>= 1;
- }
-}
-
-static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
-{
- UInt32 price = 0;
- symbol |= (1 << numBitLevels);
- while (symbol != 1)
- {
- price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
- symbol >>= 1;
- }
- return price;
-}
-
-static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, unsigned numBits, UInt32 symbol)
{
- UInt32 price = 0;
- UInt32 m = 1;
- int i;
- for (i = numBitLevels; i != 0; i--)
+ UInt32 range = rc->range;
+ unsigned m = 1;
+ do
{
- UInt32 bit = symbol & 1;
+ UInt32 ttt, newBound;
+ unsigned bit = symbol & 1;
+ // RangeEnc_EncodeBit(rc, probs + m, bit);
symbol >>= 1;
- price += GET_PRICEa(probs[m], bit);
+ RC_BIT(rc, probs + m, bit);
m = (m << 1) | bit;
}
- return price;
+ while (--numBits);
+ rc->range = range;
}
+
static void LenEnc_Init(CLenEnc *p)
{
unsigned i;
- p->choice = p->choice2 = kProbInitValue;
- for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)); i++)
p->low[i] = kProbInitValue;
- for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
- p->mid[i] = kProbInitValue;
for (i = 0; i < kLenNumHighSymbols; i++)
p->high[i] = kProbInitValue;
}
-static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned symbol, unsigned posState)
{
- if (symbol < kLenNumLowSymbols)
- {
- RangeEnc_EncodeBit(rc, &p->choice, 0);
- RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
- }
- else
+ UInt32 range, ttt, newBound;
+ CLzmaProb *probs = p->low;
+ range = rc->range;
+ RC_BIT_PRE(rc, probs);
+ if (symbol >= kLenNumLowSymbols)
{
- RangeEnc_EncodeBit(rc, &p->choice, 1);
- if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
+ RC_BIT_1(rc, probs);
+ probs += kLenNumLowSymbols;
+ RC_BIT_PRE(rc, probs);
+ if (symbol >= kLenNumLowSymbols * 2)
{
- RangeEnc_EncodeBit(rc, &p->choice2, 0);
- RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
- }
- else
- {
- RangeEnc_EncodeBit(rc, &p->choice2, 1);
- RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
+ RC_BIT_1(rc, probs);
+ rc->range = range;
+ // RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols * 2);
+ LitEnc_Encode(rc, p->high, symbol - kLenNumLowSymbols * 2);
+ return;
}
+ symbol -= kLenNumLowSymbols;
}
-}
-static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, const UInt32 *ProbPrices)
-{
- UInt32 a0 = GET_PRICE_0a(p->choice);
- UInt32 a1 = GET_PRICE_1a(p->choice);
- UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
- UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
- UInt32 i = 0;
- for (i = 0; i < kLenNumLowSymbols; i++)
+ // RcTree_Encode(rc, probs + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
{
- if (i >= numSymbols)
- return;
- prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
- }
- for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
- {
- if (i >= numSymbols)
- return;
- prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
+ unsigned m;
+ unsigned bit;
+ RC_BIT_0(rc, probs);
+ probs += (posState << (1 + kLenNumLowBits));
+ bit = (symbol >> 2) ; RC_BIT(rc, probs + 1, bit); m = (1 << 1) + bit;
+ bit = (symbol >> 1) & 1; RC_BIT(rc, probs + m, bit); m = (m << 1) + bit;
+ bit = symbol & 1; RC_BIT(rc, probs + m, bit);
+ rc->range = range;
}
- for (; i < numSymbols; i++)
- prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
}
-static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, const UInt32 *ProbPrices)
+static void SetPrices_3(const CLzmaProb *probs, UInt32 startPrice, UInt32 *prices, const CProbPrice *ProbPrices)
{
- LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
- p->counters[posState] = p->tableSize;
+ unsigned i;
+ for (i = 0; i < 8; i += 2)
+ {
+ UInt32 price = startPrice;
+ UInt32 prob;
+ price += GET_PRICEa(probs[1 ], (i >> 2));
+ price += GET_PRICEa(probs[2 + (i >> 2)], (i >> 1) & 1);
+ prob = probs[4 + (i >> 1)];
+ prices[i ] = price + GET_PRICEa_0(prob);
+ prices[i + 1] = price + GET_PRICEa_1(prob);
+ }
}
-static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, const UInt32 *ProbPrices)
+
+MY_NO_INLINE static void MY_FAST_CALL LenPriceEnc_UpdateTable(
+ CLenPriceEnc *p, unsigned posState,
+ const CLenEnc *enc,
+ const CProbPrice *ProbPrices)
{
- UInt32 posState;
- for (posState = 0; posState < numPosStates; posState++)
- LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+ // int y; for (y = 0; y < 100; y++) {
+ UInt32 a;
+ unsigned i, numSymbols;
+
+ UInt32 *prices = p->prices[posState];
+ {
+ const CLzmaProb *probs = enc->low + (posState << (1 + kLenNumLowBits));
+ SetPrices_3(probs, GET_PRICEa_0(enc->low[0]), prices, ProbPrices);
+ a = GET_PRICEa_1(enc->low[0]);
+ SetPrices_3(probs + kLenNumLowSymbols, a + GET_PRICEa_0(enc->low[kLenNumLowSymbols]), prices + kLenNumLowSymbols, ProbPrices);
+ a += GET_PRICEa_1(enc->low[kLenNumLowSymbols]);
+ }
+ numSymbols = p->tableSize;
+ p->counters[posState] = numSymbols;
+ for (i = kLenNumLowSymbols * 2; i < numSymbols; i += 1)
+ {
+ prices[i] = a +
+ // RcTree_GetPrice(enc->high, kLenNumHighBits, i - kLenNumLowSymbols * 2, ProbPrices);
+ LitEnc_GetPrice(enc->high, i - kLenNumLowSymbols * 2, ProbPrices);
+ /*
+ unsigned sym = (i - kLenNumLowSymbols * 2) >> 1;
+ UInt32 price = a + RcTree_GetPrice(enc->high, kLenNumHighBits - 1, sym, ProbPrices);
+ UInt32 prob = enc->high[(1 << 7) + sym];
+ prices[i ] = price + GET_PRICEa_0(prob);
+ prices[i + 1] = price + GET_PRICEa_1(prob);
+ */
+ }
+ // }
}
-static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, const UInt32 *ProbPrices)
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, unsigned numPosStates,
+ const CLenEnc *enc,
+ const CProbPrice *ProbPrices)
{
- LenEnc_Encode(&p->p, rc, symbol, posState);
- if (updatePrice)
- if (--p->counters[posState] == 0)
- LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+ unsigned posState;
+ for (posState = 0; posState < numPosStates; posState++)
+ LenPriceEnc_UpdateTable(p, posState, enc, ProbPrices);
}
-
-
-static void MovePos(CLzmaEnc *p, UInt32 num)
-{
+/*
#ifdef SHOW_STAT
g_STAT_OFFSET += num;
printf("\n MovePos %u", num);
#endif
+*/
- if (num != 0)
- {
- p->additionalOffset += num;
- p->matchFinder.Skip(p->matchFinderObj, num);
- }
-}
+#define MOVE_POS(p, num) { \
+ p->additionalOffset += (num); \
+ p->matchFinder.Skip(p->matchFinderObj, (num)); }
+
-static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
+static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
{
- UInt32 lenRes = 0, numPairs;
+ unsigned numPairs;
+
+ p->additionalOffset++;
p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
+ *numPairsRes = numPairs;
#ifdef SHOW_STAT
printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);
g_STAT_OFFSET++;
{
- UInt32 i;
+ unsigned i;
for (i = 0; i < numPairs; i += 2)
printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);
}
#endif
- if (numPairs > 0)
+ if (numPairs == 0)
+ return 0;
{
- lenRes = p->matches[(size_t)numPairs - 2];
- if (lenRes == p->numFastBytes)
+ unsigned len = p->matches[(size_t)numPairs - 2];
+ if (len != p->numFastBytes)
+ return len;
{
UInt32 numAvail = p->numAvail;
if (numAvail > LZMA_MATCH_LEN_MAX)
numAvail = LZMA_MATCH_LEN_MAX;
{
- const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
- const Byte *pby = pbyCur + lenRes;
+ const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ const Byte *p2 = p1 + len;
ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[(size_t)numPairs - 1];
- const Byte *pbyLim = pbyCur + numAvail;
- for (; pby != pbyLim && *pby == pby[dif]; pby++);
- lenRes = (UInt32)(pby - pbyCur);
+ const Byte *lim = p1 + numAvail;
+ for (; p2 != lim && *p2 == p2[dif]; p2++);
+ return (unsigned)(p2 - p1);
}
}
}
- p->additionalOffset++;
- *numDistancePairsRes = numPairs;
- return lenRes;
}
+#define MARK_LIT ((UInt32)(Int32)-1)
-#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
-#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
-#define IsShortRep(p) ((p)->backPrev == 0)
+#define MakeAs_Lit(p) { (p)->dist = MARK_LIT; (p)->extra = 0; }
+#define MakeAs_ShortRep(p) { (p)->dist = 0; (p)->extra = 0; }
+#define IsShortRep(p) ((p)->dist == 0)
-static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
-{
- return
- GET_PRICE_0(p->isRepG0[state]) +
- GET_PRICE_0(p->isRep0Long[state][posState]);
-}
-static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
+#define GetPrice_ShortRep(p, state, posState) \
+ ( GET_PRICE_0(p->isRepG0[state]) + GET_PRICE_0(p->isRep0Long[state][posState]))
+
+#define GetPrice_Rep_0(p, state, posState) ( \
+ GET_PRICE_1(p->isMatch[state][posState]) \
+ + GET_PRICE_1(p->isRep0Long[state][posState])) \
+ + GET_PRICE_1(p->isRep[state]) \
+ + GET_PRICE_0(p->isRepG0[state])
+
+
+static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState)
{
UInt32 price;
+ UInt32 prob = p->isRepG0[state];
if (repIndex == 0)
{
- price = GET_PRICE_0(p->isRepG0[state]);
+ price = GET_PRICE_0(prob);
price += GET_PRICE_1(p->isRep0Long[state][posState]);
}
else
{
- price = GET_PRICE_1(p->isRepG0[state]);
+ price = GET_PRICE_1(prob);
+ prob = p->isRepG1[state];
if (repIndex == 1)
- price += GET_PRICE_0(p->isRepG1[state]);
+ price += GET_PRICE_0(prob);
else
{
- price += GET_PRICE_1(p->isRepG1[state]);
+ price += GET_PRICE_1(prob);
price += GET_PRICE(p->isRepG2[state], repIndex - 2);
}
}
return price;
}
-static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
-{
- return p->repLenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN] +
- GetPureRepPrice(p, repIndex, state, posState);
-}
-static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
+static unsigned Backward(CLzmaEnc *p, unsigned cur)
{
- UInt32 posMem = p->opt[cur].posPrev;
- UInt32 backMem = p->opt[cur].backPrev;
- p->optimumEndIndex = cur;
- do
+ unsigned wr = cur + 1;
+ p->optEnd = wr;
+
+ for (;;)
{
- if (p->opt[cur].prev1IsChar)
+ UInt32 dist = p->opt[cur].dist;
+ UInt32 len = p->opt[cur].len;
+ UInt32 extra = p->opt[cur].extra;
+ cur -= len;
+
+ if (extra)
{
- MakeAsChar(&p->opt[posMem])
- p->opt[posMem].posPrev = posMem - 1;
- if (p->opt[cur].prev2)
+ wr--;
+ p->opt[wr].len = len;
+ cur -= extra;
+ len = extra;
+ if (extra == 1)
+ {
+ p->opt[wr].dist = dist;
+ dist = MARK_LIT;
+ }
+ else
{
- p->opt[(size_t)posMem - 1].prev1IsChar = False;
- p->opt[(size_t)posMem - 1].posPrev = p->opt[cur].posPrev2;
- p->opt[(size_t)posMem - 1].backPrev = p->opt[cur].backPrev2;
+ p->opt[wr].dist = 0;
+ len--;
+ wr--;
+ p->opt[wr].dist = MARK_LIT;
+ p->opt[wr].len = 1;
}
}
+
+ if (cur == 0)
{
- 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;
+ p->backRes = dist;
+ p->optCur = wr;
+ return len;
}
+
+ wr--;
+ p->opt[wr].dist = dist;
+ p->opt[wr].len = len;
}
- while (cur != 0);
- *backRes = p->opt[0].backPrev;
- p->optimumCurrentIndex = p->opt[0].posPrev;
- return p->optimumCurrentIndex;
}
-#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * (UInt32)0x300)
-static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
-{
- UInt32 lenEnd, cur;
- UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
- UInt32 *matches;
-
- {
- UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len;
- UInt32 matchPrice, repMatchPrice, normalMatchPrice;
- const Byte *data;
- Byte curByte, matchByte;
+#define LIT_PROBS(pos, prevByte) \
+ (p->litProbs + (UInt32)3 * (((((pos) << 8) + (prevByte)) & p->lpMask) << p->lc))
- if (p->optimumEndIndex != p->optimumCurrentIndex)
- {
- const COptimal *opt = &p->opt[p->optimumCurrentIndex];
- UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
- *backRes = opt->backPrev;
- p->optimumCurrentIndex = opt->posPrev;
- return lenRes;
- }
- p->optimumCurrentIndex = p->optimumEndIndex = 0;
-
- if (p->additionalOffset == 0)
- mainLen = ReadMatchDistances(p, &numPairs);
- else
- {
- mainLen = p->longestMatchLength;
- numPairs = p->numPairs;
- }
- numAvail = p->numAvail;
- if (numAvail < 2)
- {
- *backRes = (UInt32)(-1);
- return 1;
- }
- if (numAvail > LZMA_MATCH_LEN_MAX)
- numAvail = LZMA_MATCH_LEN_MAX;
+static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
+{
+ unsigned last, cur;
+ UInt32 reps[LZMA_NUM_REPS];
+ unsigned repLens[LZMA_NUM_REPS];
+ UInt32 *matches;
- data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
- repMaxIndex = 0;
- for (i = 0; i < LZMA_NUM_REPS; i++)
{
- UInt32 lenTest;
- const Byte *data2;
- reps[i] = p->reps[i];
- data2 = data - reps[i] - 1;
- if (data[0] != data2[0] || data[1] != data2[1])
+ UInt32 numAvail;
+ unsigned numPairs, mainLen, repMaxIndex, i, posState;
+ UInt32 matchPrice, repMatchPrice;
+ const Byte *data;
+ Byte curByte, matchByte;
+
+ p->optCur = p->optEnd = 0;
+
+ if (p->additionalOffset == 0)
+ mainLen = ReadMatchDistances(p, &numPairs);
+ else
{
- repLens[i] = 0;
- continue;
+ mainLen = p->longestMatchLen;
+ numPairs = p->numPairs;
}
- for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
- repLens[i] = lenTest;
- if (lenTest > repLens[repMaxIndex])
- repMaxIndex = i;
- }
- if (repLens[repMaxIndex] >= p->numFastBytes)
- {
- UInt32 lenRes;
- *backRes = repMaxIndex;
- lenRes = repLens[repMaxIndex];
- MovePos(p, lenRes - 1);
- return lenRes;
- }
-
- matches = p->matches;
- if (mainLen >= p->numFastBytes)
- {
- *backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
- MovePos(p, mainLen - 1);
- return mainLen;
- }
- curByte = *data;
- matchByte = *(data - (reps[0] + 1));
-
- if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
- {
- *backRes = (UInt32)-1;
- return 1;
- }
-
- p->opt[0].state = (CState)p->state;
-
- posState = (position & p->pbMask);
-
- {
- const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
- p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
- (!IsCharState(p->state) ?
- LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
- LitEnc_GetPrice(probs, curByte, p->ProbPrices));
- }
-
- MakeAsChar(&p->opt[1]);
-
- matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
- repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
-
- if (matchByte == curByte)
- {
- UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
- if (shortRepPrice < p->opt[1].price)
+
+ numAvail = p->numAvail;
+ if (numAvail < 2)
{
- p->opt[1].price = shortRepPrice;
- MakeAsShortRep(&p->opt[1]);
+ p->backRes = MARK_LIT;
+ return 1;
}
- }
- lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
-
- if (lenEnd < 2)
- {
- *backRes = p->opt[1].backPrev;
- return 1;
- }
-
- p->opt[1].posPrev = 0;
- for (i = 0; i < LZMA_NUM_REPS; i++)
- p->opt[0].backs[i] = reps[i];
-
- len = lenEnd;
- do
- p->opt[len--].price = kInfinityPrice;
- while (len >= 2);
-
- for (i = 0; i < LZMA_NUM_REPS; i++)
- {
- UInt32 repLen = repLens[i];
- UInt32 price;
- if (repLen < 2)
- continue;
- price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
- do
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ repMaxIndex = 0;
+
+ for (i = 0; i < LZMA_NUM_REPS; i++)
{
- UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)repLen - 2];
- COptimal *opt = &p->opt[repLen];
- if (curAndLenPrice < opt->price)
+ unsigned len;
+ const Byte *data2;
+ reps[i] = p->reps[i];
+ data2 = data - reps[i];
+ if (data[0] != data2[0] || data[1] != data2[1])
{
- opt->price = curAndLenPrice;
- opt->posPrev = 0;
- opt->backPrev = i;
- opt->prev1IsChar = False;
+ repLens[i] = 0;
+ continue;
}
+ for (len = 2; len < numAvail && data[len] == data2[len]; len++);
+ repLens[i] = len;
+ if (len > repLens[repMaxIndex])
+ repMaxIndex = i;
}
- while (--repLen >= 2);
- }
-
- normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
-
- len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
- if (len <= mainLen)
- {
- UInt32 offs = 0;
- while (len > matches[offs])
- offs += 2;
- for (; ; len++)
+
+ if (repLens[repMaxIndex] >= p->numFastBytes)
{
- COptimal *opt;
- UInt32 distance = matches[(size_t)offs + 1];
-
- UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];
- UInt32 lenToPosState = GetLenToPosState(len);
- if (distance < kNumFullDistances)
- curAndLenPrice += p->distancesPrices[lenToPosState][distance];
- else
+ unsigned len;
+ p->backRes = repMaxIndex;
+ len = repLens[repMaxIndex];
+ MOVE_POS(p, len - 1)
+ return len;
+ }
+
+ matches = p->matches;
+
+ if (mainLen >= p->numFastBytes)
+ {
+ p->backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
+ MOVE_POS(p, mainLen - 1)
+ return mainLen;
+ }
+
+ curByte = *data;
+ matchByte = *(data - reps[0]);
+
+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
+ {
+ p->backRes = MARK_LIT;
+ return 1;
+ }
+
+ p->opt[0].state = (CState)p->state;
+
+ posState = (position & p->pbMask);
+
+ {
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
+ (!IsLitState(p->state) ?
+ LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
+ }
+
+ MakeAs_Lit(&p->opt[1]);
+
+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
+
+ if (matchByte == curByte)
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, p->state, posState);
+ if (shortRepPrice < p->opt[1].price)
{
- UInt32 slot;
- GetPosSlot2(distance, slot);
- curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
+ p->opt[1].price = shortRepPrice;
+ MakeAs_ShortRep(&p->opt[1]);
}
- opt = &p->opt[len];
- if (curAndLenPrice < opt->price)
+ }
+
+ last = (mainLen >= repLens[repMaxIndex] ? mainLen : repLens[repMaxIndex]);
+
+ if (last < 2)
+ {
+ p->backRes = p->opt[1].dist;
+ return 1;
+ }
+
+ p->opt[1].len = 1;
+
+ p->opt[0].reps[0] = reps[0];
+ p->opt[0].reps[1] = reps[1];
+ p->opt[0].reps[2] = reps[2];
+ p->opt[0].reps[3] = reps[3];
+
+ {
+ unsigned len = last;
+ do
+ p->opt[len--].price = kInfinityPrice;
+ while (len >= 2);
+ }
+
+ // ---------- REP ----------
+
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ unsigned repLen = repLens[i];
+ UInt32 price;
+ if (repLen < 2)
+ continue;
+ price = repMatchPrice + GetPrice_PureRep(p, i, p->state, posState);
+ do
{
- opt->price = curAndLenPrice;
- opt->posPrev = 0;
- opt->backPrev = distance + LZMA_NUM_REPS;
- opt->prev1IsChar = False;
+ UInt32 price2 = price + p->repLenEnc.prices[posState][(size_t)repLen - 2];
+ COptimal *opt = &p->opt[repLen];
+ if (price2 < opt->price)
+ {
+ opt->price = price2;
+ opt->len = repLen;
+ opt->dist = i;
+ opt->extra = 0;
+ }
}
- if (len == matches[offs])
+ while (--repLen >= 2);
+ }
+
+
+ // ---------- MATCH ----------
+ {
+ unsigned len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+ if (len <= mainLen)
{
- offs += 2;
- if (offs == numPairs)
- break;
+ unsigned offs = 0;
+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
+
+ while (len > matches[offs])
+ offs += 2;
+
+ for (; ; len++)
+ {
+ COptimal *opt;
+ UInt32 dist = matches[(size_t)offs + 1];
+ UInt32 price2 = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];
+ unsigned lenToPosState = GetLenToPosState(len);
+
+ if (dist < kNumFullDistances)
+ price2 += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)];
+ else
+ {
+ unsigned slot;
+ GetPosSlot2(dist, slot);
+ price2 += p->alignPrices[dist & kAlignMask];
+ price2 += p->posSlotPrices[lenToPosState][slot];
+ }
+
+ opt = &p->opt[len];
+
+ if (price2 < opt->price)
+ {
+ opt->price = price2;
+ opt->len = len;
+ opt->dist = dist + LZMA_NUM_REPS;
+ opt->extra = 0;
+ }
+
+ if (len == matches[offs])
+ {
+ offs += 2;
+ if (offs == numPairs)
+ break;
+ }
+ }
}
}
- }
+
- cur = 0;
+ cur = 0;
#ifdef SHOW_STAT2
/* if (position >= 0) */
{
unsigned i;
printf("\n pos = %4X", position);
- for (i = cur; i <= lenEnd; i++)
+ for (i = cur; i <= last; i++)
printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);
}
#endif
-
}
+
+
+ // ---------- Optimal Parsing ----------
+
for (;;)
{
- UInt32 numAvail;
- UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
- UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
- Bool nextIsChar;
+ UInt32 numAvail, numAvailFull;
+ unsigned newLen, numPairs, prev, state, posState, startLen;
+ UInt32 curPrice, litPrice, matchPrice, repMatchPrice;
+ Bool nextIsLit;
Byte curByte, matchByte;
const Byte *data;
- COptimal *curOpt;
- COptimal *nextOpt;
+ COptimal *curOpt, *nextOpt;
- cur++;
- if (cur == lenEnd)
- return Backward(p, backRes, cur);
+ if (++cur == last)
+ return Backward(p, cur);
newLen = ReadMatchDistances(p, &numPairs);
+
if (newLen >= p->numFastBytes)
{
p->numPairs = numPairs;
- p->longestMatchLength = newLen;
- return Backward(p, backRes, cur);
+ p->longestMatchLen = newLen;
+ return Backward(p, cur);
}
- position++;
+
curOpt = &p->opt[cur];
- posPrev = curOpt->posPrev;
- if (curOpt->prev1IsChar)
- {
- posPrev--;
- if (curOpt->prev2)
- {
- state = p->opt[curOpt->posPrev2].state;
- if (curOpt->backPrev2 < LZMA_NUM_REPS)
- state = kRepNextStates[state];
- else
- state = kMatchNextStates[state];
- }
- else
- state = p->opt[posPrev].state;
- state = kLiteralNextStates[state];
- }
- else
- state = p->opt[posPrev].state;
- if (posPrev == cur - 1)
+ prev = cur - curOpt->len;
+
+ if (curOpt->len == 1)
{
+ state = p->opt[prev].state;
if (IsShortRep(curOpt))
state = kShortRepNextStates[state];
else
@@ -1244,92 +1310,136 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
}
else
{
- UInt32 pos;
const COptimal *prevOpt;
- if (curOpt->prev1IsChar && curOpt->prev2)
+ UInt32 b0;
+ UInt32 dist = curOpt->dist;
+
+ if (curOpt->extra)
{
- posPrev = curOpt->posPrev2;
- pos = curOpt->backPrev2;
- state = kRepNextStates[state];
+ prev -= curOpt->extra;
+ state = kState_RepAfterLit;
+ if (curOpt->extra == 1)
+ state = (dist < LZMA_NUM_REPS) ? kState_RepAfterLit : kState_MatchAfterLit;
}
else
{
- pos = curOpt->backPrev;
- if (pos < LZMA_NUM_REPS)
+ state = p->opt[prev].state;
+ if (dist < LZMA_NUM_REPS)
state = kRepNextStates[state];
else
state = kMatchNextStates[state];
}
- prevOpt = &p->opt[posPrev];
- if (pos < LZMA_NUM_REPS)
+
+ prevOpt = &p->opt[prev];
+ b0 = prevOpt->reps[0];
+
+ if (dist < LZMA_NUM_REPS)
{
- UInt32 i;
- reps[0] = prevOpt->backs[pos];
- for (i = 1; i <= pos; i++)
- reps[i] = prevOpt->backs[(size_t)i - 1];
- for (; i < LZMA_NUM_REPS; i++)
- reps[i] = prevOpt->backs[i];
+ if (dist == 0)
+ {
+ reps[0] = b0;
+ reps[1] = prevOpt->reps[1];
+ reps[2] = prevOpt->reps[2];
+ reps[3] = prevOpt->reps[3];
+ }
+ else
+ {
+ reps[1] = b0;
+ b0 = prevOpt->reps[1];
+ if (dist == 1)
+ {
+ reps[0] = b0;
+ reps[2] = prevOpt->reps[2];
+ reps[3] = prevOpt->reps[3];
+ }
+ else
+ {
+ reps[2] = b0;
+ reps[0] = prevOpt->reps[dist];
+ reps[3] = prevOpt->reps[dist ^ 1];
+ }
+ }
}
else
{
- UInt32 i;
- reps[0] = (pos - LZMA_NUM_REPS);
- for (i = 1; i < LZMA_NUM_REPS; i++)
- reps[i] = prevOpt->backs[(size_t)i - 1];
+ reps[0] = (dist - LZMA_NUM_REPS + 1);
+ reps[1] = b0;
+ reps[2] = prevOpt->reps[1];
+ reps[3] = prevOpt->reps[2];
}
}
+
curOpt->state = (CState)state;
+ curOpt->reps[0] = reps[0];
+ curOpt->reps[1] = reps[1];
+ curOpt->reps[2] = reps[2];
+ curOpt->reps[3] = reps[3];
- curOpt->backs[0] = reps[0];
- curOpt->backs[1] = reps[1];
- curOpt->backs[2] = reps[2];
- curOpt->backs[3] = reps[3];
-
- curPrice = curOpt->price;
- nextIsChar = False;
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
curByte = *data;
- matchByte = *(data - (reps[0] + 1));
+ matchByte = *(data - reps[0]);
+ position++;
posState = (position & p->pbMask);
- curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
- {
- const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
- curAnd1Price +=
- (!IsCharState(state) ?
- LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
- LitEnc_GetPrice(probs, curByte, p->ProbPrices));
- }
+ /*
+ The order of Price checks:
+ < LIT
+ <= SHORT_REP
+ < LIT : REP_0
+ < REP [ : LIT : REP_0 ]
+ < MATCH [ : LIT : REP_0 ]
+ */
+
+ curPrice = curOpt->price;
+ litPrice = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
nextOpt = &p->opt[(size_t)cur + 1];
+ nextIsLit = False;
- if (curAnd1Price < nextOpt->price)
+ // if (litPrice >= nextOpt->price) litPrice = 0; else // 18.new
{
- nextOpt->price = curAnd1Price;
- nextOpt->posPrev = cur;
- MakeAsChar(nextOpt);
- nextIsChar = True;
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+ litPrice += (!IsLitState(state) ?
+ LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
+
+ if (litPrice < nextOpt->price)
+ {
+ nextOpt->price = litPrice;
+ nextOpt->len = 1;
+ MakeAs_Lit(nextOpt);
+ nextIsLit = True;
+ }
}
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))
+ // ---------- SHORT_REP ----------
+ // if (IsLitState(state)) // 18.new
+ if (matchByte == curByte)
+ // if (repMatchPrice < nextOpt->price) // 18.new
+ if (nextOpt->len < 2
+ || (nextOpt->dist != 0
+ && nextOpt->extra <= 1 // 17.old
+ ))
{
- UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
- if (shortRepPrice <= nextOpt->price)
+ UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, state, posState);
+ if (shortRepPrice <= nextOpt->price) // 17.old
+ // if (shortRepPrice < nextOpt->price) // 18.new
{
nextOpt->price = shortRepPrice;
- nextOpt->posPrev = cur;
- MakeAsShortRep(nextOpt);
- nextIsChar = True;
+ nextOpt->len = 1;
+ MakeAs_ShortRep(nextOpt);
+ nextIsLit = False;
}
}
+
numAvailFull = p->numAvail;
{
UInt32 temp = kNumOpts - 1 - cur;
- if (temp < numAvailFull)
+ if (numAvailFull > temp)
numAvailFull = temp;
}
@@ -1337,41 +1447,53 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
continue;
numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
- if (!nextIsChar && matchByte != curByte) /* speed optimization */
+ // numAvail <= p->numFastBytes
+
+ // ---------- LIT : REP_0 ----------
+
+ if (
+ // litPrice != 0 && // 18.new
+ !nextIsLit
+ && matchByte != curByte
+ && numAvailFull > 2)
{
- /* try Literal + rep0 */
- UInt32 temp;
- UInt32 lenTest2;
- const Byte *data2 = data - reps[0] - 1;
- UInt32 limit = p->numFastBytes + 1;
- if (limit > numAvailFull)
- limit = numAvailFull;
-
- for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
- lenTest2 = temp - 1;
- if (lenTest2 >= 2)
+ const Byte *data2 = data - reps[0];
+ if (data[1] == data2[1] && data[2] == data2[2])
{
- UInt32 state2 = kLiteralNextStates[state];
- UInt32 posStateNext = (position + 1) & p->pbMask;
- UInt32 nextRepMatchPrice = curAnd1Price +
- GET_PRICE_1(p->isMatch[state2][posStateNext]) +
- GET_PRICE_1(p->isRep[state2]);
- /* for (; lenTest2 >= 2; lenTest2--) */
+ unsigned len;
+ unsigned limit = p->numFastBytes + 1;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+ for (len = 3; len < limit && data[len] == data2[len]; len++);
+
{
- UInt32 curAndLenPrice;
- COptimal *opt;
- UInt32 offset = cur + 1 + lenTest2;
- while (lenEnd < offset)
- p->opt[++lenEnd].price = kInfinityPrice;
- curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
- opt = &p->opt[offset];
- if (curAndLenPrice < opt->price)
+ unsigned state2 = kLiteralNextStates[state];
+ unsigned posState2 = (position + 1) & p->pbMask;
+ UInt32 price = litPrice + GetPrice_Rep_0(p, state2, posState2);
{
- opt->price = curAndLenPrice;
- opt->posPrev = cur + 1;
- opt->backPrev = 0;
- opt->prev1IsChar = True;
- opt->prev2 = False;
+ unsigned offset = cur + len;
+ while (last < offset)
+ p->opt[++last].price = kInfinityPrice;
+
+ // do
+ {
+ UInt32 price2;
+ COptimal *opt;
+ len--;
+ // price2 = price + GetPrice_Len_Rep_0(p, len, state2, posState2);
+ price2 = price + p->repLenEnc.prices[posState2][len - LZMA_MATCH_LEN_MIN];
+
+ opt = &p->opt[offset];
+ // offset--;
+ if (price2 < opt->price)
+ {
+ opt->price = price2;
+ opt->len = len;
+ opt->dist = 0;
+ opt->extra = 1;
+ }
+ }
+ // while (len >= 3);
}
}
}
@@ -1379,87 +1501,105 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
startLen = 2; /* speed optimization */
{
- UInt32 repIndex;
- for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
- {
- UInt32 lenTest;
- UInt32 lenTestTemp;
- UInt32 price;
- const Byte *data2 = data - reps[repIndex] - 1;
- if (data[0] != data2[0] || data[1] != data2[1])
- continue;
- for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
- while (lenEnd < cur + lenTest)
- p->opt[++lenEnd].price = kInfinityPrice;
- lenTestTemp = lenTest;
- price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
- do
+ // ---------- REP ----------
+ unsigned repIndex = 0; // 17.old
+ // unsigned repIndex = IsLitState(state) ? 0 : 1; // 18.notused
+ for (; repIndex < LZMA_NUM_REPS; repIndex++)
{
- UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)lenTest - 2];
- COptimal *opt = &p->opt[cur + lenTest];
- if (curAndLenPrice < opt->price)
+ unsigned len;
+ UInt32 price;
+ const Byte *data2 = data - reps[repIndex];
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+
+ for (len = 2; len < numAvail && data[len] == data2[len]; len++);
+
+ // if (len < startLen) continue; // 18.new: speed optimization
+
+ while (last < cur + len)
+ p->opt[++last].price = kInfinityPrice;
{
- opt->price = curAndLenPrice;
- opt->posPrev = cur;
- opt->backPrev = repIndex;
- opt->prev1IsChar = False;
+ unsigned len2 = len;
+ price = repMatchPrice + GetPrice_PureRep(p, repIndex, state, posState);
+ do
+ {
+ UInt32 price2 = price + p->repLenEnc.prices[posState][(size_t)len2 - 2];
+ COptimal *opt = &p->opt[cur + len2];
+ if (price2 < opt->price)
+ {
+ opt->price = price2;
+ opt->len = len2;
+ opt->dist = repIndex;
+ opt->extra = 0;
+ }
+ }
+ while (--len2 >= 2);
}
- }
- while (--lenTest >= 2);
- lenTest = lenTestTemp;
-
- if (repIndex == 0)
- startLen = lenTest + 1;
- /* if (_maxMode) */
+ if (repIndex == 0) startLen = len + 1; // 17.old
+ // startLen = len + 1; // 18.new
+
+ /* if (_maxMode) */
{
- UInt32 lenTest2 = lenTest + 1;
- UInt32 limit = lenTest2 + p->numFastBytes;
+ // ---------- REP : LIT : REP_0 ----------
+ // numFastBytes + 1 + numFastBytes
+
+ unsigned len2 = len + 1;
+ unsigned limit = len2 + p->numFastBytes;
if (limit > numAvailFull)
limit = numAvailFull;
- for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
- lenTest2 -= lenTest + 1;
- if (lenTest2 >= 2)
+
+ for (; len2 < limit && data[len2] == data2[len2]; len2++);
+
+ len2 -= len;
+ if (len2 >= 3)
{
- UInt32 nextRepMatchPrice;
- UInt32 state2 = kRepNextStates[state];
- UInt32 posStateNext = (position + lenTest) & p->pbMask;
- UInt32 curAndLenCharPrice =
- price + p->repLenEnc.prices[posState][(size_t)lenTest - 2] +
- GET_PRICE_0(p->isMatch[state2][posStateNext]) +
- LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]),
- data[lenTest], data2[lenTest], p->ProbPrices);
- state2 = kLiteralNextStates[state2];
- posStateNext = (position + lenTest + 1) & p->pbMask;
- nextRepMatchPrice = curAndLenCharPrice +
- GET_PRICE_1(p->isMatch[state2][posStateNext]) +
- GET_PRICE_1(p->isRep[state2]);
+ unsigned state2 = kRepNextStates[state];
+ unsigned posState2 = (position + len) & p->pbMask;
+ price +=
+ p->repLenEnc.prices[posState][(size_t)len - 2]
+ + GET_PRICE_0(p->isMatch[state2][posState2])
+ + LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),
+ data[len], data2[len], p->ProbPrices);
- /* for (; lenTest2 >= 2; lenTest2--) */
+ // state2 = kLiteralNextStates[state2];
+ state2 = kState_LitAfterRep;
+ posState2 = (posState2 + 1) & p->pbMask;
+
+
+ price += GetPrice_Rep_0(p, state2, posState2);
{
- UInt32 curAndLenPrice;
- COptimal *opt;
- UInt32 offset = cur + lenTest + 1 + lenTest2;
- while (lenEnd < offset)
- p->opt[++lenEnd].price = kInfinityPrice;
- curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
- opt = &p->opt[offset];
- if (curAndLenPrice < opt->price)
+ unsigned offset = cur + len + len2;
+ while (last < offset)
+ p->opt[++last].price = kInfinityPrice;
+ // do
{
- opt->price = curAndLenPrice;
- opt->posPrev = cur + lenTest + 1;
- opt->backPrev = 0;
- opt->prev1IsChar = True;
- opt->prev2 = True;
- opt->posPrev2 = cur;
- opt->backPrev2 = repIndex;
+ unsigned price2;
+ COptimal *opt;
+ len2--;
+ // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);
+ price2 = price + p->repLenEnc.prices[posState2][len2 - LZMA_MATCH_LEN_MIN];
+
+ opt = &p->opt[offset];
+ // offset--;
+ if (price2 < opt->price)
+ {
+ opt->price = price2;
+ opt->len = len2;
+ opt->extra = (CExtra)(len + 1);
+ opt->dist = repIndex;
+ }
}
+ // while (len2 >= 3);
}
}
}
+ }
}
- }
- /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
+
+
+ // ---------- MATCH ----------
+ /* for (unsigned len = 2; len <= newLen; len++) */
if (newLen > numAvail)
{
newLen = numAvail;
@@ -1467,134 +1607,148 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
matches[numPairs] = newLen;
numPairs += 2;
}
+
if (newLen >= startLen)
{
UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
- UInt32 offs, curBack, posSlot;
- UInt32 lenTest;
- while (lenEnd < cur + newLen)
- p->opt[++lenEnd].price = kInfinityPrice;
+ UInt32 dist;
+ unsigned offs, posSlot, len;
+ while (last < cur + newLen)
+ p->opt[++last].price = kInfinityPrice;
offs = 0;
while (startLen > matches[offs])
offs += 2;
- curBack = matches[(size_t)offs + 1];
- GetPosSlot2(curBack, posSlot);
- for (lenTest = /*2*/ startLen; ; lenTest++)
+ dist = matches[(size_t)offs + 1];
+
+ // if (dist >= kNumFullDistances)
+ GetPosSlot2(dist, posSlot);
+
+ for (len = /*2*/ startLen; ; len++)
{
- UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)lenTest - LZMA_MATCH_LEN_MIN];
- {
- UInt32 lenToPosState = GetLenToPosState(lenTest);
- COptimal *opt;
- if (curBack < kNumFullDistances)
- curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
- else
- curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
-
- opt = &p->opt[cur + lenTest];
- if (curAndLenPrice < opt->price)
+ UInt32 price = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];
{
- opt->price = curAndLenPrice;
- opt->posPrev = cur;
- opt->backPrev = curBack + LZMA_NUM_REPS;
- opt->prev1IsChar = False;
- }
+ COptimal *opt;
+ unsigned lenToPosState = len - 2; lenToPosState = GetLenToPosState2(lenToPosState);
+ if (dist < kNumFullDistances)
+ price += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)];
+ else
+ price += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[dist & kAlignMask];
+
+ opt = &p->opt[cur + len];
+ if (price < opt->price)
+ {
+ opt->price = price;
+ opt->len = len;
+ opt->dist = dist + LZMA_NUM_REPS;
+ opt->extra = 0;
+ }
}
- if (/*_maxMode && */lenTest == matches[offs])
+ if (/*_maxMode && */ len == matches[offs])
{
- /* Try Match + Literal + Rep0 */
- const Byte *data2 = data - curBack - 1;
- UInt32 lenTest2 = lenTest + 1;
- UInt32 limit = lenTest2 + p->numFastBytes;
+ // MATCH : LIT : REP_0
+
+ const Byte *data2 = data - dist - 1;
+ unsigned len2 = len + 1;
+ unsigned limit = len2 + p->numFastBytes;
if (limit > numAvailFull)
limit = numAvailFull;
- for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
- lenTest2 -= lenTest + 1;
- if (lenTest2 >= 2)
+
+ for (; len2 < limit && data[len2] == data2[len2]; len2++);
+
+ len2 -= len;
+
+ if (len2 >= 3)
{
- UInt32 nextRepMatchPrice;
- UInt32 state2 = kMatchNextStates[state];
- UInt32 posStateNext = (position + lenTest) & p->pbMask;
- UInt32 curAndLenCharPrice = curAndLenPrice +
- GET_PRICE_0(p->isMatch[state2][posStateNext]) +
- LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]),
- data[lenTest], data2[lenTest], p->ProbPrices);
- state2 = kLiteralNextStates[state2];
- posStateNext = (posStateNext + 1) & p->pbMask;
- nextRepMatchPrice = curAndLenCharPrice +
- GET_PRICE_1(p->isMatch[state2][posStateNext]) +
- GET_PRICE_1(p->isRep[state2]);
-
- /* for (; lenTest2 >= 2; lenTest2--) */
+ unsigned state2 = kMatchNextStates[state];
+ unsigned posState2 = (position + len) & p->pbMask;
+ unsigned offset;
+ price += GET_PRICE_0(p->isMatch[state2][posState2]);
+ price += LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),
+ data[len], data2[len], p->ProbPrices);
+
+ // state2 = kLiteralNextStates[state2];
+ state2 = kState_LitAfterMatch;
+
+ posState2 = (posState2 + 1) & p->pbMask;
+ price += GetPrice_Rep_0(p, state2, posState2);
+
+ offset = cur + len + len2;
+ while (last < offset)
+ p->opt[++last].price = kInfinityPrice;
+ // do
{
- UInt32 offset = cur + lenTest + 1 + lenTest2;
- UInt32 curAndLenPrice2;
+ UInt32 price2;
COptimal *opt;
- while (lenEnd < offset)
- p->opt[++lenEnd].price = kInfinityPrice;
- curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ len2--;
+ // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);
+ price2 = price + p->repLenEnc.prices[posState2][len2 - LZMA_MATCH_LEN_MIN];
opt = &p->opt[offset];
- if (curAndLenPrice2 < opt->price)
+ // offset--;
+ if (price2 < opt->price)
{
- opt->price = curAndLenPrice2;
- opt->posPrev = cur + lenTest + 1;
- opt->backPrev = 0;
- opt->prev1IsChar = True;
- opt->prev2 = True;
- opt->posPrev2 = cur;
- opt->backPrev2 = curBack + LZMA_NUM_REPS;
+ opt->price = price2;
+ opt->len = len2;
+ opt->extra = (CExtra)(len + 1);
+ opt->dist = dist + LZMA_NUM_REPS;
}
}
+ // while (len2 >= 3);
}
+
offs += 2;
if (offs == numPairs)
break;
- curBack = matches[(size_t)offs + 1];
- if (curBack >= kNumFullDistances)
- GetPosSlot2(curBack, posSlot);
+ dist = matches[(size_t)offs + 1];
+ // if (dist >= kNumFullDistances)
+ GetPosSlot2(dist, posSlot);
}
}
}
}
}
+
+
#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
-static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
+
+
+static unsigned GetOptimumFast(CLzmaEnc *p)
{
- UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
+ UInt32 numAvail, mainDist;
+ unsigned mainLen, numPairs, repIndex, repLen, i;
const Byte *data;
- const UInt32 *matches;
if (p->additionalOffset == 0)
mainLen = ReadMatchDistances(p, &numPairs);
else
{
- mainLen = p->longestMatchLength;
+ mainLen = p->longestMatchLen;
numPairs = p->numPairs;
}
numAvail = p->numAvail;
- *backRes = (UInt32)-1;
+ p->backRes = MARK_LIT;
if (numAvail < 2)
return 1;
if (numAvail > LZMA_MATCH_LEN_MAX)
numAvail = LZMA_MATCH_LEN_MAX;
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-
repLen = repIndex = 0;
+
for (i = 0; i < LZMA_NUM_REPS; i++)
{
- UInt32 len;
- const Byte *data2 = data - p->reps[i] - 1;
+ unsigned len;
+ const Byte *data2 = data - p->reps[i];
if (data[0] != data2[0] || data[1] != data2[1])
continue;
for (len = 2; len < numAvail && data[len] == data2[len]; len++);
if (len >= p->numFastBytes)
{
- *backRes = i;
- MovePos(p, len - 1);
+ p->backRes = i;
+ MOVE_POS(p, len - 1)
return len;
}
if (len > repLen)
@@ -1604,84 +1758,152 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
}
}
- matches = p->matches;
if (mainLen >= p->numFastBytes)
{
- *backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
- MovePos(p, mainLen - 1);
+ p->backRes = p->matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
+ MOVE_POS(p, mainLen - 1)
return mainLen;
}
mainDist = 0; /* for GCC */
+
if (mainLen >= 2)
{
- mainDist = matches[(size_t)numPairs - 1];
- while (numPairs > 2 && mainLen == matches[(size_t)numPairs - 4] + 1)
+ mainDist = p->matches[(size_t)numPairs - 1];
+ while (numPairs > 2)
{
- if (!ChangePair(matches[(size_t)numPairs - 3], mainDist))
+ UInt32 dist2;
+ if (mainLen != p->matches[(size_t)numPairs - 4] + 1)
+ break;
+ dist2 = p->matches[(size_t)numPairs - 3];
+ if (!ChangePair(dist2, mainDist))
break;
numPairs -= 2;
- mainLen = matches[(size_t)numPairs - 2];
- mainDist = matches[(size_t)numPairs - 1];
+ mainLen--;
+ mainDist = dist2;
}
if (mainLen == 2 && mainDist >= 0x80)
mainLen = 1;
}
- if (repLen >= 2 && (
- (repLen + 1 >= mainLen) ||
- (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
- (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
+ if (repLen >= 2)
+ if ( repLen + 1 >= mainLen
+ || (repLen + 2 >= mainLen && mainDist >= (1 << 9))
+ || (repLen + 3 >= mainLen && mainDist >= (1 << 15)))
{
- *backRes = repIndex;
- MovePos(p, repLen - 1);
+ p->backRes = repIndex;
+ MOVE_POS(p, repLen - 1)
return repLen;
}
if (mainLen < 2 || numAvail <= 2)
return 1;
- p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
- if (p->longestMatchLength >= 2)
{
- UInt32 newDistance = matches[(size_t)p->numPairs - 1];
- if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
- (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
- (p->longestMatchLength > mainLen + 1) ||
- (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
- return 1;
+ unsigned len1 = ReadMatchDistances(p, &p->numPairs);
+ p->longestMatchLen = len1;
+
+ if (len1 >= 2)
+ {
+ UInt32 newDist = p->matches[(size_t)p->numPairs - 1];
+ if ( (len1 >= mainLen && newDist < mainDist)
+ || (len1 == mainLen + 1 && !ChangePair(mainDist, newDist))
+ || (len1 > mainLen + 1)
+ || (len1 + 1 >= mainLen && mainLen >= 3 && ChangePair(newDist, mainDist)))
+ return 1;
+ }
}
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+
for (i = 0; i < LZMA_NUM_REPS; i++)
{
- UInt32 len, limit;
- const Byte *data2 = data - p->reps[i] - 1;
+ unsigned len, limit;
+ const Byte *data2 = data - p->reps[i];
if (data[0] != data2[0] || data[1] != data2[1])
continue;
limit = mainLen - 1;
- for (len = 2; len < limit && data[len] == data2[len]; len++);
- if (len >= limit)
- return 1;
+ for (len = 2;; len++)
+ {
+ if (len >= limit)
+ return 1;
+ if (data[len] != data2[len])
+ break;
+ }
+ }
+
+ p->backRes = mainDist + LZMA_NUM_REPS;
+ if (mainLen != 2)
+ {
+ MOVE_POS(p, mainLen - 2)
}
- *backRes = mainDist + LZMA_NUM_REPS;
- MovePos(p, mainLen - 2);
return mainLen;
}
-static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
+
+
+
+static void WriteEndMarker(CLzmaEnc *p, unsigned posState)
{
- UInt32 len;
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
- RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+ UInt32 range;
+ range = p->rc.range;
+ {
+ UInt32 ttt, newBound;
+ CLzmaProb *prob = &p->isMatch[p->state][posState];
+ RC_BIT_PRE(&p->rc, prob)
+ RC_BIT_1(&p->rc, prob)
+ prob = &p->isRep[p->state];
+ RC_BIT_PRE(&p->rc, prob)
+ RC_BIT_0(&p->rc, prob)
+ }
p->state = kMatchNextStates[p->state];
- len = LZMA_MATCH_LEN_MIN;
- LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
- RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
- RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
- RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
+
+ p->rc.range = range;
+ LenEnc_Encode(&p->lenProbs, &p->rc, 0, posState);
+ range = p->rc.range;
+
+ {
+ // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[0], (1 << kNumPosSlotBits) - 1);
+ CLzmaProb *probs = p->posSlotEncoder[0];
+ unsigned m = 1;
+ do
+ {
+ UInt32 ttt, newBound;
+ RC_BIT_PRE(p, probs + m)
+ RC_BIT_1(&p->rc, probs + m);
+ m = (m << 1) + 1;
+ }
+ while (m < (1 << kNumPosSlotBits));
+ }
+ {
+ // RangeEnc_EncodeDirectBits(&p->rc, ((UInt32)1 << (30 - kNumAlignBits)) - 1, 30 - kNumAlignBits); UInt32 range = p->range;
+ unsigned numBits = 30 - kNumAlignBits;
+ do
+ {
+ range >>= 1;
+ p->rc.low += range;
+ RC_NORM(&p->rc)
+ }
+ while (--numBits);
+ }
+
+ {
+ // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
+ CLzmaProb *probs = p->posAlignEncoder;
+ unsigned m = 1;
+ do
+ {
+ UInt32 ttt, newBound;
+ RC_BIT_PRE(p, probs + m)
+ RC_BIT_1(&p->rc, probs + m);
+ m = (m << 1) + 1;
+ }
+ while (m < kAlignTableSize);
+ }
+ p->rc.range = range;
}
+
static SRes CheckErrors(CLzmaEnc *p)
{
if (p->result != SZ_OK)
@@ -1695,7 +1917,8 @@ static SRes CheckErrors(CLzmaEnc *p)
return p->result;
}
-static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
+
+MY_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
{
/* ReleaseMFStream(); */
p->finished = True;
@@ -1706,47 +1929,108 @@ static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
return CheckErrors(p);
}
+
+
static void FillAlignPrices(CLzmaEnc *p)
{
- UInt32 i;
- for (i = 0; i < kAlignTableSize; i++)
- p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
+ unsigned i;
+ const CProbPrice *ProbPrices = p->ProbPrices;
+ const CLzmaProb *probs = p->posAlignEncoder;
p->alignPriceCount = 0;
+ for (i = 0; i < kAlignTableSize / 2; i++)
+ {
+ UInt32 price = 0;
+ unsigned symbol = i;
+ unsigned m = 1;
+ unsigned bit;
+ UInt32 prob;
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
+ prob = probs[m];
+ p->alignPrices[i ] = price + GET_PRICEa_0(prob);
+ p->alignPrices[i + 8] = price + GET_PRICEa_1(prob);
+ // p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
+ }
}
+
static void FillDistancesPrices(CLzmaEnc *p)
{
UInt32 tempPrices[kNumFullDistances];
- UInt32 i, lenToPosState;
+ unsigned i, lenToPosState;
+
+ const CProbPrice *ProbPrices = p->ProbPrices;
+ p->matchPriceCount = 0;
+
for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
{
- UInt32 posSlot = GetPosSlot1(i);
- UInt32 footerBits = ((posSlot >> 1) - 1);
- UInt32 base = ((2 | (posSlot & 1)) << footerBits);
- tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
+ unsigned posSlot = GetPosSlot1(i);
+ unsigned footerBits = ((posSlot >> 1) - 1);
+ unsigned base = ((2 | (posSlot & 1)) << footerBits);
+ // tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base, footerBits, i - base, p->ProbPrices);
+
+ const CLzmaProb *probs = p->posEncoders + base;
+ UInt32 price = 0;
+ unsigned m = 1;
+ unsigned symbol = i - base;
+ do
+ {
+ unsigned bit = symbol & 1;
+ symbol >>= 1;
+ price += GET_PRICEa(probs[m], bit);
+ m = (m << 1) + bit;
+ }
+ while (--footerBits);
+ tempPrices[i] = price;
}
for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
{
- UInt32 posSlot;
+ unsigned posSlot;
const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
- for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
- posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
- for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
- posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
+ unsigned distTableSize = p->distTableSize;
+ const CLzmaProb *probs = encoder;
+ for (posSlot = 0; posSlot < distTableSize; posSlot += 2)
+ {
+ // posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
+ UInt32 price = 0;
+ unsigned bit;
+ unsigned symbol = (posSlot >> 1) + (1 << (kNumPosSlotBits - 1));
+ UInt32 prob;
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);
+ bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);
+ prob = probs[(posSlot >> 1) + (1 << (kNumPosSlotBits - 1))];
+ posSlotPrices[posSlot ] = price + GET_PRICEa_0(prob);
+ posSlotPrices[posSlot + 1] = price + GET_PRICEa_1(prob);
+ }
+ for (posSlot = kEndPosModelIndex; posSlot < distTableSize; posSlot++)
+ posSlotPrices[posSlot] += ((UInt32)(((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
{
UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
- for (i = 0; i < kStartPosModelIndex; i++)
- distancesPrices[i] = posSlotPrices[i];
- for (; i < kNumFullDistances; i++)
- distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
+ {
+ distancesPrices[0] = posSlotPrices[0];
+ distancesPrices[1] = posSlotPrices[1];
+ distancesPrices[2] = posSlotPrices[2];
+ distancesPrices[3] = posSlotPrices[3];
+ }
+ for (i = 4; i < kNumFullDistances; i += 2)
+ {
+ UInt32 slotPrice = posSlotPrices[GetPosSlot1(i)];
+ distancesPrices[i ] = slotPrice + tempPrices[i];
+ distancesPrices[i + 1] = slotPrice + tempPrices[i + 1];
+ }
}
}
- p->matchPriceCount = 0;
}
+
+
void LzmaEnc_Construct(CLzmaEnc *p)
{
RangeEnc_Construct(&p->rc);
@@ -1770,6 +2054,7 @@ void LzmaEnc_Construct(CLzmaEnc *p)
LzmaEnc_InitPriceTables(p->ProbPrices);
p->litProbs = NULL;
p->saveState.litProbs = NULL;
+
}
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
@@ -1806,7 +2091,8 @@ void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
ISzAlloc_Free(alloc, p);
}
-static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
+
+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize)
{
UInt32 nowPos32, startPos32;
if (p->needInit)
@@ -1824,13 +2110,13 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
if (p->nowPos64 == 0)
{
- UInt32 numPairs;
+ unsigned numPairs;
Byte curByte;
if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
return Flush(p, nowPos32);
ReadMatchDistances(p, &numPairs);
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
- p->state = kLiteralNextStates[p->state];
+ RangeEnc_EncodeBit_0(&p->rc, &p->isMatch[kState_Start][0]);
+ // p->state = kLiteralNextStates[p->state];
curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset);
LitEnc_Encode(&p->rc, p->litProbs, curByte);
p->additionalOffset--;
@@ -1838,109 +2124,225 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
}
if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
+
for (;;)
{
- UInt32 pos, len, posState;
-
+ UInt32 dist;
+ unsigned len, posState;
+ UInt32 range, ttt, newBound;
+ CLzmaProb *probs;
+
if (p->fastMode)
- len = GetOptimumFast(p, &pos);
+ len = GetOptimumFast(p);
else
- len = GetOptimum(p, nowPos32, &pos);
+ {
+ unsigned oci = p->optCur;
+ if (p->optEnd == oci)
+ len = GetOptimum(p, nowPos32);
+ else
+ {
+ const COptimal *opt = &p->opt[oci];
+ len = opt->len;
+ p->backRes = opt->dist;
+ p->optCur = oci + 1;
+ }
+ }
+
+ posState = (unsigned)nowPos32 & p->pbMask;
+ range = p->rc.range;
+ probs = &p->isMatch[p->state][posState];
+
+ RC_BIT_PRE(&p->rc, probs)
+
+ dist = p->backRes;
#ifdef SHOW_STAT2
- printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos);
+ printf("\n pos = %6X, len = %3u pos = %6u", nowPos32, len, dist);
#endif
- posState = nowPos32 & p->pbMask;
- if (len == 1 && pos == (UInt32)-1)
+ if (dist == MARK_LIT)
{
Byte curByte;
- CLzmaProb *probs;
const Byte *data;
+ unsigned state;
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
+ RC_BIT_0(&p->rc, probs);
+ p->rc.range = range;
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
- curByte = *data;
probs = LIT_PROBS(nowPos32, *(data - 1));
- if (IsCharState(p->state))
+ curByte = *data;
+ state = p->state;
+ p->state = kLiteralNextStates[state];
+ if (IsLitState(state))
LitEnc_Encode(&p->rc, probs, curByte);
else
- LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
- p->state = kLiteralNextStates[p->state];
+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0]));
}
else
{
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
- if (pos < LZMA_NUM_REPS)
+ RC_BIT_1(&p->rc, probs);
+ probs = &p->isRep[p->state];
+ RC_BIT_PRE(&p->rc, probs)
+
+ if (dist < LZMA_NUM_REPS)
{
- RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
- if (pos == 0)
+ RC_BIT_1(&p->rc, probs);
+ probs = &p->isRepG0[p->state];
+ RC_BIT_PRE(&p->rc, probs)
+ if (dist == 0)
{
- RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
- RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
+ RC_BIT_0(&p->rc, probs);
+ probs = &p->isRep0Long[p->state][posState];
+ RC_BIT_PRE(&p->rc, probs)
+ if (len != 1)
+ {
+ RC_BIT_1_BASE(&p->rc, probs);
+ }
+ else
+ {
+ RC_BIT_0_BASE(&p->rc, probs);
+ p->state = kShortRepNextStates[p->state];
+ }
}
else
{
- UInt32 distance = p->reps[pos];
- RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
- if (pos == 1)
- RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
+ RC_BIT_1(&p->rc, probs);
+ probs = &p->isRepG1[p->state];
+ RC_BIT_PRE(&p->rc, probs)
+ if (dist == 1)
+ {
+ RC_BIT_0_BASE(&p->rc, probs);
+ dist = p->reps[1];
+ }
else
{
- RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
- RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
- if (pos == 3)
+ RC_BIT_1(&p->rc, probs);
+ probs = &p->isRepG2[p->state];
+ RC_BIT_PRE(&p->rc, probs)
+ if (dist == 2)
+ {
+ RC_BIT_0_BASE(&p->rc, probs);
+ dist = p->reps[2];
+ }
+ else
+ {
+ RC_BIT_1_BASE(&p->rc, probs);
+ dist = p->reps[3];
p->reps[3] = p->reps[2];
+ }
p->reps[2] = p->reps[1];
}
p->reps[1] = p->reps[0];
- p->reps[0] = distance;
+ p->reps[0] = dist;
}
- if (len == 1)
- p->state = kShortRepNextStates[p->state];
- else
+
+ RC_NORM(&p->rc)
+
+ p->rc.range = range;
+
+ if (len != 1)
{
- LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+ LenEnc_Encode(&p->repLenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);
+ if (!p->fastMode)
+ if (--p->repLenEnc.counters[posState] == 0)
+ LenPriceEnc_UpdateTable(&p->repLenEnc, posState, &p->repLenProbs, p->ProbPrices);
+
p->state = kRepNextStates[p->state];
}
}
else
{
- UInt32 posSlot;
- RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+ unsigned posSlot;
+ RC_BIT_0(&p->rc, probs);
+ p->rc.range = range;
p->state = kMatchNextStates[p->state];
- LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
- pos -= LZMA_NUM_REPS;
- GetPosSlot(pos, posSlot);
- RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
+
+ LenEnc_Encode(&p->lenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);
+ if (!p->fastMode)
+ if (--p->lenEnc.counters[posState] == 0)
+ LenPriceEnc_UpdateTable(&p->lenEnc, posState, &p->lenProbs, p->ProbPrices);
+
+ dist -= LZMA_NUM_REPS;
+ p->reps[3] = p->reps[2];
+ p->reps[2] = p->reps[1];
+ p->reps[1] = p->reps[0];
+ p->reps[0] = dist + 1;
- if (posSlot >= kStartPosModelIndex)
+ p->matchPriceCount++;
+ GetPosSlot(dist, posSlot);
+ // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot);
{
- UInt32 footerBits = ((posSlot >> 1) - 1);
- UInt32 base = ((2 | (posSlot & 1)) << footerBits);
- UInt32 posReduced = pos - base;
+ UInt32 symbol = posSlot + (1 << kNumPosSlotBits);
+ range = p->rc.range;
+ probs = p->posSlotEncoder[GetLenToPosState(len)];
+ do
+ {
+ CLzmaProb *prob = probs + (symbol >> kNumPosSlotBits);
+ UInt32 bit = (symbol >> (kNumPosSlotBits - 1)) & 1;
+ symbol <<= 1;
+ RC_BIT(&p->rc, prob, bit);
+ }
+ while (symbol < (1 << kNumPosSlotBits * 2));
+ p->rc.range = range;
+ }
+
+ if (dist >= kStartPosModelIndex)
+ {
+ unsigned footerBits = ((posSlot >> 1) - 1);
- if (posSlot < kEndPosModelIndex)
- RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
+ if (dist < kNumFullDistances)
+ {
+ unsigned base = ((2 | (posSlot & 1)) << footerBits);
+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base, footerBits, dist - base);
+ }
else
{
- RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
- RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
- p->alignPriceCount++;
+ UInt32 pos2 = (dist | 0xF) << (32 - footerBits);
+ range = p->rc.range;
+ // RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ /*
+ do
+ {
+ range >>= 1;
+ p->rc.low += range & (0 - ((dist >> --footerBits) & 1));
+ RC_NORM(&p->rc)
+ }
+ while (footerBits > kNumAlignBits);
+ */
+ do
+ {
+ range >>= 1;
+ p->rc.low += range & (0 - (pos2 >> 31));
+ pos2 += pos2;
+ RC_NORM(&p->rc)
+ }
+ while (pos2 != 0xF0000000);
+
+
+ // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
+
+ {
+ unsigned m = 1;
+ unsigned bit;
+ bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;
+ bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;
+ bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;
+ bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit);
+ p->rc.range = range;
+ p->alignPriceCount++;
+ }
}
}
- p->reps[3] = p->reps[2];
- p->reps[2] = p->reps[1];
- p->reps[1] = p->reps[0];
- p->reps[0] = pos;
- p->matchPriceCount++;
}
}
- p->additionalOffset -= len;
+
nowPos32 += len;
+ p->additionalOffset -= len;
+
if (p->additionalOffset == 0)
{
UInt32 processed;
+
if (!p->fastMode)
{
if (p->matchPriceCount >= (1 << 7))
@@ -1948,13 +2350,15 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
if (p->alignPriceCount >= kAlignTableSize)
FillAlignPrices(p);
}
+
if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
break;
processed = nowPos32 - startPos32;
- if (useLimits)
+
+ if (maxPackSize)
{
- if (processed + kNumOpts + 300 >= maxUnpackSize ||
- RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
+ if (processed + kNumOpts + 300 >= maxUnpackSize
+ || RangeEnc_GetProcessed_sizet(&p->rc) + kPackReserve >= maxPackSize)
break;
}
else if (processed >= (1 << 17))
@@ -1964,10 +2368,13 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
}
}
}
+
p->nowPos64 += nowPos32 - startPos32;
return Flush(p, nowPos32);
}
+
+
#define kBigHashDicLimit ((UInt32)1 << 24)
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
@@ -2004,7 +2411,10 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc,
#ifndef _7ZIP_ST
if (p->mtMode)
{
- RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes,
+ LZMA_MATCH_LEN_MAX
+ + 1 /* 18.04 */
+ , allocBig));
p->matchFinderObj = &p->matchFinderMt;
p->matchFinderBase.bigHash = (Byte)(
(p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0);
@@ -2024,17 +2434,21 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc,
void LzmaEnc_Init(CLzmaEnc *p)
{
- UInt32 i;
+ unsigned i;
p->state = 0;
- for (i = 0 ; i < LZMA_NUM_REPS; i++)
- p->reps[i] = 0;
+ p->reps[0] =
+ p->reps[1] =
+ p->reps[2] =
+ p->reps[3] = 1;
RangeEnc_Init(&p->rc);
+ for (i = 0; i < (1 << kNumAlignBits); i++)
+ p->posAlignEncoder[i] = kProbInitValue;
for (i = 0; i < kNumStates; i++)
{
- UInt32 j;
+ unsigned j;
for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
{
p->isMatch[i][j] = kProbInitValue;
@@ -2047,38 +2461,37 @@ void LzmaEnc_Init(CLzmaEnc *p)
}
{
- UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
- CLzmaProb *probs = p->litProbs;
- for (i = 0; i < num; i++)
- probs[i] = kProbInitValue;
- }
-
- {
for (i = 0; i < kNumLenToPosStates; i++)
{
CLzmaProb *probs = p->posSlotEncoder[i];
- UInt32 j;
+ unsigned j;
for (j = 0; j < (1 << kNumPosSlotBits); j++)
probs[j] = kProbInitValue;
}
}
{
- for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ for (i = 0; i < kNumFullDistances; i++)
p->posEncoders[i] = kProbInitValue;
}
- LenEnc_Init(&p->lenEnc.p);
- LenEnc_Init(&p->repLenEnc.p);
+ {
+ UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
+ UInt32 k;
+ CLzmaProb *probs = p->litProbs;
+ for (k = 0; k < num; k++)
+ probs[k] = kProbInitValue;
+ }
- for (i = 0; i < (1 << kNumAlignBits); i++)
- p->posAlignEncoder[i] = kProbInitValue;
- p->optimumEndIndex = 0;
- p->optimumCurrentIndex = 0;
+ LenEnc_Init(&p->lenProbs);
+ LenEnc_Init(&p->repLenProbs);
+
+ p->optEnd = 0;
+ p->optCur = 0;
p->additionalOffset = 0;
p->pbMask = (1 << p->pb) - 1;
- p->lpMask = (1 << p->lp) - 1;
+ p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc);
}
void LzmaEnc_InitPrices(CLzmaEnc *p)
@@ -2092,14 +2505,14 @@ void LzmaEnc_InitPrices(CLzmaEnc *p)
p->lenEnc.tableSize =
p->repLenEnc.tableSize =
p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
- LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
- LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices);
+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, &p->repLenProbs, p->ProbPrices);
}
static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
- UInt32 i;
- for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
+ unsigned i;
+ for (i = kEndPosModelIndex / 2; i < kDicLogSizeMax; i++)
if (p->dictSize <= ((UInt32)1 << i))
break;
p->distTableSize = i * 2;
@@ -2220,11 +2633,15 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
if (reInit)
LzmaEnc_Init(p);
LzmaEnc_InitPrices(p);
+
nowPos64 = p->nowPos64;
RangeEnc_Init(&p->rc);
p->rc.outStream = &outStream.vt;
- res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
+ if (desiredPackSize == 0)
+ return SZ_ERROR_OUTPUT_EOF;
+
+ res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize);
*unpackSize = (UInt32)(p->nowPos64 - nowPos64);
*destLen -= outStream.rem;
@@ -2247,7 +2664,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
for (;;)
{
- res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
+ res = LzmaEnc_CodeOneBlock(p, 0, 0);
if (res != SZ_OK || p->finished)
break;
if (progress)
diff --git a/C/Util/7z/7zMain.c b/C/Util/7z/7zMain.c
index cb60a9ba..ea93d63f 100644
--- a/C/Util/7z/7zMain.c
+++ b/C/Util/7z/7zMain.c
@@ -1,5 +1,5 @@
/* 7zMain.c - Test application for 7z Decoder
-2017-08-26 : Igor Pavlov : Public domain */
+2018-04-19 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -606,6 +606,31 @@ int MY_CDECL main(int numargs, char *args[])
res = SZ_ERROR_FAIL;
break;
}
+
+ #ifdef USE_WINDOWS_FILE
+ {
+ FILETIME mtime, ctime;
+ FILETIME *mtimePtr = NULL;
+ FILETIME *ctimePtr = NULL;
+
+ if (SzBitWithVals_Check(&db.MTime, i))
+ {
+ const CNtfsFileTime *t = &db.MTime.Vals[i];
+ mtime.dwLowDateTime = (DWORD)(t->Low);
+ mtime.dwHighDateTime = (DWORD)(t->High);
+ mtimePtr = &mtime;
+ }
+ if (SzBitWithVals_Check(&db.CTime, i))
+ {
+ const CNtfsFileTime *t = &db.CTime.Vals[i];
+ ctime.dwLowDateTime = (DWORD)(t->Low);
+ ctime.dwHighDateTime = (DWORD)(t->High);
+ ctimePtr = &ctime;
+ }
+ if (mtimePtr || ctimePtr)
+ SetFileTime(outFile.handle, ctimePtr, NULL, mtimePtr);
+ }
+ #endif
if (File_Close(&outFile))
{
diff --git a/C/Util/7zipInstall/makefile b/C/Util/7zipInstall/makefile
index e84d552d..5c3082e9 100644
--- a/C/Util/7zipInstall/makefile
+++ b/C/Util/7zipInstall/makefile
@@ -1,4 +1,5 @@
PROG = 7zipInstall.exe
+MY_FIXED = 1
LIBS = $(LIBS) version.lib
diff --git a/C/Util/7zipUninstall/makefile b/C/Util/7zipUninstall/makefile
index 6c7a22ee..60c2fe20 100644
--- a/C/Util/7zipUninstall/makefile
+++ b/C/Util/7zipUninstall/makefile
@@ -1,4 +1,5 @@
PROG = 7zipUninstall.exe
+MY_FIXED = 1
!IFDEF _64BIT_INSTALLER
CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER
diff --git a/C/Util/SfxSetup/makefile b/C/Util/SfxSetup/makefile
index 76cd9112..544da67d 100644
--- a/C/Util/SfxSetup/makefile
+++ b/C/Util/SfxSetup/makefile
@@ -1,4 +1,5 @@
PROG = 7zS2.sfx
+MY_FIXED = 1
C_OBJS = \
$O\7zAlloc.obj \
diff --git a/C/Util/SfxSetup/makefile_con b/C/Util/SfxSetup/makefile_con
index ed9174d3..d0f83525 100644
--- a/C/Util/SfxSetup/makefile_con
+++ b/C/Util/SfxSetup/makefile_con
@@ -1,4 +1,5 @@
PROG = 7zS2con.sfx
+MY_FIXED = 1
CFLAGS = $(CFLAGS) -D_CONSOLE
C_OBJS = \
diff --git a/C/XzDec.c b/C/XzDec.c
index 685394b0..b973e686 100644
--- a/C/XzDec.c
+++ b/C/XzDec.c
@@ -1,5 +1,5 @@
/* XzDec.c -- Xz Decode
-2018-02-28 : Igor Pavlov : Public domain */
+2018-04-24 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -2673,7 +2673,7 @@ SRes XzDecMt_Decode(CXzDecMtHandle pp,
if (p->finishedDecoderIndex >= 0)
{
- CXzDecMtThread *coder = &p->coders[p->finishedDecoderIndex];
+ CXzDecMtThread *coder = &p->coders[(unsigned)p->finishedDecoderIndex];
codeRes = coder->codeRes;
dec = &coder->dec;
status = coder->status;
diff --git a/C/XzEnc.c b/C/XzEnc.c
index 69c881f2..82e70888 100644
--- a/C/XzEnc.c
+++ b/C/XzEnc.c
@@ -1,5 +1,5 @@
/* XzEnc.c -- Xz Encode
-2018-02-21 : Igor Pavlov : Public domain */
+2018-04-28 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -1254,6 +1254,8 @@ SRes XzEnc_Encode(CXzEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStr
&& props->reduceSize >= progress2.inOffset)
rem = props->reduceSize - progress2.inOffset;
*/
+
+ blockSizes.headerSize = 0; // for GCC
RINOK(Xz_CompressBlock(
&p->lzmaf_Items[0],
diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp
index c62efbd8..4395ae1a 100644
--- a/CPP/7zip/Archive/Cab/CabHandler.cpp
+++ b/CPP/7zip/Archive/Cab/CabHandler.cpp
@@ -549,9 +549,9 @@ private:
Byte *TempBuf;
UInt32 TempBufSize;
+ UInt32 TempBufWritten;
unsigned NumIdenticalFiles;
bool TempBufMode;
- UInt32 m_BufStartFolderOffset;
unsigned m_StartIndex;
unsigned m_CurrentIndex;
@@ -575,7 +575,6 @@ private:
HRESULT OpenFile();
HRESULT CloseFileWithResOp(Int32 resOp);
HRESULT CloseFile();
- HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
public:
HRESULT WriteEmptyFiles();
@@ -672,11 +671,11 @@ HRESULT CFolderOutStream::OpenFile()
FreeTempBuf();
TempBuf = (Byte *)MyAlloc(item.Size);
TempBufSize = item.Size;
- if (TempBuf == NULL)
+ if (!TempBuf)
return E_OUTOFMEMORY;
}
TempBufMode = true;
- m_BufStartFolderOffset = item.Offset;
+ TempBufWritten = 0;
}
else if (numExtractItems == 1)
{
@@ -725,8 +724,9 @@ HRESULT CFolderOutStream::WriteEmptyFiles()
}
-HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK)
+HRESULT CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
+ // (data == NULL) means Error_Data for solid folder flushing
COM_TRY_BEGIN
UInt32 realProcessed = 0;
@@ -741,21 +741,34 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
HRESULT res = S_OK;
if (numBytesToWrite != 0)
{
- if (!isOK)
+ if (!data)
m_IsOk = false;
+
if (m_RealOutStream)
{
UInt32 processedSizeLocal = 0;
- res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal);
+ // 18.01 : we don't want ZEROs instead of missing data
+ if (data)
+ res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal);
+ else
+ processedSizeLocal = numBytesToWrite;
numBytesToWrite = processedSizeLocal;
}
+
if (TempBufMode && TempBuf)
- memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite);
+ {
+ if (data)
+ {
+ memcpy(TempBuf + TempBufWritten, data, numBytesToWrite);
+ TempBufWritten += numBytesToWrite;
+ }
+ }
}
realProcessed += numBytesToWrite;
if (processedSize)
*processedSize = realProcessed;
- data = (const void *)((const Byte *)data + numBytesToWrite);
+ if (data)
+ data = (const void *)((const Byte *)data + numBytesToWrite);
size -= numBytesToWrite;
m_RemainFileSize -= numBytesToWrite;
m_PosInFolder += numBytesToWrite;
@@ -773,7 +786,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
m_FileIsOpen = true;
m_CurrentIndex++;
if (result == S_OK && m_RealOutStream && TempBuf)
- result = WriteStream(m_RealOutStream, TempBuf, (size_t)(m_PosInFolder - m_BufStartFolderOffset));
+ result = WriteStream(m_RealOutStream, TempBuf, TempBufWritten);
if (!TempBuf && TempBufMode && m_RealOutStream)
{
@@ -822,7 +835,8 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
realProcessed += numBytesToWrite;
if (processedSize)
*processedSize = realProcessed;
- data = (const void *)((const Byte *)data + numBytesToWrite);
+ if (data)
+ data = (const void *)((const Byte *)data + numBytesToWrite);
size -= numBytesToWrite;
m_PosInFolder += numBytesToWrite;
}
@@ -843,12 +857,6 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
}
-STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write2(data, size, processedSize, true);
-}
-
-
HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
{
if (!NeedMoreWrite())
@@ -862,19 +870,16 @@ HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
return S_OK;
}
- const unsigned kBufSize = (1 << 12);
- Byte buf[kBufSize];
- for (unsigned i = 0; i < kBufSize; i++)
- buf[i] = 0;
-
for (;;)
{
if (!NeedMoreWrite())
return S_OK;
UInt64 remain = GetRemain();
- UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize);
+ UInt32 size = (UInt32)1 << 20;
+ if (size > remain)
+ size = (UInt32)remain;
UInt32 processedSizeLocal = 0;
- RINOK(Write2(buf, size, &processedSizeLocal, false));
+ RINOK(Write(NULL, size, &processedSizeLocal));
}
}
diff --git a/CPP/7zip/Archive/DmgHandler.cpp b/CPP/7zip/Archive/DmgHandler.cpp
index 608ad4c4..5fe372dd 100644
--- a/CPP/7zip/Archive/DmgHandler.cpp
+++ b/CPP/7zip/Archive/DmgHandler.cpp
@@ -219,6 +219,7 @@ class CHandler:
bool _masterCrcError;
bool _headersError;
+ UInt32 _dataStartOffset;
UInt64 _startPos;
UInt64 _phySize;
@@ -333,6 +334,7 @@ static const Byte kProps[] =
kpidCRC,
kpidComment,
kpidMethod
+ // kpidOffset
};
IMP_IInArchive_Props
@@ -631,17 +633,40 @@ bool CHandler::ParseBlob(const CByteBuffer &data)
HRESULT CHandler::Open2(IInStream *stream)
{
+ /*
+ - usual dmg contains Koly Header at the end:
+ - rare case dmg contains Koly Header at the start.
+ */
+
+ _dataStartOffset = 0;
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_startPos));
+ UInt64 fileSize = 0;
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize));
+ RINOK(stream->Seek(_startPos, STREAM_SEEK_SET, NULL));
+
Byte buf[HEADER_SIZE];
RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE));
UInt64 headerPos;
+ bool startKolyMode = false;
+
if (IsKoly(buf))
+ {
+ // it can be normal koly-at-the-end or koly-at-the-start
headerPos = _startPos;
+ if (_startPos <= (1 << 8))
+ {
+ // we want to support startKolyMode, even if there is
+ // some data before dmg file, like 128 bytes MacBin header
+ _dataStartOffset = HEADER_SIZE;
+ startKolyMode = true;
+ }
+ }
else
{
- RINOK(stream->Seek(0, STREAM_SEEK_END, &headerPos));
+ // we check only koly-at-the-end
+ headerPos = fileSize;
if (headerPos < HEADER_SIZE)
return S_FALSE;
headerPos -= HEADER_SIZE;
@@ -667,24 +692,35 @@ HRESULT CHandler::Open2(IInStream *stream)
// CChecksum dataForkChecksum;
// dataForkChecksum.Parse(buf + 0x50);
- _startPos = 0;
-
UInt64 top = 0;
- if (!dataForkPair.UpdateTop(headerPos, top)) return S_FALSE;
- if (!xmlPair.UpdateTop(headerPos, top)) return S_FALSE;
- if (!rsrcPair.UpdateTop(headerPos, top)) return S_FALSE;
+ UInt64 limit = startKolyMode ? fileSize : headerPos;
+
+ if (!dataForkPair.UpdateTop(limit, top)) return S_FALSE;
+ if (!xmlPair.UpdateTop(limit, top)) return S_FALSE;
+ if (!rsrcPair.UpdateTop(limit, top)) return S_FALSE;
/* Some old dmg files contain garbage data in blobPair field.
So we need to ignore such garbage case;
And we still need to detect offset of start of archive for "parser" mode. */
- bool useBlob = blobPair.UpdateTop(headerPos, top);
+ bool useBlob = blobPair.UpdateTop(limit, top);
- _startPos = 0;
- _phySize = headerPos + HEADER_SIZE;
- if (top != headerPos)
+ if (startKolyMode)
+ _phySize = top;
+ else
{
+ _phySize = headerPos + HEADER_SIZE;
+ _startPos = 0;
+ if (top != headerPos)
+ {
+ /*
+ if expected absolute offset is not equal to real header offset,
+ 2 cases are possible:
+ - additional (unknown) headers
+ - archive with offset.
+ So we try to read XML with absolute offset to select from these two ways.
+ */
CForkPair xmlPair2 = xmlPair;
const char *sz = "<?xml version";
const unsigned len = (unsigned)strlen(sz);
@@ -694,9 +730,11 @@ HRESULT CHandler::Open2(IInStream *stream)
if (ReadData(stream, xmlPair2, buf2) != S_OK
|| memcmp(buf2, sz, len) != 0)
{
+ // if absolute offset is not OK, probably it's archive with offset
_startPos = headerPos - top;
_phySize = top + HEADER_SIZE;
}
+ }
}
// Byte reserved[0x78]
@@ -1041,6 +1079,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break;
}
+ /*
+ case kpidOffset:
+ {
+ prop = item.StartPos;
+ break;
+ }
+ */
+
case kpidMethod:
{
CMethods m;
@@ -1384,7 +1430,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
break;
}
- RINOK(_inStream->Seek(_startPos + item.StartPos + block.PackPos, STREAM_SEEK_SET, NULL));
+ RINOK(_inStream->Seek(_startPos + _dataStartOffset + item.StartPos + block.PackPos, STREAM_SEEK_SET, NULL));
streamSpec->Init(block.PackSize);
bool realMethod = true;
outStreamSpec->Init(block.UnpSize);
@@ -1781,7 +1827,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
spec->Stream = _inStream;
spec->Size = spec->File->Size;
- RINOK(spec->InitAndSeek(_startPos));
+ RINOK(spec->InitAndSeek(_startPos + _dataStartOffset));
*stream = specStream.Detach();
return S_OK;
diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp
index 62674774..c5ce279e 100644
--- a/CPP/7zip/Archive/ElfHandler.cpp
+++ b/CPP/7zip/Archive/ElfHandler.cpp
@@ -567,6 +567,7 @@ static const char * const g_Machines[] =
static const CUInt32PCharPair g_MachinePairs[] =
{
+ { 243, "RISC-V" },
{ 47787, "Xilinx MicroBlaze" }
// { 0x9026, "Alpha" }
};
diff --git a/CPP/7zip/Archive/HfsHandler.cpp b/CPP/7zip/Archive/HfsHandler.cpp
index d02f0725..3ff2e86e 100644
--- a/CPP/7zip/Archive/HfsHandler.cpp
+++ b/CPP/7zip/Archive/HfsHandler.cpp
@@ -317,11 +317,15 @@ public:
// bool CaseSensetive;
UString ResFileName;
+ UInt64 SpecOffset;
UInt64 PhySize;
+ UInt64 PhySize2;
void Clear()
{
+ SpecOffset = 0;
PhySize = 0;
+ PhySize2 = 0;
HeadersError = false;
ThereAreAltStreams = false;
// CaseSensetive = false;
@@ -444,7 +448,7 @@ HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inSt
e.NumBlocks > fork.NumBlocks - curBlock ||
e.NumBlocks > Header.NumBlocks - e.Pos)
return S_FALSE;
- RINOK(inStream->Seek((UInt64)e.Pos << Header.BlockSizeLog, STREAM_SEEK_SET, NULL));
+ RINOK(inStream->Seek(SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog), STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(inStream,
(Byte *)buf + ((size_t)curBlock << Header.BlockSizeLog),
(size_t)e.NumBlocks << Header.BlockSizeLog));
@@ -1154,13 +1158,36 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
}
static const unsigned kHeaderPadSize = (1 << 10);
+static const unsigned kMainHeaderSize = 512;
+static const unsigned kHfsHeaderSize = kHeaderPadSize + kMainHeaderSize;
+
+API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size)
+{
+ if (size < kHfsHeaderSize)
+ return k_IsArc_Res_NEED_MORE;
+ p += kHeaderPadSize;
+ if (p[0] == 'B' && p[1] == 'D')
+ {
+ if (p[0x7C] != 'H' || p[0x7C + 1] != '+')
+ return k_IsArc_Res_NO;
+ }
+ else
+ {
+ if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X'))
+ return k_IsArc_Res_NO;
+ UInt32 version = Get16(p + 2);
+ if (version < 4 || version > 5)
+ return k_IsArc_Res_NO;
+ }
+ return k_IsArc_Res_YES;
+}
+}
HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
{
Clear();
- static const unsigned kHeaderSize = kHeaderPadSize + 512;
- Byte buf[kHeaderSize];
- RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize));
+ Byte buf[kHfsHeaderSize];
+ RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize));
{
for (unsigned i = 0; i < kHeaderPadSize; i++)
if (buf[i] != 0)
@@ -1171,6 +1198,67 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
h.Header[0] = p[0];
h.Header[1] = p[1];
+
+ if (p[0] == 'B' && p[1] == 'D')
+ {
+ /*
+ It's header for old HFS format.
+ We don't support old HFS format, but we support
+ special HFS volume that contains embedded HFS+ volume
+ */
+
+ if (p[0x7C] != 'H' || p[0x7C + 1] != '+')
+ return S_FALSE;
+
+ /*
+ h.CTime = Get32(p + 0x2);
+ h.MTime = Get32(p + 0x6);
+
+ h.NumFiles = Get32(p + 0x54);
+ h.NumFolders = Get32(p + 0x58);
+
+ if (h.NumFolders > ((UInt32)1 << 29) ||
+ h.NumFiles > ((UInt32)1 << 30))
+ return S_FALSE;
+ if (progress)
+ {
+ UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1;
+ RINOK(progress->SetTotal(&numFiles, NULL));
+ }
+ h.NumFreeBlocks = Get16(p + 0x22);
+ */
+
+ UInt32 blockSize = Get32(p + 0x14);
+
+ {
+ unsigned i;
+ for (i = 9; ((UInt32)1 << i) != blockSize; i++)
+ if (i == 31)
+ return S_FALSE;
+ h.BlockSizeLog = i;
+ }
+
+ h.NumBlocks = Get16(p + 0x12);
+ /*
+ we suppose that it has the follwing layout
+ {
+ start block with header
+ [h.NumBlocks]
+ end block with header
+ }
+ */
+ PhySize2 = ((UInt64)h.NumBlocks + 2) << h.BlockSizeLog;
+
+ UInt32 startBlock = Get16(p + 0x7C + 2);
+ UInt32 blockCount = Get16(p + 0x7C + 4);
+ SpecOffset = (UInt64)(1 + startBlock) << h.BlockSizeLog;
+ UInt64 phy = SpecOffset + ((UInt64)blockCount << h.BlockSizeLog);
+ if (PhySize2 < phy)
+ PhySize2 = phy;
+ RINOK(inStream->Seek(SpecOffset, STREAM_SEEK_SET, NULL));
+ RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize));
+ }
+
if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X'))
return S_FALSE;
h.Version = Get16(p + 2);
@@ -1330,7 +1418,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
case kpidExtension: prop = Header.IsHfsX() ? "hfsx" : "hfs"; break;
case kpidMethod: prop = Header.IsHfsX() ? "HFSX" : "HFS+"; break;
- case kpidPhySize: prop = PhySize; break;
+ case kpidPhySize:
+ {
+ UInt64 v = SpecOffset + PhySize;
+ if (v < PhySize2)
+ v = PhySize2;
+ prop = v;
+ break;
+ }
case kpidClusterSize: prop = (UInt32)1 << Header.BlockSizeLog; break;
case kpidFreeSpace: prop = (UInt64)Header.GetFreeSize(); break;
case kpidMTime: HfsTimeToProp(Header.MTime, prop); break;
@@ -1754,7 +1849,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (fork.Size == pos)
break;
const CExtent &e = fork.Extents[extentIndex];
- RINOK(_stream->Seek((UInt64)e.Pos << Header.BlockSizeLog, STREAM_SEEK_SET, NULL));
+ RINOK(_stream->Seek(SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog), STREAM_SEEK_SET, NULL));
UInt64 extentRem = (UInt64)e.NumBlocks << Header.BlockSizeLog;
while (extentRem != 0)
{
@@ -1865,6 +1960,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
}
static const Byte k_Signature[] = {
+ 2, 'B', 'D',
4, 'H', '+', 0, 4,
4, 'H', 'X', 0, 5 };
@@ -1873,6 +1969,6 @@ REGISTER_ARC_I(
k_Signature,
kHeaderPadSize,
NArcInfoFlags::kMultiSignature,
- NULL)
+ IsArc_HFS)
}}
diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp
index cb0836cc..a751351c 100644
--- a/CPP/7zip/Archive/PeHandler.cpp
+++ b/CPP/7zip/Archive/PeHandler.cpp
@@ -2201,6 +2201,11 @@ bool CHeader::ParseCoff(const Byte *p)
return false;
if (OptHeaderSize != 0 && OptHeaderSize < k_OptHeader32_Size_MIN)
return false;
+
+ // 18.04: we reduce false detections
+ if (NumSections == 0 && OptHeaderSize == 0)
+ return false;
+
for (unsigned i = 0; i < ARRAY_SIZE(g_MachinePairs); i++)
if (Machine == g_MachinePairs[i].Value)
return true;
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
index ab8c70e3..17fcccc3 100644
--- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp
+++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
@@ -139,11 +139,10 @@ static unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val)
{
*val = 0;
- for (unsigned i = 0; i < maxSize;)
+ for (unsigned i = 0; i < maxSize && i < 10;)
{
Byte b = p[i];
- if (i < 10)
- *val |= (UInt64)(b & 0x7F) << (7 * i);
+ *val |= (UInt64)(b & 0x7F) << (7 * i);
i++;
if ((b & 0x80) == 0)
return i;
@@ -1363,7 +1362,9 @@ static const Byte kProps[] =
kpidCharacts,
kpidSymLink,
kpidHardLink,
- kpidCopyLink
+ kpidCopyLink,
+
+ kpidVolumeIndex
};
@@ -1794,6 +1795,18 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidSplitBefore: prop = item.IsSplitBefore(); break;
case kpidSplitAfter: prop = lastItem.IsSplitAfter(); break;
+
+ case kpidVolumeIndex:
+ {
+ if (item.VolIndex < _arcs.Size())
+ {
+ const CInArcInfo &arcInfo = _arcs[item.VolIndex].Info;
+ if (arcInfo.IsVolume())
+ prop = (UInt64)arcInfo.GetVolIndex();
+ }
+ break;
+ }
+
case kpidCRC:
{
const CItem *item2 = (lastItem.IsSplitAfter() ? &item : &lastItem);
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.h b/CPP/7zip/Archive/Rar/Rar5Handler.h
index d3e33d7c..3b3b940a 100644
--- a/CPP/7zip/Archive/Rar/Rar5Handler.h
+++ b/CPP/7zip/Archive/Rar/Rar5Handler.h
@@ -180,7 +180,7 @@ struct CItem
AString Name;
- int VolIndex;
+ unsigned VolIndex;
int NextItem;
UInt32 UnixMTime;
diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp
index fb5ef756..4b54e071 100644
--- a/CPP/7zip/Archive/Rar/RarHandler.cpp
+++ b/CPP/7zip/Archive/Rar/RarHandler.cpp
@@ -777,7 +777,9 @@ static const Byte kProps[] =
kpidCRC,
kpidHostOS,
kpidMethod,
- kpidUnpackVer
+ kpidUnpackVer,
+
+ kpidVolumeIndex
};
static const Byte kArcProps[] =
@@ -995,6 +997,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidCommented: prop = item.IsCommented(); break;
case kpidSplitBefore: prop = item.IsSplitBefore(); break;
case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break;
+
+ case kpidVolumeIndex:
+ if (_arcInfo.Is_VolNumber_Defined())
+ prop = (UInt32)(_arcInfo.VolNumber + refItem.VolumeIndex);
+ break;
+
case kpidCRC:
{
prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC);
diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h
index 901406d4..e444bd77 100644
--- a/CPP/7zip/Archive/Rar/RarHandler.h
+++ b/CPP/7zip/Archive/Rar/RarHandler.h
@@ -26,7 +26,7 @@ struct CInArcInfo
UInt32 DataCRC;
bool EndOfArchive_was_Read;
- CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false) {}
+ CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false), VolNumber(0) {}
UInt64 GetPhySize() const { return EndPos - StartPos; }
diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp
index 760bfa92..d432c318 100644
--- a/CPP/7zip/Archive/Tar/TarIn.cpp
+++ b/CPP/7zip/Archive/Tar/TarIn.cpp
@@ -94,7 +94,9 @@ static bool ParseInt64(const char *p, Int64 &val)
static bool ParseInt64_MTime(const char *p, Int64 &val)
{
- // rare case tar contains spaces instead of MTime
+ // rare case tar : ZEROs in Docker-Windows TARs
+ // rare case tar : spaces
+ if (GetUi32(p) != 0)
for (unsigned i = 0; i < 12; i++)
if (p[i] != ' ')
return ParseInt64(p, val);
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index 9e9918dc..aa7184af 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -1993,6 +1993,13 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
}
else if (ext.IsEqualTo_Ascii_NoCase("exe"))
{
+ /* possible cases:
+ - exe with zip inside
+ - sfx: a.exe, a.z02, a.z03,... , a.zip
+ a.exe is start volume.
+ - zip renamed to exe
+ */
+
StartIsExe = true;
BaseName = name;
StartVolIndex = 0;
@@ -2000,7 +2007,22 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
We can open arc.zip, if it was requesed to open arc.exe.
But it's possible that arc.exe and arc.zip are not parts of same archive.
So we can disable such operation */
- return S_FALSE; // don't open arc.zip instead of arc.exe
+
+ // 18.04: we still want to open zip renamed to exe.
+ /*
+ {
+ UString volName = name;
+ volName += IsUpperCase ? "Z01" : "z01";
+ {
+ CMyComPtr<IInStream> stream;
+ HRESULT res2 = volCallback->GetStream(volName, &stream);
+ if (res2 == S_OK)
+ DisableVolsSearch = true;
+ }
+ }
+ */
+ DisableVolsSearch = true;
+ return S_OK;
}
else if (ext[0] == 'z' || ext[0] == 'Z')
{
@@ -2040,6 +2062,9 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback,
unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols)
{
+ if (Vols.DisableVolsSearch)
+ return S_OK;
+
numMissingVols = 0;
for (unsigned i = start;; i++)
@@ -2090,6 +2115,8 @@ HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback,
}
if (res == S_FALSE || !stream)
{
+ if (i == 1 && Vols.StartIsExe)
+ return S_OK;
if (Vols.MissingName.IsEmpty())
Vols.MissingName = volName;
numMissingVols++;
diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h
index e67bce42..88f29569 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.h
+++ b/CPP/7zip/Archive/Zip/ZipIn.h
@@ -162,6 +162,7 @@ struct CVols
bool NeedSeek;
+ bool DisableVolsSearch;
bool StartIsExe; // is .exe
bool StartIsZ; // is .zip or .zNN
bool StartIsZip; // is .zip
@@ -201,6 +202,7 @@ struct CVols
StreamIndex = -1;
NeedSeek = false;
+ DisableVolsSearch = false;
StartIsExe = false;
StartIsZ = false;
StartIsZip = false;
diff --git a/CPP/7zip/Bundles/Alone/Alone.dsp b/CPP/7zip/Bundles/Alone/Alone.dsp
index 71715aae..733635bd 100644
--- a/CPP/7zip/Bundles/Alone/Alone.dsp
+++ b/CPP/7zip/Bundles/Alone/Alone.dsp
@@ -1112,18 +1112,6 @@ SOURCE=..\..\Compress\ShrinkDecoder.cpp
SOURCE=..\..\Compress\ShrinkDecoder.h
# End Source File
# End Group
-# Begin Group "Z"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\Compress\ZDecoder.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\Compress\ZDecoder.h
-# End Source File
-# End Group
# Begin Group "BWT"
# PROP Default_Filter ""
@@ -1648,10 +1636,6 @@ SOURCE=..\..\Archive\SplitHandler.cpp
SOURCE=..\..\Archive\XzHandler.cpp
# End Source File
-# Begin Source File
-
-SOURCE=..\..\Archive\ZHandler.cpp
-# End Source File
# End Group
# Begin Group "UI Common"
diff --git a/CPP/7zip/Bundles/Alone/makefile b/CPP/7zip/Bundles/Alone/makefile
index ba68fe54..8229103c 100644
--- a/CPP/7zip/Bundles/Alone/makefile
+++ b/CPP/7zip/Bundles/Alone/makefile
@@ -75,7 +75,6 @@ AR_OBJS = \
$O\LzmaHandler.obj \
$O\SplitHandler.obj \
$O\XzHandler.obj \
- $O\ZHandler.obj \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
@@ -169,7 +168,6 @@ COMPRESS_OBJS = \
$O\ShrinkDecoder.obj \
$O\XzDecoder.obj \
$O\XzEncoder.obj \
- $O\ZDecoder.obj \
CRYPTO_OBJS = \
$O\7zAes.obj \
diff --git a/CPP/7zip/Bundles/Alone/resource.rc b/CPP/7zip/Bundles/Alone/resource.rc
index fc9063c1..c85acaa9 100644
--- a/CPP/7zip/Bundles/Alone/resource.rc
+++ b/CPP/7zip/Bundles/Alone/resource.rc
@@ -1,3 +1,7 @@
#include "../../MyVersionInfo.rc"
MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za")
+
+#ifndef UNDER_CE
+1 24 MOVEABLE PURE "../../UI/Console/Console.manifest"
+#endif
diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsp b/CPP/7zip/Bundles/Alone7z/Alone.dsp
index 65308db4..eeab209e 100644
--- a/CPP/7zip/Bundles/Alone7z/Alone.dsp
+++ b/CPP/7zip/Bundles/Alone7z/Alone.dsp
@@ -44,7 +44,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /FAc /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAc /Yu"StdAfx.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -69,7 +69,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /Gr /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gr /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
@@ -94,7 +94,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /Yu"StdAfx.h" /FD /c
-# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -121,7 +121,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
-# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
@@ -482,6 +482,14 @@ SOURCE=..\..\..\Windows\FileName.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Windows\FileSystem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileSystem.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\Handle.h
# End Source File
# Begin Source File
diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile
index 98600154..da305780 100644
--- a/CPP/7zip/Bundles/Alone7z/makefile
+++ b/CPP/7zip/Bundles/Alone7z/makefile
@@ -3,7 +3,7 @@ MY_CONSOLE = 1
CFLAGS = $(CFLAGS) -DPROG_VARIANT_R
!IFNDEF UNDER_CE
-CFLAGS = $(CFLAGS) -DWIN_LONG_PATH
+CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE
!ENDIF
COMMON_OBJS = \
@@ -33,6 +33,7 @@ WIN_OBJS = \
$O\FileIO.obj \
$O\FileLink.obj \
$O\FileName.obj \
+ $O\FileSystem.obj \
$O\MemoryLock.obj \
$O\PropVariant.obj \
$O\PropVariantConv.obj \
diff --git a/CPP/7zip/Bundles/Alone7z/resource.rc b/CPP/7zip/Bundles/Alone7z/resource.rc
index b3fb079a..59378500 100644
--- a/CPP/7zip/Bundles/Alone7z/resource.rc
+++ b/CPP/7zip/Bundles/Alone7z/resource.rc
@@ -1,3 +1,7 @@
#include "../../../../C/7zVersion.rc"
MY_VERSION_INFO_APP("7-Zip Reduced Standalone Console", "7zr")
+
+#ifndef UNDER_CE
+1 24 MOVEABLE PURE "../../UI/Console/Console.manifest"
+#endif
diff --git a/CPP/7zip/Bundles/Fm/FM.dsp b/CPP/7zip/Bundles/Fm/FM.dsp
index 82ac7fa4..38770405 100644
--- a/CPP/7zip/Bundles/Fm/FM.dsp
+++ b/CPP/7zip/Bundles/Fm/FM.dsp
@@ -677,6 +677,14 @@ SOURCE=..\..\UI\FileManager\DialogSize.h
# End Source File
# Begin Source File
+SOURCE=..\..\UI\FileManager\EditDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\EditDialog.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\UI\FileManager\LinkDialog.cpp
# End Source File
# Begin Source File
@@ -1567,14 +1575,6 @@ SOURCE=..\..\..\Common\Wildcard.h
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\UI\Common\ArchiveCommandLine.h
-# End Source File
-# Begin Source File
-
SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/Bundles/Fm/makefile b/CPP/7zip/Bundles/Fm/makefile
index 8ae5f4f6..367b30d5 100644
--- a/CPP/7zip/Bundles/Fm/makefile
+++ b/CPP/7zip/Bundles/Fm/makefile
@@ -48,7 +48,6 @@ WIN_CTRL_OBJS = \
$O\FileStreams.obj \
UI_COMMON_OBJS = \
- $O\ArchiveCommandLine.obj \
$O\ArchiveExtractCallback.obj \
$O\ArchiveName.obj \
$O\ArchiveOpenCallback.obj \
diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
index c5a0ceff..0f032d81 100644
--- a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
+++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
@@ -117,10 +117,6 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h
# End Source File
# Begin Source File
-SOURCE=..\..\Archive\Common\HandlerOut.cpp
-# End Source File
-# Begin Source File
-
SOURCE=..\..\Archive\Common\HandlerOut.h
# End Source File
# Begin Source File
diff --git a/CPP/7zip/Bundles/SFXCon/makefile b/CPP/7zip/Bundles/SFXCon/makefile
index 01d1bf60..67fc5896 100644
--- a/CPP/7zip/Bundles/SFXCon/makefile
+++ b/CPP/7zip/Bundles/SFXCon/makefile
@@ -1,5 +1,7 @@
PROG = 7zCon.sfx
MY_CONSOLE = 1
+MY_FIXED = 1
+
CFLAGS = $(CFLAGS) \
-DEXTRACT_ONLY \
-DNO_READ_FROM_CODER \
diff --git a/CPP/7zip/Bundles/SFXSetup/makefile b/CPP/7zip/Bundles/SFXSetup/makefile
index 19afc3b3..9fddbc07 100644
--- a/CPP/7zip/Bundles/SFXSetup/makefile
+++ b/CPP/7zip/Bundles/SFXSetup/makefile
@@ -1,4 +1,6 @@
PROG = 7zS.sfx
+MY_FIXED = 1
+
CFLAGS = $(CFLAGS) \
-DNO_REGISTRY \
-DEXTRACT_ONLY \
diff --git a/CPP/7zip/Bundles/SFXWin/makefile b/CPP/7zip/Bundles/SFXWin/makefile
index d6556961..b3b4546f 100644
--- a/CPP/7zip/Bundles/SFXWin/makefile
+++ b/CPP/7zip/Bundles/SFXWin/makefile
@@ -1,4 +1,6 @@
PROG = 7z.sfx
+MY_FIXED = 1
+
CFLAGS = $(CFLAGS) \
-DNO_REGISTRY \
-DEXTRACT_ONLY \
diff --git a/CPP/7zip/Compress/Lzma2Encoder.cpp b/CPP/7zip/Compress/Lzma2Encoder.cpp
index a3ef4b57..caecbc09 100644
--- a/CPP/7zip/Compress/Lzma2Encoder.cpp
+++ b/CPP/7zip/Compress/Lzma2Encoder.cpp
@@ -22,7 +22,7 @@ namespace NLzma2 {
CEncoder::CEncoder()
{
_encoder = NULL;
- _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc);
+ _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc);
if (!_encoder)
throw 1;
}
diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp
index c64f580a..e47f776b 100644
--- a/CPP/7zip/Compress/LzmaEncoder.cpp
+++ b/CPP/7zip/Compress/LzmaEncoder.cpp
@@ -15,7 +15,7 @@ namespace NLzma {
CEncoder::CEncoder()
{
_encoder = NULL;
- _encoder = LzmaEnc_Create(&g_Alloc);
+ _encoder = LzmaEnc_Create(&g_AlignedAlloc);
if (!_encoder)
throw 1;
}
@@ -23,7 +23,7 @@ CEncoder::CEncoder()
CEncoder::~CEncoder()
{
if (_encoder)
- LzmaEnc_Destroy(_encoder, &g_Alloc, &g_BigAlloc);
+ LzmaEnc_Destroy(_encoder, &g_AlignedAlloc, &g_BigAlloc);
}
static inline wchar_t GetUpperChar(wchar_t c)
@@ -168,7 +168,7 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
progressWrap.Init(progress);
SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt,
- progress ? &progressWrap.vt : NULL, &g_Alloc, &g_BigAlloc);
+ progress ? &progressWrap.vt : NULL, &g_AlignedAlloc, &g_BigAlloc);
_inputProcessed = inWrap.Processed;
diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp
index f5f3a79d..6b55705b 100644
--- a/CPP/7zip/Compress/Rar1Decoder.cpp
+++ b/CPP/7zip/Compress/Rar1Decoder.cpp
@@ -9,77 +9,85 @@
namespace NCompress {
namespace NRar1 {
-static const UInt32 PosL1[] = {0,0,0,2,3,5,7,11,16,20,24,32,32, 256};
-static const UInt32 PosL2[] = {0,0,0,0,5,7,9,13,18,22,26,34,36, 256};
-static const UInt32 PosHf0[] = {0,0,0,0,0,8,16,24,33,33,33,33,33, 257};
-static const UInt32 PosHf1[] = {0,0,0,0,0,0,4,44,60,76,80,80,127, 257};
-static const UInt32 PosHf2[] = {0,0,0,0,0,0,2,7,53,117,233, 257,0};
-static const UInt32 PosHf3[] = {0,0,0,0,0,0,0,2,16,218,251, 257,0};
-static const UInt32 PosHf4[] = {0,0,0,0,0,0,0,0,0,255, 257,0,0};
+static const unsigned kNumBits = 12;
-static const UInt32 kHistorySize = (1 << 16);
+static const Byte kShortLen1[16 * 3] =
+{
+ 0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0,0,
+ 1,3,4,4,5,6,7,8,8,4,4,5,6,6,0,0,
+ 1,4,4,4,5,6,7,8,8,4,4,5,6,6,4,0
+};
-/*
-class CCoderReleaser
+static const Byte kShortLen2[16 * 3] =
{
- CDecoder *m_Coder;
-public:
- CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
- ~CCoderReleaser() { m_Coder->ReleaseStreams(); }
+ 0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0,0,
+ 2,3,3,3,4,4,5,6,6,4,4,5,6,6,0,0,
+ 2,3,3,4,4,4,5,6,6,4,4,5,6,6,4,0
};
-*/
-CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { }
+static const Byte PosL1[kNumBits + 1] = { 0,0,2,1,2,2,4,5,4,4,8,0,224 };
+static const Byte PosL2[kNumBits + 1] = { 0,0,0,5,2,2,4,5,4,4,8,2,220 };
-void CDecoder::InitStructures()
-{
- for (int i = 0; i < kNumRepDists; i++)
- m_RepDists[i] = 0;
- m_RepDistPtr = 0;
- LastLength = 0;
- LastDist = 0;
-}
+static const Byte PosHf0[kNumBits + 1] = { 0,0,0,0,8,8,8,9,0,0,0,0,224 };
+static const Byte PosHf1[kNumBits + 1] = { 0,0,0,0,0,4,40,16,16,4,0,47,130 };
+static const Byte PosHf2[kNumBits + 1] = { 0,0,0,0,0,2,5,46,64,116,24,0,0 };
+static const Byte PosHf3[kNumBits + 1] = { 0,0,0,0,0,0,2,14,202,33,6,0,0 };
+static const Byte PosHf4[kNumBits + 1] = { 0,0,0,0,0,0,0,0,255,2,0,0,0 };
+
+static const UInt32 kHistorySize = (1 << 16);
+
+CDecoder::CDecoder():
+ _isSolid(false),
+ _solidAllowed(false)
+ { }
-UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); }
+UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numBits); }
HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len)
{
if (len == 0)
return S_FALSE;
+ if (m_UnpackSize < len)
+ return S_FALSE;
m_UnpackSize -= len;
return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE;
}
-UInt32 CDecoder::DecodeNum(const UInt32 *posTab)
+UInt32 CDecoder::DecodeNum(const Byte *numTab)
{
- UInt32 startPos = 2;
- UInt32 num = m_InBitStream.GetValue(12);
+ /*
+ {
+ // we can check that tables are correct
+ UInt32 sum = 0;
+ for (unsigned i = 0; i <= kNumBits; i++)
+ sum += ((UInt32)numTab[i] << (kNumBits - i));
+ if (sum != (1 << kNumBits))
+ throw 111;
+ }
+ */
+
+ UInt32 val = m_InBitStream.GetValue(kNumBits);
+ UInt32 sum = 0;
+ unsigned i = 2;
+
for (;;)
{
- UInt32 cur = (posTab[(size_t)startPos + 1] - posTab[startPos]) << (12 - startPos);
- if (num < cur)
+ UInt32 num = numTab[i];
+ UInt32 cur = num << (kNumBits - i);
+ if (val < cur)
break;
- startPos++;
- num -= cur;
+ i++;
+ val -= cur;
+ sum += num;
}
- m_InBitStream.MovePos(startPos);
- return((num >> (12 - startPos)) + posTab[startPos]);
+ m_InBitStream.MovePos(i);
+ return ((val >> (kNumBits - i)) + sum);
}
-static const Byte kShortLen1 [] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 };
-static const Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 };
-static const Byte kShortLen2 [] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 };
-static const Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 };
-static const UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0};
-static const UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0};
HRESULT CDecoder::ShortLZ()
{
- UInt32 len, saveLen, dist;
- int distancePlace;
- const Byte *kShortLen;
- const UInt32 *kShortXor;
NumHuf = 0;
if (LCount == 2)
@@ -91,20 +99,14 @@ HRESULT CDecoder::ShortLZ()
UInt32 bitField = m_InBitStream.GetValue(8);
- if (AvrLn1 < 37)
+ UInt32 len, dist;
{
- kShortLen = Buf60 ? kShortLen1a : kShortLen1;
- kShortXor = kShortXor1;
+ const Byte *xors = (AvrLn1 < 37) ? kShortLen1 : kShortLen2;
+ const Byte *lens = xors + 16 + Buf60;
+ for (len = 0; ((bitField ^ xors[len]) >> (8 - lens[len])) != 0; len++);
+ m_InBitStream.MovePos(lens[len]);
}
- else
- {
- kShortLen = Buf60 ? kShortLen2a : kShortLen2;
- kShortXor = kShortXor2;
- }
-
- for (len = 0; ((bitField ^ kShortXor[len]) & (~(0xff >> kShortLen[len]))) != 0; len++);
- m_InBitStream.MovePos(kShortLen[len]);
-
+
if (len >= 9)
{
if (len == 9)
@@ -112,9 +114,11 @@ HRESULT CDecoder::ShortLZ()
LCount++;
return CopyBlock(LastDist, LastLength);
}
+
+ LCount = 0;
+
if (len == 14)
{
- LCount = 0;
len = DecodeNum(PosL2) + 5;
dist = 0x8000 + ReadBits(15) - 1;
LastLength = len;
@@ -122,19 +126,22 @@ HRESULT CDecoder::ShortLZ()
return CopyBlock(dist, len);
}
- LCount = 0;
- saveLen = len;
+ UInt32 saveLen = len;
dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3];
- len = DecodeNum(PosL1) + 2;
- if (len == 0x101 && saveLen == 10)
+
+ len = DecodeNum(PosL1);
+
+ if (len == 0xff && saveLen == 10)
{
- Buf60 ^= 1;
+ Buf60 ^= 16;
return S_OK;
}
if (dist >= 256)
+ {
len++;
- if (dist >= MaxDist3 - 1)
- len++;
+ if (dist >= MaxDist3 - 1)
+ len++;
+ }
}
else
{
@@ -142,21 +149,23 @@ HRESULT CDecoder::ShortLZ()
AvrLn1 += len;
AvrLn1 -= AvrLn1 >> 4;
- distancePlace = DecodeNum(PosHf2) & 0xff;
- dist = ChSetA[(unsigned)distancePlace];
- if (--distancePlace != -1)
+ unsigned distancePlace = DecodeNum(PosHf2) & 0xff;
+
+ dist = ChSetA[distancePlace];
+
+ if (distancePlace != 0)
{
PlaceA[dist]--;
- UInt32 lastDistance = ChSetA[(unsigned)distancePlace];
+ UInt32 lastDistance = ChSetA[(size_t)distancePlace - 1];
PlaceA[lastDistance]++;
- ChSetA[(size_t)(unsigned)distancePlace + 1] = lastDistance;
- ChSetA[(unsigned)distancePlace] = dist;
+ ChSetA[distancePlace] = lastDistance;
+ ChSetA[(size_t)distancePlace - 1] = dist;
}
- len += 2;
}
m_RepDists[m_RepDistPtr++] = dist;
m_RepDistPtr &= 3;
+ len += 2;
LastLength = len;
LastDist = dist;
return CopyBlock(dist, len);
@@ -177,12 +186,10 @@ HRESULT CDecoder::LongLZ()
Nlzb = 0x90;
Nhfb >>= 1;
}
- oldAvr2=AvrLn2;
+ oldAvr2 = AvrLn2;
- if (AvrLn2 >= 122)
- len = DecodeNum(PosL2);
- else if (AvrLn2 >= 64)
- len = DecodeNum(PosL1);
+ if (AvrLn2 >= 64)
+ len = DecodeNum(AvrLn2 < 122 ? PosL1 : PosL2);
else
{
UInt32 bitField = m_InBitStream.GetValue(16);
@@ -193,8 +200,8 @@ HRESULT CDecoder::LongLZ()
}
else
{
- for (len = 0; ((bitField << len) & 0x8000) == 0; len++)
- ;
+ for (len = 0; ((bitField << len) & 0x8000) == 0; len++);
+
m_InBitStream.MovePos(len + 1);
}
}
@@ -202,24 +209,26 @@ HRESULT CDecoder::LongLZ()
AvrLn2 += len;
AvrLn2 -= AvrLn2 >> 5;
- if (AvrPlcB > 0x28ff)
- distancePlace = DecodeNum(PosHf2);
- else if (AvrPlcB > 0x6ff)
- distancePlace = DecodeNum(PosHf1);
- else
- distancePlace = DecodeNum(PosHf0);
+ {
+ const Byte *tab;
+ if (AvrPlcB >= 0x2900) tab = PosHf2;
+ else if (AvrPlcB >= 0x0700) tab = PosHf1;
+ else tab = PosHf0;
+ distancePlace = DecodeNum(tab); // [0, 256]
+ }
AvrPlcB += distancePlace;
AvrPlcB -= AvrPlcB >> 8;
+
+ distancePlace &= 0xff;
for (;;)
{
- dist = ChSetB[distancePlace & 0xff];
+ dist = ChSetB[distancePlace];
newDistancePlace = NToPlB[dist++ & 0xff]++;
- if (!(dist & 0xff))
- CorrHuff(ChSetB,NToPlB);
- else
+ if (dist & 0xff)
break;
+ CorrHuff(ChSetB,NToPlB);
}
ChSetB[distancePlace] = ChSetB[newDistancePlace];
@@ -235,9 +244,8 @@ HRESULT CDecoder::LongLZ()
AvrLn3++;
AvrLn3 -= AvrLn3 >> 8;
}
- else
- if (AvrLn3 > 0)
- AvrLn3--;
+ else if (AvrLn3 > 0)
+ AvrLn3--;
len += 3;
@@ -265,57 +273,62 @@ HRESULT CDecoder::HuffDecode()
UInt32 curByte, newBytePlace;
UInt32 len;
UInt32 dist;
- int bytePlace;
-
- if (AvrPlc > 0x75ff) bytePlace = DecodeNum(PosHf4);
- else if (AvrPlc > 0x5dff) bytePlace = DecodeNum(PosHf3);
- else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2);
- else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1);
- else bytePlace = DecodeNum(PosHf0);
+ unsigned bytePlace;
+ {
+ const Byte *tab;
+
+ if (AvrPlc >= 0x7600) tab = PosHf4;
+ else if (AvrPlc >= 0x5e00) tab = PosHf3;
+ else if (AvrPlc >= 0x3600) tab = PosHf2;
+ else if (AvrPlc >= 0x0e00) tab = PosHf1;
+ else tab = PosHf0;
+
+ bytePlace = DecodeNum(tab); // [0, 256]
+ }
if (StMode)
{
- if (--bytePlace == -1)
+ if (bytePlace == 0)
{
if (ReadBits(1))
{
- NumHuf = StMode = 0;
+ NumHuf = 0;
+ StMode = false;
return S_OK;
}
- else
- {
- len = (ReadBits(1)) ? 4 : 3;
- dist = DecodeNum(PosHf2);
- dist = (dist << 5) | ReadBits(5);
- return CopyBlock(dist - 1, len);
- }
+ len = ReadBits(1) + 3;
+ dist = DecodeNum(PosHf2);
+ dist = (dist << 5) | ReadBits(5);
+ if (dist == 0)
+ return S_FALSE;
+ return CopyBlock(dist - 1, len);
}
+ bytePlace--; // bytePlace is [0, 255]
}
else if (NumHuf++ >= 16 && FlagsCnt == 0)
- StMode = 1;
+ StMode = true;
bytePlace &= 0xff;
AvrPlc += bytePlace;
AvrPlc -= AvrPlc >> 8;
- Nhfb+=16;
+ Nhfb += 16;
if (Nhfb > 0xff)
{
- Nhfb=0x90;
+ Nhfb = 0x90;
Nlzb >>= 1;
}
- m_UnpackSize --;
+ m_UnpackSize--;
m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8));
for (;;)
{
curByte = ChSet[bytePlace];
newBytePlace = NToPl[curByte++ & 0xff]++;
- if ((curByte & 0xff) > 0xa1)
- CorrHuff(ChSet, NToPl);
- else
+ if ((curByte & 0xff) <= 0xa1)
break;
+ CorrHuff(ChSet, NToPl);
}
ChSet[bytePlace] = ChSet[newBytePlace];
@@ -327,7 +340,10 @@ HRESULT CDecoder::HuffDecode()
void CDecoder::GetFlagsBuf()
{
UInt32 flags, newFlagsPlace;
- UInt32 flagsPlace = DecodeNum(PosHf2);
+ UInt32 flagsPlace = DecodeNum(PosHf2); // [0, 256]
+
+ if (flagsPlace >= ARRAY_SIZE(ChSetC))
+ return;
for (;;)
{
@@ -343,20 +359,6 @@ void CDecoder::GetFlagsBuf()
ChSetC[newFlagsPlace] = flags;
}
-void CDecoder::InitData()
-{
- if (!m_IsSolid)
- {
- AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
- AvrPlc = 0x3500;
- MaxDist3 = 0x2001;
- Nhfb = Nlzb = 0x80;
- }
- FlagsCnt = 0;
- FlagBuf = 0;
- StMode = 0;
- LCount = 0;
-}
void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace)
{
@@ -369,129 +371,145 @@ void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace)
NumToPlace[i] = (7 - i) * 32;
}
-void CDecoder::InitHuff()
-{
- for (UInt32 i = 0; i < 256; i++)
- {
- Place[i] = PlaceA[i] = PlaceB[i] = i;
- PlaceC[i] = (~i + 1) & 0xff;
- ChSet[i] = ChSetB[i] = i << 8;
- ChSetA[i] = i;
- ChSetC[i] = ((~i + 1) & 0xff) << 8;
- }
- memset(NToPl, 0, sizeof(NToPl));
- memset(NToPlB, 0, sizeof(NToPlB));
- memset(NToPlC, 0, sizeof(NToPlC));
- CorrHuff(ChSetB, NToPlB);
-}
+
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo * /* progress */)
{
- if (inSize == NULL || outSize == NULL)
+ if (!inSize || !outSize)
return E_INVALIDARG;
+ if (_isSolid && !_solidAllowed)
+ return S_FALSE;
+
+ _solidAllowed = false;
+
if (!m_OutWindowStream.Create(kHistorySize))
return E_OUTOFMEMORY;
if (!m_InBitStream.Create(1 << 20))
return E_OUTOFMEMORY;
- m_UnpackSize = (Int64)*outSize;
+ m_UnpackSize = *outSize;
+
m_OutWindowStream.SetStream(outStream);
- m_OutWindowStream.Init(m_IsSolid);
+ m_OutWindowStream.Init(_isSolid);
m_InBitStream.SetStream(inStream);
m_InBitStream.Init();
- // CCoderReleaser coderReleaser(this);
- InitData();
- if (!m_IsSolid)
+ // InitData
+
+ FlagsCnt = 0;
+ FlagBuf = 0;
+ StMode = false;
+ LCount = 0;
+
+ if (!_isSolid)
{
- _errorMode = false;
- InitStructures();
- InitHuff();
- }
-
- if (_errorMode)
- return S_FALSE;
+ AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
+ AvrPlc = 0x3500;
+ MaxDist3 = 0x2001;
+ Nhfb = Nlzb = 0x80;
+
+ {
+ // InitStructures
+ for (int i = 0; i < kNumRepDists; i++)
+ m_RepDists[i] = 0;
+ m_RepDistPtr = 0;
+ LastLength = 0;
+ LastDist = 0;
+ }
+
+ // InitHuff
+ for (UInt32 i = 0; i < 256; i++)
+ {
+ Place[i] = PlaceA[i] = PlaceB[i] = i;
+ UInt32 c = (~i + 1) & 0xff;
+ PlaceC[i] = c;
+ ChSet[i] = ChSetB[i] = i << 8;
+ ChSetA[i] = i;
+ ChSetC[i] = c << 8;
+ }
+ memset(NToPl, 0, sizeof(NToPl));
+ memset(NToPlB, 0, sizeof(NToPlB));
+ memset(NToPlC, 0, sizeof(NToPlC));
+ CorrHuff(ChSetB, NToPlB);
+ }
+
if (m_UnpackSize > 0)
{
GetFlagsBuf();
FlagsCnt = 8;
}
- while (m_UnpackSize > 0)
+ while (m_UnpackSize != 0)
{
- if (StMode)
+ if (!StMode)
{
- RINOK(HuffDecode());
- continue;
- }
-
- if (--FlagsCnt < 0)
- {
- GetFlagsBuf();
- FlagsCnt=7;
- }
-
- if (FlagBuf & 0x80)
- {
- FlagBuf <<= 1;
- if (Nlzb > Nhfb)
- {
- RINOK(LongLZ());
- }
- else
- {
- RINOK(HuffDecode());
- }
- }
- else
- {
- FlagBuf <<= 1;
if (--FlagsCnt < 0)
{
GetFlagsBuf();
FlagsCnt = 7;
}
+
if (FlagBuf & 0x80)
{
FlagBuf <<= 1;
if (Nlzb > Nhfb)
{
- RINOK(HuffDecode());
- }
- else
- {
RINOK(LongLZ());
+ continue;
}
}
else
{
FlagBuf <<= 1;
- RINOK(ShortLZ());
+
+ if (--FlagsCnt < 0)
+ {
+ GetFlagsBuf();
+ FlagsCnt = 7;
+ }
+
+ if ((FlagBuf & 0x80) == 0)
+ {
+ FlagBuf <<= 1;
+ RINOK(ShortLZ());
+ continue;
+ }
+
+ FlagBuf <<= 1;
+
+ if (Nlzb <= Nhfb)
+ {
+ RINOK(LongLZ());
+ continue;
+ }
}
}
+
+ RINOK(HuffDecode());
}
- if (m_UnpackSize < 0)
- return S_FALSE;
+
+ _solidAllowed = true;
return m_OutWindowStream.Flush();
}
+
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
- catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; }
- catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; }
- catch(...) { _errorMode = true; return S_FALSE; }
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const CLzOutWindowException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
}
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
{
if (size < 1)
return E_INVALIDARG;
- m_IsSolid = ((data[0] & 1) != 0);
+ _isSolid = ((data[0] & 1) != 0);
return S_OK;
}
diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h
index 01b606b3..52907e5c 100644
--- a/CPP/7zip/Compress/Rar1Decoder.h
+++ b/CPP/7zip/Compress/Rar1Decoder.h
@@ -20,49 +20,45 @@ namespace NRar1 {
const UInt32 kNumRepDists = 4;
-typedef NBitm::CDecoder<CInBuffer> CBitDecoder;
-
class CDecoder :
public ICompressCoder,
public ICompressSetDecoderProperties2,
public CMyUnknownImp
{
-public:
CLzOutWindow m_OutWindowStream;
- CBitDecoder m_InBitStream;
+ NBitm::CDecoder<CInBuffer> m_InBitStream;
- UInt32 m_RepDists[kNumRepDists];
- UInt32 m_RepDistPtr;
+ UInt64 m_UnpackSize;
UInt32 LastDist;
UInt32 LastLength;
- Int64 m_UnpackSize;
- bool m_IsSolid;
- bool _errorMode;
+ UInt32 m_RepDistPtr;
+ UInt32 m_RepDists[kNumRepDists];
- UInt32 ReadBits(int numBits);
- HRESULT CopyBlock(UInt32 distance, UInt32 len);
+ bool _isSolid;
+ bool _solidAllowed;
- UInt32 DecodeNum(const UInt32 *posTab);
+ bool StMode;
+ int FlagsCnt;
+ UInt32 FlagBuf, AvrPlc, AvrPlcB, AvrLn1, AvrLn2, AvrLn3;
+ unsigned Buf60, NumHuf, LCount;
+ UInt32 Nhfb, Nlzb, MaxDist3;
+
+ UInt32 ChSet[256], ChSetA[256], ChSetB[256], ChSetC[256];
+ UInt32 Place[256], PlaceA[256], PlaceB[256], PlaceC[256];
+ UInt32 NToPl[256], NToPlB[256], NToPlC[256];
+
+ UInt32 ReadBits(unsigned numBits);
+ HRESULT CopyBlock(UInt32 distance, UInt32 len);
+ UInt32 DecodeNum(const Byte *numTab);
HRESULT ShortLZ();
HRESULT LongLZ();
HRESULT HuffDecode();
void GetFlagsBuf();
- void InitData();
- void InitHuff();
void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace);
void OldUnpWriteBuf();
- UInt32 ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
- UInt32 Place[256],PlaceA[256],PlaceB[256],PlaceC[256];
- UInt32 NToPl[256],NToPlB[256],NToPlC[256];
- UInt32 FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
- int Buf60,NumHuf,StMode,LCount,FlagsCnt;
- UInt32 Nhfb,Nlzb,MaxDist3;
-
- void InitStructures();
-
HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
@@ -71,14 +67,6 @@ public:
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
- /*
- void ReleaseStreams()
- {
- m_OutWindowStream.ReleaseStream();
- m_InBitStream.ReleaseStream();
- }
- */
-
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp
index 1488444e..fe458c85 100644
--- a/CPP/7zip/Compress/Rar2Decoder.cpp
+++ b/CPP/7zip/Compress/Rar2Decoder.cpp
@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20;
static const UInt32 kWindowReservSize = (1 << 22) + 256;
CDecoder::CDecoder():
- m_IsSolid(false),
+ _isSolid(false),
+ _solidAllowed(false),
m_TablesOK(false)
{
}
@@ -227,18 +228,6 @@ bool CDecoder::ReadLastTables()
return true;
}
-/*
-class CCoderReleaser
-{
- CDecoder *m_Coder;
-public:
- CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
- ~CCoderReleaser()
- {
- m_Coder->ReleaseStreams();
- }
-};
-*/
bool CDecoder::DecodeMm(UInt32 pos)
{
@@ -343,9 +332,13 @@ bool CDecoder::DecodeLz(Int32 pos)
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
- if (inSize == NULL || outSize == NULL)
+ if (!inSize || !outSize)
return E_INVALIDARG;
+ if (_isSolid && !_solidAllowed)
+ return S_FALSE;
+ _solidAllowed = false;
+
if (!m_OutWindowStream.Create(kHistorySize))
return E_OUTOFMEMORY;
if (!m_InBitStream.Create(1 << 20))
@@ -356,12 +349,12 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
UInt64 pos = 0, unPackSize = *outSize;
m_OutWindowStream.SetStream(outStream);
- m_OutWindowStream.Init(m_IsSolid);
+ m_OutWindowStream.Init(_isSolid);
m_InBitStream.SetStream(inStream);
m_InBitStream.Init();
// CCoderReleaser coderReleaser(this);
- if (!m_IsSolid)
+ if (!_isSolid)
{
InitStructures();
if (unPackSize == 0)
@@ -369,6 +362,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect;
if (!ReadTables())
return S_FALSE;
+ _solidAllowed = true;
return S_OK;
}
ReadTables();
@@ -415,6 +409,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
if (!ReadLastTables())
return S_FALSE;
+
+ _solidAllowed = true;
+
return m_OutWindowStream.Flush();
}
@@ -431,7 +428,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
{
if (size < 1)
return E_INVALIDARG;
- m_IsSolid = ((data[0] & 1) != 0);
+ _isSolid = ((data[0] & 1) != 0);
return S_OK;
}
diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h
index 0d8142b5..f42f228d 100644
--- a/CPP/7zip/Compress/Rar2Decoder.h
+++ b/CPP/7zip/Compress/Rar2Decoder.h
@@ -125,7 +125,8 @@ class CDecoder :
UInt32 m_LastLength;
- bool m_IsSolid;
+ bool _isSolid;
+ bool _solidAllowed;
bool m_TablesOK;
bool m_AudioMode;
@@ -159,14 +160,6 @@ public:
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
- /*
- void ReleaseStreams()
- {
- m_OutWindowStream.ReleaseStream();
- m_InBitStream.ReleaseStream();
- }
- */
-
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp
index 4da89a65..10e8bff6 100644
--- a/CPP/7zip/Compress/Rar3Decoder.cpp
+++ b/CPP/7zip/Compress/Rar3Decoder.cpp
@@ -94,8 +94,8 @@ CDecoder::CDecoder():
_writtenFileSize(0),
_vmData(0),
_vmCode(0),
- m_IsSolid(false),
- _errorMode(false)
+ _isSolid(false),
+ _solidAllowed(false)
{
Ppmd7_Construct(&_ppmd);
}
@@ -829,7 +829,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
_writtenFileSize = 0;
_unsupportedFilter = false;
- if (!m_IsSolid)
+ if (!_isSolid)
{
_lzSize = 0;
_winPos = 0;
@@ -842,18 +842,23 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
PpmEscChar = 2;
PpmError = true;
InitFilters();
- _errorMode = false;
+ // _errorMode = false;
}
+ /*
if (_errorMode)
return S_FALSE;
+ */
- if (!m_IsSolid || !TablesRead)
+ if (!_isSolid || !TablesRead)
{
bool keepDecompressing;
RINOK(ReadTables(keepDecompressing));
if (!keepDecompressing)
+ {
+ _solidAllowed = true;
return S_OK;
+ }
}
for (;;)
@@ -878,6 +883,9 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
if (!keepDecompressing)
break;
}
+
+ _solidAllowed = true;
+
RINOK(WriteBuf());
UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize();
RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize));
@@ -898,6 +906,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
if (!inSize)
return E_INVALIDARG;
+ if (_isSolid && !_solidAllowed)
+ return S_FALSE;
+ _solidAllowed = false;
+
if (!_vmData)
{
_vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax);
@@ -926,8 +938,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
_unpackSize = outSize ? *outSize : (UInt64)(Int64)-1;
return CodeReal(progress);
}
- catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; }
- catch(...) { _errorMode = true; return S_FALSE; }
+ catch(const CInBufferException &e) { /* _errorMode = true; */ return e.ErrorCode; }
+ catch(...) { /* _errorMode = true; */ return S_FALSE; }
// CNewException is possible here. But probably CNewException is caused
// by error in data stream.
}
@@ -936,7 +948,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
{
if (size < 1)
return E_INVALIDARG;
- m_IsSolid = ((data[0] & 1) != 0);
+ _isSolid = ((data[0] & 1) != 0);
return S_OK;
}
diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h
index f3c1528c..fbc5ac2e 100644
--- a/CPP/7zip/Compress/Rar3Decoder.h
+++ b/CPP/7zip/Compress/Rar3Decoder.h
@@ -191,8 +191,9 @@ class CDecoder:
CRecordVector<CTempFilter *> _tempFilters;
UInt32 _lastFilter;
- bool m_IsSolid;
- bool _errorMode;
+ bool _isSolid;
+ bool _solidAllowed;
+ // bool _errorMode;
bool _lzMode;
bool _unsupportedFilter;
diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp
index e6c3e467..d7c68e21 100644
--- a/CPP/7zip/Compress/Rar5Decoder.cpp
+++ b/CPP/7zip/Compress/Rar5Decoder.cpp
@@ -72,6 +72,7 @@ CDecoder::CDecoder():
_writtenFileSize(0),
_dictSizeLog(0),
_isSolid(false),
+ _solidAllowed(false),
_wasInit(false),
_inputBuf(NULL)
{
@@ -334,58 +335,63 @@ HRESULT CDecoder::ReadTables(CBitDecoder &_bitStream)
{
if (_progress)
{
- UInt64 packSize = _bitStream.GetProcessedSize();
+ const UInt64 packSize = _bitStream.GetProcessedSize();
RINOK(_progress->SetRatioInfo(&packSize, &_writtenFileSize));
}
_bitStream.AlignToByte();
_bitStream.Prepare();
- unsigned flags = _bitStream.ReadByteInAligned();
- unsigned checkSum = _bitStream.ReadByteInAligned();
- checkSum ^= flags;
-
- UInt32 blockSize;
{
+ unsigned flags = _bitStream.ReadByteInAligned();
+ unsigned checkSum = _bitStream.ReadByteInAligned();
+ checkSum ^= flags;
unsigned num = (flags >> 3) & 3;
if (num == 3)
return S_FALSE;
- blockSize = _bitStream.ReadByteInAligned();
- if (num > 0)
+ UInt32 blockSize = _bitStream.ReadByteInAligned();
+ checkSum ^= blockSize;
+
+ if (num != 0)
{
- blockSize += (UInt32)_bitStream.ReadByteInAligned() << 8;
+ unsigned b = _bitStream.ReadByteInAligned();
+ checkSum ^= b;
+ blockSize += (UInt32)b << 8;
if (num > 1)
- blockSize += (UInt32)_bitStream.ReadByteInAligned() << 16;
+ {
+ b = _bitStream.ReadByteInAligned();
+ checkSum ^= b;
+ blockSize += (UInt32)b << 16;
+ }
}
- }
-
- checkSum ^= blockSize ^ (blockSize >> 8) ^ (blockSize >> 16);
- if ((Byte)checkSum != 0x5A)
- return S_FALSE;
-
- unsigned blockSizeBits7 = (flags & 7) + 1;
-
- if (blockSize == 0 && blockSizeBits7 != 8)
- return S_FALSE;
-
- blockSize += (blockSizeBits7 >> 3);
- blockSize--;
-
- _bitStream._blockEndBits7 = (Byte)(blockSizeBits7 & 7);
- _bitStream._blockEnd = _bitStream.GetProcessedSize_Round() + blockSize;
-
- _bitStream.SetCheck2();
-
- _isLastBlock = ((flags & 0x40) != 0);
+
+ if (checkSum != 0x5A)
+ return S_FALSE;
- if ((flags & 0x80) == 0)
- {
- if (!_tableWasFilled && blockSize != 0)
+ unsigned blockSizeBits7 = (flags & 7) + 1;
+ blockSize += (blockSizeBits7 >> 3);
+ if (blockSize == 0)
return S_FALSE;
- return S_OK;
- }
+ blockSize--;
+ blockSizeBits7 &= 7;
- _tableWasFilled = false;
+ _bitStream._blockEndBits7 = (Byte)blockSizeBits7;
+ _bitStream._blockEnd = _bitStream.GetProcessedSize_Round() + blockSize;
+
+ _bitStream.SetCheck2();
+
+ _isLastBlock = ((flags & 0x40) != 0);
+
+ if ((flags & 0x80) == 0)
+ {
+ if (!_tableWasFilled)
+ if (blockSize != 0 || blockSizeBits7 != 0)
+ return S_FALSE;
+ return S_OK;
+ }
+
+ _tableWasFilled = false;
+ }
{
Byte lens2[kLevelTableSize];
@@ -596,6 +602,10 @@ HRESULT CDecoder::DecodeLZ()
}
}
}
+
+ // that check is not required, but it can help, if there is BUG in another code
+ if (!_tableWasFilled)
+ break; // return S_FALSE;
}
UInt32 sym = m_MainDecoder.Decode(&_bitStream);
@@ -797,7 +807,10 @@ HRESULT CDecoder::CodeReal()
*/
if (res == S_OK)
+ {
+ _solidAllowed = true;
res = res2;
+ }
if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize)
return S_FALSE;
@@ -817,6 +830,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
{
try
{
+ if (_isSolid && !_solidAllowed)
+ return S_FALSE;
+ _solidAllowed = false;
+
if (_dictSizeLog >= sizeof(size_t) * 8)
return E_NOTIMPL;
diff --git a/CPP/7zip/Compress/Rar5Decoder.h b/CPP/7zip/Compress/Rar5Decoder.h
index c37cb0e0..8174c4af 100644
--- a/CPP/7zip/Compress/Rar5Decoder.h
+++ b/CPP/7zip/Compress/Rar5Decoder.h
@@ -127,7 +127,7 @@ public:
return *_buf++;
}
- UInt32 GetValue(unsigned numBits)
+ UInt32 GetValue(unsigned numBits) const
{
UInt32 v = ((UInt32)_buf[0] << 16) | ((UInt32)_buf[1] << 8) | (UInt32)_buf[2];
v >>= (24 - numBits - _bitPos);
@@ -218,6 +218,13 @@ class CDecoder:
bool _unsupportedFilter;
bool _lzError;
bool _writeError;
+
+ bool _isSolid;
+ bool _solidAllowed;
+ bool _tableWasFilled;
+ bool _wasInit;
+
+ Byte _dictSizeLog;
// CBitDecoder _bitStream;
Byte *_window;
@@ -238,11 +245,6 @@ class CDecoder:
UInt64 _writtenFileSize;
size_t _winSizeAllocated;
- Byte _dictSizeLog;
- bool _tableWasFilled;
- bool _isSolid;
- bool _wasInit;
-
UInt32 _reps[kNumReps];
UInt32 _lastLen;
diff --git a/CPP/7zip/Crypto/Rar5Aes.cpp b/CPP/7zip/Crypto/Rar5Aes.cpp
index dc1f4ce6..005fa6bc 100644
--- a/CPP/7zip/Crypto/Rar5Aes.cpp
+++ b/CPP/7zip/Crypto/Rar5Aes.cpp
@@ -30,14 +30,13 @@ CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {}
static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val)
{
- unsigned i;
*val = 0;
- for (i = 0; i < maxSize;)
+ for (unsigned i = 0; i < maxSize && i < 10;)
{
Byte b = p[i];
- if (i < 10)
- *val |= (UInt64)(b & 0x7F) << (7 * i++);
+ *val |= (UInt64)(b & 0x7F) << (7 * i);
+ i++;
if ((b & 0x80) == 0)
return i;
}
diff --git a/CPP/7zip/GuiCommon.rc b/CPP/7zip/GuiCommon.rc
index 6b26ddd8..b67409b9 100644
--- a/CPP/7zip/GuiCommon.rc
+++ b/CPP/7zip/GuiCommon.rc
@@ -71,6 +71,9 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
DEFPUSHBUTTON "OK", IDOK, bx2, by, bxs, bys \
PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
+#define MY_BUTTON__CLOSE \
+ DEFPUSHBUTTON "&Close", IDCLOSE, bx1, by, bxs, bys
+
#define MY_COMBO CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
#define MY_COMBO_SORTED MY_COMBO | CBS_SORT
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
index 56f4fbd8..c0a7bcd0 100644
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -8,9 +8,17 @@
#ifndef UNDER_CE
#include <io.h>
#endif
+#else
+// for isatty()
+#include <unistd.h>
#endif
+
#include <stdio.h>
+#ifdef _7ZIP_LARGE_PAGES
+#include "../../../../C/Alloc.h"
+#endif
+
#include "../../../Common/ListFileUtils.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
@@ -19,18 +27,20 @@
#include "../../../Windows/FileName.h"
#ifdef _WIN32
#include "../../../Windows/FileMapping.h"
+#include "../../../Windows/MemoryLock.h"
#include "../../../Windows/Synchronization.h"
#endif
#include "ArchiveCommandLine.h"
#include "EnumDirItems.h"
-#include "SortUtils.h"
#include "Update.h"
#include "UpdateAction.h"
extern bool g_CaseSensitive;
extern bool g_PathTrailReplaceMode;
+bool g_LargePagesMode = false;
+
#ifdef UNDER_CE
#define MY_IS_TERMINAL(x) false;
@@ -60,15 +70,6 @@ static bool StringToUInt32(const wchar_t *s, UInt32 &v)
return *end == 0;
}
-CArcCmdLineException::CArcCmdLineException(const char *a, const wchar_t *u)
-{
- (*this) += a;
- if (u)
- {
- Add_LF();
- (*this) += u;
- }
-}
int g_CodePage = -1;
@@ -240,7 +241,7 @@ static const CSwitchForm kSwitchForms[] =
{ "si", NSwitchType::kString },
{ "so" },
- { "slp", NSwitchType::kMinus },
+ { "slp", NSwitchType::kString },
{ "scs", NSwitchType::kString },
{ "scc", NSwitchType::kString },
{ "slt" },
@@ -282,7 +283,6 @@ static const char * const kIncorrectListFile = "Incorrect item in listfile.\nChe
static const char * const kTerminalOutError = "I won't write compressed data to a terminal";
static const char * const kSameTerminalError = "I won't write data and program's messages to same stream";
static const char * const kEmptyFilePath = "Empty file path";
-static const char * const kCannotFindArchive = "Cannot find archive";
bool CArcCommand::IsFromExtractGroup() const
{
@@ -615,84 +615,6 @@ static void AddSwitchWildcardsToCensor(
throw CArcCmdLineException(errorMessage, strings[i]);
}
-#ifdef _WIN32
-
-// This code converts all short file names to long file names.
-
-static void ConvertToLongName(const UString &prefix, UString &name)
-{
- if (name.IsEmpty() || DoesNameContainWildcard(name))
- return;
- NFind::CFileInfo fi;
- const FString path (us2fs(prefix + name));
- #ifndef UNDER_CE
- if (NFile::NName::IsDevicePath(path))
- return;
- #endif
- if (fi.Find(path))
- name = fs2us(fi.Name);
-}
-
-static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
-{
- FOR_VECTOR (i, items)
- {
- NWildcard::CItem &item = items[i];
- if (item.Recursive || item.PathParts.Size() != 1)
- continue;
- if (prefix.IsEmpty() && item.IsDriveItem())
- continue;
- ConvertToLongName(prefix, item.PathParts.Front());
- }
-}
-
-static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
-{
- ConvertToLongNames(prefix, node.IncludeItems);
- ConvertToLongNames(prefix, node.ExcludeItems);
- unsigned i;
- for (i = 0; i < node.SubNodes.Size(); i++)
- {
- UString &name = node.SubNodes[i].Name;
- if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name))
- continue;
- ConvertToLongName(prefix, name);
- }
- // mix folders with same name
- for (i = 0; i < node.SubNodes.Size(); i++)
- {
- NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
- for (unsigned j = i + 1; j < node.SubNodes.Size();)
- {
- const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
- if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name))
- {
- nextNode1.IncludeItems += nextNode2.IncludeItems;
- nextNode1.ExcludeItems += nextNode2.ExcludeItems;
- node.SubNodes.Delete(j);
- }
- else
- j++;
- }
- }
- for (i = 0; i < node.SubNodes.Size(); i++)
- {
- NWildcard::CCensorNode &nextNode = node.SubNodes[i];
- ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode);
- }
-}
-
-void ConvertToLongNames(NWildcard::CCensor &censor)
-{
- FOR_VECTOR (i, censor.Pairs)
- {
- NWildcard::CPair &pair = censor.Pairs[i];
- ConvertToLongNames(pair.Prefix, pair.Head);
- }
-}
-
-#endif
-
/*
static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
{
@@ -922,9 +844,45 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
options.CaseSensitive = g_CaseSensitive;
}
- options.LargePages = false;
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ NSecurity::EnablePrivilege_SymLink();
+ #endif
+
+ // options.LargePages = false;
+
if (parser[NKey::kLargePages].ThereIs)
- options.LargePages = !parser[NKey::kLargePages].WithMinus;
+ {
+ unsigned slp = 0;
+ const UString &s = parser[NKey::kLargePages].PostStrings[0];
+ if (s.IsEmpty())
+ slp = 1;
+ else if (s != L"-")
+ {
+ if (!StringToUInt32(s, slp))
+ throw CArcCmdLineException("Unsupported switch postfix for -slp", s);
+ }
+
+ #ifdef _7ZIP_LARGE_PAGES
+ if (slp >
+ #ifndef UNDER_CE
+ (unsigned)NSecurity::Get_LargePages_RiskLevel()
+ #else
+ 0
+ #endif
+ )
+ {
+ SetLargePageSize();
+ // note: this process also can inherit that Privilege from parent process
+ g_LargePagesMode =
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ NSecurity::EnablePrivilege_LockMemory();
+ #else
+ true;
+ #endif
+ }
+ #endif
+ }
#ifndef UNDER_CE
@@ -996,64 +954,6 @@ static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned key
}
}
-HRESULT EnumerateDirItemsAndSort(
- NWildcard::CCensor &censor,
- NWildcard::ECensorPathMode censorPathMode,
- const UString &addPathPrefix,
- UStringVector &sortedPaths,
- UStringVector &sortedFullPaths,
- CDirItemsStat &st,
- IDirItemsCallback *callback)
-{
- FStringVector paths;
-
- {
- CDirItems dirItems;
- dirItems.Callback = callback;
- {
- HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems);
- st = dirItems.Stat;
- RINOK(res);
- }
-
- FOR_VECTOR (i, dirItems.Items)
- {
- const CDirItem &dirItem = dirItems.Items[i];
- if (!dirItem.IsDir())
- paths.Add(dirItems.GetPhyPath(i));
- }
- }
-
- if (paths.Size() == 0)
- throw CArcCmdLineException(kCannotFindArchive);
-
- UStringVector fullPaths;
-
- unsigned i;
-
- for (i = 0; i < paths.Size(); i++)
- {
- FString fullPath;
- NFile::NDir::MyGetFullPathName(paths[i], fullPath);
- fullPaths.Add(fs2us(fullPath));
- }
-
- CUIntVector indices;
- SortFileNames(fullPaths, indices);
- sortedPaths.ClearAndReserve(indices.Size());
- sortedFullPaths.ClearAndReserve(indices.Size());
-
- for (i = 0; i < indices.Size(); i++)
- {
- unsigned index = indices[i];
- sortedPaths.AddInReserved(fs2us(paths[index]));
- sortedFullPaths.AddInReserved(fullPaths[index]);
- if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0)
- throw CArcCmdLineException("Duplicate archive path:", sortedFullPaths[i]);
- }
-
- return S_OK;
-}
static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp)
{
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h
index 1c96601a..9ed0825f 100644
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.h
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h
@@ -6,14 +6,13 @@
#include "../../../Common/CommandLineParser.h"
#include "../../../Common/Wildcard.h"
+#include "EnumDirItems.h"
+
#include "Extract.h"
#include "HashCalc.h"
#include "Update.h"
-struct CArcCmdLineException: public UString
-{
- CArcCmdLineException(const char *a, const wchar_t *u = NULL);
-};
+typedef CMessagePathException CArcCmdLineException;
namespace NCommandType { enum EEnum
{
@@ -51,7 +50,7 @@ struct CArcCmdLineOptions
{
bool HelpMode;
- bool LargePages;
+ // bool LargePages;
bool CaseSensitiveChange;
bool CaseSensitive;
@@ -110,7 +109,7 @@ struct CArcCmdLineOptions
UInt32 NumIterations;
CArcCmdLineOptions():
- LargePages(false),
+ // LargePages(false),
CaseSensitiveChange(false),
CaseSensitive(false),
@@ -134,13 +133,4 @@ public:
void Parse2(CArcCmdLineOptions &options);
};
-HRESULT EnumerateDirItemsAndSort(
- NWildcard::CCensor &censor,
- NWildcard::ECensorPathMode pathMode,
- const UString &addPathPrefix,
- UStringVector &sortedPaths,
- UStringVector &sortedFullPaths,
- CDirItemsStat &st,
- IDirItemsCallback *callback);
-
#endif
diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp
index e4ac64ec..e86db15d 100644
--- a/CPP/7zip/UI/Common/Bench.cpp
+++ b/CPP/7zip/UI/Common/Bench.cpp
@@ -2602,7 +2602,8 @@ static void SysInfo_To_String(AString &s, const SYSTEM_INFO &si)
PrintHex(s, si.wProcessorLevel);
s += ".";
PrintHex(s, si.wProcessorRevision);
- if (si.dwActiveProcessorMask + 1 != ((UInt64)1 << si.dwNumberOfProcessors))
+ if ((UInt64)si.dwActiveProcessorMask + 1 != ((UInt64)1 << si.dwNumberOfProcessors))
+ if ((UInt64)si.dwActiveProcessorMask + 1 != 0 || si.dwNumberOfProcessors != sizeof(UInt64) * 8)
{
s += " act:";
PrintHex(s, si.dwActiveProcessorMask);
@@ -2686,13 +2687,15 @@ void GetCpuName(AString &s)
AString s2;
x86cpuid_to_String(cpuid, s2);
s += s2;
- return;
}
+ else
+ {
#ifdef MY_CPU_AMD64
s += "x64";
#else
s += "x86";
#endif
+ }
}
#else
@@ -2703,6 +2706,9 @@ void GetCpuName(AString &s)
#endif
#endif
+
+ if (g_LargePagesMode)
+ s += " (LP)";
}
@@ -2725,6 +2731,27 @@ void GetCpuFeatures(AString &s)
}
+#ifdef _WIN32
+#ifndef UNDER_CE
+
+typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *);
+
+static BOOL My_RtlGetVersion(OSVERSIONINFOEXW *vi)
+{
+ HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll");
+ if (!ntdll)
+ return FALSE;
+ Func_RtlGetVersion func = (Func_RtlGetVersion)GetProcAddress(ntdll, "RtlGetVersion");
+ if (!func)
+ return FALSE;
+ func(vi);
+ return TRUE;
+}
+
+#endif
+#endif
+
+
HRESULT Bench(
DECL_EXTERNAL_CODECS_LOC_VARS
IBenchPrintCallback *printCallback,
@@ -2859,6 +2886,30 @@ HRESULT Bench(
if (printCallback)
{
+ #ifdef _WIN32
+ #ifndef UNDER_CE
+ {
+ AString s;
+ // OSVERSIONINFO vi;
+ OSVERSIONINFOEXW vi;
+ vi.dwOSVersionInfoSize = sizeof(vi);
+ // if (::GetVersionEx(&vi))
+ if (My_RtlGetVersion(&vi))
+ {
+ s += "Windows";
+ if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ s.Add_UInt32(vi.dwPlatformId);
+ s += " "; s.Add_UInt32(vi.dwMajorVersion);
+ s += "."; s.Add_UInt32(vi.dwMinorVersion);
+ s += " "; s.Add_UInt32(vi.dwBuildNumber);
+ // s += " "; s += GetAnsiString(vi.szCSDVersion);
+ }
+ printCallback->Print(s);
+ printCallback->NewLine();
+ }
+ #endif
+ #endif
+
{
AString s1, s2;
GetSysInfo(s1, s2);
diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp
index c9aa5fdf..42cb0d23 100644
--- a/CPP/7zip/UI/Common/CompressCall.cpp
+++ b/CPP/7zip/UI/Common/CompressCall.cpp
@@ -13,6 +13,7 @@
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileMapping.h"
+#include "../../../Windows/MemoryLock.h"
#include "../../../Windows/ProcessUtils.h"
#include "../../../Windows/Synchronization.h"
@@ -94,6 +95,9 @@ static HRESULT Call7zGui(const UString &params,
static void AddLagePagesSwitch(UString &params)
{
if (ReadLockMemoryEnable())
+ #ifndef UNDER_CE
+ if (NSecurity::Get_LargePages_RiskLevel() == 0)
+ #endif
params += " -slp";
}
diff --git a/CPP/7zip/UI/Common/CompressCall2.cpp b/CPP/7zip/UI/Common/CompressCall2.cpp
index fb67ed12..5bad774b 100644
--- a/CPP/7zip/UI/Common/CompressCall2.cpp
+++ b/CPP/7zip/UI/Common/CompressCall2.cpp
@@ -1,10 +1,10 @@
-// CompressCall.cpp
+// CompressCall2.cpp
#include "StdAfx.h"
#include "../../../Common/MyException.h"
-#include "../../UI/common/ArchiveCommandLine.h"
+#include "../../UI/Common/EnumDirItems.h"
#include "../../UI/GUI/BenchmarkDialog.h"
#include "../../UI/GUI/ExtractGUI.h"
@@ -20,6 +20,7 @@ extern HWND g_HWND;
#define MY_TRY_BEGIN HRESULT result; try {
#define MY_TRY_FINISH } \
catch(CSystemException &e) { result = e.ErrorCode; } \
+ catch(UString &s) { ErrorMessage(s); result = E_FAIL; } \
catch(...) { result = E_FAIL; } \
if (result != S_OK && result != E_ABORT) \
ErrorMessageHRESULT(result);
diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp
index 0eee7443..0828dfbc 100644
--- a/CPP/7zip/UI/Common/EnumDirItems.cpp
+++ b/CPP/7zip/UI/Common/EnumDirItems.cpp
@@ -16,6 +16,7 @@
#endif
#include "EnumDirItems.h"
+#include "SortUtils.h"
using namespace NWindows;
using namespace NFile;
@@ -925,3 +926,161 @@ void CDirItems::FillFixedReparse()
}
#endif
+
+
+
+static const char * const kCannotFindArchive = "Cannot find archive";
+
+HRESULT EnumerateDirItemsAndSort(
+ NWildcard::CCensor &censor,
+ NWildcard::ECensorPathMode censorPathMode,
+ const UString &addPathPrefix,
+ UStringVector &sortedPaths,
+ UStringVector &sortedFullPaths,
+ CDirItemsStat &st,
+ IDirItemsCallback *callback)
+{
+ FStringVector paths;
+
+ {
+ CDirItems dirItems;
+ dirItems.Callback = callback;
+ {
+ HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems);
+ st = dirItems.Stat;
+ RINOK(res);
+ }
+
+ FOR_VECTOR (i, dirItems.Items)
+ {
+ const CDirItem &dirItem = dirItems.Items[i];
+ if (!dirItem.IsDir())
+ paths.Add(dirItems.GetPhyPath(i));
+ }
+ }
+
+ if (paths.Size() == 0)
+ {
+ // return S_OK;
+ throw CMessagePathException(kCannotFindArchive);
+ }
+
+ UStringVector fullPaths;
+
+ unsigned i;
+
+ for (i = 0; i < paths.Size(); i++)
+ {
+ FString fullPath;
+ NFile::NDir::MyGetFullPathName(paths[i], fullPath);
+ fullPaths.Add(fs2us(fullPath));
+ }
+
+ CUIntVector indices;
+ SortFileNames(fullPaths, indices);
+ sortedPaths.ClearAndReserve(indices.Size());
+ sortedFullPaths.ClearAndReserve(indices.Size());
+
+ for (i = 0; i < indices.Size(); i++)
+ {
+ unsigned index = indices[i];
+ sortedPaths.AddInReserved(fs2us(paths[index]));
+ sortedFullPaths.AddInReserved(fullPaths[index]);
+ if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0)
+ throw CMessagePathException("Duplicate archive path:", sortedFullPaths[i]);
+ }
+
+ return S_OK;
+}
+
+
+
+
+#ifdef _WIN32
+
+// This code converts all short file names to long file names.
+
+static void ConvertToLongName(const UString &prefix, UString &name)
+{
+ if (name.IsEmpty() || DoesNameContainWildcard(name))
+ return;
+ NFind::CFileInfo fi;
+ const FString path (us2fs(prefix + name));
+ #ifndef UNDER_CE
+ if (NFile::NName::IsDevicePath(path))
+ return;
+ #endif
+ if (fi.Find(path))
+ name = fs2us(fi.Name);
+}
+
+static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
+{
+ FOR_VECTOR (i, items)
+ {
+ NWildcard::CItem &item = items[i];
+ if (item.Recursive || item.PathParts.Size() != 1)
+ continue;
+ if (prefix.IsEmpty() && item.IsDriveItem())
+ continue;
+ ConvertToLongName(prefix, item.PathParts.Front());
+ }
+}
+
+static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
+{
+ ConvertToLongNames(prefix, node.IncludeItems);
+ ConvertToLongNames(prefix, node.ExcludeItems);
+ unsigned i;
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ {
+ UString &name = node.SubNodes[i].Name;
+ if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name))
+ continue;
+ ConvertToLongName(prefix, name);
+ }
+ // mix folders with same name
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ {
+ NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
+ for (unsigned j = i + 1; j < node.SubNodes.Size();)
+ {
+ const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
+ if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name))
+ {
+ nextNode1.IncludeItems += nextNode2.IncludeItems;
+ nextNode1.ExcludeItems += nextNode2.ExcludeItems;
+ node.SubNodes.Delete(j);
+ }
+ else
+ j++;
+ }
+ }
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ {
+ NWildcard::CCensorNode &nextNode = node.SubNodes[i];
+ ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode);
+ }
+}
+
+void ConvertToLongNames(NWildcard::CCensor &censor)
+{
+ FOR_VECTOR (i, censor.Pairs)
+ {
+ NWildcard::CPair &pair = censor.Pairs[i];
+ ConvertToLongNames(pair.Prefix, pair.Head);
+ }
+}
+
+#endif
+
+
+CMessagePathException::CMessagePathException(const char *a, const wchar_t *u)
+{
+ (*this) += a;
+ if (u)
+ {
+ Add_LF();
+ (*this) += u;
+ }
+}
diff --git a/CPP/7zip/UI/Common/EnumDirItems.h b/CPP/7zip/UI/Common/EnumDirItems.h
index 7afb800a..37ebed4c 100644
--- a/CPP/7zip/UI/Common/EnumDirItems.h
+++ b/CPP/7zip/UI/Common/EnumDirItems.h
@@ -18,4 +18,24 @@ HRESULT EnumerateItems(
const UString &addPathPrefix,
CDirItems &dirItems);
+
+struct CMessagePathException: public UString
+{
+ CMessagePathException(const char *a, const wchar_t *u = NULL);
+};
+
+
+HRESULT EnumerateDirItemsAndSort(
+ NWildcard::CCensor &censor,
+ NWildcard::ECensorPathMode pathMode,
+ const UString &addPathPrefix,
+ UStringVector &sortedPaths,
+ UStringVector &sortedFullPaths,
+ CDirItemsStat &st,
+ IDirItemsCallback *callback);
+
+#ifdef _WIN32
+void ConvertToLongNames(NWildcard::CCensor &censor);
+#endif
+
#endif
diff --git a/CPP/7zip/UI/Common/HashCalc.h b/CPP/7zip/UI/Common/HashCalc.h
index 38908e2e..3b4ec30d 100644
--- a/CPP/7zip/UI/Common/HashCalc.h
+++ b/CPP/7zip/UI/Common/HashCalc.h
@@ -9,7 +9,6 @@
#include "../../Common/MethodProps.h"
#include "DirItem.h"
-#include "Property.h"
const unsigned k_HashCalc_DigestSize_Max = 64;
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
index b9b4abd9..11d512ae 100644
--- a/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -992,7 +992,7 @@ static void MakeCheckOrder(CCodecs *codecs,
int index = orderIndices[i];
if (index < 0)
continue;
- const CArcInfoEx &ai = codecs->Formats[index];
+ const CArcInfoEx &ai = codecs->Formats[(unsigned)index];
if (ai.SignatureOffset != 0)
{
orderIndices2.Add(index);
@@ -2295,7 +2295,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
int index = orderIndices[i];
if (index < 0)
continue;
- const CArcInfoEx &ai = op.codecs->Formats[index];
+ const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index];
bool isDifficult = false;
// if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31)
if (!ai.NewInterface)
@@ -2327,7 +2327,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (isDifficult)
{
difficultFormats.Add(index);
- difficultBools[index] = true;
+ difficultBools[(unsigned)index] = true;
}
}
diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp
index 8a194840..7702e222 100644
--- a/CPP/7zip/UI/Common/PropIDUtils.cpp
+++ b/CPP/7zip/UI/Common/PropIDUtils.cpp
@@ -369,7 +369,7 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
int index = FindPairIndex(sid_32_Names, ARRAY_SIZE(sid_32_Names), v1);
if (index >= 0)
{
- s += sid_32_Names[index].sz;
+ s += sid_32_Names[(unsigned)index].sz;
return;
}
}
@@ -379,7 +379,7 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
int index = FindPairIndex(sid_21_Names, ARRAY_SIZE(sid_21_Names), v4);
if (index >= 0)
{
- s += sid_21_Names[index].sz;
+ s += sid_21_Names[(unsigned)index].sz;
return;
}
}
@@ -630,7 +630,7 @@ bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
{
int index = FindPairIndex(k_ReparseTags, ARRAY_SIZE(k_ReparseTags), tag);
if (index >= 0)
- s += k_ReparseTags[index].sz;
+ s += k_ReparseTags[(unsigned)index].sz;
else
{
s += "REPARSE:";
diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp
index 5d3c4484..081d38eb 100644
--- a/CPP/7zip/UI/Common/Update.cpp
+++ b/CPP/7zip/UI/Common/Update.cpp
@@ -1046,10 +1046,6 @@ static HRESULT EnumerateInArchiveItems(
#endif
-#ifdef _WIN32
-void ConvertToLongNames(NWildcard::CCensor &censor);
-#endif
-
HRESULT UpdateArchive(
CCodecs *codecs,
const CObjectVector<COpenType> &types,
diff --git a/CPP/7zip/UI/Console/Console.manifest b/CPP/7zip/UI/Console/Console.manifest
new file mode 100644
index 00000000..58b68ced
--- /dev/null
+++ b/CPP/7zip/UI/Console/Console.manifest
@@ -0,0 +1,13 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7z" type="win32"></assemblyIdentity>
+<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+<security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false">
+</requestedExecutionLevel></requestedPrivileges></security></trustInfo>
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
+<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+</application></compatibility>
+</assembly> \ No newline at end of file
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
index 897a2757..21c2f071 100644
--- a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
@@ -60,8 +60,9 @@ HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError)
if (_se)
{
- *_se << endl << kError << NError::MyFormatMessage(systemError) << endl <<
- fs2us(path) << endl << endl;
+ *_se << endl << kError << NError::MyFormatMessage(systemError) << endl;
+ _se->NormalizePrint_UString(fs2us(path));
+ *_se << endl << endl;
_se->Flush();
}
return HRESULT_FROM_WIN32(systemError);
@@ -251,7 +252,9 @@ static const char * const kTab = " ";
static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size)
{
- *_so << kTab << "Path: " << path << endl;
+ *_so << kTab << "Path: ";
+ _so->NormalizePrint_wstr(path);
+ *_so << endl;
if (size && *size != (UInt64)(Int64)-1)
{
AString s;
@@ -340,7 +343,10 @@ STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3
_tempU.Empty();
if (name)
+ {
_tempU = name;
+ _so->Normalize_UString(_tempU);
+ }
_so->PrintUString(_tempU, _tempA);
if (position)
*_so << " <" << *position << ">";
@@ -461,7 +467,10 @@ STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encr
*_se << s;
if (!_currentName.IsEmpty())
- *_se << " : " << _currentName;
+ {
+ *_se << " : ";
+ _se->NormalizePrint_UString(_currentName);
+ }
*_se << endl;
_se->Flush();
}
@@ -513,7 +522,11 @@ HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode)
ClosePercents_for_so();
if (_so)
- *_so << endl << (testMode ? kTesting : kExtracting) << name << endl;
+ {
+ *_so << endl << (testMode ? kTesting : kExtracting);
+ _so->NormalizePrint_wstr(name);
+ *_so << endl;
+ }
if (NeedPercents())
_percent.Command = "Open";
@@ -573,8 +586,9 @@ void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, c
{
const CArcErrorInfo &er = arc.ErrorInfo;
- UString s ("WARNING:\n");
- s += arc.Path;
+ *_so << "WARNING:\n";
+ _so->NormalizePrint_UString(arc.Path);
+ UString s;
if (arc.FormatIndex == er.ErrorFormatIndex)
{
s.Add_LF();
@@ -619,7 +633,10 @@ HRESULT CExtractCallbackConsole::OpenResult(
{
*_se << endl;
if (level != 0)
- *_se << arc.Path << endl;
+ {
+ _se->NormalizePrint_UString(arc.Path);
+ *_se << endl;
+ }
}
if (errorFlags != 0)
@@ -653,7 +670,10 @@ HRESULT CExtractCallbackConsole::OpenResult(
{
*_so << endl;
if (level != 0)
- *_so << arc.Path << endl;
+ {
+ _so->NormalizePrint_UString(arc.Path);
+ *_so << endl;
+ }
}
if (warningFlags != 0)
@@ -708,7 +728,9 @@ HRESULT CExtractCallbackConsole::OpenResult(
_so->Flush();
if (_se)
{
- *_se << kError << name << endl;
+ *_se << kError;
+ _se->NormalizePrint_wstr(name);
+ *_se << endl;
HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink);
RINOK(res);
if (result == S_FALSE)
diff --git a/CPP/7zip/UI/Console/HashCon.cpp b/CPP/7zip/UI/Console/HashCon.cpp
index 8ff90753..ab80ce37 100644
--- a/CPP/7zip/UI/Console/HashCon.cpp
+++ b/CPP/7zip/UI/Console/HashCon.cpp
@@ -269,7 +269,7 @@ HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBun
if (_fileName.IsEmpty())
*_so << kEmptyFileAlias;
else
- *_so << _fileName;
+ _so->NormalizePrint_UString(_fileName);
}
*_so << endl;
}
diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp
index 57d1d1bc..38e23e21 100644
--- a/CPP/7zip/UI/Console/List.cpp
+++ b/CPP/7zip/UI/Console/List.cpp
@@ -560,7 +560,7 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
{
if (!techMode)
g_StdOut << temp;
- g_StdOut.PrintUString(FilePath, TempAString);
+ g_StdOut.NormalizePrint_UString(FilePath, TempWString, TempAString);
if (techMode)
g_StdOut << MY_ENDL;
continue;
@@ -671,9 +671,10 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
else if (prop.vt == VT_BSTR)
{
TempWString.SetFromBstr(prop.bstrVal);
+ // do we need multi-line support here ?
+ g_StdOut.Normalize_UString(TempWString);
if (techMode)
{
- // replace CR/LF here.
g_StdOut.PrintUString(TempWString, TempAString);
}
else
@@ -815,9 +816,63 @@ static void PrintPropNameAndNumber_Signed(CStdOutStream &so, PROPID propID, Int6
so << val << endl;
}
-static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val)
+
+static void UString_Replace_CRLF_to_LF(UString &s)
+{
+ // s.Replace(L"\r\n", L"\n");
+ wchar_t *src = s.GetBuf();
+ wchar_t *dest = src;
+ for (;;)
+ {
+ wchar_t c = *src++;
+ if (c == 0)
+ break;
+ if (c == '\r' && *src == '\n')
+ {
+ src++;
+ c = '\n';
+ }
+ *dest++ = c;
+ }
+ s.ReleaseBuf_SetEnd((unsigned)(dest - s.GetBuf()));
+}
+
+
+static void PrintPropVal_MultiLine(CStdOutStream &so, const wchar_t *val)
{
- so << name << " = " << val << endl;
+ UString s = val;
+ if (s.Find(L'\n') >= 0)
+ {
+ so << endl;
+ so << "{";
+ so << endl;
+ UString_Replace_CRLF_to_LF(s);
+ so.Normalize_UString__LF_Allowed(s);
+ so << s;
+ so << endl;
+ so << "}";
+ }
+ else
+ {
+ so.Normalize_UString(s);
+ so << s;
+ }
+ so << endl;
+}
+
+
+static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val, bool multiLine)
+{
+ so << name << " = ";
+ if (multiLine)
+ {
+ PrintPropVal_MultiLine(so, val);
+ return;
+ }
+ UString s = val;
+ so.Normalize_UString(s);
+ so << s;
+ so << endl;
}
@@ -831,9 +886,11 @@ static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *
UString nameU;
GetPropName(propID, name, nameA, nameU);
if (!nameA.IsEmpty())
- PrintPropPair(so, nameA, s);
+ so << nameA;
else
- so << nameU << " = " << s << endl;
+ so << nameU;
+ so << " = ";
+ PrintPropVal_MultiLine(so, s);
}
}
@@ -862,11 +919,11 @@ static void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er)
{
PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags());
if (!er.ErrorMessage.IsEmpty())
- PrintPropPair(so, "ERROR", er.ErrorMessage);
+ PrintPropPair(so, "ERROR", er.ErrorMessage, true);
PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags());
if (!er.WarningMessage.IsEmpty())
- PrintPropPair(so, "WARNING", er.WarningMessage);
+ PrintPropPair(so, "WARNING", er.WarningMessage, true);
}
HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink)
@@ -877,7 +934,7 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const
const CArcErrorInfo &er = arc.ErrorInfo;
so << "--\n";
- PrintPropPair(so, "Path", arc.Path);
+ PrintPropPair(so, "Path", arc.Path, false);
if (er.ErrorFormatIndex >= 0)
{
if (er.ErrorFormatIndex == arc.FormatIndex)
@@ -885,7 +942,7 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const
else
PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true);
}
- PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex));
+ PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex), false);
ErrorInfo_Print(so, er);
@@ -943,7 +1000,8 @@ HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const
{
if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
{
- so << arcLink.NonOpen_ArcPath << endl;
+ so.NormalizePrint_UString(arcLink.NonOpen_ArcPath);
+ so << endl;
PrintArcTypeError(so, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
}
else
@@ -1014,15 +1072,18 @@ HRESULT ListArchives(CCodecs *codecs,
errorCode = ERROR_FILE_NOT_FOUND;
lastError = HRESULT_FROM_WIN32(lastError);;
g_StdOut.Flush();
- *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) <<
- endl << arcPath << endl << endl;
+ *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl;
+ g_ErrStream->NormalizePrint_UString(arcPath);
+ *g_ErrStream << endl << endl;
numErrors++;
continue;
}
if (fi.IsDir())
{
g_StdOut.Flush();
- *g_ErrStream << endl << kError << arcPath << " is not a file" << endl << endl;
+ *g_ErrStream << endl << kError;
+ g_ErrStream->NormalizePrint_UString(arcPath);
+ *g_ErrStream << " is not a file" << endl << endl;
numErrors++;
continue;
}
@@ -1061,7 +1122,9 @@ HRESULT ListArchives(CCodecs *codecs,
if (enableHeaders)
{
- g_StdOut << endl << kListing << arcPath << endl << endl;
+ g_StdOut << endl << kListing;
+ g_StdOut.NormalizePrint_UString(arcPath);
+ g_StdOut << endl << endl;
}
HRESULT result = arcLink.Open_Strict(options, &openCallback);
@@ -1071,7 +1134,9 @@ HRESULT ListArchives(CCodecs *codecs,
if (result == E_ABORT)
return result;
g_StdOut.Flush();
- *g_ErrStream << endl << kError << arcPath << " : ";
+ *g_ErrStream << endl << kError;
+ g_ErrStream->NormalizePrint_UString(arcPath);
+ *g_ErrStream << " : ";
if (result == S_FALSE)
{
Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink);
@@ -1255,7 +1320,7 @@ HRESULT ListArchives(CCodecs *codecs,
if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
{
g_StdOut << "----------\n";
- PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath);
+ PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath, false);
PrintArcTypeError(g_StdOut, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
}
}
diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp
index 436a6cd1..a632c1b4 100644
--- a/CPP/7zip/UI/Console/Main.cpp
+++ b/CPP/7zip/UI/Console/Main.cpp
@@ -10,10 +10,6 @@
#include "../../../../C/CpuArch.h"
-#if defined( _7ZIP_LARGE_PAGES)
-#include "../../../../C/Alloc.h"
-#endif
-
#include "../../../Common/MyInitGuid.h"
#include "../../../Common/CommandLineParser.h"
@@ -25,10 +21,6 @@
#include "../../../Windows/ErrorMsg.h"
-#ifdef _WIN32
-#include "../../../Windows/MemoryLock.h"
-#endif
-
#include "../../../Windows/TimeUtils.h"
#include "../Common/ArchiveCommandLine.h"
@@ -64,7 +56,7 @@ using namespace NCommandLineParser;
HINSTANCE g_hInstance = 0;
#endif
-bool g_LargePagesMode = false;
+extern bool g_LargePagesMode;
extern CStdOutStream *g_StdStream;
extern CStdOutStream *g_ErrStream;
@@ -244,7 +236,8 @@ static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so)
{
FOR_VECTOR(i, pc.Paths)
{
- so << pc.Paths[i] << " : ";
+ so.NormalizePrint_UString(pc.Paths[i]);
+ so << " : ";
so << NError::MyFormatMessage(pc.Codes[i]) << endl;
}
so << "----------------" << endl;
@@ -383,6 +376,8 @@ static void PrintMemUsage(const char *s, UInt64 val)
*g_StdStream << " " << s << " Memory =";
PrintNum(SHIFT_SIZE_VALUE(val, 20), 7);
*g_StdStream << " MB";
+ if (g_LargePagesMode)
+ *g_StdStream << " (LP)";
}
EXTERN_C_BEGIN
@@ -524,6 +519,8 @@ int Main2(
parser.Parse1(commandStrings, options);
+ g_StdOut.IsTerminalMode = options.IsStdOutTerminal;
+ g_StdErr.IsTerminalMode = options.IsStdErrTerminal;
if (options.Number_for_Out != k_OutStream_stdout)
g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL);
@@ -541,24 +538,6 @@ int Main2(
return 0;
}
- #if defined(_WIN32) && !defined(UNDER_CE)
- NSecurity::EnablePrivilege_SymLink();
- #endif
-
- #ifdef _7ZIP_LARGE_PAGES
- if (options.LargePages)
- {
- SetLargePageSize();
- // note: this process also can inherit that Privilege from parent process
- g_LargePagesMode =
- #if defined(_WIN32) && !defined(UNDER_CE)
- NSecurity::EnablePrivilege_LockMemory();
- #else
- true;
- #endif
- }
- #endif
-
if (options.EnableHeaders)
ShowCopyrightAndHelp(g_StdStream, false);
diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp
index 68e5fe97..d257e6a8 100644
--- a/CPP/7zip/UI/Console/MainAr.cpp
+++ b/CPP/7zip/UI/Console/MainAr.cpp
@@ -79,7 +79,7 @@ int MY_CDECL main
PrintError(kUserBreakMessage);
return (NExitCode::kUserBreak);
}
- catch(const CArcCmdLineException &e)
+ catch(const CMessagePathException &e)
{
PrintError(kException_CmdLine_Error_Message);
if (g_ErrStream)
diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp
index e3e8d599..b2426878 100644
--- a/CPP/7zip/UI/Console/PercentPrinter.cpp
+++ b/CPP/7zip/UI/Console/PercentPrinter.cpp
@@ -141,8 +141,9 @@ void CPercentPrinter::Print()
{
_s += ' ';
- StdOut_Convert_UString_to_AString(FileName, _temp);
- _temp.Replace('\n', ' ');
+ _tempU = FileName;
+ _so->Normalize_UString(_tempU);
+ StdOut_Convert_UString_to_AString(_tempU, _temp);
if (_s.Len() + _temp.Len() > MaxLen)
{
unsigned len = FileName.Len();
@@ -153,8 +154,9 @@ void CPercentPrinter::Print()
delta = 1;
len -= delta;
_tempU = FileName;
- _tempU.Delete(len / 2, FileName.Len() - len);
+ _tempU.Delete(len / 2, _tempU.Len() - len);
_tempU.Insert(len / 2, L" . ");
+ _so->Normalize_UString(_tempU);
StdOut_Convert_UString_to_AString(_tempU, _temp);
if (_s.Len() + _temp.Len() <= MaxLen)
break;
diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
index e58e22d7..cd232fff 100644
--- a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
@@ -143,7 +143,9 @@ HRESULT CUpdateCallbackConsole::OpenResult(
_so->Flush();
if (_se)
{
- *_se << kError << name << endl;
+ *_se << kError;
+ _se->NormalizePrint_wstr(name);
+ *_se << endl;
HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink);
RINOK(res);
_se->Flush();
@@ -185,7 +187,9 @@ void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, b
*_se << endl << (isWarning ? kWarning : kError)
<< NError::MyFormatMessage(systemError)
- << endl << fs2us(path) << endl << endl;
+ << endl;
+ _se->NormalizePrint_UString(fs2us(path));
+ *_se << endl << endl;
_se->Flush();
}
}
@@ -281,8 +285,8 @@ HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
if (_so)
{
*_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage);
- if (name != 0)
- *_so << name;
+ if (name)
+ _so->NormalizePrint_wstr(name);
else
*_so << k_StdOut_ArcName;
*_so << endl << endl;
@@ -343,6 +347,7 @@ HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool
_tempA.Add_Space();
*_so << _tempA;
_tempU = fs2us(path);
+ _so->Normalize_UString(_tempU);
_so->PrintUString(_tempU, _tempA);
*_so << endl;
if (NeedFlush)
@@ -475,7 +480,10 @@ HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *com
_tempU.Empty();
if (name)
+ {
_tempU = name;
+ _so->Normalize_UString(_tempU);
+ }
_so->PrintUString(_tempU, _tempA);
*_so << endl;
if (NeedFlush)
@@ -568,7 +576,9 @@ HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypt
AString s;
SetExtractErrorMessage(opRes, isEncrypted, s);
- *_se << s << " : " << endl << name << endl << endl;
+ *_se << s << " : " << endl;
+ _se->NormalizePrint_wstr(name);
+ *_se << endl << endl;
_se->Flush();
}
return S_OK;
diff --git a/CPP/7zip/UI/Console/resource.rc b/CPP/7zip/UI/Console/resource.rc
index 2f7ef073..414427fb 100644
--- a/CPP/7zip/UI/Console/resource.rc
+++ b/CPP/7zip/UI/Console/resource.rc
@@ -1,3 +1,7 @@
#include "../../MyVersionInfo.rc"
MY_VERSION_INFO_APP("7-Zip Console" , "7z")
+
+#ifndef UNDER_CE
+1 24 MOVEABLE PURE "Console.manifest"
+#endif
diff --git a/CPP/7zip/UI/Explorer/Explorer.dsp b/CPP/7zip/UI/Explorer/Explorer.dsp
index 2a6166ee..c156b3d6 100644
--- a/CPP/7zip/UI/Explorer/Explorer.dsp
+++ b/CPP/7zip/UI/Explorer/Explorer.dsp
@@ -479,6 +479,14 @@ SOURCE=..\..\..\Windows\MemoryGlobal.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Windows\MemoryLock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\Menu.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/UI/Explorer/makefile b/CPP/7zip/UI/Explorer/makefile
index 1c8639be..7f50f20c 100644
--- a/CPP/7zip/UI/Explorer/makefile
+++ b/CPP/7zip/UI/Explorer/makefile
@@ -34,6 +34,7 @@ WIN_OBJS = \
$O\FileFind.obj \
$O\FileIO.obj \
$O\FileName.obj \
+ $O\MemoryLock.obj \
$O\Menu.obj \
$O\ProcessUtils.obj \
$O\Registry.obj \
diff --git a/CPP/7zip/UI/Far/ExtractEngine.cpp b/CPP/7zip/UI/Far/ExtractEngine.cpp
index 04bad724..3567c048 100644
--- a/CPP/7zip/UI/Far/ExtractEngine.cpp
+++ b/CPP/7zip/UI/Far/ExtractEngine.cpp
@@ -209,6 +209,8 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s)
s = "Is not archive";
else if (opRes == NArchive::NExtract::NOperationResult::kHeadersError)
s = "kHeaders Error";
+ else if (opRes == NArchive::NExtract::NOperationResult::kWrongPassword)
+ s = "Wrong Password";
else
{
s = "Error #";
diff --git a/CPP/7zip/UI/FileManager/7zFM.exe.manifest b/CPP/7zip/UI/FileManager/7zFM.exe.manifest
index e8237451..6a13c923 100644
--- a/CPP/7zip/UI/FileManager/7zFM.exe.manifest
+++ b/CPP/7zip/UI/FileManager/7zFM.exe.manifest
@@ -5,6 +5,13 @@
<dependency>
<dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly>
</dependency>
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
+<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+</application></compatibility>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
diff --git a/CPP/7zip/UI/FileManager/EditDialog.cpp b/CPP/7zip/UI/FileManager/EditDialog.cpp
new file mode 100644
index 00000000..7f596722
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/EditDialog.cpp
@@ -0,0 +1,57 @@
+// EditDialog.cpp
+
+#include "StdAfx.h"
+
+#include "EditDialog.h"
+
+#ifdef LANG
+#include "LangUtils.h"
+#endif
+
+bool CEditDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetDlgItems(*this, NULL, 0);
+ #endif
+ _edit.Attach(GetItem(IDE_EDIT));
+
+ SetText(Title);
+ _edit.SetText(Text);
+
+ NormalizeSize();
+ return CModalDialog::OnInit();
+}
+
+// #define MY_CLOSE_BUTTON__ID IDCANCEL
+#define MY_CLOSE_BUTTON__ID IDCLOSE
+
+bool CEditDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
+{
+ int mx, my;
+ GetMargins(8, mx, my);
+ int bx1, by;
+ GetItemSizes(MY_CLOSE_BUTTON__ID, bx1, by);
+
+ // int bx2;
+ // GetItemSizes(IDOK, bx2, by);
+
+ int y = ySize - my - by;
+ int x = xSize - mx - bx1;
+
+ /*
+ RECT rect;
+ GetClientRect(&rect);
+ rect.top = y - my;
+ InvalidateRect(&rect);
+ */
+ InvalidateRect(NULL);
+
+ MoveItem(MY_CLOSE_BUTTON__ID, x, y, bx1, by);
+ // MoveItem(IDOK, x - mx - bx2, y, bx2, by);
+ /*
+ if (wParam == SIZE_MAXSHOW || wParam == SIZE_MAXIMIZED || wParam == SIZE_MAXHIDE)
+ mx = 0;
+ */
+ _edit.Move(mx, my, xSize - mx * 2, y - my * 2);
+ return false;
+}
diff --git a/CPP/7zip/UI/FileManager/EditDialog.h b/CPP/7zip/UI/FileManager/EditDialog.h
new file mode 100644
index 00000000..d820516a
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/EditDialog.h
@@ -0,0 +1,25 @@
+// EditDialog.h
+
+#ifndef __EDIT_DIALOG_H
+#define __EDIT_DIALOG_H
+
+#include "../../../Windows/Control/Dialog.h"
+#include "../../../Windows/Control/Edit.h"
+
+#include "EditDialogRes.h"
+
+class CEditDialog: public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CEdit _edit;
+ virtual bool OnInit();
+ virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
+public:
+ UString Title;
+ UString Text;
+
+ INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_EDIT_DLG, wndParent); }
+
+ CEditDialog() {}
+};
+
+#endif
diff --git a/CPP/7zip/UI/FileManager/EditDialog.rc b/CPP/7zip/UI/FileManager/EditDialog.rc
new file mode 100644
index 00000000..cdb0b445
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/EditDialog.rc
@@ -0,0 +1,15 @@
+#include "EditDialogRes.h"
+#include "../../GuiCommon.rc"
+
+#define xc 320
+#define yc 240
+
+IDD_EDIT_DLG DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT
+CAPTION "Edit"
+{
+ // OK_CANCEL
+ MY_BUTTON__CLOSE
+
+ EDITTEXT IDE_EDIT, m, m, xc, yc - bys - m,
+ ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | ES_WANTRETURN
+}
diff --git a/CPP/7zip/UI/FileManager/EditDialogRes.h b/CPP/7zip/UI/FileManager/EditDialogRes.h
new file mode 100644
index 00000000..58c5ca91
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/EditDialogRes.h
@@ -0,0 +1,2 @@
+#define IDD_EDIT_DLG 94
+#define IDE_EDIT 100
diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp
index ddde804b..4dac07e3 100644
--- a/CPP/7zip/UI/FileManager/FM.cpp
+++ b/CPP/7zip/UI/FileManager/FM.cpp
@@ -383,6 +383,7 @@ static void SetMemoryLock()
NSecurity::AddLockMemoryPrivilege();
if (ReadLockMemoryEnable())
+ if (NSecurity::Get_LargePages_RiskLevel() == 0)
{
// note: child processes can inherit that Privilege
g_LargePagesMode = NSecurity::EnablePrivilege_LockMemory();
diff --git a/CPP/7zip/UI/FileManager/FM.dsp b/CPP/7zip/UI/FileManager/FM.dsp
index 3b2fb2e3..6bf74436 100644
--- a/CPP/7zip/UI/FileManager/FM.dsp
+++ b/CPP/7zip/UI/FileManager/FM.dsp
@@ -491,6 +491,14 @@ SOURCE=.\DialogSize.h
# End Source File
# Begin Source File
+SOURCE=.\EditDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\EditDialog.h
+# End Source File
+# Begin Source File
+
SOURCE=.\LinkDialog.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/UI/FileManager/FM.mak b/CPP/7zip/UI/FileManager/FM.mak
index 6a85ea2f..e6545113 100644
--- a/CPP/7zip/UI/FileManager/FM.mak
+++ b/CPP/7zip/UI/FileManager/FM.mak
@@ -46,6 +46,7 @@ FM_OBJS = \
$O\AboutDialog.obj \
$O\ComboDialog.obj \
$O\CopyDialog.obj \
+ $O\EditDialog.obj \
$O\EditPage.obj \
$O\LangPage.obj \
$O\ListViewDialog.obj \
diff --git a/CPP/7zip/UI/FileManager/LangUtils.cpp b/CPP/7zip/UI/FileManager/LangUtils.cpp
index 94e9ecba..bcaa5f1e 100644
--- a/CPP/7zip/UI/FileManager/LangUtils.cpp
+++ b/CPP/7zip/UI/FileManager/LangUtils.cpp
@@ -58,6 +58,7 @@ static const CIDLangPair kLangPairs[] =
{ IDCANCEL, 402 },
{ IDYES, 406 },
{ IDNO, 407 },
+ { IDCLOSE, 408 },
{ IDHELP, 409 }
};
diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp
index 80cdd7f6..9ad7bcc5 100644
--- a/CPP/7zip/UI/FileManager/ListViewDialog.cpp
+++ b/CPP/7zip/UI/FileManager/ListViewDialog.cpp
@@ -2,6 +2,9 @@
#include "StdAfx.h"
+#include "../../../Windows/Clipboard.h"
+
+#include "EditDialog.h"
#include "ListViewDialog.h"
#include "RegistryUtils.h"
@@ -11,6 +14,23 @@
using namespace NWindows;
+static const unsigned kOneStringMaxSize = 1024;
+
+
+static void ListView_GetSelected(NControl::CListView &listView, CUIntVector &vector)
+{
+ vector.Clear();
+ int index = -1;
+ for (;;)
+ {
+ index = listView.GetNextSelectedItem(index);
+ if (index < 0)
+ break;
+ vector.Add(index);
+ }
+}
+
+
bool CListViewDialog::OnInit()
{
#ifdef LANG
@@ -18,28 +38,92 @@ bool CListViewDialog::OnInit()
#endif
_listView.Attach(GetItem(IDL_LISTVIEW));
+ if (NumColumns > 1)
+ {
+ LONG_PTR style = _listView.GetStyle();
+ style &= ~(LONG_PTR)LVS_NOCOLUMNHEADER;
+ _listView.SetStyle(style);
+ }
+
CFmSettings st;
st.Load();
+
+ DWORD exStyle = 0;
+
if (st.SingleClick)
- _listView.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT);
+ exStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT;
+
+ exStyle |= LVS_EX_FULLROWSELECT;
+ if (exStyle != 0)
+ _listView.SetExtendedListViewStyle(exStyle);
+
SetText(Title);
+ const int kWidth = 400;
+
LVCOLUMN columnInfo;
columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
columnInfo.fmt = LVCFMT_LEFT;
columnInfo.iSubItem = 0;
- columnInfo.cx = 200;
+ columnInfo.cx = kWidth;
+ columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Property"
+
+ if (NumColumns > 1)
+ {
+ columnInfo.cx = 100;
+ /*
+ // Windows always uses LVCFMT_LEFT for first column.
+ // if we need LVCFMT_RIGHT, we can create dummy column and then remove it
+
+ // columnInfo.mask |= LVCF_TEXT;
+ _listView.InsertColumn(0, &columnInfo);
+
+ columnInfo.iSubItem = 1;
+ columnInfo.fmt = LVCFMT_RIGHT;
+ _listView.InsertColumn(1, &columnInfo);
+ _listView.DeleteColumn(0);
+ */
+ }
+ // else
+ _listView.InsertColumn(0, &columnInfo);
+
+ if (NumColumns > 1)
+ {
+ // columnInfo.fmt = LVCFMT_LEFT;
+ columnInfo.cx = kWidth - columnInfo.cx;
+ columnInfo.iSubItem = 1;
+ // columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Value"
+ _listView.InsertColumn(1, &columnInfo);
+ }
- _listView.InsertColumn(0, &columnInfo);
+ UString s;
+
FOR_VECTOR (i, Strings)
+ {
_listView.InsertItem(i, Strings[i]);
- if (Strings.Size() > 0)
+ if (NumColumns > 1 && i < Values.Size())
+ {
+ s = Values[i];
+ if (s.Len() > kOneStringMaxSize)
+ {
+ s.DeleteFrom(kOneStringMaxSize);
+ s += " ...";
+ }
+ s.Replace(L"\r\n", L" ");
+ s.Replace(L"\n", L" ");
+ _listView.SetSubItem(i, 1, s);
+ }
+ }
+
+ if (SelectFirst && Strings.Size() > 0)
_listView.SetItemState_FocusedSelected(0);
_listView.SetColumnWidthAuto(0);
+ if (NumColumns > 1)
+ _listView.SetColumnWidthAuto(1);
StringsWereChanged = false;
NormalizeSize();
@@ -74,8 +158,97 @@ bool CListViewDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
return false;
}
+
extern bool g_LVN_ITEMACTIVATE_Support;
+void CListViewDialog::CopyToClipboard()
+{
+ CUIntVector indexes;
+ ListView_GetSelected(_listView, indexes);
+ UString s;
+
+ FOR_VECTOR (i, indexes)
+ {
+ unsigned index = indexes[i];
+ s += Strings[index];
+ if (NumColumns > 1 && index < Values.Size())
+ {
+ const UString &v = Values[index];
+ // if (!v.IsEmpty())
+ {
+ s += ": ";
+ s += v;
+ }
+ }
+ // if (indexes.Size() > 1)
+ {
+ s +=
+ #ifdef _WIN32
+ "\r\n"
+ #else
+ "\n"
+ #endif
+ ;
+ }
+ }
+
+ ClipboardSetText(*this, s);
+}
+
+
+void CListViewDialog::ShowItemInfo()
+{
+ CUIntVector indexes;
+ ListView_GetSelected(_listView, indexes);
+ if (indexes.Size() != 1)
+ return;
+ unsigned index = indexes[0];
+
+ CEditDialog dlg;
+ if (NumColumns == 1)
+ dlg.Text = Strings[index];
+ else
+ {
+ dlg.Title = Strings[index];
+ if (index < Values.Size())
+ dlg.Text = Values[index];
+ }
+ dlg.Create(*this);
+}
+
+
+void CListViewDialog::DeleteItems()
+{
+ for (;;)
+ {
+ int index = _listView.GetNextSelectedItem(-1);
+ if (index < 0)
+ break;
+ StringsWereChanged = true;
+ _listView.DeleteItem(index);
+ if ((unsigned)index < Strings.Size())
+ Strings.Delete(index);
+ if ((unsigned)index < Values.Size())
+ Values.Delete(index);
+ }
+ int focusedIndex = _listView.GetFocusedItem();
+ if (focusedIndex >= 0)
+ _listView.SetItemState_FocusedSelected(focusedIndex);
+ _listView.SetColumnWidthAuto(0);
+}
+
+
+void CListViewDialog::OnEnter()
+{
+ if (IsKeyDown(VK_MENU)
+ || NumColumns > 1)
+ {
+ ShowItemInfo();
+ return;
+ }
+ OnOK();
+}
+
bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
{
if (header->hwndFrom != _listView)
@@ -85,7 +258,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
case LVN_ITEMACTIVATE:
if (g_LVN_ITEMACTIVATE_Support)
{
- OnOK();
+ OnEnter();
return true;
}
break;
@@ -93,7 +266,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
case NM_RETURN: // probabably it's unused
if (!g_LVN_ITEMACTIVATE_Support)
{
- OnOK();
+ OnEnter();
return true;
}
break;
@@ -107,19 +280,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
{
if (!DeleteIsAllowed)
return false;
- for (;;)
- {
- int index = _listView.GetNextSelectedItem(-1);
- if (index < 0)
- break;
- StringsWereChanged = true;
- _listView.DeleteItem(index);
- Strings.Delete(index);
- }
- int focusedIndex = _listView.GetFocusedItem();
- if (focusedIndex >= 0)
- _listView.SetItemState_FocusedSelected(focusedIndex);
- _listView.SetColumnWidthAuto(0);
+ DeleteItems();
return true;
}
case 'A':
@@ -129,6 +290,17 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
_listView.SelectAll();
return true;
}
+ break;
+ }
+ case VK_INSERT:
+ case 'C':
+ {
+ if (IsKeyDown(VK_CONTROL))
+ {
+ CopyToClipboard();
+ return true;
+ }
+ break;
}
}
}
diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.h b/CPP/7zip/UI/FileManager/ListViewDialog.h
index b7ba3830..00206afd 100644
--- a/CPP/7zip/UI/FileManager/ListViewDialog.h
+++ b/CPP/7zip/UI/FileManager/ListViewDialog.h
@@ -15,16 +15,32 @@ class CListViewDialog: public NWindows::NControl::CModalDialog
virtual bool OnInit();
virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
virtual bool OnNotify(UINT controlID, LPNMHDR header);
+ void CopyToClipboard();
+ void DeleteItems();
+ void ShowItemInfo();
+ void OnEnter();
public:
UString Title;
+
+ bool SelectFirst;
bool DeleteIsAllowed;
bool StringsWereChanged;
+
UStringVector Strings;
+ UStringVector Values;
+
int FocusedItemIndex;
+ unsigned NumColumns;
INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_LISTVIEW, wndParent); }
- CListViewDialog(): DeleteIsAllowed(false) {}
+ CListViewDialog():
+ SelectFirst(false),
+ DeleteIsAllowed(false),
+ StringsWereChanged(false),
+ FocusedItemIndex(-1),
+ NumColumns(1)
+ {}
};
#endif
diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.rc b/CPP/7zip/UI/FileManager/ListViewDialog.rc
index 14d3b2e6..961d224a 100644
--- a/CPP/7zip/UI/FileManager/ListViewDialog.rc
+++ b/CPP/7zip/UI/FileManager/ListViewDialog.rc
@@ -1,8 +1,8 @@
#include "ListViewDialogRes.h"
#include "../../GuiCommon.rc"
-#define xc 320
-#define yc 240
+#define xc 440
+#define yc 320
IDD_LISTVIEW DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT
CAPTION "ListView"
diff --git a/CPP/7zip/UI/FileManager/PanelCopy.cpp b/CPP/7zip/UI/FileManager/PanelCopy.cpp
index d07def1d..5715d9de 100644
--- a/CPP/7zip/UI/FileManager/PanelCopy.cpp
+++ b/CPP/7zip/UI/FileManager/PanelCopy.cpp
@@ -16,7 +16,11 @@ using namespace NWindows;
class CPanelCopyThread: public CProgressThreadVirt
{
+ bool ResultsWereShown;
+ bool NeedShowRes;
+
HRESULT ProcessVirt();
+ virtual void ProcessWasFinished_GuiVirt();
public:
const CCopyToOptions *options;
CMyComPtr<IFolderOperations> FolderOperations;
@@ -28,11 +32,31 @@ public:
UString FirstFilePath;
HRESULT Result;
-
- CPanelCopyThread(): Result(E_FAIL) {}
+ void ShowFinalResults(HWND hwnd);
+
+ CPanelCopyThread():
+ Result(E_FAIL),
+ ResultsWereShown(false),
+ NeedShowRes(false)
+ {}
};
+
+void CPanelCopyThread::ShowFinalResults(HWND hwnd)
+{
+ if (NeedShowRes)
+ if (!ResultsWereShown)
+ {
+ ResultsWereShown = true;
+ ShowHashResults(Hash, fs2us(FirstFilePath), hwnd);
+ }
+}
+void CPanelCopyThread::ProcessWasFinished_GuiVirt()
+{
+ ShowFinalResults(*this);
+}
+
HRESULT CPanelCopyThread::ProcessVirt()
{
/*
@@ -69,11 +93,15 @@ HRESULT CPanelCopyThread::ProcessVirt()
BoolToInt(options->replaceAltStreamChars),
options->folder, ExtractCallback);
- if (Result == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors &&
- (!options->hashMethods.IsEmpty() || options->testMode))
+ if (Result == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors)
{
- CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0);
- AddHashBundleRes(pair.Message, Hash, FirstFilePath);
+ if (!options->hashMethods.IsEmpty())
+ NeedShowRes = true;
+ else if (options->testMode)
+ {
+ CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0);
+ AddHashBundleRes(pair.Message, Hash, FirstFilePath);
+ }
}
return Result;
@@ -92,7 +120,6 @@ static void ThrowException_if_Error(HRESULT res)
#endif
*/
-
HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &indices,
UStringVector *messages,
bool &usePassword, UString &password)
@@ -102,7 +129,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED);
if (options.showErrorMessages)
MessageBox_Error(errorMessage);
- else if (messages != 0)
+ else if (messages)
messages->Add(errorMessage);
return E_FAIL;
}
@@ -124,8 +151,8 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
extracter.ExtractCallback = extracter.ExtractCallbackSpec;
extracter.options = &options;
- extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog;
- extracter.ProgressDialog.CompressingMode = false;
+ extracter.ExtractCallbackSpec->ProgressDialog = &extracter;
+ extracter.CompressingMode = false;
extracter.ExtractCallbackSpec->StreamMode = options.streamMode;
@@ -185,9 +212,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE);
- extracter.ProgressDialog.MainWindow = GetParent();
- extracter.ProgressDialog.MainTitle = progressWindowTitle;
- extracter.ProgressDialog.MainAddTitle = title + L' ';
+ extracter.MainWindow = GetParent();
+ extracter.MainTitle = progressWindowTitle;
+ extracter.MainAddTitle = title + L' ';
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAsk;
extracter.ExtractCallbackSpec->Init();
@@ -199,8 +226,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
RINOK(extracter.Create(title, GetParent()));
- if (messages != 0)
- *messages = extracter.ProgressDialog.Sync.Messages;
+
+ if (messages)
+ *messages = extracter.Sync.Messages;
res = extracter.Result;
if (res == S_OK && extracter.ExtractCallbackSpec->IsOK())
@@ -208,6 +236,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
usePassword = extracter.ExtractCallbackSpec->PasswordIsDefined;
password = extracter.ExtractCallbackSpec->Password;
}
+
+ extracter.ShowFinalResults(_window);
+
}
RefreshTitleAlways();
@@ -296,8 +327,8 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
NWindows::CThread thread;
RINOK(thread.Create(CThreadUpdate::MyThreadFunction, &updater));
updater.ProgressDialog.Create(title, thread, GetParent());
-
- if (messages != 0)
+
+ if (messages)
*messages = updater.ProgressDialog.Sync.Messages;
res = updater.Result;
@@ -308,7 +339,7 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED);
if (showErrorMessages)
MessageBox_Error(errorMessage);
- else if (messages != 0)
+ else if (messages)
messages->Add(errorMessage);
return E_ABORT;
}
diff --git a/CPP/7zip/UI/FileManager/PanelCrc.cpp b/CPP/7zip/UI/FileManager/PanelCrc.cpp
index 227c4533..7b918a02 100644
--- a/CPP/7zip/UI/FileManager/PanelCrc.cpp
+++ b/CPP/7zip/UI/FileManager/PanelCrc.cpp
@@ -139,18 +139,44 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r
class CThreadCrc: public CProgressThreadVirt
{
+ bool ResultsWereShown;
+ bool WasFinished;
+
HRESULT ProcessVirt();
+ virtual void ProcessWasFinished_GuiVirt();
public:
CDirEnumerator Enumerator;
CHashBundle Hash;
+ FString FirstFilePath;
void SetStatus(const UString &s);
void AddErrorMessage(DWORD systemError, const FChar *name);
+ void ShowFinalResults(HWND hwnd);
+
+ CThreadCrc():
+ ResultsWereShown(false),
+ WasFinished(false)
+ {}
};
+void CThreadCrc::ShowFinalResults(HWND hwnd)
+{
+ if (WasFinished)
+ if (!ResultsWereShown)
+ {
+ ResultsWereShown = true;
+ ShowHashResults(Hash, fs2us(FirstFilePath), hwnd);
+ }
+}
+
+void CThreadCrc::ProcessWasFinished_GuiVirt()
+{
+ ShowFinalResults(*this);
+}
+
void CThreadCrc::AddErrorMessage(DWORD systemError, const FChar *name)
{
- ProgressDialog.Sync.AddError_Code_Name(systemError, fs2us(Enumerator.BasePrefix + name));
+ Sync.AddError_Code_Name(systemError, fs2us(Enumerator.BasePrefix + name));
Hash.NumErrors++;
}
@@ -162,7 +188,7 @@ void CThreadCrc::SetStatus(const UString &s2)
s.Add_Space_if_NotEmpty();
s += fs2us(Enumerator.BasePrefix);
}
- ProgressDialog.Sync.Set_Status(s);
+ Sync.Set_Status(s);
}
HRESULT CThreadCrc::ProcessVirt()
@@ -173,7 +199,7 @@ HRESULT CThreadCrc::ProcessVirt()
if (!buf.Allocate(kBufSize))
return E_OUTOFMEMORY;
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
SetStatus(LangString(IDS_SCANNING));
@@ -233,7 +259,6 @@ HRESULT CThreadCrc::ProcessVirt()
Enumerator.Init();
FString tempPath;
- FString firstFilePath;
bool isFirstFile = true;
UInt64 errorsFilesSize = 0;
@@ -264,7 +289,7 @@ HRESULT CThreadCrc::ProcessVirt()
}
if (isFirstFile)
{
- firstFilePath = path;
+ FirstFilePath = path;
isFirstFile = false;
}
sync.Set_FilePath(fs2us(path));
@@ -303,12 +328,13 @@ HRESULT CThreadCrc::ProcessVirt()
SetStatus(L"");
CProgressMessageBoxPair &pair = GetMessagePair(Hash.NumErrors != 0);
- AddHashBundleRes(pair.Message, Hash, fs2us(firstFilePath));
+ WasFinished = true;
LangString(IDS_CHECKSUM_INFORMATION, pair.Title);
return S_OK;
}
+
HRESULT CApp::CalculateCrc2(const UString &methodName)
{
unsigned srcPanelIndex = GetFocusedPanelIndex();
@@ -338,6 +364,7 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
{
CThreadCrc t;
+
{
UStringVector methods;
methods.Add(methodName);
@@ -360,17 +387,20 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
t.Enumerator.EnterToDirs = !GetFlatMode();
- t.ProgressDialog.ShowCompressionInfo = false;
+ t.ShowCompressionInfo = false;
UString title = LangString(IDS_CHECKSUM_CALCULATING);
- t.ProgressDialog.MainWindow = _window;
- t.ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
- t.ProgressDialog.MainAddTitle = title;
- t.ProgressDialog.MainAddTitle.Add_Space();
+ t.MainWindow = _window;
+ t.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
+ t.MainAddTitle = title;
+ t.MainAddTitle.Add_Space();
RINOK(t.Create(title, _window));
+
+ t.ShowFinalResults(_window);
}
+
RefreshTitleAlways();
return S_OK;
}
diff --git a/CPP/7zip/UI/FileManager/PanelDrag.cpp b/CPP/7zip/UI/FileManager/PanelDrag.cpp
index b6fca594..9f64c2c8 100644
--- a/CPP/7zip/UI/FileManager/PanelDrag.cpp
+++ b/CPP/7zip/UI/FileManager/PanelDrag.cpp
@@ -81,15 +81,17 @@ CDataObject::CDataObject()
STDMETHODIMP CDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL /* release */)
{
- if (etc->cfFormat == m_SetFolderFormat && etc->tymed == TYMED_HGLOBAL &&
- etc->dwAspect == DVASPECT_CONTENT && medium->tymed == TYMED_HGLOBAL)
+ if (etc->cfFormat == m_SetFolderFormat
+ && etc->tymed == TYMED_HGLOBAL
+ && etc->dwAspect == DVASPECT_CONTENT
+ && medium->tymed == TYMED_HGLOBAL)
{
Path.Empty();
- if (medium->hGlobal == 0)
+ if (!medium->hGlobal)
return S_OK;
size_t size = GlobalSize(medium->hGlobal) / sizeof(wchar_t);
const wchar_t *src = (const wchar_t *)GlobalLock(medium->hGlobal);
- if (src != 0)
+ if (src)
{
for (size_t i = 0; i < size; i++)
{
@@ -109,13 +111,13 @@ static HGLOBAL DuplicateGlobalMem(HGLOBAL srcGlobal)
{
SIZE_T size = GlobalSize(srcGlobal);
const void *src = GlobalLock(srcGlobal);
- if (src == 0)
+ if (!src)
return 0;
HGLOBAL destGlobal = GlobalAlloc(GHND | GMEM_SHARE, size);
- if (destGlobal != 0)
+ if (destGlobal)
{
void *dest = GlobalLock(destGlobal);
- if (dest == 0)
+ if (!dest)
{
GlobalFree(destGlobal);
destGlobal = 0;
@@ -136,7 +138,7 @@ STDMETHODIMP CDataObject::GetData(LPFORMATETC etc, LPSTGMEDIUM medium)
medium->tymed = m_Etc.tymed;
medium->pUnkForRelease = 0;
medium->hGlobal = DuplicateGlobalMem(hGlobal);
- if (medium->hGlobal == 0)
+ if (!medium->hGlobal)
return E_OUTOFMEMORY;
return S_OK;
}
@@ -261,7 +263,7 @@ static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &na
NMemory::CGlobalLock dropLock(hgDrop);
DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
- if (dropFiles == 0)
+ if (!dropFiles)
return false;
dropFiles->fNC = FALSE;
dropFiles->pt.x = 0;
@@ -291,7 +293,7 @@ static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &na
NMemory::CGlobalLock dropLock(hgDrop);
DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
- if (dropFiles == 0)
+ if (!dropFiles)
return false;
dropFiles->fNC = FALSE;
dropFiles->pt.x = 0;
@@ -336,7 +338,11 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
dirPrefix = us2fs(GetFsPath());
else
{
- tempDirectory.Create(kTempDirPrefix);
+ if (!tempDirectory.Create(kTempDirPrefix))
+ {
+ MessageBox_Error(L"Can't create temp folder");
+ return;
+ }
dirPrefix = tempDirectory.GetPath();
// dirPrefix2 = dirPrefix;
NFile::NName::NormalizeDirPathPrefix(dirPrefix);
@@ -394,11 +400,67 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
dropSourceSpec->DataObjectSpec = dataObjectSpec;
dropSourceSpec->DataObject = dataObjectSpec;
- bool moveIsAllowed = isFSFolder;
+
+ /*
+ CTime - file creation timestamp.
+ There are two operations in Windows with Drag and Drop:
+ COPY_OPERATION - icon with Plus sign - CTime will be set as current_time.
+ MOVE_OPERATION - icon without Plus sign - CTime will be preserved
+
+ Note: if we call DoDragDrop() with (effectsOK = DROPEFFECT_MOVE), then
+ it will use MOVE_OPERATION and CTime will be preserved.
+ But MoveFile() function doesn't preserve CTime, if different volumes are used.
+ Why it's so?
+ Does DoDragDrop() use some another function (not MoveFile())?
+
+ if (effectsOK == DROPEFFECT_COPY) it works as COPY_OPERATION
+
+ if (effectsOK == DROPEFFECT_MOVE) drag works as MOVE_OPERATION
+
+ if (effectsOK == (DROPEFFECT_COPY | DROPEFFECT_MOVE))
+ {
+ if we drag file to same volume, then Windows suggests:
+ CTRL - COPY_OPERATION
+ [default] - MOVE_OPERATION
+
+ if we drag file to another volume, then Windows suggests
+ [default] - COPY_OPERATION
+ SHIFT - MOVE_OPERATION
+ }
+
+ We want to use MOVE_OPERATION for extracting from archive (open in 7-Zip) to Explorer:
+ It has the following advantages:
+ 1) it uses fast MOVE_OPERATION instead of slow COPY_OPERATION and DELETE, if same volume.
+ 2) it preserved CTime
+
+ Some another programs support only COPY_OPERATION.
+ So we can use (DROPEFFECT_COPY | DROPEFFECT_MOVE)
+
+ Also another program can return from DoDragDrop() before
+ files using. But we delete temp folder after DoDragDrop(),
+ and another program can't open input files in that case.
+
+ We create objects:
+ IDropSource *dropSource
+ IDataObject *dataObject
+ if DropTarget is 7-Zip window, then 7-Zip's
+ IDropTarget::DragOver() sets Path in IDataObject.
+ and
+ IDropSource::QueryContinueDrag() sets NeedPostCopy, if Path is not epmty.
+ So we can detect destination path after DoDragDrop().
+ Now we don't know any good way to detect destination path for D&D to Explorer.
+ */
+ bool moveIsAllowed = isFSFolder;
+ /*
DWORD effectsOK = DROPEFFECT_COPY;
if (moveIsAllowed)
effectsOK |= DROPEFFECT_MOVE;
+ */
+
+ // 18.04: was changed
+ DWORD effectsOK = DROPEFFECT_MOVE | DROPEFFECT_COPY;
+
DWORD effect;
_panelCallback->DragBegin();
@@ -418,7 +480,8 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
NFile::NName::NormalizeDirPathPrefix(dataObjectSpec->Path);
CCopyToOptions options;
options.folder = dataObjectSpec->Path;
- options.moveMode = (effect == DROPEFFECT_MOVE);
+ // if MOVE is not allowed, we just use COPY operation
+ options.moveMode = (effect == DROPEFFECT_MOVE && moveIsAllowed);
res = CopyTo(options, indices, &dropSourceSpec->Messages);
}
/*
@@ -475,7 +538,7 @@ static void MySetDropHighlighted(HWND hWnd, int index, bool enable)
void CDropTarget::RemoveSelection()
{
- if (m_SelectionIndex >= 0 && m_Panel != 0)
+ if (m_SelectionIndex >= 0 && m_Panel)
MySetDropHighlighted(m_Panel->_listView, m_SelectionIndex, false);
m_SelectionIndex = -1;
}
@@ -555,7 +618,7 @@ void CDropTarget::PositionCursor(POINTL ptl)
bool CDropTarget::IsFsFolderPath() const
{
- if (!m_IsAppTarget && m_Panel != 0)
+ if (!m_IsAppTarget && m_Panel)
return (m_Panel->IsFSFolder() || (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0));
return false;
}
@@ -614,7 +677,7 @@ static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names
size_t blockSize = GlobalSize(medium.hGlobal);
NMemory::CGlobalLock dropLock(medium.hGlobal);
const DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
- if (dropFiles == 0)
+ if (!dropFiles)
return;
if (blockSize < dropFiles->pFiles)
return;
@@ -629,7 +692,7 @@ static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names
bool CDropTarget::IsItSameDrive() const
{
- if (m_Panel == 0)
+ if (!m_Panel)
return false;
if (!IsFsFolderPath())
return false;
@@ -662,6 +725,21 @@ bool CDropTarget::IsItSameDrive() const
return true;
}
+
+/*
+ There are 2 different actions, when we drag to 7-Zip:
+ 1) Drag from any external program except of Explorer to "7-Zip" FS folder.
+ We want to create new archive for that operation.
+ 2) all another operation work as usual file COPY/MOVE
+ - Drag from "7-Zip" FS to "7-Zip" FS.
+ COPY/MOVE are supported.
+ - Drag to open archive in 7-Zip.
+ We want to update archive.
+ We replace COPY to MOVE.
+ - Drag from "7-Zip" archive to "7-Zip" FS.
+ We replace COPY to MOVE.
+*/
+
DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect)
{
if (!m_DropIsAllowed || !m_PanelDropIsAllowed)
@@ -671,10 +749,12 @@ DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffec
allowedEffect &= ~DROPEFFECT_MOVE;
DWORD effect = 0;
+
if (keyState & MK_CONTROL)
effect = allowedEffect & DROPEFFECT_COPY;
else if (keyState & MK_SHIFT)
effect = allowedEffect & DROPEFFECT_MOVE;
+
if (effect == 0)
{
if (allowedEffect & DROPEFFECT_COPY)
@@ -716,10 +796,10 @@ bool CDropTarget::SetPath(bool enablePath) const
path = GetTargetPath();
size_t size = path.Len() + 1;
medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size * sizeof(wchar_t));
- if (medium.hGlobal == 0)
+ if (!medium.hGlobal)
return false;
wchar_t *dest = (wchar_t *)GlobalLock(medium.hGlobal);
- if (dest == 0)
+ if (!dest)
{
GlobalUnlock(medium.hGlobal);
return false;
diff --git a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
index 1f93f862..38b83124 100644
--- a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
+++ b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
@@ -625,6 +625,7 @@ void CPanel::FoldersHistory()
{
CListViewDialog listViewDialog;
listViewDialog.DeleteIsAllowed = true;
+ listViewDialog.SelectFirst = true;
LangString(IDS_FOLDERS_HISTORY, listViewDialog.Title);
_appState->FolderHistory.GetList(listViewDialog.Strings);
if (listViewDialog.Create(GetParent()) != IDOK)
diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
index f7c05a39..89f49bf6 100644
--- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
@@ -674,7 +674,7 @@ static const char * const kStartExtensions =
#endif
" exe bat ps1 com"
" chm"
- " msi doc xls ppt pps wps wpt wks xlr wdb vsd pub"
+ " msi doc dot xls ppt pps wps wpt wks xlr wdb vsd pub"
" docx docm dotx dotm xlsx xlsm xltx xltm xlsb xps"
" xlam pptx pptm potx potm ppam ppsx ppsm xsn"
@@ -1151,7 +1151,7 @@ HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
CThreadCopyFrom t;
t.UpdateCallbackSpec = new CUpdateCallback100Imp;
t.UpdateCallback = t.UpdateCallbackSpec;
- t.UpdateCallbackSpec->ProgressDialog = &t.ProgressDialog;
+ t.UpdateCallbackSpec->ProgressDialog = &t;
t.ItemIndex = index;
t.FullPath = fullFilePath;
t.FolderOperations = _folderOperations;
diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp
index 3db65be4..11c6d7c1 100644
--- a/CPP/7zip/UI/FileManager/PanelMenu.cpp
+++ b/CPP/7zip/UI/FileManager/PanelMenu.cpp
@@ -16,6 +16,7 @@
#include "App.h"
#include "FormatUtils.h"
#include "LangUtils.h"
+#include "ListViewDialog.h"
#include "MyLoadMenu.h"
#include "PropertyName.h"
@@ -50,17 +51,40 @@ void CPanel::InvokeSystemCommand(const char *command)
contextMenu->InvokeCommand(&ci);
}
-static const char * const kSeparator = "----------------------------\n";
-static const char * const kSeparatorSmall = "----\n";
-static const char * const kPropValueSeparator = ": ";
+static const char * const kSeparator = "------------------------";
+static const char * const kSeparatorSmall = "----------------";
extern UString ConvertSizeToString(UInt64 value) throw();
bool IsSizeProp(UINT propID) throw();
UString GetOpenArcErrorMessage(UInt32 errorFlags);
+
+static void AddListAscii(CListViewDialog &dialog, const char *s)
+{
+ dialog.Strings.Add((UString)s);
+ dialog.Values.AddNew();
+}
+
+static void AddSeparator(CListViewDialog &dialog)
+{
+ AddListAscii(dialog, kSeparator);
+}
+
+static void AddSeparatorSmall(CListViewDialog &dialog)
+{
+ AddListAscii(dialog, kSeparatorSmall);
+}
+
+static void AddPropertyPair(const UString &name, const UString &val, CListViewDialog &dialog)
+{
+ dialog.Strings.Add(name);
+ dialog.Values.Add(val);
+}
+
+
static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
- const NCOM::CPropVariant &prop, UString &s)
+ const NCOM::CPropVariant &prop, CListViewDialog &dialog)
{
if (prop.vt != VT_EMPTY)
{
@@ -87,23 +111,16 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
if (!val.IsEmpty())
{
- s += GetNameOfProperty(propID, nameBSTR);
- s += kPropValueSeparator;
- /*
- if (propID == kpidComment)
- s.Add_LF();
- */
- s += val;
- s.Add_LF();
+ AddPropertyPair(GetNameOfProperty(propID, nameBSTR), val, dialog);
}
}
}
-static void AddPropertyString(PROPID propID, UInt64 val, UString &s)
+static void AddPropertyString(PROPID propID, UInt64 val, CListViewDialog &dialog)
{
NCOM::CPropVariant prop = val;
- AddPropertyString(propID, NULL, prop, s);
+ AddPropertyString(propID, NULL, prop, dialog);
}
@@ -137,7 +154,9 @@ void CPanel::Properties()
}
{
- UString message;
+ CListViewDialog message;
+ // message.DeleteIsAllowed = false;
+ // message.SelectFirst = false;
CRecordVector<UInt32> operatedIndices;
GetOperatedItemIndices(operatedIndices);
@@ -205,15 +224,12 @@ void CPanel::Properties()
}
}
}
- message += GetNameOfProperty(propID, name);
- message += kPropValueSeparator;
- message += s.Ptr();
- message.Add_LF();
+ AddPropertyPair(GetNameOfProperty(propID, name), (UString)s.Ptr(), message);
}
}
}
- message += kSeparator;
+ AddSeparator(message);
}
else if (operatedIndices.Size() >= 1)
{
@@ -239,8 +255,7 @@ void CPanel::Properties()
{
wchar_t temp[32];
ConvertUInt32ToString(operatedIndices.Size(), temp);
- message += MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp);
- message.Add_LF();
+ AddPropertyPair(L"", MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp), message);
}
if (numDirs != 0)
@@ -250,7 +265,7 @@ void CPanel::Properties()
AddPropertyString(kpidSize, unpackSize, message);
AddPropertyString(kpidPackSize, packSize, message);
- message += kSeparator;
+ AddSeparator(message);
}
@@ -309,7 +324,7 @@ void CPanel::Properties()
{
const int kNumSpecProps = ARRAY_SIZE(kSpecProps);
- message += kSeparator;
+ AddSeparator(message);
for (Int32 i = -(int)kNumSpecProps; i < (Int32)numProps; i++)
{
@@ -334,7 +349,7 @@ void CPanel::Properties()
UInt32 numProps;
if (getProps->GetArcNumProps2(level, &numProps) == S_OK)
{
- message += kSeparatorSmall;
+ AddSeparatorSmall(message);
for (Int32 i = 0; i < (Int32)numProps; i++)
{
CMyComBSTR name;
@@ -352,10 +367,15 @@ void CPanel::Properties()
}
}
}
- ::MessageBoxW(*(this), message, LangString(IDS_PROPERTIES), MB_OK);
+
+ message.Title = LangString(IDS_PROPERTIES);
+ message.NumColumns = 2;
+ message.Create(GetParent());
}
}
+
+
void CPanel::EditCut()
{
// InvokeSystemCommand("cut");
diff --git a/CPP/7zip/UI/FileManager/PanelOperations.cpp b/CPP/7zip/UI/FileManager/PanelOperations.cpp
index d049a3ce..00bda1a9 100644
--- a/CPP/7zip/UI/FileManager/PanelOperations.cpp
+++ b/CPP/7zip/UI/FileManager/PanelOperations.cpp
@@ -79,10 +79,10 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
{
UpdateCallbackSpec = new CUpdateCallback100Imp;
UpdateCallback = UpdateCallbackSpec;
- UpdateCallbackSpec->ProgressDialog = &ProgressDialog;
+ UpdateCallbackSpec->ProgressDialog = this;
- ProgressDialog.WaitMode = true;
- ProgressDialog.Sync.FinalMessage.ErrorMessage.Title = titleError;
+ WaitMode = true;
+ Sync.FinalMessage.ErrorMessage.Title = titleError;
Result = S_OK;
UpdateCallbackSpec->Init();
@@ -95,11 +95,11 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
}
- ProgressDialog.MainWindow = panel._mainWindow; // panel.GetParent()
- ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
- ProgressDialog.MainAddTitle = progressTitle + L' ';
+ MainWindow = panel._mainWindow; // panel.GetParent()
+ MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
+ MainAddTitle = progressTitle + L' ';
- RINOK(Create(progressTitle, ProgressDialog.MainWindow));
+ RINOK(Create(progressTitle, MainWindow));
return Result;
}
diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
index 7cab2cf9..7c633323 100644
--- a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
@@ -157,7 +157,7 @@ HRESULT CThreadSplit::ProcessVirt()
if (!inFile.GetLength(length))
return GetLastError();
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
sync.Set_NumBytesTotal(length);
UInt64 pos = 0;
@@ -306,7 +306,7 @@ void CApp::Split()
CThreadSplit spliter;
spliter.NumVolumes = numVolumes;
- CProgressDialog &progressDialog = spliter.ProgressDialog;
+ CProgressDialog &progressDialog = spliter;
UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000);
UString title = LangString(IDS_SPLITTING);
@@ -362,7 +362,7 @@ HRESULT CThreadCombine::ProcessVirt()
return res;
}
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
sync.Set_NumBytesTotal(TotalSize);
CMyBuffer bufferObject;
@@ -534,7 +534,7 @@ void CApp::Combine()
return;
}
- CProgressDialog &progressDialog = combiner.ProgressDialog;
+ CProgressDialog &progressDialog = combiner;
progressDialog.ShowCompressionInfo = false;
UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000);
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
index 762f2492..28e3eae7 100644
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
@@ -236,7 +236,10 @@ void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name)
AddError_Message_Name(s, name);
}
-CProgressDialog::CProgressDialog(): _timer(0), CompressingMode(true), MainWindow(0)
+CProgressDialog::CProgressDialog():
+ _timer(0),
+ CompressingMode(true),
+ MainWindow(0)
{
_isDir = false;
@@ -974,7 +977,9 @@ bool CProgressDialog::OnExternalCloseMessage()
::SendMessage(GetItem(IDCANCEL), BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0));
HideItem(IDB_PROGRESS_BACKGROUND);
HideItem(IDB_PAUSE);
-
+
+ ProcessWasFinished_GuiVirt();
+
bool thereAreMessages;
CProgressFinalMessage fm;
{
@@ -982,6 +987,7 @@ bool CProgressDialog::OnExternalCloseMessage()
thereAreMessages = !Sync.Messages.IsEmpty();
fm = Sync.FinalMessage;
}
+
if (!fm.ErrorMessage.Message.IsEmpty())
{
MessagesDisplayed = true;
@@ -992,6 +998,7 @@ bool CProgressDialog::OnExternalCloseMessage()
else if (!thereAreMessages)
{
MessagesDisplayed = true;
+
if (!fm.OkMessage.Message.IsEmpty())
{
if (fm.OkMessage.Title.IsEmpty())
@@ -1245,11 +1252,24 @@ void CProgressDialog::ProcessWasFinished()
}
+static THREAD_FUNC_DECL MyThreadFunction(void *param)
+{
+ CProgressThreadVirt *p = (CProgressThreadVirt *)param;
+ try
+ {
+ p->Process();
+ p->ThreadFinishedOK = true;
+ }
+ catch (...) { p->Result = E_FAIL; }
+ return 0;
+}
+
+
HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow)
{
NWindows::CThread thread;
RINOK(thread.Create(MyThreadFunction, this));
- ProgressDialog.Create(title, thread, parentWindow);
+ CProgressDialog::Create(title, thread, parentWindow);
return S_OK;
}
@@ -1265,7 +1285,7 @@ static void AddMessageToString(UString &dest, const UString &src)
void CProgressThreadVirt::Process()
{
- CProgressCloser closer(ProgressDialog);
+ CProgressCloser closer(*this);
UString m;
try { Result = ProcessVirt(); }
catch(const wchar_t *s) { m = s; }
@@ -1293,7 +1313,7 @@ void CProgressThreadVirt::Process()
}
}
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
NSynchronization::CCriticalSectionLock lock(sync._cs);
if (m.IsEmpty())
{
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h
index 03f836da..6c4213ac 100644
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.h
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h
@@ -261,7 +261,18 @@ public:
INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0);
+
+ /* how it works:
+ 1) the working thread calls ProcessWasFinished()
+ that sends kCloseMessage message to CProgressDialog (GUI) thread
+ 2) CProgressDialog (GUI) thread receives kCloseMessage message and
+ calls ProcessWasFinished_GuiVirt();
+ So we can implement ProcessWasFinished_GuiVirt() and show special
+ results window in GUI thread with CProgressDialog as parent window
+ */
+
void ProcessWasFinished();
+ virtual void ProcessWasFinished_GuiVirt() {}
};
@@ -273,7 +284,8 @@ public:
~CProgressCloser() { _p->ProcessWasFinished(); }
};
-class CProgressThreadVirt
+
+class CProgressThreadVirt: public CProgressDialog
{
protected:
FStringVector ErrorPaths;
@@ -281,33 +293,59 @@ protected:
// error if any of HRESULT, ErrorMessage, ErrorPath
virtual HRESULT ProcessVirt() = 0;
- void Process();
public:
HRESULT Result;
bool ThreadFinishedOK; // if there is no fatal exception
- CProgressDialog ProgressDialog;
-
- static THREAD_FUNC_DECL MyThreadFunction(void *param)
- {
- CProgressThreadVirt *p = (CProgressThreadVirt *)param;
- try
- {
- p->Process();
- p->ThreadFinishedOK = true;
- }
- catch (...) { p->Result = E_FAIL; }
- return 0;
- }
+ void Process();
void AddErrorPath(const FString &path) { ErrorPaths.Add(path); }
HRESULT Create(const UString &title, HWND parentWindow = 0);
CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; }
-
};
UString HResultToMessage(HRESULT errorCode);
+/*
+how it works:
+
+client code inherits CProgressThreadVirt and calls
+CProgressThreadVirt::Create()
+{
+ it creates new thread that calls CProgressThreadVirt::Process();
+ it creates modal progress dialog window with ProgressDialog.Create()
+}
+
+CProgressThreadVirt::Process()
+{
+ {
+ ProcessVirt(); // virtual function that must implement real work
+ }
+ if (exceptions) or FinalMessage.ErrorMessage.Message
+ {
+ set message to ProgressDialog.Sync.FinalMessage.ErrorMessage.Message
+ }
+ else if (FinalMessage.OkMessage.Message)
+ {
+ set message to ProgressDialog.Sync.FinalMessage.OkMessage
+ }
+
+ PostMsg(kCloseMessage);
+}
+
+
+CProgressDialog::OnExternalCloseMessage()
+{
+ if (ProgressDialog.Sync.FinalMessage)
+ {
+ WorkWasFinishedVirt();
+ Show (ProgressDialog.Sync.FinalMessage)
+ MessagesDisplayed = true;
+ }
+}
+
+*/
+
#endif
diff --git a/CPP/7zip/UI/FileManager/resource.rc b/CPP/7zip/UI/FileManager/resource.rc
index a166129b..6d259eb0 100644
--- a/CPP/7zip/UI/FileManager/resource.rc
+++ b/CPP/7zip/UI/FileManager/resource.rc
@@ -247,6 +247,7 @@ END
#include "BrowseDialog.rc"
#include "ComboDialog.rc"
#include "CopyDialog.rc"
+#include "EditDialog.rc"
#include "EditPage.rc"
#include "FoldersPage.rc"
#include "LangPage.rc"
diff --git a/CPP/7zip/UI/GUI/7zG.exe.manifest b/CPP/7zip/UI/GUI/7zG.exe.manifest
index 68c6047e..39f516cd 100644
--- a/CPP/7zip/UI/GUI/7zG.exe.manifest
+++ b/CPP/7zip/UI/GUI/7zG.exe.manifest
@@ -5,6 +5,13 @@
<dependency>
<dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly>
</dependency>
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
+<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+</application></compatibility>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp
index 5071d1f0..814415f6 100644
--- a/CPP/7zip/UI/GUI/ExtractGUI.cpp
+++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp
@@ -52,22 +52,9 @@ static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColo
static void AddSizePair(UString &s, UINT resourceID, UInt64 value)
{
- {
- wchar_t sz[32];
- AddLangString(s, resourceID);
- s += ": ";
- ConvertUInt64ToString(value, sz);
- s += MyFormatNew(IDS_FILE_SIZE, sz);
- }
- // s += sz;
- if (value >= (1 << 20))
- {
- char sz[32];
- ConvertUInt64ToString(value >> 20, sz);
- s += " (";
- s += sz;
- s += " MB)";
- }
+ AddLangString(s, resourceID);
+ s += ": ";
+ AddSizeValue(s, value);
s.Add_LF();
}
@@ -86,16 +73,31 @@ public:
UStringVector *ArchivePathsFull;
const NWildcard::CCensorNode *WildcardCensor;
const CExtractOptions *Options;
+
#ifndef _SFX
CHashBundle *HashBundle;
+ virtual void ProcessWasFinished_GuiVirt();
#endif
+
CMyComPtr<IExtractCallbackUI> ExtractCallback;
UString Title;
+
+ CPropNameValPairs Pairs;
};
+
+#ifndef _SFX
+void CThreadExtracting::ProcessWasFinished_GuiVirt()
+{
+ if (HashBundle && !Pairs.IsEmpty())
+ ShowHashResults(Pairs, *this);
+}
+#endif
+
HRESULT CThreadExtracting::ProcessVirt()
{
CDecompressStat Stat;
+
#ifndef _SFX
if (HashBundle)
HashBundle->Init();
@@ -109,16 +111,23 @@ HRESULT CThreadExtracting::ProcessVirt()
HashBundle,
#endif
FinalMessage.ErrorMessage.Message, Stat);
+
#ifndef _SFX
- if (res == S_OK && Options->TestMode && ExtractCallbackSpec->IsOK())
+ if (res == S_OK && ExtractCallbackSpec->IsOK())
{
- UString s;
+ if (HashBundle)
+ {
+ AddValuePair(Pairs, IDS_ARCHIVES_COLON, Stat.NumArchives);
+ AddSizeValuePair(Pairs, IDS_PROP_PACKED_SIZE, Stat.PackSize);
+ AddHashBundleRes(Pairs, *HashBundle, UString());
+ }
+ else if (Options->TestMode)
+ {
+ UString s;
- AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false);
- AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize);
+ AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false);
+ AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize);
- if (!HashBundle)
- {
if (Stat.NumFolders != 0)
AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders);
AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles);
@@ -129,24 +138,19 @@ HRESULT CThreadExtracting::ProcessVirt()
AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams);
AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize);
}
- }
-
- if (HashBundle)
- {
s.Add_LF();
- AddHashBundleRes(s, *HashBundle, UString());
+ AddLangString(s, IDS_MESSAGE_NO_ERRORS);
+ FinalMessage.OkMessage.Title = Title;
+ FinalMessage.OkMessage.Message = s;
}
-
- s.Add_LF();
- AddLangString(s, IDS_MESSAGE_NO_ERRORS);
-
- FinalMessage.OkMessage.Title = Title;
- FinalMessage.OkMessage.Message = s;
}
#endif
+
return res;
}
+
+
HRESULT ExtractGUI(
CCodecs *codecs,
const CObjectVector<COpenType> &formatIndices,
@@ -252,11 +256,11 @@ HRESULT ExtractGUI(
extracter.Title = title;
extracter.ExtractCallbackSpec = extractCallback;
- extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog;
+ extracter.ExtractCallbackSpec->ProgressDialog = &extracter;
extracter.ExtractCallback = extractCallback;
extracter.ExtractCallbackSpec->Init();
- extracter.ProgressDialog.CompressingMode = false;
+ extracter.CompressingMode = false;
extracter.ArchivePaths = &archivePaths;
extracter.ArchivePathsFull = &archivePathsFull;
@@ -266,10 +270,9 @@ HRESULT ExtractGUI(
extracter.HashBundle = hb;
#endif
- extracter.ProgressDialog.IconID = IDI_ICON;
+ extracter.IconID = IDI_ICON;
RINOK(extracter.Create(title, hwndParent));
- messageWasDisplayed = extracter.ThreadFinishedOK &
- extracter.ProgressDialog.MessagesDisplayed;
+ messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed;
return extracter.Result;
}
diff --git a/CPP/7zip/UI/GUI/GUI.cpp b/CPP/7zip/UI/GUI/GUI.cpp
index 6bbfb740..2708fbd7 100644
--- a/CPP/7zip/UI/GUI/GUI.cpp
+++ b/CPP/7zip/UI/GUI/GUI.cpp
@@ -6,8 +6,6 @@
#include <shlwapi.h>
-#include "../../../../C/Alloc.h"
-
#include "../../../Common/MyInitGuid.h"
#include "../../../Common/CommandLineParser.h"
@@ -16,9 +14,6 @@
#include "../../../Windows/FileDir.h"
#include "../../../Windows/NtCheck.h"
-#ifdef _WIN32
-#include "../../../Windows/MemoryLock.h"
-#endif
#include "../Common/ArchiveCommandLine.h"
#include "../Common/ExitCode.h"
@@ -37,8 +32,6 @@ using namespace NWindows;
HINSTANCE g_hInstance;
-bool g_LargePagesMode = false;
-
#ifndef UNDER_CE
DWORD g_ComCtl32Version;
@@ -126,24 +119,6 @@ static int Main2()
parser.Parse1(commandStrings, options);
parser.Parse2(options);
- #if defined(_WIN32) && !defined(UNDER_CE)
- NSecurity::EnablePrivilege_SymLink();
- #endif
-
- #ifdef _7ZIP_LARGE_PAGES
- if (options.LargePages)
- {
- SetLargePageSize();
- // note: this process also can inherit that Privilege from parent process
- g_LargePagesMode =
- #if defined(_WIN32) && !defined(UNDER_CE)
- NSecurity::EnablePrivilege_LockMemory();
- #else
- true;
- #endif
- }
- #endif
-
CREATE_CODECS_OBJECT
codecs->CaseSensitiveChange = options.CaseSensitiveChange;
@@ -403,7 +378,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
{
return ShowMemErrorMessage();
}
- catch(const CArcCmdLineException &e)
+ catch(const CMessagePathException &e)
{
ErrorMessage(e);
return NExitCode::kUserError;
diff --git a/CPP/7zip/UI/GUI/GUI.dsp b/CPP/7zip/UI/GUI/GUI.dsp
index c022088e..52d6ac46 100644
--- a/CPP/7zip/UI/GUI/GUI.dsp
+++ b/CPP/7zip/UI/GUI/GUI.dsp
@@ -425,6 +425,14 @@ SOURCE=.\CompressDialog.h
# End Source File
# Begin Source File
+SOURCE=..\FileManager\EditDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\FileManager\EditDialog.h
+# End Source File
+# Begin Source File
+
SOURCE=.\ExtractDialog.cpp
# End Source File
# Begin Source File
@@ -433,6 +441,14 @@ SOURCE=.\ExtractDialog.h
# End Source File
# Begin Source File
+SOURCE=..\FileManager\ListViewDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\FileManager\ListViewDialog.h
+# End Source File
+# Begin Source File
+
SOURCE=..\FileManager\OverwriteDialog.cpp
# End Source File
# Begin Source File
@@ -975,6 +991,14 @@ SOURCE=..\..\..\Windows\Control\Static.h
# End Group
# Begin Source File
+SOURCE=..\..\..\Windows\Clipboard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Clipboard.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\COM.h
# End Source File
# Begin Source File
@@ -1051,6 +1075,14 @@ SOURCE=..\..\..\Windows\FileSystem.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Windows\MemoryGlobal.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryGlobal.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\MemoryLock.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/UI/GUI/HashGUI.cpp b/CPP/7zip/UI/GUI/HashGUI.cpp
index cc93f07e..7cb00973 100644
--- a/CPP/7zip/UI/GUI/HashGUI.cpp
+++ b/CPP/7zip/UI/GUI/HashGUI.cpp
@@ -9,6 +9,7 @@
#include "../FileManager/FormatUtils.h"
#include "../FileManager/LangUtils.h"
+#include "../FileManager/ListViewDialog.h"
#include "../FileManager/OverwriteDialogRes.h"
#include "../FileManager/ProgressDialog2.h"
#include "../FileManager/ProgressDialog2Res.h"
@@ -19,13 +20,18 @@
using namespace NWindows;
+
+
class CHashCallbackGUI: public CProgressThreadVirt, public IHashCallbackUI
{
UInt64 NumFiles;
bool _curIsFolder;
UString FirstFileName;
+ CPropNameValPairs PropNameValPairs;
+
HRESULT ProcessVirt();
+ virtual void ProcessWasFinished_GuiVirt();
public:
const NWildcard::CCensor *censor;
@@ -40,49 +46,62 @@ public:
void AddErrorMessage(DWORD systemError, const wchar_t *name)
{
- ProgressDialog.Sync.AddError_Code_Name(systemError, name);
+ Sync.AddError_Code_Name(systemError, name);
}
};
-static void AddValuePair(UString &s, UINT resourceID, UInt64 value)
+
+void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value)
{
- AddLangString(s, resourceID);
- s += ": ";
+ CProperty &pair = pairs.AddNew();
+ AddLangString(pair.Name, resourceID);
char sz[32];
ConvertUInt64ToString(value, sz);
- s += sz;
- s.Add_LF();
+ pair.Value = sz;
}
-static void AddSizeValuePair(UString &s, UINT resourceID, UInt64 value)
+
+void AddSizeValue(UString &s, UInt64 value)
{
- AddLangString(s, resourceID);
- s += ": ";
{
wchar_t sz[32];
ConvertUInt64ToString(value, sz);
s += MyFormatNew(IDS_FILE_SIZE, sz);
}
+ if (value >= (1 << 10))
{
+ char c;
+ if (value >= ((UInt64)10 << 30)) { value >>= 30; c = 'G'; }
+ if (value >= (10 << 20)) { value >>= 20; c = 'M'; }
+ else { value >>= 10; c = 'K'; }
char sz[32];
- ConvertUInt64ToString(value >> 20, sz);
+ ConvertUInt64ToString(value, sz);
s += " (";
s += sz;
- s += " MB)";
- s.Add_LF();
+ s += " ";
+ s += (wchar_t)c;
+ s += "iB)";
}
}
+void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value)
+{
+ CProperty &pair = pairs.AddNew();
+ LangString(resourceID, pair.Name);
+ AddSizeValue(pair.Value, value);
+}
+
+
HRESULT CHashCallbackGUI::StartScanning()
{
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
sync.Set_Status(LangString(IDS_SCANNING));
return CheckBreak();
}
HRESULT CHashCallbackGUI::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir)
{
- return ProgressDialog.Sync.ScanProgress(st.NumFiles, st.GetTotalBytes(), path, isDir);
+ return Sync.ScanProgress(st.NumFiles, st.GetTotalBytes(), path, isDir);
}
HRESULT CHashCallbackGUI::ScanError(const FString &path, DWORD systemError)
@@ -98,26 +117,26 @@ HRESULT CHashCallbackGUI::FinishScanning(const CDirItemsStat &st)
HRESULT CHashCallbackGUI::CheckBreak()
{
- return ProgressDialog.Sync.CheckStop();
+ return Sync.CheckStop();
}
HRESULT CHashCallbackGUI::SetNumFiles(UInt64 numFiles)
{
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
sync.Set_NumFilesTotal(numFiles);
return CheckBreak();
}
HRESULT CHashCallbackGUI::SetTotal(UInt64 size)
{
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
sync.Set_NumBytesTotal(size);
return CheckBreak();
}
HRESULT CHashCallbackGUI::SetCompleted(const UInt64 *completed)
{
- return ProgressDialog.Sync.Set_NumBytesCur(completed);
+ return Sync.Set_NumBytesCur(completed);
}
HRESULT CHashCallbackGUI::BeforeFirstFile(const CHashBundle & /* hb */)
@@ -130,7 +149,7 @@ HRESULT CHashCallbackGUI::GetStream(const wchar_t *name, bool isFolder)
if (NumFiles == 0)
FirstFileName = name;
_curIsFolder = isFolder;
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
sync.Set_FilePath(name, isFolder);
return CheckBreak();
}
@@ -147,49 +166,47 @@ HRESULT CHashCallbackGUI::OpenFileError(const FString &path, DWORD systemError)
HRESULT CHashCallbackGUI::SetOperationResult(UInt64 /* fileSize */, const CHashBundle & /* hb */, bool /* showHash */)
{
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
if (!_curIsFolder)
NumFiles++;
sync.Set_NumFilesCur(NumFiles);
return CheckBreak();
}
-static void AddHashString(UString &s, const CHasherState &h, unsigned digestIndex, const wchar_t *title)
+static void AddHashString(CProperty &s, const CHasherState &h, unsigned digestIndex)
{
- s += title;
- s.Add_Space();
char temp[k_HashCalc_DigestSize_Max * 2 + 4];
AddHashHexToString(temp, h.Digests[digestIndex], h.DigestSize);
- s += temp;
- s.Add_LF();
+ s.Value = temp;
}
-static void AddHashResString(UString &s, const CHasherState &h, unsigned digestIndex, UInt32 resID)
+static void AddHashResString(CPropNameValPairs &s, const CHasherState &h, unsigned digestIndex, UInt32 resID)
{
- UString s2 = LangString(resID);
+ CProperty &pair = s.AddNew();
+ UString &s2 = pair.Name;
+ LangString(resID, s2);
UString name (h.Name);
s2.Replace(L"CRC", name);
- AddHashString(s, h, digestIndex, s2);
+ s2.Replace(L":", L"");
+ AddHashString(pair, h, digestIndex);
}
-void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName)
+
+void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString &firstFileName)
{
if (hb.NumErrors != 0)
- {
AddValuePair(s, IDS_PROP_NUM_ERRORS, hb.NumErrors);
- s.Add_LF();
- }
if (hb.NumFiles == 1 && hb.NumDirs == 0 && !firstFileName.IsEmpty())
{
- AddLangString(s, IDS_PROP_NAME);
- s += ": ";
- s += firstFileName;
- s.Add_LF();
+ CProperty &pair = s.AddNew();
+ LangString(IDS_PROP_NAME, pair.Name);
+ pair.Value = firstFileName;
}
else
{
- AddValuePair(s, IDS_PROP_FOLDERS, hb.NumDirs);
+ if (hb.NumDirs != 0)
+ AddValuePair(s, IDS_PROP_FOLDERS, hb.NumDirs);
AddValuePair(s, IDS_PROP_FILES, hb.NumFiles);
}
@@ -197,25 +214,18 @@ void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFil
if (hb.NumAltStreams != 0)
{
- s.Add_LF();
AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, hb.NumAltStreams);
AddSizeValuePair(s, IDS_PROP_ALT_STREAMS_SIZE, hb.AltStreamsSize);
}
- if (hb.NumErrors == 0 && hb.Hashers.IsEmpty())
- {
- s.Add_LF();
- AddLangString(s, IDS_MESSAGE_NO_ERRORS);
- }
-
FOR_VECTOR (i, hb.Hashers)
{
- s.Add_LF();
const CHasherState &h = hb.Hashers[i];
if (hb.NumFiles == 1 && hb.NumDirs == 0)
{
- s += h.Name;
- AddHashString(s, h, k_HashCalc_Index_DataSum, L":");
+ CProperty &pair = s.AddNew();
+ pair.Name += h.Name;
+ AddHashString(pair, h, k_HashCalc_Index_DataSum);
}
else
{
@@ -229,32 +239,55 @@ void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFil
}
}
+
+void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName)
+{
+ CPropNameValPairs pairs;
+ AddHashBundleRes(pairs, hb, firstFileName);
+
+ FOR_VECTOR (i, pairs)
+ {
+ const CProperty &pair = pairs[i];
+ s += pair.Name;
+ s += ": ";
+ s += pair.Value;
+ s.Add_LF();
+ }
+
+ if (hb.NumErrors == 0 && hb.Hashers.IsEmpty())
+ {
+ s.Add_LF();
+ AddLangString(s, IDS_MESSAGE_NO_ERRORS);
+ s.Add_LF();
+ }
+}
+
+
HRESULT CHashCallbackGUI::AfterLastFile(const CHashBundle &hb)
{
- UString s;
- AddHashBundleRes(s, hb, FirstFileName);
+ AddHashBundleRes(PropNameValPairs, hb, FirstFileName);
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
sync.Set_NumFilesCur(hb.NumFiles);
- CProgressMessageBoxPair &pair = GetMessagePair(hb.NumErrors != 0);
- pair.Message = s;
- LangString(IDS_CHECKSUM_INFORMATION, pair.Title);
+ // CProgressMessageBoxPair &pair = GetMessagePair(hb.NumErrors != 0);
+ // pair.Message = s;
+ // LangString(IDS_CHECKSUM_INFORMATION, pair.Title);
return S_OK;
}
+
HRESULT CHashCallbackGUI::ProcessVirt()
{
NumFiles = 0;
-
AString errorInfo;
HRESULT res = HashCalc(EXTERNAL_CODECS_LOC_VARS
*censor, *options, errorInfo, this);
-
return res;
}
+
HRESULT HashCalcGUI(
DECL_EXTERNAL_CODECS_LOC_VARS
const NWildcard::CCensor &censor,
@@ -268,15 +301,49 @@ HRESULT HashCalcGUI(
t.censor = &censor;
t.options = &options;
- t.ProgressDialog.ShowCompressionInfo = false;
+ t.ShowCompressionInfo = false;
const UString title = LangString(IDS_CHECKSUM_CALCULATING);
- t.ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
- t.ProgressDialog.MainAddTitle = title;
- t.ProgressDialog.MainAddTitle.Add_Space();
+ t.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
+ t.MainAddTitle = title;
+ t.MainAddTitle.Add_Space();
RINOK(t.Create(title));
- messageWasDisplayed = t.ThreadFinishedOK && t.ProgressDialog.MessagesDisplayed;
+ messageWasDisplayed = t.ThreadFinishedOK && t.MessagesDisplayed;
return S_OK;
}
+
+
+void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd)
+{
+ CListViewDialog lv;
+
+ FOR_VECTOR (i, propPairs)
+ {
+ const CProperty &pair = propPairs[i];
+ lv.Strings.Add(pair.Name);
+ lv.Values.Add(pair.Value);
+ }
+
+ lv.Title = LangString(IDS_CHECKSUM_INFORMATION);
+ lv.DeleteIsAllowed = true;
+ lv.SelectFirst = false;
+ lv.NumColumns = 2;
+
+ lv.Create(hwnd);
+}
+
+
+void ShowHashResults(const CHashBundle &hb, const UString &firstFileName, HWND hwnd)
+{
+ CPropNameValPairs propPairs;
+ AddHashBundleRes(propPairs, hb, firstFileName);
+ ShowHashResults(propPairs, hwnd);
+}
+
+
+void CHashCallbackGUI::ProcessWasFinished_GuiVirt()
+{
+ ShowHashResults(PropNameValPairs, *this);
+}
diff --git a/CPP/7zip/UI/GUI/HashGUI.h b/CPP/7zip/UI/GUI/HashGUI.h
index 40340365..4035abf1 100644
--- a/CPP/7zip/UI/GUI/HashGUI.h
+++ b/CPP/7zip/UI/GUI/HashGUI.h
@@ -4,6 +4,7 @@
#define __HASH_GUI_H
#include "../Common/HashCalc.h"
+#include "../Common/Property.h"
HRESULT HashCalcGUI(
DECL_EXTERNAL_CODECS_LOC_VARS
@@ -11,6 +12,16 @@ HRESULT HashCalcGUI(
const CHashOptions &options,
bool &messageWasDisplayed);
+typedef CObjectVector<CProperty> CPropNameValPairs;
+
+void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value);
+void AddSizeValue(UString &s, UInt64 value);
+void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value);
+
+void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString &firstFileName);
void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName);
+void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd);
+void ShowHashResults(const CHashBundle &hb, const UString &firstFileName, HWND hwnd);
+
#endif
diff --git a/CPP/7zip/UI/GUI/UpdateGUI.cpp b/CPP/7zip/UI/GUI/UpdateGUI.cpp
index 261b1e2b..2e738d3a 100644
--- a/CPP/7zip/UI/GUI/UpdateGUI.cpp
+++ b/CPP/7zip/UI/GUI/UpdateGUI.cpp
@@ -460,7 +460,7 @@ HRESULT UpdateGUI(
tu.cmdArcPath = &cmdArcPath;
tu.UpdateCallbackGUI = callback;
- tu.UpdateCallbackGUI->ProgressDialog = &tu.ProgressDialog;
+ tu.UpdateCallbackGUI->ProgressDialog = &tu;
tu.UpdateCallbackGUI->Init();
UString title = LangString(IDS_PROGRESS_COMPRESSING);
@@ -476,10 +476,10 @@ HRESULT UpdateGUI(
tu.WildcardCensor = &censor;
tu.Options = &options;
- tu.ProgressDialog.IconID = IDI_ICON;
+ tu.IconID = IDI_ICON;
RINOK(tu.Create(title, hwndParent));
- messageWasDisplayed = tu.ThreadFinishedOK && tu.ProgressDialog.MessagesDisplayed;
+ messageWasDisplayed = tu.ThreadFinishedOK && tu.MessagesDisplayed;
return tu.Result;
}
diff --git a/CPP/7zip/UI/GUI/makefile b/CPP/7zip/UI/GUI/makefile
index bcafa0e5..ffab9abb 100644
--- a/CPP/7zip/UI/GUI/makefile
+++ b/CPP/7zip/UI/GUI/makefile
@@ -36,6 +36,7 @@ COMMON_OBJS = \
$O\Wildcard.obj \
WIN_OBJS = \
+ $O\Clipboard.obj \
$O\CommonDialog.obj \
$O\DLL.obj \
$O\ErrorMsg.obj \
@@ -45,6 +46,7 @@ WIN_OBJS = \
$O\FileLink.obj \
$O\FileName.obj \
$O\FileSystem.obj \
+ $O\MemoryGlobal.obj \
$O\MemoryLock.obj \
$O\PropVariant.obj \
$O\PropVariantConv.obj \
@@ -102,10 +104,12 @@ AR_COMMON_OBJS = \
$O\OutStreamWithCRC.obj \
FM_OBJS = \
+ $O\EditDialog.obj \
$O\ExtractCallback.obj \
$O\FormatUtils.obj \
$O\HelpUtils.obj \
$O\LangUtils.obj \
+ $O\ListViewDialog.obj \
$O\OpenCallback.obj \
$O\ProgramLocation.obj \
$O\PropertyName.obj \
diff --git a/CPP/7zip/UI/GUI/resource.rc b/CPP/7zip/UI/GUI/resource.rc
index 13a09c64..04af8157 100644
--- a/CPP/7zip/UI/GUI/resource.rc
+++ b/CPP/7zip/UI/GUI/resource.rc
@@ -21,3 +21,5 @@ IDI_ICON ICON "FM.ico"
#include "Extract.rc"
#include "../FileManager/BrowseDialog.rc"
#include "../FileManager/ComboDialog.rc"
+#include "../FileManager/EditDialog.rc"
+#include "../FileManager/ListViewDialog.rc"
diff --git a/CPP/Build.mak b/CPP/Build.mak
index d59578a5..5a11d066 100644
--- a/CPP/Build.mak
+++ b/CPP/Build.mak
@@ -82,8 +82,10 @@ LFLAGS = $(LFLAGS) /LARGEADDRESSAWARE
!IFDEF DEF_FILE
LFLAGS = $(LFLAGS) -DLL -DEF:$(DEF_FILE)
!ELSE
-!IF "$(CPU)" != "ARM" && "$(CPU)" != "ARM64"
+!IF defined(MY_FIXED) && "$(CPU)" != "ARM" && "$(CPU)" != "ARM64"
LFLAGS = $(LFLAGS) /FIXED
+!ELSE
+LFLAGS = $(LFLAGS) /FIXED:NO
!ENDIF
# /BASE:0x400000
!ENDIF
diff --git a/CPP/Common/MyString.h b/CPP/Common/MyString.h
index 1c7357e4..abdc8cf8 100644
--- a/CPP/Common/MyString.h
+++ b/CPP/Common/MyString.h
@@ -545,6 +545,8 @@ public:
void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
+ wchar_t *GetBuf() { return _chars; }
+
wchar_t *GetBuf(unsigned minLen)
{
if (minLen > _limit)
@@ -571,7 +573,7 @@ public:
}
UString &operator=(wchar_t c);
- UString &operator=(char c) { return (*this)=((wchar_t)c); }
+ UString &operator=(char c) { return (*this)=((wchar_t)(unsigned char)c); }
UString &operator=(const wchar_t *s);
UString &operator=(const UString &s);
void SetFrom(const wchar_t *s, unsigned len); // no check
diff --git a/CPP/Common/MyWindows.h b/CPP/Common/MyWindows.h
index a8db9e65..db3f35d8 100644
--- a/CPP/Common/MyWindows.h
+++ b/CPP/Common/MyWindows.h
@@ -16,6 +16,7 @@
#include <stddef.h> // for wchar_t
#include <string.h>
+// #include <stdint.h> // for uintptr_t
#include "MyGuidDef.h"
@@ -53,6 +54,8 @@ typedef long BOOL;
// typedef size_t ULONG_PTR;
typedef size_t DWORD_PTR;
+// typedef uintptr_t UINT_PTR;
+// typedef ptrdiff_t UINT_PTR;
typedef Int64 LONGLONG;
typedef UInt64 ULONGLONG;
@@ -81,6 +84,8 @@ typedef struct _FILETIME
typedef ULONG PROPID;
typedef LONG SCODE;
+#define ERROR_NEGATIVE_SEEK 131L
+
#define S_OK ((HRESULT)0x00000000L)
#define S_FALSE ((HRESULT)0x00000001L)
#define E_NOTIMPL ((HRESULT)0x80004001L)
diff --git a/CPP/Common/StdOutStream.cpp b/CPP/Common/StdOutStream.cpp
index 19e0329f..8236072d 100644
--- a/CPP/Common/StdOutStream.cpp
+++ b/CPP/Common/StdOutStream.cpp
@@ -75,6 +75,65 @@ void CStdOutStream::PrintUString(const UString &s, AString &temp)
*this << (const char *)temp;
}
+
+static const wchar_t kReplaceChar = '_';
+
+void CStdOutStream::Normalize_UString__LF_Allowed(UString &s)
+{
+ unsigned len = s.Len();
+ wchar_t *d = s.GetBuf();
+
+ if (IsTerminalMode)
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = d[i];
+ if (c <= 13 && c >= 7 && c != '\n')
+ d[i] = kReplaceChar;
+ }
+}
+
+void CStdOutStream::Normalize_UString(UString &s)
+{
+ unsigned len = s.Len();
+ wchar_t *d = s.GetBuf();
+
+ if (IsTerminalMode)
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = d[i];
+ if (c <= 13 && c >= 7)
+ d[i] = kReplaceChar;
+ }
+ else
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = d[i];
+ if (c == '\n')
+ d[i] = kReplaceChar;
+ }
+}
+
+void CStdOutStream::NormalizePrint_UString(const UString &s, UString &tempU, AString &tempA)
+{
+ tempU = s;
+ Normalize_UString(tempU);
+ PrintUString(tempU, tempA);
+}
+
+void CStdOutStream::NormalizePrint_UString(const UString &s)
+{
+ NormalizePrint_wstr(s);
+}
+
+void CStdOutStream::NormalizePrint_wstr(const wchar_t *s)
+{
+ UString tempU = s;
+ Normalize_UString(tempU);
+ AString tempA;
+ PrintUString(tempU, tempA);
+}
+
+
CStdOutStream & CStdOutStream::operator<<(Int32 number) throw()
{
char s[32];
diff --git a/CPP/Common/StdOutStream.h b/CPP/Common/StdOutStream.h
index 1837bfb0..2e637e8f 100644
--- a/CPP/Common/StdOutStream.h
+++ b/CPP/Common/StdOutStream.h
@@ -13,7 +13,9 @@ class CStdOutStream
FILE *_stream;
bool _streamIsOpen;
public:
- CStdOutStream(): _stream(0), _streamIsOpen(false) {};
+ bool IsTerminalMode;
+
+ CStdOutStream(): _stream(0), _streamIsOpen(false), IsTerminalMode(false) {};
CStdOutStream(FILE *stream): _stream(stream), _streamIsOpen(false) {};
~CStdOutStream() { Close(); }
@@ -50,6 +52,13 @@ public:
CStdOutStream & operator<<(const wchar_t *s);
void PrintUString(const UString &s, AString &temp);
+
+ void Normalize_UString__LF_Allowed(UString &s);
+ void Normalize_UString(UString &s);
+
+ void NormalizePrint_UString(const UString &s, UString &tempU, AString &tempA);
+ void NormalizePrint_UString(const UString &s);
+ void NormalizePrint_wstr(const wchar_t *s);
};
CStdOutStream & endl(CStdOutStream & outStream) throw();
diff --git a/CPP/Windows/Control/Dialog.cpp b/CPP/Windows/Control/Dialog.cpp
index 9df3ef5e..020694a6 100644
--- a/CPP/Windows/Control/Dialog.cpp
+++ b/CPP/Windows/Control/Dialog.cpp
@@ -72,6 +72,7 @@ bool CDialog::OnButtonClicked(int buttonID, HWND /* buttonHWND */)
{
case IDOK: OnOK(); break;
case IDCANCEL: OnCancel(); break;
+ case IDCLOSE: OnClose(); break;
case IDHELP: OnHelp(); break;
default: return false;
}
diff --git a/CPP/Windows/Control/Dialog.h b/CPP/Windows/Control/Dialog.h
index 59b9f419..33caa5b2 100644
--- a/CPP/Windows/Control/Dialog.h
+++ b/CPP/Windows/Control/Dialog.h
@@ -105,6 +105,7 @@ public:
virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
virtual void OnOK() {};
virtual void OnCancel() {};
+ virtual void OnClose() {}
virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */) { return false; }
virtual bool OnTimer(WPARAM /* timerID */, LPARAM /* callback */) { return false; }
@@ -133,6 +134,7 @@ public:
#endif
virtual void OnOK() { Destroy(); }
virtual void OnCancel() { Destroy(); }
+ virtual void OnClose() { Destroy(); }
};
class CModalDialog: public CDialog
@@ -147,6 +149,7 @@ public:
bool End(INT_PTR result) { return BOOLToBool(::EndDialog(_window, result)); }
virtual void OnOK() { End(IDOK); }
virtual void OnCancel() { End(IDCANCEL); }
+ virtual void OnClose() { End(IDCLOSE); }
};
class CDialogChildControl: public NWindows::CWindow
diff --git a/CPP/Windows/MemoryLock.cpp b/CPP/Windows/MemoryLock.cpp
index b628a03e..8d2134b1 100644
--- a/CPP/Windows/MemoryLock.cpp
+++ b/CPP/Windows/MemoryLock.cpp
@@ -67,6 +67,31 @@ bool EnablePrivilege(LPCTSTR privilegeName, bool enable)
return res;
}
+
+
+typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *);
+
+/*
+ We suppose that Window 10 works incorrectly with "Large Pages" at:
+ - Windows 10 1703 (15063)
+ - Windows 10 1709 (16299)
+*/
+
+unsigned Get_LargePages_RiskLevel()
+{
+ OSVERSIONINFOEXW vi;
+ HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll");
+ if (!ntdll)
+ return 0;
+ Func_RtlGetVersion func = (Func_RtlGetVersion)GetProcAddress(ntdll, "RtlGetVersion");
+ if (!func)
+ return 0;
+ func(&vi);
+ return (vi.dwPlatformId == VER_PLATFORM_WIN32_NT
+ && vi.dwMajorVersion + vi.dwMinorVersion == 10
+ && vi.dwBuildNumber <= 16299) ? 1 : 0;
+}
+
#endif
}}
diff --git a/CPP/Windows/MemoryLock.h b/CPP/Windows/MemoryLock.h
index 4a5dafcf..dcaf182e 100644
--- a/CPP/Windows/MemoryLock.h
+++ b/CPP/Windows/MemoryLock.h
@@ -31,6 +31,8 @@ inline void EnablePrivilege_SymLink()
// Do we need to set SE_BACKUP_NAME ?
}
+unsigned Get_LargePages_RiskLevel();
+
#endif
}}
diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp
index c000e628..a2893131 100644
--- a/CPP/Windows/Registry.cpp
+++ b/CPP/Windows/Registry.cpp
@@ -152,7 +152,7 @@ LONG CKey::SetValue(LPCWSTR name, LPCWSTR value)
MYASSERT(value != NULL);
MYASSERT(_object != NULL);
if (g_IsNT)
- return RegSetValueExW(_object, name, NULL, REG_SZ,
+ return RegSetValueExW(_object, name, 0, REG_SZ,
(const BYTE * )value, (DWORD)((wcslen(value) + 1) * sizeof(wchar_t)));
return SetValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name),
value == 0 ? 0 : (LPCSTR)GetSystemString(value));
diff --git a/DOC/7zip.inf b/DOC/7zip.inf
index 0062a907..6fc1e064 100644
--- a/DOC/7zip.inf
+++ b/DOC/7zip.inf
@@ -10,8 +10,8 @@ AppName = "7-Zip"
InstallDir = %CE1%\%AppName%
[Strings]
-AppVer = "18.03"
-AppDate = "2018-03-04"
+AppVer = "18.05"
+AppDate = "2018-04-30"
[CEDevice]
; ProcessorType = 2577 ; ARM
diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi
index 91554ec4..fcb8952e 100644
--- a/DOC/7zip.nsi
+++ b/DOC/7zip.nsi
@@ -2,7 +2,7 @@
;Defines
!define VERSION_MAJOR 18
-!define VERSION_MINOR 03
+!define VERSION_MINOR 05
!define VERSION_POSTFIX_FULL ""
!ifdef WIN64
!ifdef IA64
diff --git a/DOC/7zip.wxs b/DOC/7zip.wxs
index 5f7896c1..04eb2605 100644
--- a/DOC/7zip.wxs
+++ b/DOC/7zip.wxs
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<?define VerMajor = "18" ?>
-<?define VerMinor = "03" ?>
+<?define VerMinor = "05" ?>
<?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?>
diff --git a/DOC/lzma.txt b/DOC/lzma.txt
index 87d727b5..a65988fe 100644
--- a/DOC/lzma.txt
+++ b/DOC/lzma.txt
@@ -33,7 +33,7 @@ If you want to use old interfaces you can download previous version of LZMA SDK
from sourceforge.net site.
To use ANSI-C LZMA Decoder you need the following files:
-1) LzmaDec.h + LzmaDec.c + Types.h
+1) LzmaDec.h + LzmaDec.c + 7zTypes.h + Precomp.h + Compiler.h
Look example code:
C/Util/Lzma/LzmaUtil.c
@@ -70,7 +70,7 @@ You can use p = p; operator to disable compiler warnings.
Single-call Decompressing
-------------------------
When to use: RAM->RAM decompressing
-Compile files: LzmaDec.h + LzmaDec.c + Types.h
+Compile files: LzmaDec.h + LzmaDec.c + 7zTypes.h
Compile defines: no defines
Memory Requirements:
- Input buffer: compressed size
@@ -124,7 +124,7 @@ Multi-call State Decompressing (zlib-like interface)
----------------------------------------------------
When to use: file->file decompressing
-Compile files: LzmaDec.h + LzmaDec.c + Types.h
+Compile files: LzmaDec.h + LzmaDec.c + 7zTypes.h
Memory Requirements:
- Buffer for input stream: any size (for example, 16 KB)
@@ -167,7 +167,7 @@ How To compress data
--------------------
Compile files:
- Types.h
+ 7zTypes.h
Threads.h
LzmaEnc.h
LzmaEnc.c
diff --git a/DOC/readme.txt b/DOC/readme.txt
index 53596c11..4cba88e6 100644
--- a/DOC/readme.txt
+++ b/DOC/readme.txt
@@ -1,4 +1,4 @@
-7-Zip 18.03 Sources
+7-Zip 18.05 Sources
-------------------
7-Zip is a file archiver for Windows.
diff --git a/DOC/src-history.txt b/DOC/src-history.txt
index f89dba04..d2bdd77f 100644
--- a/DOC/src-history.txt
+++ b/DOC/src-history.txt
@@ -1,6 +1,16 @@
HISTORY of the 7-Zip source code
--------------------------------
+18.05 2018-04-30
+-------------------------
+- The speed for LZMA/LZMA2 compressing was increased
+ by 8% for fastest/fast compression levels and
+ by 3% for normal/maximum compression levels.
+- Previous versions of 7-Zip could work incorrectly in "Large memory pages" mode in
+ Windows 10 because of some BUG with "Large Pages" in Windows 10.
+ Now 7-Zip doesn't use "Large Pages" on Windows 10 up to revision 1709 (16299).
+
+
18.03 beta 2018-03-04
-------------------------
- Asm\x86\LzmaDecOpt.asm: new optimized LZMA decoder written in asm